Skip to content

Add API to get ipv6 link local address #11279

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions TESTS/network/interface/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,10 +155,14 @@ Test `NetworkInterface::get_connection_status()`.
1. Check that `get_connection_status()` returns status `NSAPI_STATUS_DISCONNECTED`.
2. Connect interface.
3. Poll the `get_connection_status()` until it returns status `NSAPI_STATUS_GLOBAL_UP`.
4. Disconnect interface.
5. Check that `get_connection_status()` returns status `NSAPI_STATUS_DISCONNECTED`.
6. Repeat connect and disconnect steps 2 to 5 four times.
4. (IPv6 only) Get IPv6 link local address using `get_ipv6_link_local_address` API.
5. (IPv6 only) Check that `get_ipv6_link_local_address` returned status `NSAPI_ERROR_OK`.
6. (IPv6 only) Check that the IP address associated with the Socket Address is not `NULL`.
7. (IPv6 only) Check that the IP version of the IPv6 link local address is `NSAPI_IPv6`.
8. Disconnect interface.
9. Check that `get_connection_status()` returns status `NSAPI_STATUS_DISCONNECTED`.
10. Repeat connect and disconnect steps 2 to 5 four times.

**Expected result:**

`Connect()` and `disconnect()` calls return `NSAPI_ERROR_OK`. The right status is returned by `get_connection_status()`.
`Connect()`, `get_ipv6_link_local_address` and `disconnect()` calls return `NSAPI_ERROR_OK`. The right status is returned by `get_connection_status()`. And the right IPv6 link local address is returned by `get_ipv6_link_local_address`.
9 changes: 9 additions & 0 deletions TESTS/network/interface/networkinterface_status.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,15 @@ void NETWORKINTERFACE_STATUS_GET()
ThisThread::sleep_for(500);
}

#if MBED_CONF_LWIP_IPV6_ENABLED
/* if IPv6 is enabled, validate ipv6_link_local_address API*/
SocketAddress ipv6_link_local_address = NULL;
err = net->get_ipv6_link_local_address(&ipv6_link_local_address);
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);
TEST_ASSERT_NOT_NULL(ipv6_link_local_address.get_ip_address());
TEST_ASSERT_EQUAL(NSAPI_IPv6, ipv6_link_local_address.get_ip_version());
#endif

err = net->disconnect();
TEST_ASSERT_EQUAL(NSAPI_ERROR_OK, err);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class EmacNetworkStackMock : public OnboardNetworkStack {
MOCK_CONST_METHOD0(get_connection_status, nsapi_connection_status_t());
MOCK_METHOD2(get_mac_address, char *(char *buf, nsapi_size_t buflen));
MOCK_METHOD2(get_ip_address, char *(char *buf, nsapi_size_t buflen));
MOCK_METHOD1(get_ipv6_link_local_address, nsapi_error_t(SocketAddress *address));
MOCK_METHOD2(get_netmask, char *(char *buf, nsapi_size_t buflen));
MOCK_METHOD2(get_gateway, char *(char *buf, nsapi_size_t buflen));
};
Expand Down
5 changes: 5 additions & 0 deletions UNITTESTS/stubs/NetworkInterface_stub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ const char *NetworkInterface::get_ip_address()
return 0;
}

nsapi_error_t NetworkInterface::get_ipv6_link_local_address(SocketAddress *address)
{
return NSAPI_ERROR_UNSUPPORTED;
}

