Skip to content

Commit 2adbf72

Browse files
author
Mika Leppänen
committed
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.
1 parent 41c647b commit 2adbf72

File tree

3 files changed

+103
-58
lines changed

3 files changed

+103
-58
lines changed

features/FEATURE_LWIP/lwip-interface/lwip_stack.c

Lines changed: 68 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -197,24 +197,25 @@ static bool convert_lwip_addr_to_mbed(nsapi_addr_t *out, const ip_addr_t *in)
197197
#endif
198198
}
199199

200+
#if LWIP_IPV4
200201
static const ip_addr_t *mbed_lwip_get_ipv4_addr(const struct netif *netif)
201202
{
202-
#if LWIP_IPV4
203203
if (!netif_is_up(netif)) {
204204
return NULL;
205205
}
206206

207207
if (!ip4_addr_isany(netif_ip4_addr(netif))) {
208208
return netif_ip_addr4(netif);
209209
}
210-
#endif
211210

212211
return NULL;
213212
}
213+
#endif
214214

215+
#if LWIP_IPV6
215216
static const ip_addr_t *mbed_lwip_get_ipv6_addr(const struct netif *netif)
216217
{
217-
#if LWIP_IPV6
218+
218219
if (!netif_is_up(netif)) {
219220
return NULL;
220221
}
@@ -225,24 +226,29 @@ static const ip_addr_t *mbed_lwip_get_ipv6_addr(const struct netif *netif)
225226
return netif_ip_addr6(netif, i);
226227
}
227228
}
228-
#endif
229229

230230
return NULL;
231-
232231
}
232+
#endif
233233

234234
const ip_addr_t *mbed_lwip_get_ip_addr(bool any_addr, const struct netif *netif)
235235
{
236236
const ip_addr_t *pref_ip_addr = 0;
237237
const ip_addr_t *npref_ip_addr = 0;
238238

239+
#if LWIP_IPV4 && LWIP_IPV6
239240
#if IP_VERSION_PREF == PREF_IPV4
240241
pref_ip_addr = mbed_lwip_get_ipv4_addr(netif);
241242
npref_ip_addr = mbed_lwip_get_ipv6_addr(netif);
242243
#else
243244
pref_ip_addr = mbed_lwip_get_ipv6_addr(netif);
244245
npref_ip_addr = mbed_lwip_get_ipv4_addr(netif);
245246
#endif
247+
#elif LWIP_IPV6
248+
pref_ip_addr = mbed_lwip_get_ipv6_addr(netif);
249+
#elif LWIP_IPV4
250+
pref_ip_addr = mbed_lwip_get_ipv4_addr(netif);
251+
#endif
246252

247253
if (pref_ip_addr) {
248254
return pref_ip_addr;
@@ -307,25 +313,38 @@ static void mbed_lwip_netif_link_irq(struct netif *lwip_netif)
307313
}
308314
}
309315

