-
Notifications
You must be signed in to change notification settings - Fork 3k
Multihoming initial release #9387
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
Conversation
@SeppoTakalo please review |
@tymoteuszblochmobica Please add a description to this PR, as it's completely unclear what this is. Also, please take a look at the |
@tymoteuszblochmobica, thank you for your changes. |
This needs description here in the first commit but more importantly in the commit message. Introducing a new functionality change . |
c5fb7f8
to
5782d1b
Compare
ea0fdb7
to
d62a3f0
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @tymoteuszblochmobica
Left couple of questions and suggestions...
features/netsocket/nsapi_types.h
Outdated
@@ -127,10 +127,14 @@ typedef enum nsapi_security { | |||
NSAPI_SECURITY_UNKNOWN = 0xFF, /*!< unknown/unsupported security in scan results */ | |||
} nsapi_security_t; | |||
|
|||
/** Maximum size of network interface name | |||
/** Size of 2 char network interface name from driver | |||
*/ | |||
#define NSAPI_INTERFACE_NAME_SIZE 2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this actually a networkinterface name prefix instead of full name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes this is a 2 char prefix from network driver.LWIP netif_add appends 8bit sequence number so range 0-255 takes 3 chars plus '\0' gives 6 char total string length
features/netsocket/nsapi_dns.cpp
Outdated
query->interface_name = NULL; | ||
} else { | ||
query->interface_name = interface_name; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This if-else is not needed.
Even if interface_name
is NULL, you can just do query->interface_name = interface_name;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
features/netsocket/SocketAddress.h
Outdated
{ | ||
_SocketAddress(nsapi_create_stack(stack), host, port); | ||
_SocketAddress(nsapi_create_stack(stack), host, port, interface_name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is deprecated function, can we just use NULL and not touch the API?
That way we would not need to touch the SocketAddress at all, just call gethostbyname()
with NULL interface.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
call_in_callback_cb_t call_in_cb = get_call_in_callback(); | ||
|
||
return nsapi_dns_query_async(this, name, callback, call_in_cb, interface_name, version); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is only one line difference to the function above, so can these two be combined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
} | ||
} | ||
|
||
return nsapi_dns_query(this, name, address, interface_name, version); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is only one line difference to the function above, so can these two be combined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
features/lwipstack/lwipopts.h
Outdated
@@ -340,6 +340,8 @@ | |||
#endif // MBED_CONF_LWIP_ETHERNET_ENABLED | |||
|
|||
#define LWIP_L3IP 0 | |||
//Maximum size of network interface name | |||
#define NETWORK_INTERFACE_NAME_MAX_SIZE 4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this is 4 and NSAPI_INTERFACE_NAME_MAX_SIZE is 6?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
@@ -136,6 +137,8 @@ enum lwip_internal_netif_client_data_index | |||
#define NETIF_CHECKSUM_DISABLE_ALL 0x0000 | |||
#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ | |||
|
|||
#define INTERFACE_NAME_SIZE 6 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use NSAPI_INTERFACE_NAME_MAX_SIZE
here? is it the same?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
INTERFACE_NAME_SIZE renamed to INTERFACE_NAME_MAX_SIZE
Modified lwipopts.h
#define INTERFACE_NAME_MAX_SIZE NSAPI_INTERFACE_NAME_MAX_SIZE to avoid including nsapi_types.h in lwip dns and netif
@@ -49,6 +49,12 @@ | |||
extern "C" { | |||
#endif | |||
|
|||
struct dns_server_interface { | |||
char interface_name [NETWORK_INTERFACE_NAME_MAX_SIZE]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the name is copied here instead of referring to const char *
?
I'm assuming that interface names do not change in run time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a local storage for DNS servers for each interface name
if (numdns < DNS_MAX_SERVERS) { | ||
return &dns_servers[numdns]; | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the comparison wrong way?
Documentation says must be < DNS_MAX_SERVERS
then you immediately return if that is true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mistake during whitespace correction. Fixed
@@ -47,6 +47,8 @@ | |||
*/ | |||
class ESP8266Interface : public NetworkStack, public WiFiInterface { | |||
public: | |||
using NetworkStack::get_ip_address; | |||
using WiFiInterface::connect; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we truly causing all external drivers to adapt to this new API?
We are not controlling all of those, so I would still consider whether this can be avoided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
d62a3f0
to
d699def
Compare
features/lwipstack/LWIPInterface.cpp
Outdated
@@ -457,6 +474,30 @@ nsapi_error_t LWIP::add_l3ip_interface(L3IP &l3ip, bool default_if, OnboardNetwo | |||
nsapi_error_t LWIP::remove_l3ip_interface(OnboardNetworkStack::Interface **interface_out) | |||
{ | |||
#if LWIP_L3IP | |||
if ((interface_out != NULL) && (*interface_out != NULL)) { | |||
|
|||
Interface *lwip = static_cast<Interface *>(*interface_out); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
extra space
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
* | ||
* @return netif name eg "en0" | ||
*/ | ||
virtual char *get_interface_name(char *buf); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this have buffer length as a parameter, also is returning the buffer needed?
{ | ||
struct netif *netif; | ||
s8_t i; | ||
|
||
if(interface_name !=NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
correct spaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
if (netif_default == netif) { | ||
return true; | ||
} else { | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -1911,13 +1911,14 @@ tcp_eff_send_mss_impl(u16_t sendmss, const ip_addr_t *dest | |||
#if LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING | |||
, const ip_addr_t *src | |||
#endif /* LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING */ | |||
, const char *interface_name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -49,6 +49,12 @@ | |||
extern "C" { | |||
#endif | |||
|
|||
struct dns_server_interface { | |||
char interface_name [INTERFACE_NAME_SIZE]; | |||
ip_addr_t dns_servers[DNS_MAX_SERVERS]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
features/lwipstack/lwipopts.h
Outdated
#define LWIP_L3IP 0 | ||
#define LWIP_L3IP 0 | ||
//Maximum size of network interface name | ||
#define INTERFACE_NAME_SIZE 6 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
spaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be defined to be NSAPI_INTERFACE_NAME_MAX_SIZE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
INTERFACE_NAME_SIZE renamed to INTERFACE_NAME_MAX_SIZE
Modified lwipopts.h
#define INTERFACE_NAME_MAX_SIZE NSAPI_INTERFACE_NAME_MAX_SIZE to avoid including nsapi_types.h in lwip dns and netif
* @param address Pointer to a SocketAddress to store the result. | ||
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates | ||
* @param interface_name Network interface name | ||
* version is chosen by the stack (defaults to NSAPI_UNSPEC). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
parameters are other way around in function prototype. Also move "version is chosen..."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
* @param address Pointer to a SocketAddress to store the result. | ||
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates | ||
* @param interface_name Network interface name | ||
* version is chosen by the stack (defaults to NSAPI_UNSPEC). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parameters are other way around, correct "version is..."
* @param callback Callback that is called for result. | ||
* @param version IP version of address to resolve, NSAPI_UNSPEC indicates | ||
* @param interface_name Network interface_name | ||
* version is chosen by the stack (defaults to NSAPI_UNSPEC). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same as above
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
48a5cf4
to
a3e6d5c
Compare
@@ -174,6 +174,9 @@ nsapi_error_t InternetSocket::setsockopt(int level, int optname, const void *opt | |||
ret = NSAPI_ERROR_NO_SOCKET; | |||
} else { | |||
ret = _stack->setsockopt(_socket, level, optname, optval, optlen); | |||
if (optname == NSAPI_BIND_TO_DEVICE && level == NSAPI_SOCKET) { | |||
strncpy(_interface_name, static_cast<const char *>(optval), optlen); | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should get cloud client input on this as well. We make the interface binding (of client socket) with options, where as linux uses the bind operation. Now they need to adapt to both options
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JanneKiiskila Mind having someone chime in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@yogpan01 @TeroJaasko @teetak01 @anttiylitokola to check it up, please.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now ready for integration, is there anything blocking ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it helps in any way, the mbed-client-testapp CI is passing fine with the most recent commit in this PR
The current DNS implementation my return IPv4 address over IPv6 network interface, if version is not explicitly given for |
@yogpan01 Who is the correct person from Client team to review this work? Basically we need opinion what do you think about Socket to use |
Too fast? I'll cancel the job (another force push) |
Test run: FAILEDSummary: 1 of 1 test jobs failed Failed test jobs:
|
bf3b3f4
to
84e0b9c
Compare
@0xc0170 , let's wait for @SeppoTakalo to double check if wiced binaries were built correctly. We've seen some failures in our local CI... |
Unittests now build and pass after API change |
Yesterday I made a mistake and pushed Wiced binaries build against master. I'll verify in CI, so wait a minute. |
Builds now. @0xc0170 This can now be tested. Thanks. |
CI restarted |
While in CI @mikaleppanen Can you review please? |
Test run: SUCCESSSummary: 12 of 12 test jobs passed |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could of things to follow up on, but seems fine.
} | ||
|
||
if (NETCONNTYPE_GROUP(s->conn->type) == NETCONN_TCP) { | ||
s->conn->pcb.tcp->interface_name = (const char *)optval; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This bends the setsockopt
API because it's not actually copying the option data. Can get away with it though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be refactored in LWIP 2.1.2.
New LWIP has new socket to name bind implementation so code must be modified.
@@ -160,6 +160,20 @@ ip4_route(const ip4_addr_t *dest) | |||
} | |||
#endif /* LWIP_MULTICAST_TX_OPTIONS */ | |||
|
|||
if(interface_name !=NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems inefficient to be doing name matching inside the stack per-packet - I would have thought the setsockopt would do lookup at that time, and then you're just netif
pointer matching per-packet. Still, just an efficiency nit.
Would mean adding a clean-up to strip stale pointers from sockets if you ever delete an interface.
On the other hand, would solve the "not copying/processing option data" issue on the setsockopt
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be refactored in LWIP 2.1.2.
New LWIP has modified ipxx_route function so name/ip matching must be implemented again.
Still waiting for #9387 (comment) , if all resolved, let us know |
Description
Added Multihoming feature to LWIP (ability to use more than one network interfaces) for increasing networking reliability.
This involves:
Release notes
Network Interface and Network Stack API is extended with new members and new parameter to specify name of network interface
LWIP IP layer IP_route function is extended for selecting interface by its name.
NSAPI DNS now has storage for each interface's DNS servers.
New members :
NetworkInterface::set_as_default
NetworkInterface::get_interface name
NetworkStack::get_ip_address_if
LWIP::setsockopt has new option NSAPI_BIND_TO_DEVICE for binding socket to interface name.
New parameter "interface_name" addded to:
NetworkInterface::add_dns_server
NetworkInterface::gethostbyname
If selection based on interface name is not needed an empty tring can be passed.
Then original functionality is preserved.
Pull request type
Reviewers
@SeppoTakalo
@mikaleppanen
@kjbracey-arm