const char *NetworkInterface::get_netmask()
{
return 0;
Expand Down
6 changes: 6 additions & 0 deletions UNITTESTS/stubs/NetworkStack_stub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ const char *NetworkStack::get_ip_address()
{
return NULL;
}

nsapi_error_t NetworkStack::get_ipv6_link_local_address(SocketAddress *address)
{
return NSAPI_ERROR_UNSUPPORTED;
}

const char *NetworkStack::get_ip_address_if(const char *interface_name)
{
return NULL;
Expand Down
25 changes: 25 additions & 0 deletions features/lwipstack/LWIPInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "lwip/udp.h"

#include "LWIPStack.h"
#include "lwip_tools.h"

LWIP::Interface *LWIP::Interface::list;

Expand Down Expand Up @@ -271,6 +272,30 @@ char *LWIP::Interface::get_interface_name(char *buf)
return buf;
}

nsapi_error_t LWIP::Interface::get_ipv6_link_local_address(SocketAddress *address)
{
#if LWIP_IPV6
const ip_addr_t *addr = LWIP::get_ipv6_link_local_addr(&netif);
nsapi_addr_t out;
bool ret;

if (!addr) {
return NSAPI_ERROR_PARAMETER;
}

ret = convert_lwip_addr_to_mbed(&out, addr);
if (ret != true) {
return NSAPI_ERROR_PARAMETER;
}

address->set_addr(out);

return NSAPI_ERROR_OK;
#else
return NSAPI_ERROR_UNSUPPORTED;
#endif
}

char *LWIP::Interface::get_ip_address(char *buf, nsapi_size_t buflen)
{
const ip_addr_t *addr = LWIP::get_ip_addr(true, &netif);
Expand Down
8 changes: 8 additions & 0 deletions features/lwipstack/LWIPStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,13 @@ class LWIP : public OnboardNetworkStack, private mbed::NonCopyable<LWIP> {
*/
virtual char *get_ip_address(char *buf, nsapi_size_t buflen);

/** Get the IPv6 link local address in SocketAddress representation
*
* @address SocketAddress representation of the link local IPv6 address
* @return NSAPI_ERROR_OK on success, or error code
*/
virtual nsapi_error_t get_ipv6_link_local_address(SocketAddress *address);

/** Copies IP address of the name based network interface to user supplied buffer
*
* @param buf buffer to which IP address will be copied as "W:X:Y:Z"
Expand Down Expand Up @@ -571,6 +578,7 @@ class LWIP : public OnboardNetworkStack, private mbed::NonCopyable<LWIP> {
static const ip_addr_t *get_ip_addr(bool any_addr, const struct netif *netif);
static const ip_addr_t *get_ipv4_addr(const struct netif *netif);
static const ip_addr_t *get_ipv6_addr(const struct netif *netif);
static const ip_addr_t *get_ipv6_link_local_addr(const struct netif *netif);

static void add_dns_addr(struct netif *lwip_netif, const char *interface_name);

Expand Down
17 changes: 17 additions & 0 deletions features/lwipstack/lwip_tools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,23 @@ const ip_addr_t *LWIP::get_ipv4_addr(const struct netif *netif)
return NULL;
}

const ip_addr_t *LWIP::get_ipv6_link_local_addr(const struct netif *netif)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this is here, instead of LWIPStack.cpp where rest of the LWIP class members are.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_ipv6_link_local_addr is a private function of the class. Public API's name is get_ipv6_link_local_address

{
#if LWIP_IPV6
if (!netif_is_up(netif)) {
return NULL;
}

for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
ip6_addr_islinklocal(netif_ip6_addr(netif, i))) {
return netif_ip_addr6(netif, i);
}
}
#endif
return NULL;
}

const ip_addr_t *LWIP::get_ipv6_addr(const struct netif *netif)
{
#if LWIP_IPV6
Expand Down
9 changes: 9 additions & 0 deletions features/netsocket/EMACInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,15 @@ const char *EMACInterface::get_ip_address()
return NULL;
}

nsapi_error_t EMACInterface::get_ipv6_link_local_address(SocketAddress *address)
{
if (_interface) {
return _interface->get_ipv6_link_local_address(address);
}

return NSAPI_ERROR_NO_CONNECTION;
}

const char *EMACInterface::get_netmask()
{
if (_interface && _interface->get_netmask(_netmask, sizeof(_netmask))) {
Expand Down
7 changes: 7 additions & 0 deletions features/netsocket/EMACInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,13 @@ class EMACInterface : public virtual NetworkInterface {
*/
virtual const char *get_ip_address();

/** Get the IPv6 link local address
*
* @address SocketAddress representation of the link local IPv6 address
* @return 0 on success, negative error code on failure
*/
virtual nsapi_error_t get_ipv6_link_local_address(SocketAddress *address);

/** Get the local network mask
*
* @return Null-terminated representation of the local network mask
Expand Down
5 changes: 5 additions & 0 deletions features/netsocket/NetworkInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ const char *NetworkInterface::get_ip_address()
return 0;
}

nsapi_error_t NetworkInterface::get_ipv6_link_local_address(SocketAddress *address)
{
return NSAPI_ERROR_UNSUPPORTED;
}

const char *NetworkInterface::get_netmask()
{
return 0;
Expand Down
7 changes: 7 additions & 0 deletions features/netsocket/NetworkInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,13 @@ class NetworkInterface: public DNS {
*/
virtual const char *get_ip_address();

/** Get the IPv6 link local address
*
* @address SocketAddress representation of the link local IPv6 address
* @return NSAPI_ERROR_OK on success, negative error code on failure
*/
virtual nsapi_error_t get_ipv6_link_local_address(SocketAddress *address);

/** Get the local network mask.
*
* @return Null-terminated representation of the local network mask
Expand Down
5 changes: 5 additions & 0 deletions features/netsocket/NetworkStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ const char *NetworkStack::get_ip_address()
return 0;
}

nsapi_error_t NetworkStack::get_ipv6_link_local_address(SocketAddress *address)
{
return NSAPI_ERROR_UNSUPPORTED;
}

const char *NetworkStack::get_ip_address_if(const char *interface_name)
{
return 0;
Expand Down
7 changes: 7 additions & 0 deletions features/netsocket/NetworkStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ class NetworkStack: public DNS {
*/
virtual const char *get_ip_address();

/** Get the IPv6 link local address
*
* @address SocketAddress representation of the link local IPv6 address
* @return NSAPI_ERROR_OK on success, negative error code on failure
*/
virtual nsapi_error_t get_ipv6_link_local_address(SocketAddress *address);

/** Get the local IP address on interface name
*
* @param interface_name Network interface_name
Expand Down
10 changes: 10 additions & 0 deletions features/netsocket/OnboardNetworkStack.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@ class OnboardNetworkStack : public NetworkStack {

virtual char *get_ip_address(char *buf, nsapi_size_t buflen) = 0;

/** Copies IPv6 link local address of the network interface in SocketAddress format
*
* @address SocketAddress representation of the link local IPv6 address
* @return NSAPI_ERROR_OK on success, negative error code on failure
*/
virtual nsapi_error_t get_ipv6_link_local_address(SocketAddress *address)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this here? There is a default implementation in NetworkInterface already for this

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some mesh interfaces, for example LoWPANNDInterface, don't inherit from NetworkInterface. Instead they are required to implement this Nanostack::Interface class, which is separate from NetworkInterface.
Not sure about the reason behind this duplication, perhaps NetworkInterface didn't always match the Nanostack's interface? We somehow don't impose the implementation of connect or disconnect and I can see LoWPANNDInterface implements its own mesh_connect()

{
return NSAPI_ERROR_UNSUPPORTED;
}

/** Copies IP address of the network interface to user supplied buffer
*
* @param buf buffer to which IP address will be copied as "W:X:Y:Z"
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.