Added dual Ipv4/Ipv6 stack support to lwip address configuration

Added new configuration option "both-addr-timeout" that defines
how long to wait that addresses from both systems become available.
pull/4911/head
Mika Leppänen 2017-08-03 15:15:20 +03:00
parent 41c647b1c9
commit 2adbf721d2
3 changed files with 103 additions and 58 deletions

View File

@ -197,9 +197,9 @@ static bool convert_lwip_addr_to_mbed(nsapi_addr_t *out, const ip_addr_t *in)
#endif
}
#if LWIP_IPV4
static const ip_addr_t *mbed_lwip_get_ipv4_addr(const struct netif *netif)
{
#if LWIP_IPV4
if (!netif_is_up(netif)) {
return NULL;
}
@ -207,14 +207,15 @@ static const ip_addr_t *mbed_lwip_get_ipv4_addr(const struct netif *netif)
if (!ip4_addr_isany(netif_ip4_addr(netif))) {
return netif_ip_addr4(netif);
}
#endif
return NULL;
}
#endif
#if LWIP_IPV6
static const ip_addr_t *mbed_lwip_get_ipv6_addr(const struct netif *netif)
{
#if LWIP_IPV6
if (!netif_is_up(netif)) {
return NULL;
}
@ -225,17 +226,17 @@ static const ip_addr_t *mbed_lwip_get_ipv6_addr(const struct netif *netif)
return netif_ip_addr6(netif, i);
}
}
#endif
return NULL;
}
#endif
const ip_addr_t *mbed_lwip_get_ip_addr(bool any_addr, const struct netif *netif)
{
const ip_addr_t *pref_ip_addr = 0;
const ip_addr_t *npref_ip_addr = 0;
#if LWIP_IPV4 && LWIP_IPV6
#if IP_VERSION_PREF == PREF_IPV4
pref_ip_addr = mbed_lwip_get_ipv4_addr(netif);
npref_ip_addr = mbed_lwip_get_ipv6_addr(netif);
@ -243,6 +244,11 @@ const ip_addr_t *mbed_lwip_get_ip_addr(bool any_addr, const struct netif *netif)
pref_ip_addr = mbed_lwip_get_ipv6_addr(netif);
npref_ip_addr = mbed_lwip_get_ipv4_addr(netif);
#endif
#elif LWIP_IPV6
pref_ip_addr = mbed_lwip_get_ipv6_addr(netif);
#elif LWIP_IPV4
pref_ip_addr = mbed_lwip_get_ipv4_addr(netif);
#endif
if (pref_ip_addr) {
return pref_ip_addr;
@ -307,25 +313,38 @@ static void mbed_lwip_netif_link_irq(struct netif *lwip_netif)
}
}
static sys_sem_t lwip_netif_has_addr;
static char lwip_has_addr_state = 0;
#define HAS_ANY_ADDR 1
static sys_sem_t lwip_netif_has_any_addr;
#if PREF_ADDR_TIMEOUT
#define HAS_PREF_ADDR 2
static sys_sem_t lwip_netif_has_pref_addr;
#endif
#if BOTH_ADDR_TIMEOUT
#define HAS_BOTH_ADDR 4
static sys_sem_t lwip_netif_has_both_addr;
#endif
static void mbed_lwip_netif_status_irq(struct netif *lwip_netif)
{
static bool any_addr = true;
if (netif_is_up(lwip_netif)) {
// Indicates that has address
if (any_addr == true && mbed_lwip_get_ip_addr(true, lwip_netif)) {
sys_sem_signal(&lwip_netif_has_addr);
any_addr = false;
return;
if (!(lwip_has_addr_state & HAS_ANY_ADDR) && mbed_lwip_get_ip_addr(true, lwip_netif)) {
sys_sem_signal(&lwip_netif_has_any_addr);
lwip_has_addr_state |= HAS_ANY_ADDR;
}
// Indicates that has preferred address
if (mbed_lwip_get_ip_addr(false, lwip_netif)) {
sys_sem_signal(&lwip_netif_has_addr);
#if PREF_ADDR_TIMEOUT
if (!(lwip_has_addr_state & HAS_PREF_ADDR) && mbed_lwip_get_ip_addr(false, lwip_netif)) {
sys_sem_signal(&lwip_netif_has_pref_addr);
lwip_has_addr_state |= HAS_PREF_ADDR;
}
} else {
any_addr = true;
#endif
#if BOTH_ADDR_TIMEOUT
if (!(lwip_has_addr_state & HAS_BOTH_ADDR) && mbed_lwip_get_ipv4_addr(lwip_netif) && mbed_lwip_get_ipv6_addr(lwip_netif)) {
sys_sem_signal(&lwip_netif_has_both_addr);
lwip_has_addr_state |= HAS_BOTH_ADDR;
}
#endif
}
}
@ -435,8 +454,13 @@ static void mbed_lwip_core_init(void)
sys_sem_new(&lwip_tcpip_inited, 0);
sys_sem_new(&lwip_netif_linked, 0);
sys_sem_new(&lwip_netif_unlinked, 0);
sys_sem_new(&lwip_netif_has_addr, 0);
sys_sem_new(&lwip_netif_has_any_addr, 0);
#if PREF_ADDR_TIMEOUT
sys_sem_new(&lwip_netif_has_pref_addr, 0);
#endif
#if BOTH_ADDR_TIMEOUT
sys_sem_new(&lwip_netif_has_both_addr, 0);
#endif
tcpip_init(mbed_lwip_tcpip_init_irq, NULL);
sys_arch_sem_wait(&lwip_tcpip_inited, 0);
@ -603,20 +627,26 @@ nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const cha
// If doesn't have address
if (!mbed_lwip_get_ip_addr(true, &lwip_netif)) {
if (sys_arch_sem_wait(&lwip_netif_has_addr, DHCP_TIMEOUT * 1000) == SYS_ARCH_TIMEOUT) {
if (sys_arch_sem_wait(&lwip_netif_has_any_addr, DHCP_TIMEOUT * 1000) == SYS_ARCH_TIMEOUT) {
if (ppp) {
ppp_lwip_disconnect();
}
return NSAPI_ERROR_DHCP_FAILURE;
}
}
#if ADDR_TIMEOUT
#if PREF_ADDR_TIMEOUT
// If address is not for preferred stack waits a while to see
// if preferred stack address is acquired
if (!mbed_lwip_get_ip_addr(false, &lwip_netif)) {
sys_arch_sem_wait(&lwip_netif_has_addr, ADDR_TIMEOUT * 1000);
sys_arch_sem_wait(&lwip_netif_has_pref_addr, PREF_ADDR_TIMEOUT * 1000);
}
#endif
#if BOTH_ADDR_TIMEOUT
// If addresses for both stacks are not available waits a while to
// see if address for both stacks are acquired
if (!(mbed_lwip_get_ipv4_addr(&lwip_netif) && mbed_lwip_get_ipv6_addr(&lwip_netif))) {
sys_arch_sem_wait(&lwip_netif_has_both_addr, BOTH_ADDR_TIMEOUT * 1000);
}
#endif
@ -677,10 +707,17 @@ nsapi_error_t mbed_lwip_bringdown_2(bool ppp)
mbed_lwip_clear_ipv6_addresses(&lwip_netif);
#endif
sys_sem_free(&lwip_netif_has_addr);
sys_sem_new(&lwip_netif_has_addr, 0);
sys_sem_free(&lwip_netif_has_any_addr);
sys_sem_new(&lwip_netif_has_any_addr, 0);
#if PREF_ADDR_TIMEOUT
sys_sem_free(&lwip_netif_has_pref_addr);
sys_sem_new(&lwip_netif_has_pref_addr, 0);
#endif
#if BOTH_ADDR_TIMEOUT
sys_sem_free(&lwip_netif_has_both_addr);
sys_sem_new(&lwip_netif_has_both_addr, 0);
#endif
lwip_has_addr_state = 0;
lwip_connected = false;
return 0;
}
@ -789,19 +826,8 @@ static nsapi_error_t mbed_lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t
enum netconn_type lwip_proto = proto == NSAPI_TCP ? NETCONN_TCP : NETCONN_UDP;
#if LWIP_IPV6 && LWIP_IPV4
const ip_addr_t *ip_addr;
ip_addr = mbed_lwip_get_ip_addr(true, &lwip_netif);
if (IP_IS_V6(ip_addr)) {
// Enable IPv6 (or dual-stack). LWIP dual-stack support is
// currently incomplete as of 2.0.0rc2 - eg we will only be able
// to do a UDP sendto to an address matching the type selected
// here. Matching "get_ip_addr" and DNS logic, use v4 if
// available.
lwip_proto |= NETCONN_TYPE_IPV6;
}
#elif LWIP_IPV6
#if LWIP_IPV6
// Enable IPv6 (or dual-stack)
lwip_proto |= NETCONN_TYPE_IPV6;
#endif

View File

@ -46,12 +46,19 @@
#error "Either IPv4 or IPv6 must be enabled."
#endif
// On dual stack configuration how long wait for preferred stack
// before selecting either IPv6 or IPv4
// On dual stack configuration how long to wait for both or preferred stack
// addresses before completing bring up.
#if LWIP_IPV4 && LWIP_IPV6
#define ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE
#define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define PREF_ADDR_TIMEOUT 0
#else
#define ADDR_TIMEOUT 0
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
#define BOTH_ADDR_TIMEOUT 0
#endif
#else
#define PREF_ADDR_TIMEOUT 0
#define BOTH_ADDR_TIMEOUT 0
#endif
#define DHCP_TIMEOUT 60
@ -242,6 +249,7 @@
#define AUTOIP_DEBUG LWIP_DBG_OFF
#define DNS_DEBUG LWIP_DBG_OFF
#define IP6_DEBUG LWIP_DBG_OFF
#if MBED_CONF_LWIP_ENABLE_PPP_TRACE
#define PPP_DEBUG LWIP_DBG_ON
#else
@ -260,6 +268,8 @@
#define LWIP_STATS 0
#endif
#define TRACE_TO_ASCII_HEX_DUMP 0
#define LWIP_PLATFORM_BYTESWAP 1
#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 1
@ -278,20 +288,25 @@
// Note generic macro name used rather than MBED_CONF_LWIP_PPP_ENABLED
// to allow users like PPPCellularInterface to detect that nsapi_ppp.h is available.
#if NSAPI_PPP_AVAILABLE
#define PPP_SUPPORT 1
#define CHAP_SUPPORT 1
#define PPP_INPROC_IRQ_SAFE 1
#define PPP_SUPPORT 1
#if MBED_CONF_LWIP_IPV6_ENABLED
#define PPP_IPV6_SUPPORT 1
// Disable DAD for PPP
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
#endif
#define CHAP_SUPPORT 1
#define PPP_INPROC_IRQ_SAFE 1
// Save RAM
#define PAP_SUPPORT 0
#define VJ_SUPPORT 0
#define PRINTPKT_SUPPORT 0
#define PAP_SUPPORT 0
#define VJ_SUPPORT 0
#define PRINTPKT_SUPPORT 0
// Broadcast
#define IP_SOF_BROADCAST 0
#define IP_SOF_BROADCAST_RECV 0
#define IP_SOF_BROADCAST 0
#define IP_SOF_BROADCAST_RECV 0
#define MAXNAMELEN 64 /* max length of hostname or name for auth */
#define MAXSECRETLEN 64
#define MAXNAMELEN 64 /* max length of hostname or name for auth */
#define MAXSECRETLEN 64
#endif // NSAPI_PPP_AVAILABLE
// Make sure we default these to off, so

View File

@ -14,9 +14,13 @@
"value": 4
},
"addr-timeout": {
"help": "On dual-stack system how long to wait preferred stack's address in seconds",
"help": "On dual-stack system how long to additionally wait for other stack's address in seconds",
"value": 5
},
},
"addr-timeout-mode": {
"help": "Address timeout mode; true: wait both stack's addresses; false: wait for preferred stack's address",
"value": true
},
"ethernet-enabled": {
"help": "Enable support for Ethernet interfaces",
"value": true