From 3c01f68a7888717bac9a267eac36281bfea095e5 Mon Sep 17 00:00:00 2001 From: Francesco Giancane Date: Mon, 17 Feb 2020 12:33:37 +0100 Subject: [PATCH 1/5] lwip: make IPV6 link-local support over PPP configurable Make the link local negotiation for IPV6 in PPP optional and configurable. This is because some modems do not support the IPV6 negotiation and sending IPV6CP frames would in some cases break the network configuration phase, resulting in a timeout during the Phase Network. Please note that this does not disable the IPV6 support for the outgoing communication (IPV6 is still enabled even if this option is not selected) but just for the local link between lwIP and modem. Signed-off-by: Francesco Giancane Merges https://github.com/espressif/esp-idf/pull/4782 Closes https://github.com/espressif/esp-idf/issues/1065 --- components/lwip/Kconfig | 11 +++++++++++ components/lwip/port/esp32/include/lwipopts.h | 8 ++++++++ 2 files changed, 19 insertions(+) diff --git a/components/lwip/Kconfig b/components/lwip/Kconfig index ffa0b4316e..5fd0868928 100644 --- a/components/lwip/Kconfig +++ b/components/lwip/Kconfig @@ -542,6 +542,17 @@ menu "LWIP" PPP over serial support is experimental and unsupported. + config LWIP_PPP_ENABLE_IPV6 + bool "Enable IPV6 support for PPP connections (IPV6CP)" + depends on LWIP_PPP_SUPPORT + default y + help + Enable IPV6 support in PPP for the local link between the DTE (processor) and DCE (modem). + There are some modems which do not support the IPV6 addressing in the local link. + If they are requested for IPV6CP negotiation, they may time out. + This would in turn fail the configuration for the whole link. + If your modem is not responding correctly to PPP Phase Network, try to disable IPV6 support. + config LWIP_PPP_NOTIFY_PHASE_SUPPORT bool "Enable Notify Phase Callback" depends on LWIP_PPP_SUPPORT diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index 3475f2986f..d6aa757f01 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -611,6 +611,14 @@ #if PPP_SUPPORT +/** + * PPP_IPV6_SUPPORT == 1: Enable IPV6 support for local link + * between modem and lwIP stack. + * Some modems do not support IPV6 addressing in local link and + * the only option available is to disable IPV6 address negotiation. + */ +#define PPP_IPV6_SUPPORT CONFIG_LWIP_PPP_ENABLE_IPV6 + /** * PPP_NOTIFY_PHASE==1: Support PPP notify phase. */ From 38060c0b58f1f96129359eff9c878a664cf94679 Mon Sep 17 00:00:00 2001 From: Francesco Giancane Date: Tue, 25 Feb 2020 13:18:50 +0100 Subject: [PATCH 2/5] examples: pppos_client: update sdkconfig.defaults As per discussion in #4782, IPV6 link local negotiation by default is disabled. Signed-off-by: Francesco Giancane --- examples/protocols/pppos_client/sdkconfig.defaults | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/protocols/pppos_client/sdkconfig.defaults b/examples/protocols/pppos_client/sdkconfig.defaults index 80613985f7..19f2ce6cd1 100644 --- a/examples/protocols/pppos_client/sdkconfig.defaults +++ b/examples/protocols/pppos_client/sdkconfig.defaults @@ -3,3 +3,5 @@ CONFIG_LWIP_PPP_SUPPORT=y CONFIG_LWIP_PPP_NOTIFY_PHASE_SUPPORT=y CONFIG_LWIP_PPP_PAP_SUPPORT=y CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096 +# Do not enable IPV6 in dte<->dce link local +CONFIG_LWIP_PPP_ENABLE_IPV6=n From 716298f8e3ddbe5490da6e79791b685232f7027a Mon Sep 17 00:00:00 2001 From: David Cermak Date: Tue, 25 Feb 2020 11:43:02 +0100 Subject: [PATCH 3/5] esp-netif-ppp: support for posting GOT_IP event for IPv6 --- .../esp_netif/lwip/esp_netif_lwip_ppp.c | 66 +++++++++++++------ .../pppos_client/main/pppos_client_main.c | 5 ++ 2 files changed, 52 insertions(+), 19 deletions(-) diff --git a/components/esp_netif/lwip/esp_netif_lwip_ppp.c b/components/esp_netif/lwip/esp_netif_lwip_ppp.c index f36538c548..68f6205d46 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_ppp.c +++ b/components/esp_netif/lwip/esp_netif_lwip_ppp.c @@ -21,6 +21,8 @@ #include "esp_event.h" #include "esp_netif_ppp.h" #include "esp_netif_lwip_internal.h" +#include "lwip/ip6_addr.h" +#include ESP_EVENT_DEFINE_BASE(NETIF_PPP_STATUS); @@ -57,28 +59,54 @@ static void on_ppp_status_changed(ppp_pcb *pcb, int err_code, void *ctx) switch (err_code) { case PPPERR_NONE: /* Connected */ ESP_LOGI(TAG, "Connected"); + if (pcb->if4_up && !ip_addr_isany(&pppif->ip_addr)) { + evt.ip_info.ip.addr = pppif->ip_addr.u_addr.ip4.addr; + evt.ip_info.gw.addr = pppif->gw.u_addr.ip4.addr; + evt.ip_info.netmask.addr = pppif->netmask.u_addr.ip4.addr; - evt.ip_info.ip.addr = pppif->ip_addr.u_addr.ip4.addr; - evt.ip_info.gw.addr = pppif->gw.u_addr.ip4.addr; - evt.ip_info.netmask.addr = pppif->netmask.u_addr.ip4.addr; + dest_ip = dns_getserver(0); + if(dest_ip != NULL){ + ns1.addr = (*dest_ip).u_addr.ip4.addr; + } + dest_ip = dns_getserver(1); + if(dest_ip != NULL){ + ns2.addr = (*dest_ip).u_addr.ip4.addr; + } + ESP_LOGI(TAG, "Name Server1: " IPSTR, IP2STR(&ns1)); + ESP_LOGI(TAG, "Name Server2: " IPSTR, IP2STR(&ns2)); - dest_ip = dns_getserver(0); - if(dest_ip != NULL){ - ns1.addr = (*dest_ip).u_addr.ip4.addr; + + err = esp_event_post(IP_EVENT, netif->get_ip_event, &evt, sizeof(evt), 0); + if (ESP_OK != err) { + ESP_LOGE(TAG, "esp_event_post failed with code %d", err); + } + return; +#if PPP_IPV6_SUPPORT + } else if (pcb->if6_up && !ip_addr_isany(&pppif->ip6_addr[0])) { + esp_netif_ip6_info_t ip6_info; + ip6_addr_t lwip_ip6_info; + ip_event_got_ip6_t ip6_event = { .esp_netif = pppif->state, .if_index = -1 }; + + ip6_addr_set(&lwip_ip6_info, ip_2_ip6(&pppif->ip6_addr[0])); +#if LWIP_IPV6_SCOPES + memcpy(&ip6_info.ip, &lwip_ip6_info, sizeof(esp_ip6_addr_t)); +#else + memcpy(&ip6_info.ip, &lwip_ip6_info, sizeof(ip6_addr_t)); + ip6_info.ip.zone = 0; // zero out zone, as not used in lwip +#endif /* LWIP_IPV6_SCOPES */ + memcpy(&ip6_event.ip6_info, &ip6_info, sizeof(esp_netif_ip6_info_t)); + + ESP_LOGI(TAG, "Got IPv6 address " IPV6STR, IPV62STR(pppif->ip6_addr[0].u_addr.ip6)); + err = esp_event_post(IP_EVENT, IP_EVENT_GOT_IP6, &ip6_event, sizeof(ip6_event), 0); + if (ESP_OK != err) { + ESP_LOGE(TAG, "esp_event_post failed with code %d", err); + } + return; +#endif /* PPP_IPV6_SUPPORT */ + } else { + ESP_LOGE(TAG, "Unexpected connected event"); + return; } - dest_ip = dns_getserver(1); - if(dest_ip != NULL){ - ns2.addr = (*dest_ip).u_addr.ip4.addr; - } - ESP_LOGI(TAG, "Name Server1: " IPSTR, IP2STR(&ns1)); - ESP_LOGI(TAG, "Name Server2: " IPSTR, IP2STR(&ns2)); - - - err = esp_event_post(IP_EVENT, netif->get_ip_event, &evt, sizeof(evt), 0); - if (ESP_OK != err) { - ESP_LOGE(TAG, "esp_event_send_internal failed with code %d", err); - } - return; case PPPERR_PARAM: ESP_LOGE(TAG, "Invalid parameter"); diff --git a/examples/protocols/pppos_client/main/pppos_client_main.c b/examples/protocols/pppos_client/main/pppos_client_main.c index 7637ba3ce7..c4b5fd8ab0 100644 --- a/examples/protocols/pppos_client/main/pppos_client_main.c +++ b/examples/protocols/pppos_client/main/pppos_client_main.c @@ -203,6 +203,11 @@ static void on_ip_event(void *arg, esp_event_base_t event_base, ESP_LOGI(TAG, "GOT ip event!!!"); } else if (event_id == IP_EVENT_PPP_LOST_IP) { ESP_LOGI(TAG, "Modem Disconnect from PPP Server"); + } else if (event_id == IP_EVENT_GOT_IP6) { + ESP_LOGI(TAG, "GOT IPv6 event!"); + + ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; + ESP_LOGI(TAG, "Got IPv6 address " IPV6STR, IPV62STR(event->ip6_info.ip)); } } From 4b59f7e2c70a9715c035b25c6fc0400bcf9173ce Mon Sep 17 00:00:00 2001 From: David Cermak Date: Tue, 3 Mar 2020 13:55:33 +0100 Subject: [PATCH 4/5] mdns: limit the GOT_IP6_EVENT to only known network interfaces --- components/mdns/mdns.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/mdns/mdns.c b/components/mdns/mdns.c index 9bee170762..711de2a451 100644 --- a/components/mdns/mdns.c +++ b/components/mdns/mdns.c @@ -3176,8 +3176,10 @@ static void _mdns_handle_system_event(esp_event_base_t event_base, case IP_EVENT_GOT_IP6: { mdns_if_t mdns_if = _mdns_get_if_from_esp_netif(interface); - _mdns_enable_pcb(mdns_if, MDNS_IP_PROTOCOL_V6); - _mdns_announce_pcb(mdns_if, MDNS_IP_PROTOCOL_V4, NULL, 0, true); + if (mdns_if != MDNS_IF_MAX) { + _mdns_enable_pcb(mdns_if, MDNS_IP_PROTOCOL_V6); + _mdns_announce_pcb(mdns_if, MDNS_IP_PROTOCOL_V4, NULL, 0, true); + } } break; From a2c55e2c37437266223c03d9efbe1fa0cd270069 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Tue, 3 Mar 2020 13:57:32 +0100 Subject: [PATCH 5/5] examples: common connect code to ignore GOT_IP6_EVENT if comes from unrelated netif --- .../common_components/protocol_examples_common/connect.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/common_components/protocol_examples_common/connect.c b/examples/common_components/protocol_examples_common/connect.c index 87b218047e..9713edda2c 100644 --- a/examples/common_components/protocol_examples_common/connect.c +++ b/examples/common_components/protocol_examples_common/connect.c @@ -65,8 +65,12 @@ static void on_got_ip(void *arg, esp_event_base_t event_base, static void on_got_ipv6(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { - ESP_LOGI(TAG, "Got IPv6 event!"); ip_event_got_ip6_t *event = (ip_event_got_ip6_t *)event_data; + if (event->esp_netif != s_example_esp_netif) { + ESP_LOGD(TAG, "Got IPv6 from another netif: ignored"); + return; + } + ESP_LOGI(TAG, "Got IPv6 event!"); memcpy(&s_ipv6_addr, &event->ip6_info.ip, sizeof(s_ipv6_addr)); xEventGroupSetBits(s_connect_event_group, GOT_IPV6_BIT); }