310-
static sys_sem_t lwip_netif_has_addr;
316+
static char lwip_has_addr_state = 0;
317+
318+
#define HAS_ANY_ADDR 1
319+
static sys_sem_t lwip_netif_has_any_addr;
320+
#if PREF_ADDR_TIMEOUT
321+
#define HAS_PREF_ADDR 2
322+
static sys_sem_t lwip_netif_has_pref_addr;
323+
#endif
324+
#if BOTH_ADDR_TIMEOUT
325+
#define HAS_BOTH_ADDR 4
326+
static sys_sem_t lwip_netif_has_both_addr;
327+
#endif
328+
311329
static void mbed_lwip_netif_status_irq(struct netif *lwip_netif)
312330
{
313-
static bool any_addr = true;
314-
315331
if (netif_is_up(lwip_netif)) {
316-
// Indicates that has address
317-
if (any_addr == true && mbed_lwip_get_ip_addr(true, lwip_netif)) {
318-
sys_sem_signal(&lwip_netif_has_addr);
319-
any_addr = false;
320-
return;
332+
if (!(lwip_has_addr_state & HAS_ANY_ADDR) && mbed_lwip_get_ip_addr(true, lwip_netif)) {
333+
sys_sem_signal(&lwip_netif_has_any_addr);
334+
lwip_has_addr_state |= HAS_ANY_ADDR;
321335
}
322-
323-
// Indicates that has preferred address
324-
if (mbed_lwip_get_ip_addr(false, lwip_netif)) {
325-
sys_sem_signal(&lwip_netif_has_addr);
336+
#if PREF_ADDR_TIMEOUT
337+
if (!(lwip_has_addr_state & HAS_PREF_ADDR) && mbed_lwip_get_ip_addr(false, lwip_netif)) {
338+
sys_sem_signal(&lwip_netif_has_pref_addr);
339+
lwip_has_addr_state |= HAS_PREF_ADDR;
326340
}
327-
} else {
328-
any_addr = true;
341+
#endif
342+
#if BOTH_ADDR_TIMEOUT
343+
if (!(lwip_has_addr_state & HAS_BOTH_ADDR) && mbed_lwip_get_ipv4_addr(lwip_netif) && mbed_lwip_get_ipv6_addr(lwip_netif)) {
344+
sys_sem_signal(&lwip_netif_has_both_addr);
345+
lwip_has_addr_state |= HAS_BOTH_ADDR;
346+
}
347+
#endif
329348
}
330349
}
331350

@@ -435,8 +454,13 @@ static void mbed_lwip_core_init(void)
435454
sys_sem_new(&lwip_tcpip_inited, 0);
436455
sys_sem_new(&lwip_netif_linked, 0);
437456
sys_sem_new(&lwip_netif_unlinked, 0);
438-
sys_sem_new(&lwip_netif_has_addr, 0);
439-
457+
sys_sem_new(&lwip_netif_has_any_addr, 0);
458+
#if PREF_ADDR_TIMEOUT
459+
sys_sem_new(&lwip_netif_has_pref_addr, 0);
460+
#endif
461+
#if BOTH_ADDR_TIMEOUT
462+
sys_sem_new(&lwip_netif_has_both_addr, 0);
463+
#endif
440464
tcpip_init(mbed_lwip_tcpip_init_irq, NULL);
441465
sys_arch_sem_wait(&lwip_tcpip_inited, 0);
442466

@@ -603,20 +627,26 @@ nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const cha
603627

604628
// If doesn't have address
605629
if (!mbed_lwip_get_ip_addr(true, &lwip_netif)) {
606-
if (sys_arch_sem_wait(&lwip_netif_has_addr, DHCP_TIMEOUT * 1000) == SYS_ARCH_TIMEOUT) {
630+
if (sys_arch_sem_wait(&lwip_netif_has_any_addr, DHCP_TIMEOUT * 1000) == SYS_ARCH_TIMEOUT) {
607631
if (ppp) {
608632
ppp_lwip_disconnect();
609633
}
610-
611634
return NSAPI_ERROR_DHCP_FAILURE;
612635
}
613636
}
614637

615-
#if ADDR_TIMEOUT
638+
#if PREF_ADDR_TIMEOUT
616639
// If address is not for preferred stack waits a while to see
617640
// if preferred stack address is acquired
618641
if (!mbed_lwip_get_ip_addr(false, &lwip_netif)) {
619-
sys_arch_sem_wait(&lwip_netif_has_addr, ADDR_TIMEOUT * 1000);
642+
sys_arch_sem_wait(&lwip_netif_has_pref_addr, PREF_ADDR_TIMEOUT * 1000);
643+
}
644+
#endif
645+
#if BOTH_ADDR_TIMEOUT
646+
// If addresses for both stacks are not available waits a while to
647+
// see if address for both stacks are acquired
648+
if (!(mbed_lwip_get_ipv4_addr(&lwip_netif) && mbed_lwip_get_ipv6_addr(&lwip_netif))) {
649+
sys_arch_sem_wait(&lwip_netif_has_both_addr, BOTH_ADDR_TIMEOUT * 1000);
620650
}
621651
#endif
622652

@@ -677,10 +707,17 @@ nsapi_error_t mbed_lwip_bringdown_2(bool ppp)
677707
mbed_lwip_clear_ipv6_addresses(&lwip_netif);
678708
#endif
679709

680-
681-
sys_sem_free(&lwip_netif_has_addr);
682-
sys_sem_new(&lwip_netif_has_addr, 0);
683-
710+
sys_sem_free(&lwip_netif_has_any_addr);
711+
sys_sem_new(&lwip_netif_has_any_addr, 0);
712+
#if PREF_ADDR_TIMEOUT
713+
sys_sem_free(&lwip_netif_has_pref_addr);
714+
sys_sem_new(&lwip_netif_has_pref_addr, 0);
715+
#endif
716+
#if BOTH_ADDR_TIMEOUT
717+
sys_sem_free(&lwip_netif_has_both_addr);
718+
sys_sem_new(&lwip_netif_has_both_addr, 0);
719+
#endif
720+
lwip_has_addr_state = 0;
684721
lwip_connected = false;
685722
return 0;
686723
}
@@ -789,19 +826,8 @@ static nsapi_error_t mbed_lwip_socket_open(nsapi_stack_t *stack, nsapi_socket_t
789826

790827
enum netconn_type lwip_proto = proto == NSAPI_TCP ? NETCONN_TCP : NETCONN_UDP;
791828

792-
#if LWIP_IPV6 && LWIP_IPV4
793-
const ip_addr_t *ip_addr;
794-
ip_addr = mbed_lwip_get_ip_addr(true, &lwip_netif);
795-
796-
if (IP_IS_V6(ip_addr)) {
797-
// Enable IPv6 (or dual-stack). LWIP dual-stack support is
798-
// currently incomplete as of 2.0.0rc2 - eg we will only be able
799-
// to do a UDP sendto to an address matching the type selected
800-
// here. Matching "get_ip_addr" and DNS logic, use v4 if
801-
// available.
802-
lwip_proto |= NETCONN_TYPE_IPV6;
803-
}
804-
#elif LWIP_IPV6
829+
#if LWIP_IPV6
830+
// Enable IPv6 (or dual-stack)
805831
lwip_proto |= NETCONN_TYPE_IPV6;
806832
#endif
807833

features/FEATURE_LWIP/lwip-interface/lwipopts.h

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,19 @@
4646
#error "Either IPv4 or IPv6 must be enabled."
4747
#endif
4848

49-
// On dual stack configuration how long wait for preferred stack
50-
// before selecting either IPv6 or IPv4
49+
// On dual stack configuration how long to wait for both or preferred stack
50+
// addresses before completing bring up.
5151
#if LWIP_IPV4 && LWIP_IPV6
52-
#define ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
52+
#if MBED_CONF_LWIP_ADDR_TIMEOUT_MODE
53+
#define BOTH_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
54+
#define PREF_ADDR_TIMEOUT 0
5355
#else
54-
#define ADDR_TIMEOUT 0
56+
#define PREF_ADDR_TIMEOUT MBED_CONF_LWIP_ADDR_TIMEOUT
57+
#define BOTH_ADDR_TIMEOUT 0
58+
#endif
59+
#else
60+
#define PREF_ADDR_TIMEOUT 0
61+
#define BOTH_ADDR_TIMEOUT 0
5562
#endif
5663

5764
#define DHCP_TIMEOUT 60
@@ -242,6 +249,7 @@
242249
#define AUTOIP_DEBUG LWIP_DBG_OFF
243250
#define DNS_DEBUG LWIP_DBG_OFF
244251
#define IP6_DEBUG LWIP_DBG_OFF
252+
245253
#if MBED_CONF_LWIP_ENABLE_PPP_TRACE
246254
#define PPP_DEBUG LWIP_DBG_ON
247255
#else
@@ -260,6 +268,8 @@
260268
#define LWIP_STATS 0
261269
#endif
262270

271+
#define TRACE_TO_ASCII_HEX_DUMP 0
272+
263273
#define LWIP_PLATFORM_BYTESWAP 1
264274

265275
#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 1
@@ -278,20 +288,25 @@
278288
// Note generic macro name used rather than MBED_CONF_LWIP_PPP_ENABLED
279289
// to allow users like PPPCellularInterface to detect that nsapi_ppp.h is available.
280290
#if NSAPI_PPP_AVAILABLE
281-
#define PPP_SUPPORT 1
282-
#define CHAP_SUPPORT 1
283-
#define PPP_INPROC_IRQ_SAFE 1
291+
#define PPP_SUPPORT 1
292+
#if MBED_CONF_LWIP_IPV6_ENABLED
293+
#define PPP_IPV6_SUPPORT 1
294+
// Disable DAD for PPP
295+
#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 0
296+
#endif
297+
#define CHAP_SUPPORT 1
298+
#define PPP_INPROC_IRQ_SAFE 1
284299
// Save RAM
285-
#define PAP_SUPPORT 0
286-
#define VJ_SUPPORT 0
287-
#define PRINTPKT_SUPPORT 0
300+
#define PAP_SUPPORT 0
301+
#define VJ_SUPPORT 0
302+
#define PRINTPKT_SUPPORT 0
288303

289304
// Broadcast
290-
#define IP_SOF_BROADCAST 0
291-
#define IP_SOF_BROADCAST_RECV 0
305+
#define IP_SOF_BROADCAST 0
306+
#define IP_SOF_BROADCAST_RECV 0
292307

293-
#define MAXNAMELEN 64 /* max length of hostname or name for auth */
294-
#define MAXSECRETLEN 64
308+
#define MAXNAMELEN 64 /* max length of hostname or name for auth */
309+
#define MAXSECRETLEN 64
295310
#endif // NSAPI_PPP_AVAILABLE
296311

297312
// Make sure we default these to off, so

features/FEATURE_LWIP/lwip-interface/mbed_lib.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,13 @@
1414
"value": 4
1515
},
1616
"addr-timeout": {
17-
"help": "On dual-stack system how long to wait preferred stack's address in seconds",
17+
"help": "On dual-stack system how long to additionally wait for other stack's address in seconds",
1818
"value": 5
19-
},
19+
},
20+
"addr-timeout-mode": {
21+
"help": "Address timeout mode; true: wait both stack's addresses; false: wait for preferred stack's address",
22+
"value": true
23+
},
2024
"ethernet-enabled": {
2125
"help": "Enable support for Ethernet interfaces",
2226
"value": true

0 commit comments

Comments
 (0)