From 5b471a18489b056f65fe8dcbb2c992d27909ebc9 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Mon, 14 Feb 2022 13:46:21 +0100 Subject: [PATCH 01/25] esp_netif/lwip: Implement basic support for vanilla-lwip (2.1.3-REL) * Reference lwip-2.1.3-REL vanilla lwip version * Use inherent NETIF callbacks instead of dhcp/ipv6/autoip --- .../asio/port/include/esp_asio_config.h | 5 +- components/esp_eth/src/esp_eth_netif_glue.c | 9 +- components/esp_netif/CMakeLists.txt | 1 + components/esp_netif/Kconfig | 8 ++ components/esp_netif/lwip/esp_netif_lwip.c | 43 +++++--- .../esp_netif/lwip/esp_netif_lwip_defaults.c | 2 +- .../esp_netif/lwip/esp_netif_lwip_internal.h | 4 +- .../esp_netif/lwip/esp_netif_lwip_orig.c | 82 ++++++++++++++++ .../esp_netif/lwip/esp_netif_lwip_orig.h | 47 +++++++++ .../esp_netif/lwip/esp_netif_lwip_ppp.h | 22 +---- components/lwip/CMakeLists.txt | 8 +- components/lwip/linker.lf | 1 - components/lwip/lwip | 2 +- .../lwip/port/esp32/include/esp_cpp_sockets.h | 98 +++++++++++++++++++ components/lwip/port/esp32/include/lwipopts.h | 25 ++++- .../lwip/port/esp32/include/sys/socket.h | 1 + components/lwip/port/esp32/vfs_lwip.c | 18 +--- tools/ci/check_copyright_ignore.txt | 3 +- 18 files changed, 314 insertions(+), 65 deletions(-) create mode 100644 components/esp_netif/lwip/esp_netif_lwip_orig.c create mode 100644 components/esp_netif/lwip/esp_netif_lwip_orig.h create mode 100644 components/lwip/port/esp32/include/esp_cpp_sockets.h diff --git a/components/asio/port/include/esp_asio_config.h b/components/asio/port/include/esp_asio_config.h index 53215ca16e..d80717ed9a 100644 --- a/components/asio/port/include/esp_asio_config.h +++ b/components/asio/port/include/esp_asio_config.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -21,8 +21,7 @@ // // LWIP compatibility inet and address macros/functions // -# define LWIP_COMPAT_SOCKET_INET 1 -# define LWIP_COMPAT_SOCKET_ADDR 1 +# include "esp_cpp_sockets.h" // // Specific ASIO feature flags diff --git a/components/esp_eth/src/esp_eth_netif_glue.c b/components/esp_eth/src/esp_eth_netif_glue.c index 58026bea8c..cfb0adf72d 100644 --- a/components/esp_eth/src/esp_eth_netif_glue.c +++ b/components/esp_eth/src/esp_eth_netif_glue.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -40,6 +40,11 @@ static esp_err_t eth_input_to_netif(esp_eth_handle_t eth_handle, uint8_t *buffer return esp_netif_receive((esp_netif_t *)priv, buffer, length, NULL); } +static void eth_l2_free(void *h, void* buffer) +{ + free(buffer); +} + static esp_err_t esp_eth_post_attach(esp_netif_t *esp_netif, void *args) { uint8_t eth_mac[6]; @@ -52,7 +57,7 @@ static esp_err_t esp_eth_post_attach(esp_netif_t *esp_netif, void *args) esp_netif_driver_ifconfig_t driver_ifconfig = { .handle = netif_glue->eth_driver, .transmit = esp_eth_transmit, - .driver_free_rx_buffer = NULL + .driver_free_rx_buffer = eth_l2_free }; ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig)); diff --git a/components/esp_netif/CMakeLists.txt b/components/esp_netif/CMakeLists.txt index 44c9ef8e0d..accc6e01a0 100644 --- a/components/esp_netif/CMakeLists.txt +++ b/components/esp_netif/CMakeLists.txt @@ -13,6 +13,7 @@ set(srcs "vfs_l2tap/esp_vfs_l2tap.c" "lwip/esp_netif_lwip.c" "lwip/esp_netif_lwip_defaults.c" + "lwip/esp_netif_lwip_orig.c" "lwip/esp_netif_sta_list.c") set(include_dirs "include") diff --git a/components/esp_netif/Kconfig b/components/esp_netif/Kconfig index 090b590145..bfa3d54bca 100644 --- a/components/esp_netif/Kconfig +++ b/components/esp_netif/Kconfig @@ -28,6 +28,14 @@ menu "ESP NETIF Adapter" help Dummy implementation of esp-netif functionality which connects driver transmit to receive function. This option is for testing purpose only + + config ESP_NETIF_TCPIP_LWIP_ORIG + bool "LwIP-orig" + depends on !LWIP_PPP_SUPPORT && !LWIP_IPV4_NAPT + help + This choice sets the original, vanilla-lwIP as the TCP/IP stack. + Warning: Current implementation does not support PPP and NAPT features + endchoice config ESP_NETIF_L2_TAP diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index 390b9708f8..7fe1d2d67a 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -10,12 +10,13 @@ #include "esp_check.h" #include "esp_netif_lwip_internal.h" +#include "esp_netif_lwip_orig.h" #include "esp_netif.h" #include "esp_netif_private.h" #include "esp_random.h" -#if CONFIG_ESP_NETIF_TCPIP_LWIP +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) #include "lwip/tcpip.h" #include "lwip/dhcp.h" @@ -99,6 +100,7 @@ static bool tcpip_initialized = false; static esp_netif_t *s_last_default_esp_netif = NULL; static bool s_is_last_default_esp_netif_overridden = false; + #if !LWIP_TCPIP_CORE_LOCKING static sys_sem_t api_sync_sem = NULL; static sys_sem_t api_lock_sem = NULL; @@ -490,7 +492,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) // Create parent esp-netif object esp_netif_t *esp_netif = calloc(1, sizeof(struct esp_netif_obj)); if (!esp_netif) { - ESP_LOGE(TAG, "Failed to allocate %d bytes (fee heap size %d)", sizeof(struct esp_netif_obj), + ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(struct esp_netif_obj), esp_get_free_heap_size()); return NULL; } @@ -498,7 +500,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) // Create ip info esp_netif_ip_info_t *ip_info = calloc(1, sizeof(esp_netif_ip_info_t)); if (!ip_info) { - ESP_LOGE(TAG, "Failed to allocate %d bytes (fee heap size %d)", sizeof(esp_netif_ip_info_t), + ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(esp_netif_ip_info_t), esp_get_free_heap_size()); free(esp_netif); return NULL; @@ -508,7 +510,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) // creating another ip info (to store old ip) ip_info = calloc(1, sizeof(esp_netif_ip_info_t)); if (!ip_info) { - ESP_LOGE(TAG, "Failed to allocate %d bytes (fee heap size %d)", sizeof(esp_netif_ip_info_t), + ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(esp_netif_ip_info_t), esp_get_free_heap_size()); free(esp_netif->ip_info); free(esp_netif); @@ -519,7 +521,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) // Create underlying lwip netif struct netif * lwip_netif = calloc(1, sizeof(struct netif)); if (!lwip_netif) { - ESP_LOGE(TAG, "Failed to allocate %d bytes (fee heap size %d)", sizeof(struct netif), + ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(struct netif), esp_get_free_heap_size()); free(esp_netif->ip_info_old); free(esp_netif->ip_info); @@ -552,6 +554,8 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) return NULL; } + set_lwip_netif_callback(); + return esp_netif; } @@ -562,6 +566,15 @@ static void esp_netif_lwip_remove(esp_netif_t *esp_netif) netif_set_down(esp_netif->lwip_netif); } netif_remove(esp_netif->lwip_netif); +#if ESP_GRATUITOUS_ARP + if (esp_netif->flags&ESP_NETIF_FLAG_GARP) { + netif_unset_garp_flag(esp_netif->lwip_netif); + } +#endif + if (esp_netif->flags & ESP_NETIF_DHCP_CLIENT) { + dhcp_cleanup(esp_netif->lwip_netif); + } + } } @@ -611,6 +624,9 @@ void esp_netif_destroy(esp_netif_t *esp_netif) { if (esp_netif) { esp_netif_remove_from_list(esp_netif); + if (esp_netif_get_nr_of_ifs() == 0) { + remove_lwip_netif_callback(); + } free(esp_netif->ip_info); free(esp_netif->ip_info_old); free(esp_netif->if_key); @@ -923,12 +939,12 @@ esp_err_t esp_netif_receive(esp_netif_t *esp_netif, void *buffer, size_t len, vo return ESP_OK; } +static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif); + // // DHCP: // -static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif); - -static void esp_netif_dhcpc_cb(struct netif *netif) +void esp_netif_internal_dhcpc_cb(struct netif *netif) { if (!netif) { ESP_LOGD(TAG, "null netif=%p", netif); @@ -941,7 +957,6 @@ static void esp_netif_dhcpc_cb(struct netif *netif) esp_netif_ip_info_t *ip_info = esp_netif->ip_info; esp_netif_ip_info_t *ip_info_old = esp_netif->ip_info_old; - if ( !ip4_addr_cmp(ip_2_ip4(&netif->ip_addr), IP4_ADDR_ANY4) ) { //check whether IP is changed @@ -1122,7 +1137,7 @@ static esp_err_t esp_netif_dhcpc_start_api(esp_netif_api_msg_t *msg) return ESP_ERR_ESP_NETIF_DHCPC_START_FAILED; } - dhcp_set_cb(p_netif, esp_netif_dhcpc_cb); + dhcp_set_cb(p_netif, esp_netif_internal_dhcpc_cb); esp_netif->dhcpc_status = ESP_NETIF_DHCP_STARTED; return ESP_OK; @@ -1624,11 +1639,11 @@ esp_ip6_addr_type_t esp_netif_ip6_get_addr_type(esp_ip6_addr_t* ip6_addr) } -static void esp_netif_nd6_cb(struct netif *p_netif, uint8_t ip_index) +void esp_netif_internal_nd6_cb(struct netif *p_netif, uint8_t ip_index) { ESP_LOGD(TAG, "%s lwip-netif:%p", __func__, p_netif); if (!p_netif) { - ESP_LOGD(TAG, "esp_netif_nd6_cb called with null p_netif"); + ESP_LOGD(TAG, "esp_netif_internal_nd6_cb called with null p_netif"); return; } @@ -1661,7 +1676,7 @@ static esp_err_t esp_netif_create_ip6_linklocal_api(esp_netif_api_msg_t *msg) struct netif *p_netif = esp_netif->lwip_netif; if (p_netif != NULL && netif_is_up(p_netif)) { netif_create_ip6_linklocal_address(p_netif, 1); - nd6_set_cb(p_netif, esp_netif_nd6_cb); + nd6_set_cb(p_netif, esp_netif_internal_nd6_cb); return ESP_OK; } else { return ESP_FAIL; @@ -2058,4 +2073,4 @@ esp_err_t esp_netif_remove_ip6_address(esp_netif_t *esp_netif, const esp_ip6_add #endif // CONFIG_LWIP_IPV6 -#endif /* CONFIG_ESP_NETIF_TCPIP_LWIP */ +#endif /* CONFIG_ESP_NETIF_TCPIP_LWIP || CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG */ diff --git a/components/esp_netif/lwip/esp_netif_lwip_defaults.c b/components/esp_netif/lwip/esp_netif_lwip_defaults.c index dc71d61e18..c57445da56 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_defaults.c +++ b/components/esp_netif/lwip/esp_netif_lwip_defaults.c @@ -8,7 +8,7 @@ #include "esp_netif_lwip_internal.h" #include "esp_netif_lwip_ppp.h" -#ifdef CONFIG_ESP_NETIF_TCPIP_LWIP +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) #include "netif/wlanif.h" #include "netif/ethernetif.h" diff --git a/components/esp_netif/lwip/esp_netif_lwip_internal.h b/components/esp_netif/lwip/esp_netif_lwip_internal.h index 66607fe495..e19163c75a 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_internal.h +++ b/components/esp_netif/lwip/esp_netif_lwip_internal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -12,7 +12,7 @@ #include "lwip/netif.h" #include "dhcpserver/dhcpserver.h" -#ifdef CONFIG_ESP_NETIF_TCPIP_LWIP +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) struct esp_netif_netstack_lwip_vanilla_config { err_t (*init_fn)(struct netif*); diff --git a/components/esp_netif/lwip/esp_netif_lwip_orig.c b/components/esp_netif/lwip/esp_netif_lwip_orig.c new file mode 100644 index 0000000000..0465aee7b8 --- /dev/null +++ b/components/esp_netif/lwip/esp_netif_lwip_orig.c @@ -0,0 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include "esp_check.h" +#include "esp_netif_lwip_internal.h" +#include "esp_netif_lwip_orig.h" + +#include "esp_netif.h" +#include "esp_netif_private.h" + +#define DHCP_CB_CHANGE (LWIP_NSC_IPV4_SETTINGS_CHANGED | LWIP_NSC_IPV4_ADDRESS_CHANGED | LWIP_NSC_IPV4_GATEWAY_CHANGED | LWIP_NSC_IPV4_NETMASK_CHANGED) + +static void netif_callback_fn(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args) +{ + if (reason & DHCP_CB_CHANGE) { + esp_netif_internal_dhcpc_cb(netif); + } +#if LWIP_IPV6 + if (reason & LWIP_NSC_IPV6_ADDR_STATE_CHANGED) { + s8_t addr_idx = args->ipv6_addr_state_changed.addr_index; + if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) { + /* address is valid -> call the callback function */ + esp_netif_internal_nd6_cb(netif, addr_idx); + } + } +#endif /* #if LWIP_IPV6 */ +} + +static netif_ext_callback_t netif_callback = { .callback_fn = NULL, .next = NULL }; + +void set_lwip_netif_callback(void) +{ + if (netif_callback.callback_fn == NULL ) { + netif_add_ext_callback(&netif_callback, netif_callback_fn); + } +} + +void remove_lwip_netif_callback(void) +{ + netif_remove_ext_callback(&netif_callback); + memset(&netif_callback, 0, sizeof(netif_callback)); +} + +void dns_clear_servers(bool keep_fallback) +{ + u8_t numdns = 0; + + for (numdns = 0; numdns < DNS_MAX_SERVERS; numdns ++) { + if (keep_fallback && numdns == DNS_FALLBACK_SERVER_INDEX) { + continue; + } + + dns_setserver(numdns, NULL); + } +} + +#ifdef CONFIG_LWIP_GARP_TMR_INTERVAL +void netif_send_garp(void *arg) +{ + struct netif *netif = arg; + etharp_gratuitous(netif); + sys_timeout(CONFIG_LWIP_GARP_TMR_INTERVAL*1000, netif_send_garp, netif); +} + +void netif_set_garp_flag(struct netif *netif) +{ + sys_timeout(CONFIG_LWIP_GARP_TMR_INTERVAL*1000, netif_send_garp, netif); +} + +void netif_unset_garp_flag(struct netif *netif) +{ + sys_untimeout(netif_send_garp, netif); +} +#endif // CONFIG_LWIP_GARP_TMR_INTERVAL diff --git a/components/esp_netif/lwip/esp_netif_lwip_orig.h b/components/esp_netif/lwip/esp_netif_lwip_orig.h new file mode 100644 index 0000000000..f3dd2d743d --- /dev/null +++ b/components/esp_netif/lwip/esp_netif_lwip_orig.h @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_netif_lwip_internal.h" + + +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) + +/** + * @brief Sets one extended lwip netif callbacks for all esp-netif + */ +void set_lwip_netif_callback(void); + +void remove_lwip_netif_callback(void); + +void esp_netif_internal_dhcpc_cb(struct netif *netif); + +void esp_netif_internal_nd6_cb(struct netif *netif, uint8_t index); + +static inline void dhcp_set_cb(struct netif *netif, void (*cb)(struct netif*)) { } + +static inline void nd6_set_cb(struct netif *netif, void (*cb)(struct netif *netif, u8_t ip_index)) { } + +void dns_clear_servers(bool keep_fallback); + +#if ESP_GRATUITOUS_ARP + +void netif_set_garp_flag(struct netif *netif); + +void netif_unset_garp_flag(struct netif *netif); + +#endif // ESP_GRATUITOUS_ARP + +#else // !CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG and !CONFIG_ESP_NETIF_TCPIP_LWIP + +static inline void set_lwip_netif_callback(void) { } + +static inline void remove_lwip_netif_callback(void) { } + +static inline void netif_unset_garp_flag(struct netif *netif) {} + +#endif // CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG or CONFIG_ESP_NETIF_TCPIP_LWIP diff --git a/components/esp_netif/lwip/esp_netif_lwip_ppp.h b/components/esp_netif/lwip/esp_netif_lwip_ppp.h index b579eb80a8..a9abba6649 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_ppp.h +++ b/components/esp_netif/lwip/esp_netif_lwip_ppp.h @@ -1,22 +1,12 @@ -// Copyright 2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _ESP_NETIF_LWIP_PPP_H_ #define _ESP_NETIF_LWIP_PPP_H_ -#if CONFIG_ESP_NETIF_TCPIP_LWIP - /** * @brief Creates new PPP related structure * @@ -77,7 +67,5 @@ esp_err_t esp_netif_stop_ppp(netif_related_data_t *netif_related); */ void esp_netif_ppp_set_default_netif(netif_related_data_t *netif_related); -#endif /* CONFIG_ESP_NETIF_TCPIP_LWIP */ - #endif // _ESP_NETIF_LWIP_PPP_H_ diff --git a/components/lwip/CMakeLists.txt b/components/lwip/CMakeLists.txt index 75dac0f804..5496efd74c 100644 --- a/components/lwip/CMakeLists.txt +++ b/components/lwip/CMakeLists.txt @@ -85,6 +85,7 @@ set(srcs "port/esp32/hooks/lwip_default_hooks.c" "port/esp32/debug/lwip_debug.c" "port/esp32/freertos/sys_arch.c" + "port/esp32/sockets_ext.c" "port/esp32/netif/wlanif.c") if(CONFIG_LWIP_PPP_SUPPORT) @@ -159,15 +160,10 @@ idf_component_register(SRCS "${srcs}" # lots of LWIP source files evaluate macros that check address of stack variables target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-address) -set_source_files_properties( - lwip/src/netif/ppp/ppp.c - PROPERTIES COMPILE_FLAGS - -Wno-uninitialized - ) set_source_files_properties( lwip/src/netif/ppp/pppos.c PROPERTIES COMPILE_FLAGS - -Wno-implicit-fallthrough + -Wno-type-limits ) # "comparison is always false due to limited range of data type" warning # when setting CONFIG_LWIP_TCP_WND_DEFAULT to 65535 diff --git a/components/lwip/linker.lf b/components/lwip/linker.lf index 28c6a14c67..bfb051a28f 100644 --- a/components/lwip/linker.lf +++ b/components/lwip/linker.lf @@ -46,7 +46,6 @@ entries: etharp:etharp_output_to_arp_index (noflash_text) etharp:etharp_output (noflash_text) ip4_addr:ip4_addr_isbroadcast_u32 (noflash_text) - ip4:ip4_route_src_hook (noflash_text) ip4:ip4_route_src (noflash_text) ip4:ip4_route (noflash_text) ip4:ip4_input (noflash_text) diff --git a/components/lwip/lwip b/components/lwip/lwip index 76303df238..6ca936f6b5 160000 --- a/components/lwip/lwip +++ b/components/lwip/lwip @@ -1 +1 @@ -Subproject commit 76303df2386902e0d7873be4217f1d9d1b50f982 +Subproject commit 6ca936f6b588cee702c638eee75c2436e6cf75de diff --git a/components/lwip/port/esp32/include/esp_cpp_sockets.h b/components/lwip/port/esp32/include/esp_cpp_sockets.h new file mode 100644 index 0000000000..e71dd36ab1 --- /dev/null +++ b/components/lwip/port/esp32/include/esp_cpp_sockets.h @@ -0,0 +1,98 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "sys/poll.h" +#include "lwip/sockets.h" +#include "netdb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) + +// lwIP's socket API is mostly implemented as macros, +// but ASIO uses the same symbols in different namespaces, where macros wouldn't work. +// Here we have to undefined the symbols for ASIO build and declare as standard functions +#undef getaddrinfo +#undef gethostbyname_r +#undef gethostbyname +#undef freeaddrinfo +#undef accept +#undef bind +#undef shutdown +#undef getpeername +#undef getsockname +#undef setsockopt +#undef setsockopt +#undef getsockopt +#undef closesocket +#undef connect +#undef listen +#undef recvmsg +#undef recv +#undef recvfrom +#undef sendmsg +#undef send +#undef sendto +#undef socket +#undef inet_ntop +#undef inet_pton +#undef poll +#undef select + +static inline int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) +{ return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop); } +static inline struct hostent *gethostbyname(const char *name) +{ return lwip_gethostbyname(name); } +static inline void freeaddrinfo(struct addrinfo *ai) +{ lwip_freeaddrinfo(ai); } +static inline int getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res) +{ return lwip_getaddrinfo(nodename, servname, hints, res); } +static inline int accept(int s,struct sockaddr *addr,socklen_t *addrlen) +{ return lwip_accept(s,addr,addrlen); } +static inline int bind(int s,const struct sockaddr *name, socklen_t namelen) +{ return lwip_bind(s,name,namelen); } +static inline int shutdown(int s,int how) +{ return lwip_shutdown(s,how); } +static inline int getpeername(int s,struct sockaddr *name,socklen_t *namelen) +{ return lwip_getpeername(s,name,namelen); } +static inline int getsockname(int s,struct sockaddr *name,socklen_t *namelen) +{ return lwip_getsockname(s,name,namelen); } +static inline int setsockopt(int s,int level,int optname,const void *opval,socklen_t optlen) +{ return lwip_setsockopt(s,level,optname,opval,optlen); } +static inline int getsockopt(int s,int level,int optname,void *opval,socklen_t *optlen) +{ return lwip_getsockopt(s,level,optname,opval,optlen); } +static inline int closesocket(int s) +{ return lwip_close(s); } +static inline int connect(int s,const struct sockaddr *name,socklen_t namelen) +{ return lwip_connect(s,name,namelen); } +static inline int listen(int s,int backlog) +{ return lwip_listen(s,backlog); } +static inline ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) +{ return lwip_recvmsg(sockfd, msg, flags); } +static inline ssize_t recv(int s,void *mem,size_t len,int flags) +{ return lwip_recv(s,mem,len,flags); } +static inline ssize_t recvfrom(int s,void *mem,size_t len,int flags,struct sockaddr *from,socklen_t *fromlen) +{ return lwip_recvfrom(s,mem,len,flags,from,fromlen); } +static inline ssize_t send(int s,const void *dataptr,size_t size,int flags) +{ return lwip_send(s,dataptr,size,flags); } +static inline ssize_t sendmsg(int s,const struct msghdr *message,int flags) +{ return lwip_sendmsg(s,message,flags); } +static inline ssize_t sendto(int s,const void *dataptr,size_t size,int flags,const struct sockaddr *to,socklen_t tolen) +{ return lwip_sendto(s,dataptr,size,flags,to,tolen); } +static inline int socket(int domain,int type,int protocol) +{ return lwip_socket(domain,type,protocol); } +static inline const char *inet_ntop(int af, const void *src, char *dst, socklen_t size) +{ return lwip_inet_ntop(af, src, dst, size); } +static inline int inet_pton(int af, const char *src, void *dst) +{ return lwip_inet_pton(af, src, dst); } +#endif // CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG || CONFIG_ESP_NETIF_TCPIP_LWIP + +#ifdef __cplusplus +} +#endif diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index af45cffecb..6fab157aa9 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -16,15 +16,17 @@ #include #include #include -#include "netif/dhcp_state.h" -#include "sntp/sntp_get_set_time.h" +#include #ifdef __linux__ #include "esp32_mock.h" #else #include "esp_task.h" #include "esp_random.h" #endif // __linux__ - +#include "sdkconfig.h" +#include "netif/dhcp_state.h" +#include "sntp/sntp_get_set_time.h" +#include "sockets_ext.h" /* ----------------------------------------------- @@ -589,6 +591,18 @@ #define LWIP_NETIF_STATUS_CALLBACK 0 #endif +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) +/** + * LWIP_NETIF_EXT_STATUS_CALLBACK==1: Support an extended callback function + * for several netif related event that supports multiple subscribers. + * + * This ext-callback is used by ESP-NETIF with lwip-orig (upstream version) + * to provide netif related events on IP4/IP6 address/status changes + */ +#define LWIP_NETIF_EXT_STATUS_CALLBACK 1 +#endif + + /** * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP *tries* to put all data * to be sent into one single pbuf. This is for compatibility with DMA-enabled @@ -1111,6 +1125,11 @@ #endif #define LWIP_HOOK_FILENAME "lwip_default_hooks.h" #define LWIP_HOOK_IP4_ROUTE_SRC ip4_route_src_hook +#define LWIP_HOOK_SOCKETS_GETSOCKOPT(s, sock, level, optname, optval, optlen, err) \ + lwip_getsockopt_impl_ext(sock, level, optname, optval, optlen, err)?(done_socket(sock), true): false + +#define LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, err) \ + lwip_setsockopt_impl_ext(sock, level, optname, optval, optlen, err)?(done_socket(sock), true): false /* --------------------------------------- diff --git a/components/lwip/port/esp32/include/sys/socket.h b/components/lwip/port/esp32/include/sys/socket.h index 5ea4db4ab8..eaaa1e0fec 100644 --- a/components/lwip/port/esp32/include/sys/socket.h +++ b/components/lwip/port/esp32/include/sys/socket.h @@ -30,6 +30,7 @@ * */ +#include "esp_cpp_sockets.h" #include "lwip/sockets.h" /* SOMAXCONN is expected to be found in this header too, diff --git a/components/lwip/port/esp32/vfs_lwip.c b/components/lwip/port/esp32/vfs_lwip.c index 517838e30e..f4c779686d 100644 --- a/components/lwip/port/esp32/vfs_lwip.c +++ b/components/lwip/port/esp32/vfs_lwip.c @@ -1,16 +1,8 @@ -// Copyright 2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index bea739ef1a..761712431f 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -475,7 +475,7 @@ components/esp_local_ctrl/src/esp_local_ctrl_transport_ble.c components/esp_netif/include/esp_netif_ppp.h components/esp_netif/include/esp_netif_slip.h components/esp_netif/loopback/esp_netif_loopback.c -components/esp_netif/lwip/esp_netif_lwip_ppp.h +components/esp_netif/lwip/esp_netif_lwip_ppp.c components/esp_netif/lwip/esp_netif_lwip_slip.c components/esp_netif/lwip/esp_netif_lwip_slip.h components/esp_netif/private_include/esp_netif_private.h @@ -984,7 +984,6 @@ components/lwip/port/esp32/netif/dhcp_state.c components/lwip/port/esp32/netif/ethernetif.c components/lwip/port/esp32/netif/wlanif.c components/lwip/port/esp32/no_vfs_syscalls.c -components/lwip/port/esp32/vfs_lwip.c components/lwip/test_afl_host/dhcp_di.h components/lwip/test_afl_host/dhcpserver_di.h components/lwip/test_afl_host/dns_di.h From b0e4ae4a5e92ffc13d8a86b1d3c3ebee69510b1b Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 17 Mar 2022 12:11:35 +0100 Subject: [PATCH 02/25] examples: Minor fixes in udp_nulticast socket examples Make sure that IPv6 mapped IPv4 addresses are not used when using vanilla lwip --- examples/protocols/sockets/udp_multicast/README.md | 2 +- .../sockets/udp_multicast/main/udp_multicast_example_main.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/protocols/sockets/udp_multicast/README.md b/examples/protocols/sockets/udp_multicast/README.md index 649bd61195..25224649f8 100644 --- a/examples/protocols/sockets/udp_multicast/README.md +++ b/examples/protocols/sockets/udp_multicast/README.md @@ -8,7 +8,7 @@ The behaviour of the example is: * Listens to specified multicast addresses (one IPV4 and/or one IPV6). * Print any UDP packets received as ASCII text. -* If no packets are received it will periodicially (after 2.5 seconds) send its own plaintext packet(s) to the multicast address(es). +* If no packets are received it will periodically (after 2.5 seconds) send its own plaintext packet(s) to the multicast address(es). ## Configuration diff --git a/examples/protocols/sockets/udp_multicast/main/udp_multicast_example_main.c b/examples/protocols/sockets/udp_multicast/main/udp_multicast_example_main.c index 2eed56f510..89eafe65e8 100644 --- a/examples/protocols/sockets/udp_multicast/main/udp_multicast_example_main.c +++ b/examples/protocols/sockets/udp_multicast/main/udp_multicast_example_main.c @@ -417,8 +417,12 @@ static void mcast_example_task(void *pvParameters) #ifdef CONFIG_EXAMPLE_IPV4_ONLY hints.ai_family = AF_INET; // For an IPv4 socket #else + +#ifdef CONFIG_ESP_NETIF_TCPIP_LWIP // Resolving IPv4 mapped IPv6 addresses is supported only in the official TCPIP_LWIP stack (esp-lwip) hints.ai_family = AF_INET6; // For an IPv4 socket with V4 mapped addresses hints.ai_flags |= AI_V4MAPPED; +#endif // CONFIG_ESP_NETIF_TCPIP_LWIP + #endif int err = getaddrinfo(CONFIG_EXAMPLE_MULTICAST_IPV4_ADDR, NULL, From 808ac7427a5c6294c2bd55c5def01b5d3902dcaf Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 17 Mar 2022 12:20:28 +0100 Subject: [PATCH 03/25] lwip: Add freertos sys-arch port layer Added sys_thread_sem_func(), sys_sem_signal_isr(), g_lwip_task --- components/lwip/CMakeLists.txt | 2 +- components/lwip/port/esp32/freertos/sys_arch.c | 6 ++++++ components/lwip/port/esp32/include/lwipopts.h | 8 ++++++++ components/lwip/port/esp32/vfs_lwip.c | 2 ++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/components/lwip/CMakeLists.txt b/components/lwip/CMakeLists.txt index 5496efd74c..48faae4e4b 100644 --- a/components/lwip/CMakeLists.txt +++ b/components/lwip/CMakeLists.txt @@ -42,7 +42,7 @@ set(srcs "lwip/src/core/ipv4/icmp.c" "lwip/src/core/ipv4/igmp.c" "lwip/src/core/ipv4/ip4.c" - "lwip/src/core/ipv4/ip4_napt.c" + #"lwip/src/core/ipv4/ip4_napt.c" "lwip/src/core/ipv4/ip4_addr.c" "lwip/src/core/ipv4/ip4_frag.c" "lwip/src/core/ipv6/dhcp6.c" diff --git a/components/lwip/port/esp32/freertos/sys_arch.c b/components/lwip/port/esp32/freertos/sys_arch.c index 867e414d29..28228ff505 100644 --- a/components/lwip/port/esp32/freertos/sys_arch.c +++ b/components/lwip/port/esp32/freertos/sys_arch.c @@ -53,6 +53,7 @@ static sys_mutex_t g_lwip_protect_mutex = NULL; static pthread_key_t sys_thread_sem_key; static void sys_thread_sem_free(void* data); +sys_thread_t g_lwip_task; #if !LWIP_COMPAT_MUTEX @@ -427,6 +428,11 @@ sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize ret = xTaskCreatePinnedToCore(thread, name, stacksize, arg, prio, &rtos_task, CONFIG_LWIP_TCPIP_TASK_AFFINITY); + g_lwip_task = rtos_task; + + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_task_hdlxxx : %x, prio:%d,stack:%d\n", + (u32_t)g_lwip_task,TCPIP_THREAD_PRIO,TCPIP_THREAD_STACKSIZE)); + if (ret != pdTRUE) { return NULL; } diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index 6fab157aa9..1aaeffc259 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -1384,4 +1384,12 @@ #endif /* CONFIG_LWIP_DHCPS */ +#if LWIP_NETCONN_SEM_PER_THREAD +#if ESP_THREAD_SAFE +#define LWIP_NETCONN_THREAD_SEM_GET() sys_thread_sem_get() +#define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_thread_sem_init() +#define LWIP_NETCONN_THREAD_SEM_FREE() sys_thread_sem_deinit() +#endif +#endif + #endif /* LWIP_HDR_ESP_LWIPOPTS_H */ diff --git a/components/lwip/port/esp32/vfs_lwip.c b/components/lwip/port/esp32/vfs_lwip.c index f4c779686d..ad50fee327 100644 --- a/components/lwip/port/esp32/vfs_lwip.c +++ b/components/lwip/port/esp32/vfs_lwip.c @@ -24,6 +24,8 @@ _Static_assert(MAX_FDS >= CONFIG_LWIP_MAX_SOCKETS, "MAX_FDS < CONFIG_LWIP_MAX_SO #ifdef CONFIG_VFS_SUPPORT_SELECT +int sys_sem_signal_isr(sys_sem_t *sem); + static void lwip_stop_socket_select(void *sem) { sys_sem_signal(sem); //socket_select will return From 06263efe0be36eb1592611cfb13e4a503f0541c8 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 17 Mar 2022 12:43:57 +0100 Subject: [PATCH 04/25] lwip: Add IPv4 route hook to the esp32 port --- .../port/esp32/hooks/lwip_default_hooks.c | 50 +++++++++++++++++++ .../port/esp32/include/lwip_default_hooks.h | 3 ++ 2 files changed, 53 insertions(+) diff --git a/components/lwip/port/esp32/hooks/lwip_default_hooks.c b/components/lwip/port/esp32/hooks/lwip_default_hooks.c index f053c16f15..db34443334 100644 --- a/components/lwip/port/esp32/hooks/lwip_default_hooks.c +++ b/components/lwip/port/esp32/hooks/lwip_default_hooks.c @@ -50,3 +50,53 @@ int __weak lwip_hook_ip6_input(struct pbuf *p, struct netif *inp) return 0; } #endif + +#ifdef LWIP_HOOK_IP4_ROUTE_SRC +#if ESP_IP4_ROUTE +#include "lwip/netif.h" + +bool ip4_netif_exist(const ip4_addr_t *src, const ip4_addr_t *dest) +{ + struct netif *netif = NULL; + + for (netif = netif_list; netif != NULL; netif = netif->next) { + /* is the netif up, does it have a link and a valid address? */ + if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) { + /* source netif and dest netif match? */ + if (ip4_addr_netcmp(src, netif_ip4_addr(netif), netif_ip4_netmask(netif)) || ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) { + /* return false when both netif don't match */ + return true; + } + } + } + + return false; +} + +/** + * Source based IPv4 routing hook function. + */ +struct netif * +ip4_route_src_hook(const ip4_addr_t *src,const ip4_addr_t *dest) +{ + struct netif *netif = NULL; + + /* destination IP is broadcast IP? */ + if ((src != NULL) && !ip4_addr_isany(src)) { + /* iterate through netifs */ + for (netif = netif_list; netif != NULL; netif = netif->next) { + /* is the netif up, does it have a link and a valid address? */ + if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) { + /* source IP matches? */ + if (ip4_addr_cmp(src, netif_ip4_addr(netif))) { + /* return netif on which to forward IP packet */ + + return netif; + } + } + } + } + return netif; +} +#endif +#endif /* LWIP_HOOK_IP4_ROUTE_SRC */ diff --git a/components/lwip/port/esp32/include/lwip_default_hooks.h b/components/lwip/port/esp32/include/lwip_default_hooks.h index 2388d4f3a0..82f30c8bbb 100644 --- a/components/lwip/port/esp32/include/lwip_default_hooks.h +++ b/components/lwip/port/esp32/include/lwip_default_hooks.h @@ -53,6 +53,9 @@ int lwip_hook_ip6_input(struct pbuf *p, struct netif *inp); #define LWIP_HOOK_IP6_INPUT lwip_hook_ip6_input #endif /* CONFIG_LWIP_HOOK_IP6_INPUT_CUSTIOM... */ +struct netif * +ip4_route_src_hook(const ip4_addr_t *src,const ip4_addr_t *dest); + #ifdef __cplusplus } #endif From 65bf5f2b10ac88bee54bb3f9074f4783e3ca8d26 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 17 Mar 2022 12:46:35 +0100 Subject: [PATCH 05/25] lwip: Add mem-heap options to support ALLOCATION_FROM_SPIRAM_FIRST --- components/lwip/port/esp32/include/lwipopts.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index 1aaeffc259..8e6353e363 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -1392,4 +1392,17 @@ #endif #endif +/** + * If CONFIG_ALLOC_MEMORY_IN_SPIRAM_FIRST is enabled, Try to + * allocate memory for lwip in SPIRAM firstly. If failed, try to allocate + * internal memory then. + */ +#if CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST +#define mem_clib_malloc(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL) +#define mem_clib_calloc(n, size) heap_caps_calloc_prefer(n, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL) +#else /* !CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST */ +#define mem_clib_malloc malloc +#define mem_clib_calloc calloc +#endif /* CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST */ + #endif /* LWIP_HDR_ESP_LWIPOPTS_H */ From dbc91f73e64548a8a81a88ba2998380fc9328226 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 17 Mar 2022 12:51:00 +0100 Subject: [PATCH 06/25] lwip: Use custom pbufs for eth and wifi port/netif --- components/lwip/CMakeLists.txt | 3 +- components/lwip/port/esp32/include/lwipopts.h | 2 +- .../port/esp32/include/netif/esp_pbuf_ref.h | 32 ++++++++++ .../lwip/port/esp32/netif/esp_pbuf_ref.c | 58 ++++++++++++++++++ components/lwip/port/esp32/netif/ethernetif.c | 37 +++-------- .../lwip/port/esp32/netif/openthreadif.c | 10 --- components/lwip/port/esp32/netif/wlanif.c | 61 +++++++------------ 7 files changed, 124 insertions(+), 79 deletions(-) create mode 100644 components/lwip/port/esp32/include/netif/esp_pbuf_ref.h create mode 100644 components/lwip/port/esp32/netif/esp_pbuf_ref.c diff --git a/components/lwip/CMakeLists.txt b/components/lwip/CMakeLists.txt index 48faae4e4b..d49b11022e 100644 --- a/components/lwip/CMakeLists.txt +++ b/components/lwip/CMakeLists.txt @@ -86,7 +86,8 @@ set(srcs "port/esp32/debug/lwip_debug.c" "port/esp32/freertos/sys_arch.c" "port/esp32/sockets_ext.c" - "port/esp32/netif/wlanif.c") + "port/esp32/netif/wlanif.c" + "port/esp32/netif/esp_pbuf_ref.c") if(CONFIG_LWIP_PPP_SUPPORT) list(APPEND srcs diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index 8e6353e363..9f36d970ce 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -1365,7 +1365,7 @@ #define ESP_LWIP_SELECT 1 #define ESP_LWIP_LOCK 1 #define ESP_THREAD_PROTECTION 1 -#define ESP_IP_FORWARD 1 +#define LWIP_SUPPORT_CUSTOM_PBUF 1 /* ----------------------------------------- diff --git a/components/lwip/port/esp32/include/netif/esp_pbuf_ref.h b/components/lwip/port/esp32/include/netif/esp_pbuf_ref.h new file mode 100644 index 0000000000..0747ad4c7a --- /dev/null +++ b/components/lwip/port/esp32/include/netif/esp_pbuf_ref.h @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @file esp_pbuf reference interface file + */ + +#ifndef __LWIP_ESP_PBUF_REF_H__ +#define __LWIP_ESP_PBUF_REF_H__ + +#include +#include "lwip/pbuf.h" +#include "esp_netif.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Allocate custom pbuf containing pointer to a private l2-free function + * + * @note pbuf_free() will deallocate this custom pbuf and call the driver assigned free function + */ +struct pbuf* esp_pbuf_allocate(esp_netif_t *esp_netif, void *buffer, size_t len, void *l2_buff); + +#ifdef __cplusplus +} +#endif + +#endif //__LWIP_ESP_PBUF_REF_H__ diff --git a/components/lwip/port/esp32/netif/esp_pbuf_ref.c b/components/lwip/port/esp32/netif/esp_pbuf_ref.c new file mode 100644 index 0000000000..e1bb54c7d1 --- /dev/null +++ b/components/lwip/port/esp32/netif/esp_pbuf_ref.c @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** + * @file esp_pbuf reference + * This file handles lwip custom pbufs interfacing with esp_netif + * and the L2 free function esp_netif_free_rx_buffer() + */ + +#include "netif/esp_pbuf_ref.h" +#include "esp_netif_net_stack.h" +#include "lwip/mem.h" + +/** + * @brief Specific pbuf structure for pbufs allocated by ESP netif + * of PBUF_REF type + */ +typedef struct esp_custom_pbuf +{ + struct pbuf_custom p; + esp_netif_t *esp_netif; + void* l2_buf; +} esp_custom_pbuf_t; + +/** + * @brief Free custom pbuf containing the L2 layer buffer allocated in the driver + * + * @param pbuf Custom pbuf holding the packet passed to lwip input + * @note This function called as a custom_free_function() upon pbuf_free() + */ +static void esp_pbuf_free(struct pbuf *pbuf) +{ + esp_custom_pbuf_t* esp_pbuf = (esp_custom_pbuf_t*)pbuf; + esp_netif_free_rx_buffer(esp_pbuf->esp_netif, esp_pbuf->l2_buf); + mem_free(pbuf); +} + + +struct pbuf* esp_pbuf_allocate(esp_netif_t *esp_netif, void *buffer, size_t len, void *l2_buff) +{ + struct pbuf *p; + + esp_custom_pbuf_t* esp_pbuf = mem_malloc(sizeof(esp_custom_pbuf_t)); + if (esp_pbuf == NULL) { + return NULL; + } + esp_pbuf->p.custom_free_function = esp_pbuf_free; + esp_pbuf->esp_netif = esp_netif; + esp_pbuf->l2_buf = l2_buff; + p = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &esp_pbuf->p, buffer, len); + if (p == NULL) { + mem_free(esp_pbuf); + return NULL; + } + return p; +} diff --git a/components/lwip/port/esp32/netif/ethernetif.c b/components/lwip/port/esp32/netif/ethernetif.c index 3b51af804d..94aaef84ab 100644 --- a/components/lwip/port/esp32/netif/ethernetif.c +++ b/components/lwip/port/esp32/netif/ethernetif.c @@ -52,22 +52,12 @@ #include "esp_netif.h" #include "esp_netif_net_stack.h" #include "esp_compiler.h" +#include "netif/esp_pbuf_ref.h" /* Define those to better describe your network interface. */ #define IFNAME0 'e' #define IFNAME1 'n' -/** - * @brief Free resources allocated in L2 layer - * - * @param buf memory alloc in L2 layer - * @note this function is also the callback when invoke pbuf_free - */ -static void ethernet_free_rx_buf_l2(struct netif *netif, void *buf) -{ - free(buf); -} - /** * In this function, the hardware should be initialized. * Invoked by ethernetif_init(). @@ -120,11 +110,6 @@ static err_t ethernet_low_level_output(struct netif *netif, struct pbuf *p) LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug")); q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM); if (q != NULL) { -#if ESP_LWIP - /* This pbuf RAM was not allocated on layer2, no extra free operation needed in pbuf_free */ - q->l2_owner = NULL; - q->l2_buf = NULL; -#endif pbuf_copy(q, p); } else { return ERR_MEM; @@ -149,33 +134,30 @@ static err_t ethernet_low_level_output(struct netif *netif, struct pbuf *p) * interface. Then the type of the received packet is determined and * the appropriate input function is called. * - * @param netif lwip network interface structure for this ethernetif + * @param h lwip network interface structure (struct netif) for this ethernetif * @param buffer ethernet buffer * @param len length of buffer + * @param l2_buff Placeholder for a separate L2 buffer. Unused for ethernet interface */ -void ethernetif_input(void *h, void *buffer, size_t len, void *eb) +void ethernetif_input(void *h, void *buffer, size_t len, void *l2_buff) { struct netif *netif = h; + esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif); struct pbuf *p; if (unlikely(buffer == NULL || !netif_is_up(netif))) { if (buffer) { - ethernet_free_rx_buf_l2(netif, buffer); + esp_netif_free_rx_buffer(esp_netif, buffer); } return; } - /* acquire new pbuf, type: PBUF_REF */ - p = pbuf_alloc(PBUF_RAW, len, PBUF_REF); + /* allocate custom pbuf to hold */ + p = esp_pbuf_allocate(esp_netif, buffer, len, buffer); if (p == NULL) { - ethernet_free_rx_buf_l2(netif, buffer); + esp_netif_free_rx_buffer(esp_netif, buffer); return; } - p->payload = buffer; -#if ESP_LWIP - p->l2_owner = netif; - p->l2_buf = buffer; -#endif /* full packet send to tcpip_thread to process */ if (unlikely(netif->input(p, netif) != ERR_OK)) { LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); @@ -228,7 +210,6 @@ err_t ethernetif_init(struct netif *netif) netif->output_ip6 = ethip6_output; #endif /* LWIP_IPV6 */ netif->linkoutput = ethernet_low_level_output; - netif->l2_buffer_free_notify = ethernet_free_rx_buf_l2; ethernet_low_level_init(netif); diff --git a/components/lwip/port/esp32/netif/openthreadif.c b/components/lwip/port/esp32/netif/openthreadif.c index b71940948b..4f26c04f30 100644 --- a/components/lwip/port/esp32/netif/openthreadif.c +++ b/components/lwip/port/esp32/netif/openthreadif.c @@ -37,11 +37,6 @@ static err_t openthread_output_ip6(struct netif *netif, struct pbuf *p, const st LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug")); q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM); if (q != NULL) { -#if ESP_LWIP - /* This pbuf RAM was not allocated on layer2, no extra free operation needed in pbuf_free */ - q->l2_owner = NULL; - q->l2_buf = NULL; -#endif pbuf_copy(q, p); } else { return ERR_MEM; @@ -84,10 +79,6 @@ void openthread_netif_input(void *h, void *buffer, size_t len, void *eb) LWIP_DEBUGF(NETIF_DEBUG, ("Failed to read OpenThread message\n")); } -#if ESP_LWIP - p->l2_owner = NULL; - p->l2_buf = NULL; -#endif /* full packet send to tcpip_thread to process */ if (unlikely(netif->input(p, netif) != ERR_OK)) { LWIP_DEBUGF(NETIF_DEBUG, ("openthread_netif_input: IP input error\n")); @@ -135,7 +126,6 @@ err_t openthread_netif_init(struct netif *netif) netif->output = NULL; netif->output_ip6 = openthread_output_ip6; netif->mld_mac_filter = openthread_netif_multicast_handler; - netif->l2_buffer_free_notify = NULL; netif_set_link_up(netif); return ERR_OK; diff --git a/components/lwip/port/esp32/netif/wlanif.c b/components/lwip/port/esp32/netif/wlanif.c index f927e2f58a..51301fb934 100644 --- a/components/lwip/port/esp32/netif/wlanif.c +++ b/components/lwip/port/esp32/netif/wlanif.c @@ -1,6 +1,6 @@ /** * @file - * Ethernet Interface Skeleton + * Ethernet Interface Skeleton used for WiFi * */ @@ -53,27 +53,14 @@ #include "esp_netif.h" #include "esp_netif_net_stack.h" #include "esp_compiler.h" - -#ifndef CONFIG_LWIP_L2_TO_L3_COPY -/** - * @brief Free resources allocated in L2 layer - * - * @param buf memory alloc in L2 layer - * @note this function is also the callback when invoke pbuf_free - */ -static void lwip_netif_wifi_free_rx_buffer(struct netif *netif, void *buf) -{ - esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif); - esp_netif_free_rx_buffer(esp_netif, buf); -} -#endif +#include "netif/esp_pbuf_ref.h" /** * In this function, the hardware should be initialized. - * Called from ethernetif_init(). + * Called from wlanif_input(). * * @param netif the already initialized lwip network interface structure - * for this ethernetif + * for this wlanif */ static void low_level_init(struct netif *netif) @@ -102,9 +89,6 @@ low_level_init(struct netif *netif) #endif #endif -#ifndef CONFIG_LWIP_L2_TO_L3_COPY - netif->l2_buffer_free_notify = lwip_netif_wifi_free_rx_buffer; -#endif } /** @@ -112,14 +96,14 @@ low_level_init(struct netif *netif) * contained in the pbuf that is passed to the function. This pbuf * might be chained. * - * @param netif the lwip network interface structure for this ethernetif + * @param netif the lwip network interface structure for this wlanif * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) * @return ERR_OK if the packet could be sent * an err_t value if the packet couldn't be sent * * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to * strange results. You might consider waiting for space in the DMA queue - * to become availale since the stack doesn't retry to send a packet + * to become available since the stack doesn't retry to send a packet * dropped because of memory failure (except for the TCP timers). */ static err_t @@ -140,7 +124,6 @@ low_level_output(struct netif *netif, struct pbuf *p) LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug")); q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM); if (q != NULL) { - q->l2_owner = NULL; pbuf_copy(q, p); } else { return ERR_MEM; @@ -168,18 +151,21 @@ low_level_output(struct netif *netif, struct pbuf *p) * interface. Then the type of the received packet is determined and * the appropriate input function is called. * - * @param netif the lwip network interface structure for this ethernetif + * @param h lwip network interface structure (struct netif) for this ethernetif + * @param buffer wlan buffer + * @param len length of buffer + * @param l2_buff wlan's L2 buffer pointer */ void -wlanif_input(void *h, void *buffer, size_t len, void* eb) +wlanif_input(void *h, void *buffer, size_t len, void* l2_buff) { struct netif * netif = h; esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif); struct pbuf *p; if(unlikely(!buffer || !netif_is_up(netif))) { - if (eb) { - esp_netif_free_rx_buffer(esp_netif, eb); + if (l2_buff) { + esp_netif_free_rx_buffer(esp_netif, l2_buff); } return; } @@ -187,26 +173,23 @@ wlanif_input(void *h, void *buffer, size_t len, void* eb) #ifdef CONFIG_LWIP_L2_TO_L3_COPY p = pbuf_alloc(PBUF_RAW, len, PBUF_RAM); if (p == NULL) { - esp_netif_free_rx_buffer(esp_netif, eb); + esp_netif_free_rx_buffer(esp_netif, l2_buff); return; } - p->l2_owner = NULL; memcpy(p->payload, buffer, len); - esp_netif_free_rx_buffer(esp_netif, eb); + esp_netif_free_rx_buffer(esp_netif, l2_buff); #else - p = pbuf_alloc(PBUF_RAW, len, PBUF_REF); - if (p == NULL){ - esp_netif_free_rx_buffer(esp_netif, eb); + p = esp_pbuf_allocate(esp_netif, buffer, len, l2_buff); + if (p == NULL) { + esp_netif_free_rx_buffer(esp_netif, l2_buff); return; } - p->payload = buffer; - p->l2_owner = netif; - p->l2_buf = eb; -#endif /* CONFIG_LWIP_L2_TO_L3_COPY */ + +#endif /* full packet send to tcpip_thread to process */ if (unlikely(netif->input(p, netif) != ERR_OK)) { - LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + LWIP_DEBUGF(NETIF_DEBUG, ("wlanif_input: IP input error\n")); pbuf_free(p); } @@ -219,7 +202,7 @@ wlanif_input(void *h, void *buffer, size_t len, void* eb) * * This function should be passed as a parameter to netif_add(). * - * @param netif the lwip network interface structure for this ethernetif + * @param netif the lwip network interface structure for this wlanif * @return ERR_OK if the loopif is initialized * ERR_MEM if private data couldn't be allocated * any other err_t on error From 44a9620c17bde23e6cb8ae8e7b83925a89ce2a2d Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 17 Mar 2022 12:59:06 +0100 Subject: [PATCH 07/25] esp_netif: Add thread safe pppapi set_auth API to esp-netif --- .../esp_netif/lwip/esp_netif_lwip_orig.c | 23 +++++++++++++++++++ .../esp_netif/lwip/esp_netif_lwip_orig.h | 8 +++++++ .../esp_netif/lwip/esp_netif_lwip_ppp.c | 1 + tools/ci/check_copyright_ignore.txt | 1 - 4 files changed, 32 insertions(+), 1 deletion(-) diff --git a/components/esp_netif/lwip/esp_netif_lwip_orig.c b/components/esp_netif/lwip/esp_netif_lwip_orig.c index 0465aee7b8..5610df4e00 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_orig.c +++ b/components/esp_netif/lwip/esp_netif_lwip_orig.c @@ -61,6 +61,29 @@ void dns_clear_servers(bool keep_fallback) dns_setserver(numdns, NULL); } } +#if PPP_SUPPORT && PPP_AUTH_SUPPORT +typedef struct { + struct tcpip_api_call_data call; + ppp_pcb *ppp; + u8_t authtype; + const char *user; + const char *passwd; +} set_auth_msg_t; + +static err_t pppapi_do_ppp_set_auth(struct tcpip_api_call_data *m) +{ + set_auth_msg_t *msg = (set_auth_msg_t *)m; + ppp_set_auth(msg->ppp, msg->authtype, msg->user, msg->passwd); + return ERR_OK; +} + +void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) +{ + set_auth_msg_t msg = { .ppp = pcb, .authtype = authtype, .user = user, .passwd = passwd}; + tcpip_api_call(pppapi_do_ppp_set_auth, &msg.call); +} + +#endif // PPP_SUPPORT && PPP_AUTH_SUPPORT #ifdef CONFIG_LWIP_GARP_TMR_INTERVAL void netif_send_garp(void *arg) diff --git a/components/esp_netif/lwip/esp_netif_lwip_orig.h b/components/esp_netif/lwip/esp_netif_lwip_orig.h index f3dd2d743d..d39e6a17e0 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_orig.h +++ b/components/esp_netif/lwip/esp_netif_lwip_orig.h @@ -11,6 +11,10 @@ #if defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) +#if PPP_SUPPORT +typedef struct ppp_pcb_s ppp_pcb; +#endif + /** * @brief Sets one extended lwip netif callbacks for all esp-netif */ @@ -28,6 +32,10 @@ static inline void nd6_set_cb(struct netif *netif, void (*cb)(struct netif *neti void dns_clear_servers(bool keep_fallback); +#if PPP_SUPPORT && PPP_AUTH_SUPPORT +void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd); +#endif + #if ESP_GRATUITOUS_ARP void netif_set_garp_flag(struct netif *netif); diff --git a/components/esp_netif/lwip/esp_netif_lwip_ppp.c b/components/esp_netif/lwip/esp_netif_lwip_ppp.c index 19907219ce..858603f69c 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_ppp.c +++ b/components/esp_netif/lwip/esp_netif_lwip_ppp.c @@ -17,6 +17,7 @@ #include "esp_event.h" #include "esp_netif_ppp.h" #include "esp_netif_lwip_internal.h" +#include "esp_netif_lwip_orig.h" #include #include "lwip/ip6_addr.h" diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 761712431f..a0d014044f 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -475,7 +475,6 @@ components/esp_local_ctrl/src/esp_local_ctrl_transport_ble.c components/esp_netif/include/esp_netif_ppp.h components/esp_netif/include/esp_netif_slip.h components/esp_netif/loopback/esp_netif_loopback.c -components/esp_netif/lwip/esp_netif_lwip_ppp.c components/esp_netif/lwip/esp_netif_lwip_slip.c components/esp_netif/lwip/esp_netif_lwip_slip.h components/esp_netif/private_include/esp_netif_private.h From e909cd52198f108f87b31795c65bb06874ca8829 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 17 Mar 2022 13:01:53 +0100 Subject: [PATCH 08/25] tcp_transport/test: Fix localhost interface name Per lwip spec it's two letter's name plus index, i.e. "lo0" (the reason "lo" was accepted before was bug in lwip) --- components/tcp_transport/test/test_transport_connect.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/tcp_transport/test/test_transport_connect.c b/components/tcp_transport/test/test_transport_connect.c index 514c8cfdf8..2160d47e9b 100644 --- a/components/tcp_transport/test/test_transport_connect.c +++ b/components/tcp_transport/test/test_transport_connect.c @@ -12,7 +12,8 @@ struct ifreq ifr; \ ifr.ifr_name[0] = 'l'; \ ifr.ifr_name[1] = 'o'; \ - ifr.ifr_name[2] = '\0'; + ifr.ifr_name[2] = '0'; \ + ifr.ifr_name[3] = '\0'; static void tcp_transport_keepalive_test(esp_transport_handle_t transport_under_test, bool async, esp_transport_keep_alive_t *config) From 53c009e62631bae569fa849c6b6c9e70a10b3afe Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 17 Mar 2022 13:07:05 +0100 Subject: [PATCH 09/25] lwip: Update socket API to include port-version of sockets/netdb Added socket extention to the lwip hooks for implementing non-vanilla {get/set}sockopts() --- .../asio/port/include/esp_asio_config.h | 4 +- components/lwip/CMakeLists.txt | 1 + components/lwip/include/lwip/netdb.h | 31 +++++ .../lwip/sockets.h} | 44 +------ components/lwip/port/esp32/include/lwipopts.h | 2 +- .../lwip/port/esp32/include/sockets_ext.h | 24 ++++ .../lwip/port/esp32/include/sys/socket.h | 1 - components/lwip/port/esp32/sockets_ext.c | 108 ++++++++++++++++++ tools/ci/check_public_headers_exceptions.txt | 1 + 9 files changed, 171 insertions(+), 45 deletions(-) create mode 100644 components/lwip/include/lwip/netdb.h rename components/lwip/{port/esp32/include/esp_cpp_sockets.h => include/lwip/sockets.h} (66%) create mode 100644 components/lwip/port/esp32/include/sockets_ext.h create mode 100644 components/lwip/port/esp32/sockets_ext.c diff --git a/components/asio/port/include/esp_asio_config.h b/components/asio/port/include/esp_asio_config.h index d80717ed9a..f8e34d617a 100644 --- a/components/asio/port/include/esp_asio_config.h +++ b/components/asio/port/include/esp_asio_config.h @@ -19,9 +19,9 @@ # endif // CONFIG_COMPILER_RTTI // -// LWIP compatibility inet and address macros/functions +// Use system sockets // -# include "esp_cpp_sockets.h" +# include "sys/socket.h" // // Specific ASIO feature flags diff --git a/components/lwip/CMakeLists.txt b/components/lwip/CMakeLists.txt index d49b11022e..e2d35384eb 100644 --- a/components/lwip/CMakeLists.txt +++ b/components/lwip/CMakeLists.txt @@ -1,4 +1,5 @@ set(include_dirs + include include/apps include/apps/sntp lwip/src/include diff --git a/components/lwip/include/lwip/netdb.h b/components/lwip/include/lwip/netdb.h new file mode 100644 index 0000000000..cc395bac61 --- /dev/null +++ b/components/lwip/include/lwip/netdb.h @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include +#include_next "lwip/netdb.h" +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) + +static inline int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) +{ return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop); } +static inline struct hostent *gethostbyname(const char *name) +{ return lwip_gethostbyname(name); } +static inline void freeaddrinfo(struct addrinfo *ai) +{ lwip_freeaddrinfo(ai); } +static inline int getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res) +{ return lwip_getaddrinfo(nodename, servname, hints, res); } + +#endif // CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG || CONFIG_ESP_NETIF_TCPIP_LWIP + +#ifdef __cplusplus +} +#endif diff --git a/components/lwip/port/esp32/include/esp_cpp_sockets.h b/components/lwip/include/lwip/sockets.h similarity index 66% rename from components/lwip/port/esp32/include/esp_cpp_sockets.h rename to components/lwip/include/lwip/sockets.h index e71dd36ab1..1b475e3719 100644 --- a/components/lwip/port/esp32/include/esp_cpp_sockets.h +++ b/components/lwip/include/lwip/sockets.h @@ -5,9 +5,8 @@ */ #pragma once -#include "sys/poll.h" -#include "lwip/sockets.h" -#include "netdb.h" +#include_next "lwip/sockets.h" +#include "sdkconfig.h" #ifdef __cplusplus extern "C" { @@ -15,44 +14,6 @@ extern "C" { #if defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) -// lwIP's socket API is mostly implemented as macros, -// but ASIO uses the same symbols in different namespaces, where macros wouldn't work. -// Here we have to undefined the symbols for ASIO build and declare as standard functions -#undef getaddrinfo -#undef gethostbyname_r -#undef gethostbyname -#undef freeaddrinfo -#undef accept -#undef bind -#undef shutdown -#undef getpeername -#undef getsockname -#undef setsockopt -#undef setsockopt -#undef getsockopt -#undef closesocket -#undef connect -#undef listen -#undef recvmsg -#undef recv -#undef recvfrom -#undef sendmsg -#undef send -#undef sendto -#undef socket -#undef inet_ntop -#undef inet_pton -#undef poll -#undef select - -static inline int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) -{ return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop); } -static inline struct hostent *gethostbyname(const char *name) -{ return lwip_gethostbyname(name); } -static inline void freeaddrinfo(struct addrinfo *ai) -{ lwip_freeaddrinfo(ai); } -static inline int getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res) -{ return lwip_getaddrinfo(nodename, servname, hints, res); } static inline int accept(int s,struct sockaddr *addr,socklen_t *addrlen) { return lwip_accept(s,addr,addrlen); } static inline int bind(int s,const struct sockaddr *name, socklen_t namelen) @@ -91,6 +52,7 @@ static inline const char *inet_ntop(int af, const void *src, char *dst, socklen_ { return lwip_inet_ntop(af, src, dst, size); } static inline int inet_pton(int af, const char *src, void *dst) { return lwip_inet_pton(af, src, dst); } + #endif // CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG || CONFIG_ESP_NETIF_TCPIP_LWIP #ifdef __cplusplus diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index 9f36d970ce..362283ad20 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -804,7 +804,7 @@ * While this helps code completion, it might conflict with existing libraries. * (only used if you use sockets.c) */ -#define LWIP_COMPAT_SOCKETS 1 +#define LWIP_COMPAT_SOCKETS 0 /** * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. diff --git a/components/lwip/port/esp32/include/sockets_ext.h b/components/lwip/port/esp32/include/sockets_ext.h new file mode 100644 index 0000000000..48ffcf61e1 --- /dev/null +++ b/components/lwip/port/esp32/include/sockets_ext.h @@ -0,0 +1,24 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define IPV6_MULTICAST_IF 0x300 +#define IPV6_MULTICAST_HOPS 0x301 +#define IPV6_MULTICAST_LOOP 0x302 + +struct lwip_sock; + +bool lwip_setsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, const void *optval, uint32_t optlen, int *err); +bool lwip_getsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, void *optval, uint32_t *optlen, int *err); +#ifdef __cplusplus +} +#endif diff --git a/components/lwip/port/esp32/include/sys/socket.h b/components/lwip/port/esp32/include/sys/socket.h index eaaa1e0fec..5ea4db4ab8 100644 --- a/components/lwip/port/esp32/include/sys/socket.h +++ b/components/lwip/port/esp32/include/sys/socket.h @@ -30,7 +30,6 @@ * */ -#include "esp_cpp_sockets.h" #include "lwip/sockets.h" /* SOMAXCONN is expected to be found in this header too, diff --git a/components/lwip/port/esp32/sockets_ext.c b/components/lwip/port/esp32/sockets_ext.c new file mode 100644 index 0000000000..fb1454b21b --- /dev/null +++ b/components/lwip/port/esp32/sockets_ext.c @@ -0,0 +1,108 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "lwip/sockets.h" +#include "lwip/priv/sockets_priv.h" +#include "lwip/api.h" +#include "lwip/sys.h" +#include "lwip/tcp.h" +#include "lwip/raw.h" +#include "lwip/udp.h" + +#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype) do { \ + if (((optlen) < sizeof(opttype)) || ((sock)->conn == NULL) || ((sock)->conn->pcb.tcp == NULL)) { *err=EINVAL; goto exit; } }while(0) + +#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, opttype, netconntype) do { \ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype); \ + if (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) != netconntype) { *err=ENOPROTOOPT; goto exit; } } while(0) + + +bool lwip_setsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, const void *optval, socklen_t optlen, int *err) +{ +#if LWIP_IPV6 + if (level != IPPROTO_IPV6) +#endif /* LWIP_IPV6 */ + { + return false; + } + +#if LWIP_IPV6 + switch (optname) { + default: + return false; + case IPV6_MULTICAST_IF: /* NB: like IP_MULTICAST_IF, this takes an IP not an index */ + { + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); + udp_set_multicast_netif_index(sock->conn->pcb.udp, (u8_t)(*(const u8_t*)optval)); + } + break; + case IPV6_MULTICAST_HOPS: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); + udp_set_multicast_ttl(sock->conn->pcb.udp, (u8_t)(*(const u8_t*)optval)); + break; + case IPV6_MULTICAST_LOOP: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); + if (*(const u8_t*)optval) { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP); + } else { + udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP); + } + break; + } +exit: + return true; +#endif /* LWIP_IPV6 */ +} + +bool lwip_getsockopt_impl_ext(struct lwip_sock* sock, int level, int optname, void *optval, uint32_t *optlen, int *err) +{ +#if LWIP_IPV6 + if (level != IPPROTO_IPV6) +#endif /* LWIP_IPV6 */ + { + return false; + } + +#if LWIP_IPV6 + switch (optname) { + default: + return false; + case IPV6_MULTICAST_IF: /* NB: like IP_MULTICAST_IF, this returns an IP not an index */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { + *err = ENOPROTOOPT; + goto exit; + } + *(u8_t*)optval = udp_get_multicast_netif_index(sock->conn->pcb.udp); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt_ext(IPPROTO_IPV6, IPV6_MULTICAST_IF) = 0x%"X32_F"\n", + *(u32_t *)optval)); + break; + case IPV6_MULTICAST_HOPS: + printf("IPV6_MULTICAST_HOPS\n"); + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { + *err = ENOPROTOOPT; + goto exit; + } + *(u8_t*)optval = udp_get_multicast_ttl(sock->conn->pcb.udp); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt_ext(IPPROTO_IPV6, IP_MULTICAST_LOOP) = %d\n", + *(int *)optval)); + break; + case IPV6_MULTICAST_LOOP: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); + if ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_MULTICAST_LOOP) != 0) { + *(u8_t*)optval = 1; + } else { + *(u8_t*)optval = 0; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt_ext(IPPROTO_IPV6, IP_MULTICAST_LOOP) = %d\n", + *(int *)optval)); + break; + } +exit: + return true; +#endif /* LWIP_IPV6 */ +} diff --git a/tools/ci/check_public_headers_exceptions.txt b/tools/ci/check_public_headers_exceptions.txt index 6bb5848ba0..049116b585 100644 --- a/tools/ci/check_public_headers_exceptions.txt +++ b/tools/ci/check_public_headers_exceptions.txt @@ -143,5 +143,6 @@ components/openssl/include/openssl/ssl.h components/ulp/include/ulp_common.h components/ulp/include/esp32s2/ulp_riscv.h components/lwip/include/apps/sntp/sntp.h +components/lwip/include/lwip/sockets.h components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h components/wifi_provisioning/include/wifi_provisioning/scheme_softap.h From 7a04eb8d66b2233602c39d86f49099f3c1fca8d0 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 17 Mar 2022 13:21:07 +0100 Subject: [PATCH 10/25] lwip: Reference specific ESP patches Also adding ip4_napt.c to sources, as it's added by ESP-patches --- components/lwip/CMakeLists.txt | 2 +- components/lwip/lwip | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/components/lwip/CMakeLists.txt b/components/lwip/CMakeLists.txt index e2d35384eb..e669e939ea 100644 --- a/components/lwip/CMakeLists.txt +++ b/components/lwip/CMakeLists.txt @@ -43,7 +43,7 @@ set(srcs "lwip/src/core/ipv4/icmp.c" "lwip/src/core/ipv4/igmp.c" "lwip/src/core/ipv4/ip4.c" - #"lwip/src/core/ipv4/ip4_napt.c" + "lwip/src/core/ipv4/ip4_napt.c" "lwip/src/core/ipv4/ip4_addr.c" "lwip/src/core/ipv4/ip4_frag.c" "lwip/src/core/ipv6/dhcp6.c" diff --git a/components/lwip/lwip b/components/lwip/lwip index 6ca936f6b5..104e8fa4c8 160000 --- a/components/lwip/lwip +++ b/components/lwip/lwip @@ -1 +1 @@ -Subproject commit 6ca936f6b588cee702c638eee75c2436e6cf75de +Subproject commit 104e8fa4c881a98eefa3776d2701a6b90b9aa63d From 356bc603c4647323cd1f3ec8361bd719525829d9 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Wed, 23 Mar 2022 19:20:06 +0100 Subject: [PATCH 11/25] lwip: Support DHCP restore last IP --- components/esp_netif/lwip/esp_netif_lwip.c | 9 +- .../port/esp32/include/lwip_default_hooks.h | 7 +- components/lwip/port/esp32/include/lwipopts.h | 19 +++-- .../port/esp32/include/netif/dhcp_state.h | 14 +-- components/lwip/port/esp32/netif/dhcp_state.c | 85 ++++++++----------- tools/ci/check_copyright_ignore.txt | 1 - 6 files changed, 66 insertions(+), 69 deletions(-) diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index 7fe1d2d67a..783ea1b81a 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -38,7 +38,7 @@ #include "esp_netif_lwip_slip.h" #include "dhcpserver/dhcpserver.h" #include "dhcpserver/dhcpserver_options.h" - +#include "netif/dhcp_state.h" #include "esp_event.h" #include "esp_log.h" @@ -987,6 +987,9 @@ void esp_netif_internal_dhcpc_cb(struct netif *netif) if (ESP_OK != ret) { ESP_LOGE(TAG, "dhcpc cb: failed to post got ip event (%x)", ret); } +#ifdef CONFIG_LWIP_DHCP_RESTORE_LAST_IP + dhcp_ip_addr_store(netif); +#endif /* CONFIG_LWIP_DHCP_RESTORE_LAST_IP */ } else { ESP_LOGD(TAG, "if%p ip unchanged", esp_netif); } @@ -1089,7 +1092,9 @@ static esp_err_t esp_netif_dhcpc_stop_api(esp_netif_api_msg_t *msg) ESP_LOGD(TAG, "dhcp client stop successfully"); esp_netif->dhcpc_status = ESP_NETIF_DHCP_STOPPED; - LWIP_DHCP_IP_ADDR_ERASE(esp_netif); +#ifdef CONFIG_LWIP_DHCP_RESTORE_LAST_IP + dhcp_ip_addr_erase(esp_netif->lwip_netif); +#endif /* CONFIG_LWIP_DHCP_RESTORE_LAST_IP */ return ESP_OK; } diff --git a/components/lwip/port/esp32/include/lwip_default_hooks.h b/components/lwip/port/esp32/include/lwip_default_hooks.h index 82f30c8bbb..1577b60e6b 100644 --- a/components/lwip/port/esp32/include/lwip_default_hooks.h +++ b/components/lwip/port/esp32/include/lwip_default_hooks.h @@ -4,12 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef _LWIP_DEFAULT_HOOKS_H_ -#define _LWIP_DEFAULT_HOOKS_H_ +#ifndef LWIP_ESP_DEFAULT_HOOKS_H_ +#define LWIP_ESP_DEFAULT_HOOKS_H_ #include "lwip/ip_addr.h" #include "lwip/arch.h" #include "lwip/err.h" #include "lwip/pbuf.h" +#include "netif/dhcp_state.h" #ifdef ESP_IDF_LWIP_HOOK_FILENAME #include ESP_IDF_LWIP_HOOK_FILENAME @@ -60,4 +61,4 @@ ip4_route_src_hook(const ip4_addr_t *src,const ip4_addr_t *dest); } #endif -#endif /* _LWIP_DEFAULT_HOOKS_H_ */ +#endif /* LWIP_ESP_DEFAULT_HOOKS_H_ */ diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index 362283ad20..7e6bc365c3 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -24,7 +24,6 @@ #include "esp_random.h" #endif // __linux__ #include "sdkconfig.h" -#include "netif/dhcp_state.h" #include "sntp/sntp_get_set_time.h" #include "sockets_ext.h" @@ -304,13 +303,19 @@ * is restored after reset/power-up. */ #ifdef CONFIG_LWIP_DHCP_RESTORE_LAST_IP -#define LWIP_DHCP_IP_ADDR_RESTORE() dhcp_ip_addr_restore(netif) -#define LWIP_DHCP_IP_ADDR_STORE() dhcp_ip_addr_store(netif) -#define LWIP_DHCP_IP_ADDR_ERASE(esp_netif) dhcp_ip_addr_erase(esp_netif) +/* + * Make the post-init hook check if we could restore the previously bound address + * - if yes reset the state to bound and mark result as ERR_OK (which skips discovery state) + * - if no, return false to continue normally to the discovery state + */ +#define LWIP_HOOK_DHCP_POST_INIT(netif, result) \ + (dhcp_ip_addr_restore(netif) ? ( dhcp_set_state(dhcp, DHCP_STATE_BOUND), \ + dhcp_network_changed(netif), \ + (result) = ERR_OK , \ + true ) : \ + false) #else -#define LWIP_DHCP_IP_ADDR_RESTORE() 0 -#define LWIP_DHCP_IP_ADDR_STORE() -#define LWIP_DHCP_IP_ADDR_ERASE(esp_netif) +#define LWIP_HOOK_DHCP_PRE_DISCOVERY(netif, result) (false) #endif /* CONFIG_LWIP_DHCP_RESTORE_LAST_IP */ /** diff --git a/components/lwip/port/esp32/include/netif/dhcp_state.h b/components/lwip/port/esp32/include/netif/dhcp_state.h index 0c2536b01c..d8bf13bb94 100644 --- a/components/lwip/port/esp32/include/netif/dhcp_state.h +++ b/components/lwip/port/esp32/include/netif/dhcp_state.h @@ -4,9 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ +#ifndef LWIP_ESP_DHCP_STATE_H +#define LWIP_ESP_DHCP_STATE_H -#ifndef _DHCP_STATE_H_ -#define _DHCP_STATE_H_ +#include +#include "lwip/netif.h" #include @@ -14,14 +16,14 @@ extern "C" { #endif -bool dhcp_ip_addr_restore(void *netif); +bool dhcp_ip_addr_restore(struct netif *netif); -void dhcp_ip_addr_store(void *netif); +void dhcp_ip_addr_store(struct netif *netif); -void dhcp_ip_addr_erase(void *esp_netif); +void dhcp_ip_addr_erase(struct netif *netif); #ifdef __cplusplus } #endif -#endif /* _DHCP_STATE_H_ */ +#endif /* LWIP_ESP_DHCP_STATE_H */ diff --git a/components/lwip/port/esp32/netif/dhcp_state.c b/components/lwip/port/esp32/netif/dhcp_state.c index 8785a6ded5..10b0981219 100644 --- a/components/lwip/port/esp32/netif/dhcp_state.c +++ b/components/lwip/port/esp32/netif/dhcp_state.c @@ -1,79 +1,64 @@ -// Copyright 2018 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at +/* + * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include #include "nvs.h" -#include "lwip/opt.h" #include "lwip/dhcp.h" #include "lwip/netif.h" -#include "esp_interface.h" -#include "esp_netif.h" -#include "esp_netif_net_stack.h" #include "netif/dhcp_state.h" #define DHCP_NAMESPACE "dhcp_state" +#define IF_KEY_SIZE 3 -// DHCP_Client has to be enabled for this netif -#define VALID_NETIF_ID(netif) (ESP_NETIF_DHCP_CLIENT&esp_netif_get_flags(netif)) +/* + * As a NVS key, use string representation of the interface index number + */ +static inline char *gen_if_key(struct netif *netif, char *name) +{ + lwip_itoa(name, IF_KEY_SIZE, netif->num); + return name; +} -bool dhcp_ip_addr_restore(void *netif) +bool dhcp_ip_addr_restore(struct netif *netif) { nvs_handle_t nvs; + char if_key[IF_KEY_SIZE]; bool err = false; - struct netif *net = (struct netif *)netif; - struct dhcp *dhcp = netif_dhcp_data(net); - esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif); + struct dhcp *dhcp = netif_dhcp_data(netif); - if(VALID_NETIF_ID(esp_netif)) { - uint32_t *ip_addr = &dhcp->offered_ip_addr.addr; - if (nvs_open(DHCP_NAMESPACE, NVS_READONLY, &nvs) == ESP_OK) { - if (nvs_get_u32(nvs, esp_netif_get_ifkey(esp_netif), ip_addr) == ESP_OK) { - err = true; - } - nvs_close(nvs); + uint32_t *ip_addr = &dhcp->offered_ip_addr.addr; + if (nvs_open(DHCP_NAMESPACE, NVS_READONLY, &nvs) == ESP_OK) { + if (nvs_get_u32(nvs, gen_if_key(netif, if_key), ip_addr) == ESP_OK) { + err = true; } + nvs_close(nvs); } return err; } -void dhcp_ip_addr_store(void *netif) +void dhcp_ip_addr_store(struct netif *netif) { nvs_handle_t nvs; - struct netif *net = (struct netif *)netif; - struct dhcp *dhcp = netif_dhcp_data(net); + char if_key[IF_KEY_SIZE]; + struct dhcp *dhcp = netif_dhcp_data(netif); uint32_t ip_addr = dhcp->offered_ip_addr.addr; - esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif); - if(VALID_NETIF_ID(esp_netif)) { - if (nvs_open(DHCP_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) { - nvs_set_u32(nvs,esp_netif_get_ifkey(esp_netif), ip_addr); - nvs_commit(nvs); - nvs_close(nvs); - } + if (nvs_open(DHCP_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) { + nvs_set_u32(nvs, gen_if_key(netif, if_key), ip_addr); + nvs_commit(nvs); + nvs_close(nvs); } } -void dhcp_ip_addr_erase(void *esp_netif) +void dhcp_ip_addr_erase(struct netif *netif) { nvs_handle_t nvs; - - if(VALID_NETIF_ID(esp_netif)) { - if (nvs_open(DHCP_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) { - nvs_erase_key(nvs, esp_netif_get_ifkey(esp_netif)); - nvs_commit(nvs); - nvs_close(nvs); - } + char if_key[IF_KEY_SIZE]; + if (nvs_open(DHCP_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) { + nvs_erase_key(nvs, gen_if_key(netif, if_key)); + nvs_commit(nvs); + nvs_close(nvs); } } diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index a0d014044f..d4b3dfeb1b 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -979,7 +979,6 @@ components/lwip/port/esp32/include/netinet/in.h components/lwip/port/esp32/include/netinet/tcp.h components/lwip/port/esp32/include/sntp/sntp_get_set_time.h components/lwip/port/esp32/include/sys/socket.h -components/lwip/port/esp32/netif/dhcp_state.c components/lwip/port/esp32/netif/ethernetif.c components/lwip/port/esp32/netif/wlanif.c components/lwip/port/esp32/no_vfs_syscalls.c From b6eb9002a8a633c4b4146e99f77317c48f475f08 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Wed, 23 Mar 2022 20:24:50 +0100 Subject: [PATCH 12/25] add dhcp custom values --- components/lwip/port/esp32/include/lwipopts.h | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index 7e6bc365c3..cc80ca3291 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -334,6 +334,30 @@ */ #define ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID +#define DHCP_DEFINE_CUSTOM_TIMEOUTS 1 +#define DHCP_COARSE_TIMER_SECS (1) +#define DHCP_NEXT_TIMEOUT_THRESHOLD (3) +/* Since for embedded devices it's not that hard to miss a discover packet, so lower + * the discover retry backoff time from (2,4,8,16,32,60,60)s to (500m,1,2,4,8,15,15)s. + */ +#define DHCP_REQUEST_TIMEOUT_SEQUENCE(tries) (( (tries) < 6 ? 1 << (tries) : 60) * 250) + +static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) +{ + uint32_t timeout = lease; + if (timeout == 0) { + timeout = min; + } + return timeout; +} + +#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T0_LEASE(dhcp) \ + timeout_from_offered((dhcp)->offered_t0_lease, 120) +#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T1_RENEW(dhcp) \ + timeout_from_offered((dhcp)->offered_t1_renew, (dhcp)->t0_timeout>>1 /* 50% */ ) +#define DHCP_CALC_TIMEOUT_FROM_OFFERED_T2_REBIND(dhcp) \ + timeout_from_offered((dhcp)->offered_t2_rebind, ((dhcp)->t0_timeout/8)*7 /* 87.5% */ ) + /* ------------------------------------ ---------- AUTOIP options ---------- From 5aa3be11fdbeb3d2a5f32c92265e57e437aad0e7 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Fri, 25 Mar 2022 18:58:44 +0100 Subject: [PATCH 13/25] dhcpserver: Minor #idfef fix --- components/lwip/apps/dhcpserver/dhcpserver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/lwip/apps/dhcpserver/dhcpserver.c b/components/lwip/apps/dhcpserver/dhcpserver.c index 0806104872..289d12495e 100644 --- a/components/lwip/apps/dhcpserver/dhcpserver.c +++ b/components/lwip/apps/dhcpserver/dhcpserver.c @@ -17,7 +17,7 @@ #include "dhcpserver/dhcpserver.h" #include "dhcpserver/dhcpserver_options.h" -#if ESP_DHCP +#if ESP_DHCPS #define BOOTP_BROADCAST 0x8000 @@ -1419,4 +1419,4 @@ err_t dhcps_dns_getserver(dhcps_t *dhcps, ip4_addr_t *dnsserver) } return ERR_ARG; } -#endif // ESP_DHCP +#endif // ESP_DHCPS From 1564e8d5a9afaa7ae3f8e304a02327aef8f9bfb6 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Fri, 25 Mar 2022 20:13:20 +0100 Subject: [PATCH 14/25] lwip: Implement DHCP hook supporting MTU option --- .../port/esp32/hooks/lwip_default_hooks.c | 26 +++++++++++++++++++ .../port/esp32/include/lwip_default_hooks.h | 3 +++ components/lwip/port/esp32/include/lwipopts.h | 5 ++++ 3 files changed, 34 insertions(+) diff --git a/components/lwip/port/esp32/hooks/lwip_default_hooks.c b/components/lwip/port/esp32/hooks/lwip_default_hooks.c index db34443334..69f3e87e0c 100644 --- a/components/lwip/port/esp32/hooks/lwip_default_hooks.c +++ b/components/lwip/port/esp32/hooks/lwip_default_hooks.c @@ -5,6 +5,8 @@ */ #include "lwip_default_hooks.h" +#include "lwip/prot/dhcp.h" +#include "lwip/dhcp.h" #define __weak __attribute__((weak)) @@ -100,3 +102,27 @@ ip4_route_src_hook(const ip4_addr_t *src,const ip4_addr_t *dest) } #endif #endif /* LWIP_HOOK_IP4_ROUTE_SRC */ + +void dhcp_parse_extra_opts(struct dhcp *dhcp, uint8_t state, uint8_t option, uint8_t len, struct pbuf* p, uint16_t offset) +{ + if ((option == DHCP_OPTION_MTU) && + (state == DHCP_STATE_REBOOTING || state == DHCP_STATE_REBINDING || + state == DHCP_STATE_RENEWING || state == DHCP_STATE_REQUESTING)) { + u32_t mtu = 0; + struct netif *netif; + LWIP_ERROR("dhcp_parse_extra_opts(): MTU option's len != 2", len == 2, return;); + LWIP_ERROR("dhcp_parse_extra_opts(): extracting MTU option failed", + pbuf_copy_partial(p, &mtu, 2, offset) == 2, return;); + mtu = lwip_htons((u16_t)mtu); + NETIF_FOREACH(netif) { + /* find the netif related to this dhcp */ + if (dhcp == netif_dhcp_data(netif)) { + if (mtu < netif->mtu) { + netif->mtu = mtu; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_parse_extra_opts(): Negotiated netif MTU is %d\n", netif->mtu)); + } + return; + } + } + } /* DHCP_OPTION_MTU */ +} diff --git a/components/lwip/port/esp32/include/lwip_default_hooks.h b/components/lwip/port/esp32/include/lwip_default_hooks.h index 1577b60e6b..464228b1e7 100644 --- a/components/lwip/port/esp32/include/lwip_default_hooks.h +++ b/components/lwip/port/esp32/include/lwip_default_hooks.h @@ -57,6 +57,9 @@ int lwip_hook_ip6_input(struct pbuf *p, struct netif *inp); struct netif * ip4_route_src_hook(const ip4_addr_t *src,const ip4_addr_t *dest); +struct dhcp; +void dhcp_parse_extra_opts(struct dhcp *dhcp, uint8_t state, uint8_t option, uint8_t len, struct pbuf* p, uint16_t offset); + #ifdef __cplusplus } #endif diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index cc80ca3291..68d948d5a5 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -358,6 +358,11 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) #define DHCP_CALC_TIMEOUT_FROM_OFFERED_T2_REBIND(dhcp) \ timeout_from_offered((dhcp)->offered_t2_rebind, ((dhcp)->t0_timeout/8)*7 /* 87.5% */ ) +#define LWIP_HOOK_DHCP_PARSE_OPTION(netif, dhcp, state, msg, msg_type, option, len, pbuf, offset) \ + do { LWIP_UNUSED_ARG(msg); \ + dhcp_parse_extra_opts(dhcp, state, option, len, pbuf, offset); \ + } while(0) + /* ------------------------------------ ---------- AUTOIP options ---------- From 5d6afa3c4bfd147e9eab3e1dff12385a9b9001ba Mon Sep 17 00:00:00 2001 From: David Cermak Date: Tue, 29 Mar 2022 18:18:35 +0200 Subject: [PATCH 15/25] dhcp: Implement additional dhcp options --- .../port/esp32/hooks/lwip_default_hooks.c | 180 ++++++++++++++++-- .../port/esp32/include/lwip_default_hooks.h | 8 + components/lwip/port/esp32/include/lwipopts.h | 3 + 3 files changed, 173 insertions(+), 18 deletions(-) diff --git a/components/lwip/port/esp32/hooks/lwip_default_hooks.c b/components/lwip/port/esp32/hooks/lwip_default_hooks.c index 69f3e87e0c..e198ee018b 100644 --- a/components/lwip/port/esp32/hooks/lwip_default_hooks.c +++ b/components/lwip/port/esp32/hooks/lwip_default_hooks.c @@ -7,6 +7,8 @@ #include "lwip_default_hooks.h" #include "lwip/prot/dhcp.h" #include "lwip/dhcp.h" +#include "lwip/prot/iana.h" +#include #define __weak __attribute__((weak)) @@ -103,26 +105,168 @@ ip4_route_src_hook(const ip4_addr_t *src,const ip4_addr_t *dest) #endif #endif /* LWIP_HOOK_IP4_ROUTE_SRC */ +#define LWIP_DHCP_ENABLE_MTU_UPDATE 1 +#define LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER +#define LWIP_DHCP_ENABLE_CLIENT_ID !ESP_DHCP_DISABLE_CLIENT_ID + +#if LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS +#define DHCP_OPTION_VSI 43 +#define DHCP_OPTION_VCI 60 +#define DHCP_OPTION_VSI_MAX 16 + +static u8_t vendor_class_len = 0; +static char *vendor_class_buf = NULL; +static u32_t dhcp_option_vsi[DHCP_OPTION_VSI_MAX] = {0}; + +void dhcp_free_vendor_class_identifier(void) +{ + mem_free(vendor_class_buf); +} + +int dhcp_get_vendor_specific_information(uint8_t len, char * str) +{ + u8_t copy_len = 0; + + if (len == 0 || str == NULL) { + return ERR_ARG; + } + + copy_len = LWIP_MIN(len, sizeof(dhcp_option_vsi)); + + memcpy(str, dhcp_option_vsi, copy_len); + + return ERR_OK; +} + +int dhcp_set_vendor_class_identifier(uint8_t len, const char * str) +{ + if (len == 0 || str == NULL) { + return ERR_ARG; + } + + if (vendor_class_buf && vendor_class_len != len) { + mem_free(vendor_class_buf); + vendor_class_buf = NULL; + } + + if (!vendor_class_buf) { + vendor_class_buf = (char *)mem_malloc(len + 1); + if (vendor_class_buf == NULL) { + return ERR_MEM; + } + + vendor_class_len = len; + } + + memcpy(vendor_class_buf, str, len); + return ERR_OK; +} +#endif /* LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS */ + void dhcp_parse_extra_opts(struct dhcp *dhcp, uint8_t state, uint8_t option, uint8_t len, struct pbuf* p, uint16_t offset) { + LWIP_UNUSED_ARG(dhcp); + LWIP_UNUSED_ARG(state); + LWIP_UNUSED_ARG(option); + LWIP_UNUSED_ARG(len); + LWIP_UNUSED_ARG(p); + LWIP_UNUSED_ARG(offset); +#if LWIP_DHCP_ENABLE_MTU_UPDATE if ((option == DHCP_OPTION_MTU) && - (state == DHCP_STATE_REBOOTING || state == DHCP_STATE_REBINDING || - state == DHCP_STATE_RENEWING || state == DHCP_STATE_REQUESTING)) { - u32_t mtu = 0; - struct netif *netif; - LWIP_ERROR("dhcp_parse_extra_opts(): MTU option's len != 2", len == 2, return;); - LWIP_ERROR("dhcp_parse_extra_opts(): extracting MTU option failed", - pbuf_copy_partial(p, &mtu, 2, offset) == 2, return;); - mtu = lwip_htons((u16_t)mtu); - NETIF_FOREACH(netif) { - /* find the netif related to this dhcp */ - if (dhcp == netif_dhcp_data(netif)) { - if (mtu < netif->mtu) { - netif->mtu = mtu; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_parse_extra_opts(): Negotiated netif MTU is %d\n", netif->mtu)); - } - return; - } + (state == DHCP_STATE_REBOOTING || state == DHCP_STATE_REBINDING || + state == DHCP_STATE_RENEWING || state == DHCP_STATE_REQUESTING)) { + u32_t mtu = 0; + struct netif *netif; + LWIP_ERROR("dhcp_parse_extra_opts(): MTU option's len != 2", len == 2, return;); + LWIP_ERROR("dhcp_parse_extra_opts(): extracting MTU option failed", + pbuf_copy_partial(p, &mtu, 2, offset) == 2, return;); + mtu = lwip_htons((u16_t)mtu); + NETIF_FOREACH(netif) { + /* find the netif related to this dhcp */ + if (dhcp == netif_dhcp_data(netif)) { + if (mtu < netif->mtu) { + netif->mtu = mtu; + LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_parse_extra_opts(): Negotiated netif MTU is %d\n", netif->mtu)); } - } /* DHCP_OPTION_MTU */ + return; + } + } + } /* DHCP_OPTION_MTU */ +#endif /* LWIP_DHCP_ENABLE_MTU_UPDATE */ +#if LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS + if ((option == DHCP_OPTION_VSI) && + (state == DHCP_STATE_REBOOTING || state == DHCP_STATE_REBINDING || + state == DHCP_STATE_RENEWING || state == DHCP_STATE_REQUESTING || state == DHCP_STATE_SELECTING)) { + u8_t n; + u32_t value; + u16_t copy_len; + for (n = 0; n < DHCP_OPTION_VSI_MAX && len > 0; n++) { + copy_len = LWIP_MIN(len, 4); + LWIP_ERROR("dhcp_parse_extra_opts(): extracting VSI option failed", + pbuf_copy_partial(p, &value, copy_len, offset) == copy_len, return;); + dhcp_option_vsi[n] = lwip_htonl(value); + len -= copy_len; + } + } /* DHCP_OPTION_VSI */ +#endif /* LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS */ +} + +void dhcp_append_extra_opts(struct netif *netif, uint8_t state, struct dhcp_msg *msg_out, uint16_t *options_out_len) +{ + LWIP_UNUSED_ARG(netif); + LWIP_UNUSED_ARG(state); + LWIP_UNUSED_ARG(msg_out); + LWIP_UNUSED_ARG(options_out_len); +#if LWIP_DHCP_ENABLE_CLIENT_ID + if (state == DHCP_STATE_RENEWING || state == DHCP_STATE_REBINDING || + state == DHCP_STATE_REBOOTING || state == DHCP_STATE_OFF || + state == DHCP_STATE_REQUESTING || state == DHCP_STATE_BACKING_OFF || state == DHCP_STATE_SELECTING) { + size_t i; + u8_t *options = msg_out->options + *options_out_len; + LWIP_ERROR("dhcp_append(client_id): options_out_len + 3 + netif->hwaddr_len <= DHCP_OPTIONS_LEN", + *options_out_len + 3U + netif->hwaddr_len <= DHCP_OPTIONS_LEN, return;); + *options_out_len = *options_out_len + netif->hwaddr_len + 3; + *options++ = DHCP_OPTION_CLIENT_ID; + *options++ = netif->hwaddr_len + 1; /* option size */ + *options++ = LWIP_IANA_HWTYPE_ETHERNET; + for (i = 0; i < netif->hwaddr_len; i++) { + *options++ = netif->hwaddr[i]; + } + } +#endif /* LWIP_DHCP_ENABLE_CLIENT_ID */ +#if LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS + if (state == DHCP_STATE_RENEWING || state == DHCP_STATE_REBINDING || + state == DHCP_STATE_REBOOTING || state == DHCP_STATE_OFF || + state == DHCP_STATE_REQUESTING || state == DHCP_STATE_BACKING_OFF || state == DHCP_STATE_SELECTING) { + size_t i; + const char *p = NULL; + u8_t len = 0; + + if (vendor_class_buf && vendor_class_len) { + p = vendor_class_buf; + len = vendor_class_len; + } else { +#if LWIP_NETIF_HOSTNAME + size_t namelen; + if (netif->hostname != NULL && (namelen = strlen(netif->hostname)) < 0xff) { + p = netif->hostname; + len = (u8_t)namelen; + } +#endif /* LWIP_NETIF_HOSTNAME */ + } + LWIP_ERROR("dhcp_append(vci): options_out_len + 3 + vci_size <= DHCP_OPTIONS_LEN", + *options_out_len + 3U + len <= DHCP_OPTIONS_LEN, return;); + if (p) { + u8_t *options = msg_out->options + *options_out_len; + *options_out_len = *options_out_len + len + 3; + *options++ = DHCP_OPTION_VCI; + *options++ = len; + for (i = 0; i < len; i ++) { + *options++ = p[i]; + } + } + return; + } +#endif /* LWIP_DHCP_ENABLE_VENDOR_SPEC_IDS */ + } diff --git a/components/lwip/port/esp32/include/lwip_default_hooks.h b/components/lwip/port/esp32/include/lwip_default_hooks.h index 464228b1e7..359263a207 100644 --- a/components/lwip/port/esp32/include/lwip_default_hooks.h +++ b/components/lwip/port/esp32/include/lwip_default_hooks.h @@ -58,8 +58,16 @@ struct netif * ip4_route_src_hook(const ip4_addr_t *src,const ip4_addr_t *dest); struct dhcp; +struct netif; +struct dhcp_msg; void dhcp_parse_extra_opts(struct dhcp *dhcp, uint8_t state, uint8_t option, uint8_t len, struct pbuf* p, uint16_t offset); +void dhcp_append_extra_opts(struct netif *netif, uint8_t state, struct dhcp_msg *msg_out, uint16_t *options_out_len); + +int dhcp_set_vendor_class_identifier(uint8_t len, const char * str); +int dhcp_get_vendor_specific_information(uint8_t len, char * str); +void dhcp_free_vendor_class_identifier(void); + #ifdef __cplusplus } #endif diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index 68d948d5a5..0693d02d18 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -363,6 +363,9 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) dhcp_parse_extra_opts(dhcp, state, option, len, pbuf, offset); \ } while(0) +#define LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, state, msg, msg_type, options_len_ptr) \ + dhcp_append_extra_opts(netif, state, msg, options_len_ptr); + /* ------------------------------------ ---------- AUTOIP options ---------- From a6154a5f10600379c3dd83a8dec07607909709fb Mon Sep 17 00:00:00 2001 From: David Cermak Date: Tue, 29 Mar 2022 18:19:31 +0200 Subject: [PATCH 16/25] lwip: Update default MEMP_NUM_SYS_TIMEOUT if timers on-demand --- components/lwip/port/esp32/include/lwipopts.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index 0693d02d18..ee1bf8030b 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -1367,6 +1367,8 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) #ifdef CONFIG_LWIP_TIMERS_ONDEMAND #define ESP_LWIP_IGMP_TIMERS_ONDEMAND 1 #define ESP_LWIP_MLD6_TIMERS_ONDEMAND 1 +#define LWIP_NUM_SYS_TIMEOUT_INTERNAL_WOUT_IGMP_MLD6 (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_DNS + PPP_NUM_TIMEOUTS + (LWIP_IPV6 * (1 + LWIP_IPV6_REASS))) +#define MEMP_NUM_SYS_TIMEOUT LWIP_NUM_SYS_TIMEOUT_INTERNAL_WOUT_IGMP_MLD6 #else #define ESP_LWIP_IGMP_TIMERS_ONDEMAND 0 #define ESP_LWIP_MLD6_TIMERS_ONDEMAND 0 From 09aa24632a96fd3ff5c79a70553859841475472e Mon Sep 17 00:00:00 2001 From: David Cermak Date: Wed, 30 Mar 2022 10:53:51 +0200 Subject: [PATCH 17/25] esp_netif: Support IPv6 autoconfig is enabled in menuconfig --- components/esp_netif/lwip/esp_netif_lwip.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index 783ea1b81a..a3fef0a31a 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -758,6 +758,9 @@ static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg) ESP_ERROR_CHECK(esp_netif_lwip_add(esp_netif)); +#if ESP_IPV6_AUTOCONFIG + esp_netif->lwip_netif->ip6_autoconfig_enabled = 1; +#endif if (esp_netif->flags&ESP_NETIF_FLAG_GARP) { #if ESP_GRATUITOUS_ARP netif_set_garp_flag(esp_netif->lwip_netif); From e7f19f39bc1f0eb25f47ac8862a24791903ac6c5 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 31 Mar 2022 11:51:56 +0200 Subject: [PATCH 18/25] lwip: Fix the CI --- components/lwip/lwip | 2 +- components/lwip/port/esp32/include/lwipopts.h | 8 ++++++++ components/lwip/test_afl_host/esp32_mock.c | 8 ++++++++ components/lwip/test_afl_host/sdkconfig.defaults | 1 + 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/components/lwip/lwip b/components/lwip/lwip index 104e8fa4c8..358ee481e5 160000 --- a/components/lwip/lwip +++ b/components/lwip/lwip @@ -1 +1 @@ -Subproject commit 104e8fa4c881a98eefa3776d2701a6b90b9aa63d +Subproject commit 358ee481e5bcd399b77ddb21d41edb499d3bc820 diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index ee1bf8030b..c539cbe0c7 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -27,6 +27,10 @@ #include "sntp/sntp_get_set_time.h" #include "sockets_ext.h" +#ifdef __cplusplus +extern "C" { +#endif + /* ----------------------------------------------- ---------- Platform specific locking ---------- @@ -1444,4 +1448,8 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) #define mem_clib_calloc calloc #endif /* CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST */ +#ifdef __cplusplus +} +#endif + #endif /* LWIP_HDR_ESP_LWIPOPTS_H */ diff --git a/components/lwip/test_afl_host/esp32_mock.c b/components/lwip/test_afl_host/esp32_mock.c index 9a7c38a5cd..960da97462 100644 --- a/components/lwip/test_afl_host/esp32_mock.c +++ b/components/lwip/test_afl_host/esp32_mock.c @@ -301,3 +301,11 @@ uint32_t esp_random(void) // Preparation for injecting favorable random numbers return g_random_numbers[g_random_numbers_cnt++ % 8]; } + +void dhcp_parse_extra_opts(struct dhcp *dhcp, uint8_t state, uint8_t option, uint8_t len, struct pbuf* p, uint16_t offset) +{ +} + +void dhcp_append_extra_opts(struct netif *netif, uint8_t state, struct dhcp_msg *msg_out, uint16_t *options_out_len) +{ +} diff --git a/components/lwip/test_afl_host/sdkconfig.defaults b/components/lwip/test_afl_host/sdkconfig.defaults index ec02309aec..81952aa5bb 100644 --- a/components/lwip/test_afl_host/sdkconfig.defaults +++ b/components/lwip/test_afl_host/sdkconfig.defaults @@ -1 +1,2 @@ CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES=n +CONFIG_FREERTOS_SMP=n From d50739adec0a7e5029dd085637686c2250972a4d Mon Sep 17 00:00:00 2001 From: David Cermak Date: Fri, 8 Apr 2022 09:53:01 +0200 Subject: [PATCH 19/25] lwip: forgotten ip4_route_src_hook to IRAM --- components/lwip/linker.lf | 1 + 1 file changed, 1 insertion(+) diff --git a/components/lwip/linker.lf b/components/lwip/linker.lf index bfb051a28f..74c8c76412 100644 --- a/components/lwip/linker.lf +++ b/components/lwip/linker.lf @@ -80,6 +80,7 @@ entries: ethernetif:ethernetif_input (noflash_text) wlanif:low_level_output (noflash_text) wlanif:wlanif_input (noflash_text) + lwip_default_hooks:ip4_route_src_hook (noflash_text) if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: * (extram_bss) From 60fc1ae03598ef48bf60ab772483b1e9bed20d38 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Tue, 12 Apr 2022 13:40:23 +0200 Subject: [PATCH 20/25] lwip: Removed incorrect-fix 358ee481 --- components/lwip/lwip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/lwip/lwip b/components/lwip/lwip index 358ee481e5..2e7efc486e 160000 --- a/components/lwip/lwip +++ b/components/lwip/lwip @@ -1 +1 @@ -Subproject commit 358ee481e5bcd399b77ddb21d41edb499d3bc820 +Subproject commit 2e7efc486e6d90dfe8a6f058682375870c05071f From 0e71a325de309400b68f018da7df52f1890c57ba Mon Sep 17 00:00:00 2001 From: David Cermak Date: Mon, 30 May 2022 08:56:14 +0200 Subject: [PATCH 21/25] lwip/wifi: Improve Rx throughput on the wifi defaults (sta+ap) --- components/esp_wifi/src/wifi_netif.c | 35 +-- components/lwip/linker.lf | 6 +- components/lwip/port/esp32/netif/wlanif.c | 266 +++++++++++++++------- tools/ci/check_copyright_ignore.txt | 1 - 4 files changed, 195 insertions(+), 113 deletions(-) diff --git a/components/esp_wifi/src/wifi_netif.c b/components/esp_wifi/src/wifi_netif.c index 54900b8f01..7683dfa62f 100644 --- a/components/esp_wifi/src/wifi_netif.c +++ b/components/esp_wifi/src/wifi_netif.c @@ -5,6 +5,7 @@ */ #include "esp_wifi.h" #include "esp_netif.h" +#include "esp_netif_net_stack.h" #include "esp_log.h" #include "esp_private/wifi.h" #include "esp_wifi_netif.h" @@ -24,28 +25,6 @@ typedef struct wifi_netif_driver { static const char* TAG = "wifi_netif"; -/** - * @brief Local storage for netif handles and callbacks for specific wifi interfaces - */ -static esp_netif_receive_t s_wifi_rxcbs[MAX_WIFI_IFS] = { NULL }; -static esp_netif_t *s_wifi_netifs[MAX_WIFI_IFS] = { NULL }; - -/** - * @brief WiFi netif driver IO functions, a thin glue layer - * to the original wifi interface API - */ -static esp_err_t wifi_sta_receive(void *buffer, uint16_t len, void *eb) -{ - return s_wifi_rxcbs[WIFI_IF_STA](s_wifi_netifs[WIFI_IF_STA], buffer, len, eb); -} - -#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT -static esp_err_t wifi_ap_receive(void *buffer, uint16_t len, void *eb) -{ - return s_wifi_rxcbs[WIFI_IF_AP](s_wifi_netifs[WIFI_IF_AP], buffer, len, eb); -} -#endif - static void wifi_free(void *h, void* buffer) { if (buffer) { @@ -88,7 +67,6 @@ void esp_wifi_destroy_if_driver(wifi_netif_driver_t h) if (h) { esp_wifi_internal_reg_rxcb(h->wifi_if, NULL); // ignore the potential error // as the wifi might have been already uninitialized - s_wifi_netifs[h->wifi_if] = NULL; } free(h); } @@ -122,6 +100,10 @@ bool esp_wifi_is_if_ready_when_started(wifi_netif_driver_t ifx) #endif } +void set_wifi_netif(int wifi_inx, void* netif); +esp_err_t wifi_rxcb_sta(void *buffer, uint16_t len, void *eb); +esp_err_t wifi_rxcb_ap(void *buffer, uint16_t len, void *eb); + esp_err_t esp_wifi_register_if_rxcb(wifi_netif_driver_t ifx, esp_netif_receive_t fn, void * arg) { if (ifx->base.netif != arg) { @@ -129,7 +111,6 @@ esp_err_t esp_wifi_register_if_rxcb(wifi_netif_driver_t ifx, esp_netif_receive_t return ESP_ERR_INVALID_ARG; } wifi_interface_t wifi_interface = ifx->wifi_if; - s_wifi_rxcbs[wifi_interface] = fn; wifi_rxcb_t rxcb = NULL; esp_err_t ret; @@ -137,12 +118,12 @@ esp_err_t esp_wifi_register_if_rxcb(wifi_netif_driver_t ifx, esp_netif_receive_t { case WIFI_IF_STA: - rxcb = wifi_sta_receive; + rxcb = wifi_rxcb_sta; break; #ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT case WIFI_IF_AP: - rxcb = wifi_ap_receive; + rxcb = wifi_rxcb_ap; break; #endif @@ -155,10 +136,10 @@ esp_err_t esp_wifi_register_if_rxcb(wifi_netif_driver_t ifx, esp_netif_receive_t return ESP_ERR_NOT_SUPPORTED; } - s_wifi_netifs[wifi_interface] = ifx->base.netif; if ((ret = esp_wifi_internal_reg_rxcb(wifi_interface, rxcb)) != ESP_OK) { ESP_LOGE(TAG, "esp_wifi_internal_reg_rxcb for if=%d failed with %d", wifi_interface, ret); return ESP_ERR_INVALID_STATE; } + set_wifi_netif(wifi_interface, esp_netif_get_netif_impl(arg)); return ESP_OK; } diff --git a/components/lwip/linker.lf b/components/lwip/linker.lf index 74c8c76412..8263efd5b5 100644 --- a/components/lwip/linker.lf +++ b/components/lwip/linker.lf @@ -78,8 +78,10 @@ entries: sys_arch:sys_arch_mbox_fetch (noflash_text) ethernetif:ethernet_low_level_output (noflash_text) ethernetif:ethernetif_input (noflash_text) - wlanif:low_level_output (noflash_text) - wlanif:wlanif_input (noflash_text) + wlanif:sta_output (noflash_text) + wlanif:ap_output (noflash_text) + wlanif:wifi_rxcb_sta (noflash_text) + wlanif:wifi_rxcb_ap (noflash_text) lwip_default_hooks:ip4_route_src_hook (noflash_text) if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: diff --git a/components/lwip/port/esp32/netif/wlanif.c b/components/lwip/port/esp32/netif/wlanif.c index 51301fb934..6268bedc3c 100644 --- a/components/lwip/port/esp32/netif/wlanif.c +++ b/components/lwip/port/esp32/netif/wlanif.c @@ -1,51 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2001-2004 Swedish Institute of Computer Science + * + * SPDX-License-Identifier: BSD-3-Clause + * + * SPDX-FileContributor: 2015-2022 Espressif Systems (Shanghai) CO LTD + */ /** * @file * Ethernet Interface Skeleton used for WiFi * */ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - #include "lwip/opt.h" #include "lwip/def.h" -#include "lwip/mem.h" +#include "lwip/memp.h" #include "lwip/pbuf.h" #include "lwip/stats.h" #include "lwip/snmp.h" #include "lwip/ethip6.h" #include "netif/etharp.h" #include "netif/wlanif.h" +#include "esp_private/wifi.h" #include #include @@ -55,6 +31,19 @@ #include "esp_compiler.h" #include "netif/esp_pbuf_ref.h" + +typedef struct wifi_custom_pbuf +{ + struct pbuf_custom p; + void* l2_buf; +} wifi_custom_pbuf_t; + +#define ESP_PBUF_POOL_SIZE 16 +LWIP_MEMPOOL_DECLARE(ESP_PBUF_POOL, ESP_PBUF_POOL_SIZE, sizeof(wifi_custom_pbuf_t), "WIFI_CUSTOM_PBUF"); + +static struct netif *s_wifi_netifs[2] = { NULL }; + + /** * In this function, the hardware should be initialized. * Called from wlanif_input(). @@ -91,59 +80,91 @@ low_level_init(struct netif *netif) } -/** - * This function should do the actual transmission of the packet. The packet is - * contained in the pbuf that is passed to the function. This pbuf - * might be chained. - * - * @param netif the lwip network interface structure for this wlanif - * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) - * @return ERR_OK if the packet could be sent - * an err_t value if the packet couldn't be sent - * - * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to - * strange results. You might consider waiting for space in the DMA queue - * to become available since the stack doesn't retry to send a packet - * dropped because of memory failure (except for the TCP timers). - */ -static err_t -low_level_output(struct netif *netif, struct pbuf *p) +void set_wifi_netif(int wifi_inx, void* netif) { - esp_netif_t *esp_netif = esp_netif_get_handle_from_netif_impl(netif); - if (esp_netif == NULL) { - return ERR_IF; - } - - struct pbuf *q = p; - esp_err_t ret; - - if(q->next == NULL) { - ret = esp_netif_transmit_wrap(esp_netif, q->payload, q->len, q); - - } else { - LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug")); - q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM); - if (q != NULL) { - pbuf_copy(q, p); - } else { - return ERR_MEM; - } - ret = esp_netif_transmit_wrap(esp_netif, q->payload, q->len, q); - - pbuf_free(q); - } - - if (ret == ESP_OK) { - return ERR_OK; - } else if (ret == ESP_ERR_NO_MEM) { - return ERR_MEM; - } else if (ret == ESP_ERR_INVALID_ARG) { - return ERR_ARG; - } else { - return ERR_IF; + if (wifi_inx < 2) { + s_wifi_netifs[wifi_inx] = netif; } } + +static void esp_pbuf_free_l2_buff(struct pbuf *p) +{ + wifi_custom_pbuf_t* wifi_pbuf = (wifi_custom_pbuf_t*)p; + esp_wifi_internal_free_rx_buffer(wifi_pbuf->l2_buf); + LWIP_MEMPOOL_FREE(ESP_PBUF_POOL, wifi_pbuf); +} + +static inline struct pbuf* pbuf_allocate(struct netif *netif, void *buffer, size_t len, void *l2_buff) +{ + struct pbuf *p; + + wifi_custom_pbuf_t* esp_pbuf = (wifi_custom_pbuf_t*)LWIP_MEMPOOL_ALLOC(ESP_PBUF_POOL); + + if (esp_pbuf == NULL) { + return NULL; + } + esp_pbuf->p.custom_free_function = esp_pbuf_free_l2_buff; + esp_pbuf->l2_buf = l2_buff; + p = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &esp_pbuf->p, buffer, len); + if (p == NULL) { + LWIP_MEMPOOL_FREE(ESP_PBUF_POOL, esp_pbuf); + return NULL; + } + return p; +} + +esp_err_t wifi_rxcb_sta(void *buffer, uint16_t len, void *l2_buff) +{ + struct netif * netif = s_wifi_netifs[0]; + struct pbuf *p; + + if(unlikely(!buffer || !netif_is_up(netif))) { + if (l2_buff) { + esp_wifi_internal_free_rx_buffer(l2_buff); + } + return ESP_FAIL; + } + + p = pbuf_allocate(netif, buffer, len, l2_buff); + if (p == NULL) { + esp_wifi_internal_free_rx_buffer(l2_buff); + return ESP_FAIL; + } + + /* full packet send to tcpip_thread to process */ + if (unlikely(netif->input(p, netif) != ERR_OK)) { + LWIP_DEBUGF(NETIF_DEBUG, ("wlanif_input: IP input error\n")); + pbuf_free(p); + } + return ESP_OK; +} + +esp_err_t wifi_rxcb_ap(void *buffer, uint16_t len, void *l2_buff) +{ + struct netif * netif = s_wifi_netifs[1]; + struct pbuf *p; + + if(unlikely(!buffer || !netif_is_up(netif))) { + if (l2_buff) { + esp_wifi_internal_free_rx_buffer(l2_buff); + } + return ESP_FAIL; + } + + p = pbuf_allocate(netif, buffer, len, l2_buff); + if (p == NULL) { + esp_wifi_internal_free_rx_buffer(l2_buff); + return ESP_FAIL; + } + + /* full packet send to tcpip_thread to process */ + if (unlikely(netif->input(p, netif) != ERR_OK)) { + LWIP_DEBUGF(NETIF_DEBUG, ("wlanif_input: IP input error\n")); + pbuf_free(p); + } + return ESP_OK; +} /** * This function should be called when a packet is ready to be read * from the interface. It uses the function low_level_input() that @@ -192,7 +213,85 @@ wlanif_input(void *h, void *buffer, size_t len, void* l2_buff) LWIP_DEBUGF(NETIF_DEBUG, ("wlanif_input: IP input error\n")); pbuf_free(p); } +} +/** + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this wlanif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become available since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ +static err_t +sta_output(struct netif *netif, struct pbuf *p) +{ + struct pbuf *q = p; + esp_err_t ret; + + if(q->next == NULL) { + ret = esp_wifi_internal_tx(WIFI_IF_STA, q->payload, q->len); + + } else { + LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug")); + q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM); + if (q != NULL) { + pbuf_copy(q, p); + } else { + return ERR_MEM; + } + ret = esp_wifi_internal_tx(WIFI_IF_STA, q->payload, q->len); + pbuf_free(q); + } + + if (ret == ESP_OK) { + return ERR_OK; + } else if (ret == ESP_ERR_NO_MEM) { + return ERR_MEM; + } else if (ret == ESP_ERR_INVALID_ARG) { + return ERR_ARG; + } else { + return ERR_IF; + } +} + +static err_t +ap_output(struct netif *netif, struct pbuf *p) +{ + struct pbuf *q = p; + esp_err_t ret; + + if(q->next == NULL) { + ret = esp_wifi_internal_tx(WIFI_IF_AP, q->payload, q->len); + + } else { + LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug")); + q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM); + if (q != NULL) { + pbuf_copy(q, p); + } else { + return ERR_MEM; + } + ret = esp_wifi_internal_tx(WIFI_IF_AP, q->payload, q->len); + pbuf_free(q); + } + + if (ret == ESP_OK) { + return ERR_OK; + } else if (ret == ESP_ERR_NO_MEM) { + return ERR_MEM; + } else if (ret == ESP_ERR_INVALID_ARG) { + return ERR_ARG; + } else { + return ERR_IF; + } } /** @@ -240,7 +339,6 @@ wlanif_init(struct netif *netif) #if LWIP_IPV6 netif->output_ip6 = ethip6_output; #endif /* LWIP_IPV6 */ - netif->linkoutput = low_level_output; /* initialize the hardware */ low_level_init(netif); @@ -251,11 +349,13 @@ wlanif_init(struct netif *netif) err_t wlanif_init_sta(struct netif *netif) { netif->name[0] = 's'; netif->name[1] = 't'; + netif->linkoutput = sta_output; return wlanif_init(netif); } err_t wlanif_init_ap(struct netif *netif) { netif->name[0] = 'a'; netif->name[1] = 'p'; + netif->linkoutput = ap_output; return wlanif_init(netif); } diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index d4b3dfeb1b..5993d748d3 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -980,7 +980,6 @@ components/lwip/port/esp32/include/netinet/tcp.h components/lwip/port/esp32/include/sntp/sntp_get_set_time.h components/lwip/port/esp32/include/sys/socket.h components/lwip/port/esp32/netif/ethernetif.c -components/lwip/port/esp32/netif/wlanif.c components/lwip/port/esp32/no_vfs_syscalls.c components/lwip/test_afl_host/dhcp_di.h components/lwip/test_afl_host/dhcpserver_di.h From 8b40579aa4bf3d022be53739321b439963573538 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Tue, 31 May 2022 15:25:27 +0200 Subject: [PATCH 22/25] lwip: Move wifi's custom pbuf alloc/free to IRAM if config --- components/lwip/linker.lf | 3 +++ components/lwip/port/esp32/netif/wlanif.c | 21 +++++++++------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/components/lwip/linker.lf b/components/lwip/linker.lf index 8263efd5b5..a77921caf5 100644 --- a/components/lwip/linker.lf +++ b/components/lwip/linker.lf @@ -61,6 +61,8 @@ entries: pbuf:pbuf_header_impl (noflash_text) pbuf:pbuf_header (noflash_text) pbuf:pbuf_free (noflash_text) + pbuf:pbuf_alloced_custom (noflash_text) + pbuf:pbuf_init_alloced_pbuf (noflash_text) udp:udp_input_local_match (noflash_text) udp:udp_input (noflash_text) udp:udp_send (noflash_text) @@ -82,6 +84,7 @@ entries: wlanif:ap_output (noflash_text) wlanif:wifi_rxcb_sta (noflash_text) wlanif:wifi_rxcb_ap (noflash_text) + wlanif:wifi_pbuf_free (noflash_text) lwip_default_hooks:ip4_route_src_hook (noflash_text) if ESP_ALLOW_BSS_SEG_EXTERNAL_MEMORY = y: diff --git a/components/lwip/port/esp32/netif/wlanif.c b/components/lwip/port/esp32/netif/wlanif.c index 6268bedc3c..ae0c888b1e 100644 --- a/components/lwip/port/esp32/netif/wlanif.c +++ b/components/lwip/port/esp32/netif/wlanif.c @@ -14,7 +14,7 @@ #include "lwip/opt.h" #include "lwip/def.h" -#include "lwip/memp.h" +#include "lwip/mem.h" #include "lwip/pbuf.h" #include "lwip/stats.h" #include "lwip/snmp.h" @@ -38,9 +38,6 @@ typedef struct wifi_custom_pbuf void* l2_buf; } wifi_custom_pbuf_t; -#define ESP_PBUF_POOL_SIZE 16 -LWIP_MEMPOOL_DECLARE(ESP_PBUF_POOL, ESP_PBUF_POOL_SIZE, sizeof(wifi_custom_pbuf_t), "WIFI_CUSTOM_PBUF"); - static struct netif *s_wifi_netifs[2] = { NULL }; @@ -88,27 +85,27 @@ void set_wifi_netif(int wifi_inx, void* netif) } -static void esp_pbuf_free_l2_buff(struct pbuf *p) +static void wifi_pbuf_free(struct pbuf *p) { wifi_custom_pbuf_t* wifi_pbuf = (wifi_custom_pbuf_t*)p; esp_wifi_internal_free_rx_buffer(wifi_pbuf->l2_buf); - LWIP_MEMPOOL_FREE(ESP_PBUF_POOL, wifi_pbuf); + mem_free(wifi_pbuf); } -static inline struct pbuf* pbuf_allocate(struct netif *netif, void *buffer, size_t len, void *l2_buff) +static inline struct pbuf* wifi_pbuf_allocate(struct netif *netif, void *buffer, size_t len, void *l2_buff) { struct pbuf *p; - wifi_custom_pbuf_t* esp_pbuf = (wifi_custom_pbuf_t*)LWIP_MEMPOOL_ALLOC(ESP_PBUF_POOL); + wifi_custom_pbuf_t* esp_pbuf = mem_malloc(sizeof(wifi_custom_pbuf_t)); if (esp_pbuf == NULL) { return NULL; } - esp_pbuf->p.custom_free_function = esp_pbuf_free_l2_buff; + esp_pbuf->p.custom_free_function = wifi_pbuf_free; esp_pbuf->l2_buf = l2_buff; p = pbuf_alloced_custom(PBUF_RAW, len, PBUF_REF, &esp_pbuf->p, buffer, len); if (p == NULL) { - LWIP_MEMPOOL_FREE(ESP_PBUF_POOL, esp_pbuf); + mem_free(esp_pbuf); return NULL; } return p; @@ -126,7 +123,7 @@ esp_err_t wifi_rxcb_sta(void *buffer, uint16_t len, void *l2_buff) return ESP_FAIL; } - p = pbuf_allocate(netif, buffer, len, l2_buff); + p = wifi_pbuf_allocate(netif, buffer, len, l2_buff); if (p == NULL) { esp_wifi_internal_free_rx_buffer(l2_buff); return ESP_FAIL; @@ -152,7 +149,7 @@ esp_err_t wifi_rxcb_ap(void *buffer, uint16_t len, void *l2_buff) return ESP_FAIL; } - p = pbuf_allocate(netif, buffer, len, l2_buff); + p = wifi_pbuf_allocate(netif, buffer, len, l2_buff); if (p == NULL) { esp_wifi_internal_free_rx_buffer(l2_buff); return ESP_FAIL; From 00377cf2e55416c5dbe90009e6da475de7aa5982 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Wed, 1 Jun 2022 14:36:58 +0200 Subject: [PATCH 23/25] lwip/ci: Cleanup public header checker ignore list --- components/lwip/port/esp32/include/netif/dhcp_state.h | 2 -- tools/ci/check_public_headers_exceptions.txt | 8 ++++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/components/lwip/port/esp32/include/netif/dhcp_state.h b/components/lwip/port/esp32/include/netif/dhcp_state.h index d8bf13bb94..13ab598699 100644 --- a/components/lwip/port/esp32/include/netif/dhcp_state.h +++ b/components/lwip/port/esp32/include/netif/dhcp_state.h @@ -10,8 +10,6 @@ #include #include "lwip/netif.h" -#include - #ifdef __cplusplus extern "C" { #endif diff --git a/tools/ci/check_public_headers_exceptions.txt b/tools/ci/check_public_headers_exceptions.txt index 049116b585..92798b815a 100644 --- a/tools/ci/check_public_headers_exceptions.txt +++ b/tools/ci/check_public_headers_exceptions.txt @@ -28,7 +28,11 @@ components/esp32/include/esp32/cache_err_int.h components/driver/include/driver/sdmmc_defs.h components/driver/include/driver/sdmmc_types.h +# LWIP: sockets.h uses #include_next<>, which doesn't work correctly with the checker +# memp_std.h is supposed to be included multiple times with different settings components/lwip/lwip/src/include/lwip/priv/memp_std.h +components/lwip/include/lwip/sockets.h +components/lwip/lwip/src/include/lwip/prot/nd6.h components/esp_phy/esp32/include/phy_init_data.h @@ -101,8 +105,6 @@ components/esp_common/include/esp_compiler.h ### To be fixed: headers that rely on implicit inclusion # -components/lwip/lwip/src/include/lwip/prot/nd6.h -components/lwip/port/esp32/include/netif/dhcp_state.h components/soc/src/esp32/rtc_clk_common.h components/esp_rom/include/esp32/rom/sha.h components/esp_rom/include/esp32/rom/secure_boot.h @@ -142,7 +144,5 @@ components/fatfs/diskio/diskio_sdmmc.h components/openssl/include/openssl/ssl.h components/ulp/include/ulp_common.h components/ulp/include/esp32s2/ulp_riscv.h -components/lwip/include/apps/sntp/sntp.h -components/lwip/include/lwip/sockets.h components/mbedtls/esp_crt_bundle/include/esp_crt_bundle.h components/wifi_provisioning/include/wifi_provisioning/scheme_softap.h From 7efcb5e6254240f2c0c1cfac4dd60e53693b9794 Mon Sep 17 00:00:00 2001 From: David Cermak Date: Wed, 1 Jun 2022 20:38:40 +0200 Subject: [PATCH 24/25] lwip: Add missing null-checks, rename to vanilla-lwip --- components/esp_netif/Kconfig | 6 ++--- components/esp_netif/lwip/esp_netif_lwip.c | 6 ++--- .../esp_netif/lwip/esp_netif_lwip_defaults.c | 2 +- .../esp_netif/lwip/esp_netif_lwip_internal.h | 2 +- .../esp_netif/lwip/esp_netif_lwip_orig.c | 6 ++--- .../esp_netif/lwip/esp_netif_lwip_orig.h | 6 ++--- components/esp_wifi/src/wifi_netif.c | 5 +--- components/lwip/include/lwip/netdb.h | 4 ++-- components/lwip/include/lwip/sockets.h | 4 ++-- components/lwip/port/esp32/include/lwipopts.h | 2 +- .../lwip/port/esp32/include/netif/wlanif.h | 24 +++++++++---------- components/lwip/port/esp32/netif/dhcp_state.c | 9 +++++++ components/lwip/port/esp32/netif/wlanif.c | 8 +++++-- tools/ci/check_copyright_ignore.txt | 1 - 14 files changed, 46 insertions(+), 39 deletions(-) diff --git a/components/esp_netif/Kconfig b/components/esp_netif/Kconfig index bfa3d54bca..1c17ff2e94 100644 --- a/components/esp_netif/Kconfig +++ b/components/esp_netif/Kconfig @@ -29,12 +29,12 @@ menu "ESP NETIF Adapter" Dummy implementation of esp-netif functionality which connects driver transmit to receive function. This option is for testing purpose only - config ESP_NETIF_TCPIP_LWIP_ORIG + config ESP_NETIF_TCPIP_VANILLA_LWIP bool "LwIP-orig" - depends on !LWIP_PPP_SUPPORT && !LWIP_IPV4_NAPT + depends on !LWIP_IPV4_NAPT help This choice sets the original, vanilla-lwIP as the TCP/IP stack. - Warning: Current implementation does not support PPP and NAPT features + Warning: Current implementation does not NAPT features endchoice diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index a3fef0a31a..5354cbcc28 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -16,7 +16,7 @@ #include "esp_netif_private.h" #include "esp_random.h" -#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) #include "lwip/tcpip.h" #include "lwip/dhcp.h" @@ -567,7 +567,7 @@ static void esp_netif_lwip_remove(esp_netif_t *esp_netif) } netif_remove(esp_netif->lwip_netif); #if ESP_GRATUITOUS_ARP - if (esp_netif->flags&ESP_NETIF_FLAG_GARP) { + if (esp_netif->flags & ESP_NETIF_FLAG_GARP) { netif_unset_garp_flag(esp_netif->lwip_netif); } #endif @@ -2081,4 +2081,4 @@ esp_err_t esp_netif_remove_ip6_address(esp_netif_t *esp_netif, const esp_ip6_add #endif // CONFIG_LWIP_IPV6 -#endif /* CONFIG_ESP_NETIF_TCPIP_LWIP || CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG */ +#endif /* CONFIG_ESP_NETIF_TCPIP_LWIP || CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP */ diff --git a/components/esp_netif/lwip/esp_netif_lwip_defaults.c b/components/esp_netif/lwip/esp_netif_lwip_defaults.c index c57445da56..6239a5b41b 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_defaults.c +++ b/components/esp_netif/lwip/esp_netif_lwip_defaults.c @@ -8,7 +8,7 @@ #include "esp_netif_lwip_internal.h" #include "esp_netif_lwip_ppp.h" -#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) #include "netif/wlanif.h" #include "netif/ethernetif.h" diff --git a/components/esp_netif/lwip/esp_netif_lwip_internal.h b/components/esp_netif/lwip/esp_netif_lwip_internal.h index e19163c75a..c6996c7700 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_internal.h +++ b/components/esp_netif/lwip/esp_netif_lwip_internal.h @@ -12,7 +12,7 @@ #include "lwip/netif.h" #include "dhcpserver/dhcpserver.h" -#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) struct esp_netif_netstack_lwip_vanilla_config { err_t (*init_fn)(struct netif*); diff --git a/components/esp_netif/lwip/esp_netif_lwip_orig.c b/components/esp_netif/lwip/esp_netif_lwip_orig.c index 5610df4e00..4cce66a614 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_orig.c +++ b/components/esp_netif/lwip/esp_netif_lwip_orig.c @@ -18,13 +18,15 @@ #define DHCP_CB_CHANGE (LWIP_NSC_IPV4_SETTINGS_CHANGED | LWIP_NSC_IPV4_ADDRESS_CHANGED | LWIP_NSC_IPV4_GATEWAY_CHANGED | LWIP_NSC_IPV4_NETMASK_CHANGED) +static netif_ext_callback_t netif_callback = { .callback_fn = NULL, .next = NULL }; + static void netif_callback_fn(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args) { if (reason & DHCP_CB_CHANGE) { esp_netif_internal_dhcpc_cb(netif); } #if LWIP_IPV6 - if (reason & LWIP_NSC_IPV6_ADDR_STATE_CHANGED) { + if ((reason & LWIP_NSC_IPV6_ADDR_STATE_CHANGED) && (args != NULL)) { s8_t addr_idx = args->ipv6_addr_state_changed.addr_index; if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) { /* address is valid -> call the callback function */ @@ -34,8 +36,6 @@ static void netif_callback_fn(struct netif* netif, netif_nsc_reason_t reason, co #endif /* #if LWIP_IPV6 */ } -static netif_ext_callback_t netif_callback = { .callback_fn = NULL, .next = NULL }; - void set_lwip_netif_callback(void) { if (netif_callback.callback_fn == NULL ) { diff --git a/components/esp_netif/lwip/esp_netif_lwip_orig.h b/components/esp_netif/lwip/esp_netif_lwip_orig.h index d39e6a17e0..f5560e055e 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_orig.h +++ b/components/esp_netif/lwip/esp_netif_lwip_orig.h @@ -9,7 +9,7 @@ #include "esp_netif_lwip_internal.h" -#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) +#if defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) #if PPP_SUPPORT typedef struct ppp_pcb_s ppp_pcb; @@ -44,7 +44,7 @@ void netif_unset_garp_flag(struct netif *netif); #endif // ESP_GRATUITOUS_ARP -#else // !CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG and !CONFIG_ESP_NETIF_TCPIP_LWIP +#else // !CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP and !CONFIG_ESP_NETIF_TCPIP_LWIP static inline void set_lwip_netif_callback(void) { } @@ -52,4 +52,4 @@ static inline void remove_lwip_netif_callback(void) { } static inline void netif_unset_garp_flag(struct netif *netif) {} -#endif // CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG or CONFIG_ESP_NETIF_TCPIP_LWIP +#endif // CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP or CONFIG_ESP_NETIF_TCPIP_LWIP diff --git a/components/esp_wifi/src/wifi_netif.c b/components/esp_wifi/src/wifi_netif.c index 7683dfa62f..9b69dc35e3 100644 --- a/components/esp_wifi/src/wifi_netif.c +++ b/components/esp_wifi/src/wifi_netif.c @@ -6,6 +6,7 @@ #include "esp_wifi.h" #include "esp_netif.h" #include "esp_netif_net_stack.h" +#include "netif/wlanif.h" #include "esp_log.h" #include "esp_private/wifi.h" #include "esp_wifi_netif.h" @@ -100,10 +101,6 @@ bool esp_wifi_is_if_ready_when_started(wifi_netif_driver_t ifx) #endif } -void set_wifi_netif(int wifi_inx, void* netif); -esp_err_t wifi_rxcb_sta(void *buffer, uint16_t len, void *eb); -esp_err_t wifi_rxcb_ap(void *buffer, uint16_t len, void *eb); - esp_err_t esp_wifi_register_if_rxcb(wifi_netif_driver_t ifx, esp_netif_receive_t fn, void * arg) { if (ifx->base.netif != arg) { diff --git a/components/lwip/include/lwip/netdb.h b/components/lwip/include/lwip/netdb.h index cc395bac61..c058e5354b 100644 --- a/components/lwip/include/lwip/netdb.h +++ b/components/lwip/include/lwip/netdb.h @@ -13,7 +13,7 @@ extern "C" { #endif -#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) +#if defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) static inline int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop); } @@ -24,7 +24,7 @@ static inline void freeaddrinfo(struct addrinfo *ai) static inline int getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { return lwip_getaddrinfo(nodename, servname, hints, res); } -#endif // CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG || CONFIG_ESP_NETIF_TCPIP_LWIP +#endif // CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP || CONFIG_ESP_NETIF_TCPIP_LWIP #ifdef __cplusplus } diff --git a/components/lwip/include/lwip/sockets.h b/components/lwip/include/lwip/sockets.h index 1b475e3719..cbb1f66bc2 100644 --- a/components/lwip/include/lwip/sockets.h +++ b/components/lwip/include/lwip/sockets.h @@ -12,7 +12,7 @@ extern "C" { #endif -#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) +#if defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) static inline int accept(int s,struct sockaddr *addr,socklen_t *addrlen) { return lwip_accept(s,addr,addrlen); } @@ -53,7 +53,7 @@ static inline const char *inet_ntop(int af, const void *src, char *dst, socklen_ static inline int inet_pton(int af, const char *src, void *dst) { return lwip_inet_pton(af, src, dst); } -#endif // CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG || CONFIG_ESP_NETIF_TCPIP_LWIP +#endif // CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP || CONFIG_ESP_NETIF_TCPIP_LWIP #ifdef __cplusplus } diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index c539cbe0c7..f66c4db1b6 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -632,7 +632,7 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) #define LWIP_NETIF_STATUS_CALLBACK 0 #endif -#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP_ORIG) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) +#if defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) /** * LWIP_NETIF_EXT_STATUS_CALLBACK==1: Support an extended callback function * for several netif related event that supports multiple subscribers. diff --git a/components/lwip/port/esp32/include/netif/wlanif.h b/components/lwip/port/esp32/include/netif/wlanif.h index 4535b6cb51..b8e9c8b32e 100644 --- a/components/lwip/port/esp32/include/netif/wlanif.h +++ b/components/lwip/port/esp32/include/netif/wlanif.h @@ -1,16 +1,8 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #ifndef _WLAN_LWIP_IF_H_ @@ -19,13 +11,19 @@ #include "esp_wifi.h" #include "lwip/err.h" +#include "lwip/netif.h" #ifdef __cplusplus extern "C" { #endif + err_t wlanif_init_ap(struct netif *netif); err_t wlanif_init_sta(struct netif *netif); +err_t set_wifi_netif(int wifi_inx, void* netif); +esp_err_t wifi_rxcb_sta(void *buffer, uint16_t len, void *eb); +esp_err_t wifi_rxcb_ap(void *buffer, uint16_t len, void *eb); + void wlanif_input(void *netif, void *buffer, size_t len, void* eb); err_t wlanif_init(struct netif *netif); diff --git a/components/lwip/port/esp32/netif/dhcp_state.c b/components/lwip/port/esp32/netif/dhcp_state.c index 10b0981219..b441c6df1f 100644 --- a/components/lwip/port/esp32/netif/dhcp_state.c +++ b/components/lwip/port/esp32/netif/dhcp_state.c @@ -26,6 +26,9 @@ bool dhcp_ip_addr_restore(struct netif *netif) nvs_handle_t nvs; char if_key[IF_KEY_SIZE]; bool err = false; + if (netif == NULL) { + return false; + } struct dhcp *dhcp = netif_dhcp_data(netif); uint32_t *ip_addr = &dhcp->offered_ip_addr.addr; @@ -42,6 +45,9 @@ void dhcp_ip_addr_store(struct netif *netif) { nvs_handle_t nvs; char if_key[IF_KEY_SIZE]; + if (netif == NULL) { + return; + } struct dhcp *dhcp = netif_dhcp_data(netif); uint32_t ip_addr = dhcp->offered_ip_addr.addr; @@ -56,6 +62,9 @@ void dhcp_ip_addr_erase(struct netif *netif) { nvs_handle_t nvs; char if_key[IF_KEY_SIZE]; + if (netif == NULL) { + return; + } if (nvs_open(DHCP_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) { nvs_erase_key(nvs, gen_if_key(netif, if_key)); nvs_commit(nvs); diff --git a/components/lwip/port/esp32/netif/wlanif.c b/components/lwip/port/esp32/netif/wlanif.c index ae0c888b1e..4824f13751 100644 --- a/components/lwip/port/esp32/netif/wlanif.c +++ b/components/lwip/port/esp32/netif/wlanif.c @@ -77,18 +77,22 @@ low_level_init(struct netif *netif) } -void set_wifi_netif(int wifi_inx, void* netif) +err_t set_wifi_netif(int wifi_inx, void* netif) { if (wifi_inx < 2) { s_wifi_netifs[wifi_inx] = netif; + return ERR_OK; } + return ERR_ARG; } static void wifi_pbuf_free(struct pbuf *p) { wifi_custom_pbuf_t* wifi_pbuf = (wifi_custom_pbuf_t*)p; - esp_wifi_internal_free_rx_buffer(wifi_pbuf->l2_buf); + if (wifi_pbuf) { + esp_wifi_internal_free_rx_buffer(wifi_pbuf->l2_buf); + } mem_free(wifi_pbuf); } diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 5993d748d3..da481e711f 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -974,7 +974,6 @@ components/lwip/port/esp32/include/debug/lwip_debug.h components/lwip/port/esp32/include/netdb.h components/lwip/port/esp32/include/netif/ethernetif.h components/lwip/port/esp32/include/netif/openthreadif.h -components/lwip/port/esp32/include/netif/wlanif.h components/lwip/port/esp32/include/netinet/in.h components/lwip/port/esp32/include/netinet/tcp.h components/lwip/port/esp32/include/sntp/sntp_get_set_time.h From c67f4c2b4c2bb4b7740f988fc0f8a3e911e56afe Mon Sep 17 00:00:00 2001 From: David Cermak Date: Thu, 2 Jun 2022 16:25:20 +0200 Subject: [PATCH 25/25] lwip: Remove vanilla-lwip config until it's fully deployable --- components/esp_netif/CMakeLists.txt | 1 - components/esp_netif/Kconfig | 7 -- components/esp_netif/lwip/esp_netif_lwip.c | 83 ++++++++++++-- .../esp_netif/lwip/esp_netif_lwip_defaults.c | 2 +- .../esp_netif/lwip/esp_netif_lwip_internal.h | 2 +- .../esp_netif/lwip/esp_netif_lwip_orig.c | 105 ------------------ .../esp_netif/lwip/esp_netif_lwip_orig.h | 55 --------- .../esp_netif/lwip/esp_netif_lwip_ppp.c | 24 +++- components/lwip/include/lwip/netdb.h | 4 - components/lwip/include/lwip/sockets.h | 4 - components/lwip/port/esp32/include/lwipopts.h | 9 +- .../lwip/port/esp32/include/netif/wlanif.h | 4 +- components/lwip/port/esp32/netif/wlanif.c | 8 +- components/lwip/port/esp32/vfs_lwip.c | 7 ++ 14 files changed, 116 insertions(+), 199 deletions(-) delete mode 100644 components/esp_netif/lwip/esp_netif_lwip_orig.c delete mode 100644 components/esp_netif/lwip/esp_netif_lwip_orig.h diff --git a/components/esp_netif/CMakeLists.txt b/components/esp_netif/CMakeLists.txt index accc6e01a0..44c9ef8e0d 100644 --- a/components/esp_netif/CMakeLists.txt +++ b/components/esp_netif/CMakeLists.txt @@ -13,7 +13,6 @@ set(srcs "vfs_l2tap/esp_vfs_l2tap.c" "lwip/esp_netif_lwip.c" "lwip/esp_netif_lwip_defaults.c" - "lwip/esp_netif_lwip_orig.c" "lwip/esp_netif_sta_list.c") set(include_dirs "include") diff --git a/components/esp_netif/Kconfig b/components/esp_netif/Kconfig index 1c17ff2e94..2bad063a25 100644 --- a/components/esp_netif/Kconfig +++ b/components/esp_netif/Kconfig @@ -29,13 +29,6 @@ menu "ESP NETIF Adapter" Dummy implementation of esp-netif functionality which connects driver transmit to receive function. This option is for testing purpose only - config ESP_NETIF_TCPIP_VANILLA_LWIP - bool "LwIP-orig" - depends on !LWIP_IPV4_NAPT - help - This choice sets the original, vanilla-lwIP as the TCP/IP stack. - Warning: Current implementation does not NAPT features - endchoice config ESP_NETIF_L2_TAP diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index 5354cbcc28..f6f5e81e58 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -10,13 +10,12 @@ #include "esp_check.h" #include "esp_netif_lwip_internal.h" -#include "esp_netif_lwip_orig.h" #include "esp_netif.h" #include "esp_netif_private.h" #include "esp_random.h" -#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) #include "lwip/tcpip.h" #include "lwip/dhcp.h" @@ -26,6 +25,7 @@ #include "lwip/nd6.h" #include "lwip/priv/tcpip_priv.h" #include "lwip/netif.h" +#include "lwip/etharp.h" #if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ #include "lwip/dns.h" #endif @@ -48,6 +48,8 @@ #define ESP_NETIF_HOSTNAME_MAX_SIZE 32 +#define DHCP_CB_CHANGE (LWIP_NSC_IPV4_SETTINGS_CHANGED | LWIP_NSC_IPV4_ADDRESS_CHANGED | LWIP_NSC_IPV4_GATEWAY_CHANGED | LWIP_NSC_IPV4_NETMASK_CHANGED) + /** * @brief lwip thread safe tcpip function utility macros */ @@ -99,7 +101,75 @@ static const char *TAG = "esp_netif_lwip"; static bool tcpip_initialized = false; static esp_netif_t *s_last_default_esp_netif = NULL; static bool s_is_last_default_esp_netif_overridden = false; +static netif_ext_callback_t netif_callback = { .callback_fn = NULL, .next = NULL }; +static void esp_netif_internal_dhcpc_cb(struct netif *netif); +#if LWIP_IPV6 +static void esp_netif_internal_nd6_cb(struct netif *p_netif, uint8_t ip_index); +#endif /* LWIP_IPV6 */ + +static void netif_callback_fn(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args) +{ + if (reason & DHCP_CB_CHANGE) { + esp_netif_internal_dhcpc_cb(netif); + } +#if LWIP_IPV6 + if ((reason & LWIP_NSC_IPV6_ADDR_STATE_CHANGED) && (args != NULL)) { + s8_t addr_idx = args->ipv6_addr_state_changed.addr_index; + if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) { + /* address is valid -> call the callback function */ + esp_netif_internal_nd6_cb(netif, addr_idx); + } + } +#endif /* #if LWIP_IPV6 */ +} + +static void set_lwip_netif_callback(void) +{ + if (netif_callback.callback_fn == NULL ) { + netif_add_ext_callback(&netif_callback, netif_callback_fn); + } +} + +static void remove_lwip_netif_callback(void) +{ + netif_remove_ext_callback(&netif_callback); + memset(&netif_callback, 0, sizeof(netif_callback)); +} + +static void dns_clear_servers(bool keep_fallback) +{ + u8_t numdns = 0; + + for (numdns = 0; numdns < DNS_MAX_SERVERS; numdns ++) { + if (keep_fallback && numdns == DNS_FALLBACK_SERVER_INDEX) { + continue; + } + + dns_setserver(numdns, NULL); + } +} + +#ifdef CONFIG_LWIP_GARP_TMR_INTERVAL + +static void netif_send_garp(void *arg) +{ + struct netif *netif = arg; + etharp_gratuitous(netif); + sys_timeout(CONFIG_LWIP_GARP_TMR_INTERVAL*1000, netif_send_garp, netif); +} + +static void netif_set_garp_flag(struct netif *netif) +{ + sys_timeout(CONFIG_LWIP_GARP_TMR_INTERVAL*1000, netif_send_garp, netif); +} + +static void netif_unset_garp_flag(struct netif *netif) +{ + sys_untimeout(netif_send_garp, netif); +} + +#endif // CONFIG_LWIP_GARP_TMR_INTERVAL #if !LWIP_TCPIP_CORE_LOCKING static sys_sem_t api_sync_sem = NULL; @@ -947,7 +1017,7 @@ static esp_err_t esp_netif_start_ip_lost_timer(esp_netif_t *esp_netif); // // DHCP: // -void esp_netif_internal_dhcpc_cb(struct netif *netif) +static void esp_netif_internal_dhcpc_cb(struct netif *netif) { if (!netif) { ESP_LOGD(TAG, "null netif=%p", netif); @@ -1145,8 +1215,6 @@ static esp_err_t esp_netif_dhcpc_start_api(esp_netif_api_msg_t *msg) return ESP_ERR_ESP_NETIF_DHCPC_START_FAILED; } - dhcp_set_cb(p_netif, esp_netif_internal_dhcpc_cb); - esp_netif->dhcpc_status = ESP_NETIF_DHCP_STARTED; return ESP_OK; } else { @@ -1647,7 +1715,7 @@ esp_ip6_addr_type_t esp_netif_ip6_get_addr_type(esp_ip6_addr_t* ip6_addr) } -void esp_netif_internal_nd6_cb(struct netif *p_netif, uint8_t ip_index) +static void esp_netif_internal_nd6_cb(struct netif *p_netif, uint8_t ip_index) { ESP_LOGD(TAG, "%s lwip-netif:%p", __func__, p_netif); if (!p_netif) { @@ -1684,7 +1752,6 @@ static esp_err_t esp_netif_create_ip6_linklocal_api(esp_netif_api_msg_t *msg) struct netif *p_netif = esp_netif->lwip_netif; if (p_netif != NULL && netif_is_up(p_netif)) { netif_create_ip6_linklocal_address(p_netif, 1); - nd6_set_cb(p_netif, esp_netif_internal_nd6_cb); return ESP_OK; } else { return ESP_FAIL; @@ -2081,4 +2148,4 @@ esp_err_t esp_netif_remove_ip6_address(esp_netif_t *esp_netif, const esp_ip6_add #endif // CONFIG_LWIP_IPV6 -#endif /* CONFIG_ESP_NETIF_TCPIP_LWIP || CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP */ +#endif /* CONFIG_ESP_NETIF_TCPIP_LWIP */ diff --git a/components/esp_netif/lwip/esp_netif_lwip_defaults.c b/components/esp_netif/lwip/esp_netif_lwip_defaults.c index 6239a5b41b..ad93d50737 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_defaults.c +++ b/components/esp_netif/lwip/esp_netif_lwip_defaults.c @@ -8,7 +8,7 @@ #include "esp_netif_lwip_internal.h" #include "esp_netif_lwip_ppp.h" -#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) #include "netif/wlanif.h" #include "netif/ethernetif.h" diff --git a/components/esp_netif/lwip/esp_netif_lwip_internal.h b/components/esp_netif/lwip/esp_netif_lwip_internal.h index c6996c7700..47a82f42bc 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_internal.h +++ b/components/esp_netif/lwip/esp_netif_lwip_internal.h @@ -12,7 +12,7 @@ #include "lwip/netif.h" #include "dhcpserver/dhcpserver.h" -#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) +#if defined(CONFIG_ESP_NETIF_TCPIP_LWIP) struct esp_netif_netstack_lwip_vanilla_config { err_t (*init_fn)(struct netif*); diff --git a/components/esp_netif/lwip/esp_netif_lwip_orig.c b/components/esp_netif/lwip/esp_netif_lwip_orig.c deleted file mode 100644 index 4cce66a614..0000000000 --- a/components/esp_netif/lwip/esp_netif_lwip_orig.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include - -#include "esp_check.h" -#include "esp_netif_lwip_internal.h" -#include "esp_netif_lwip_orig.h" - -#include "esp_netif.h" -#include "esp_netif_private.h" - -#define DHCP_CB_CHANGE (LWIP_NSC_IPV4_SETTINGS_CHANGED | LWIP_NSC_IPV4_ADDRESS_CHANGED | LWIP_NSC_IPV4_GATEWAY_CHANGED | LWIP_NSC_IPV4_NETMASK_CHANGED) - -static netif_ext_callback_t netif_callback = { .callback_fn = NULL, .next = NULL }; - -static void netif_callback_fn(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args) -{ - if (reason & DHCP_CB_CHANGE) { - esp_netif_internal_dhcpc_cb(netif); - } -#if LWIP_IPV6 - if ((reason & LWIP_NSC_IPV6_ADDR_STATE_CHANGED) && (args != NULL)) { - s8_t addr_idx = args->ipv6_addr_state_changed.addr_index; - if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) { - /* address is valid -> call the callback function */ - esp_netif_internal_nd6_cb(netif, addr_idx); - } - } -#endif /* #if LWIP_IPV6 */ -} - -void set_lwip_netif_callback(void) -{ - if (netif_callback.callback_fn == NULL ) { - netif_add_ext_callback(&netif_callback, netif_callback_fn); - } -} - -void remove_lwip_netif_callback(void) -{ - netif_remove_ext_callback(&netif_callback); - memset(&netif_callback, 0, sizeof(netif_callback)); -} - -void dns_clear_servers(bool keep_fallback) -{ - u8_t numdns = 0; - - for (numdns = 0; numdns < DNS_MAX_SERVERS; numdns ++) { - if (keep_fallback && numdns == DNS_FALLBACK_SERVER_INDEX) { - continue; - } - - dns_setserver(numdns, NULL); - } -} -#if PPP_SUPPORT && PPP_AUTH_SUPPORT -typedef struct { - struct tcpip_api_call_data call; - ppp_pcb *ppp; - u8_t authtype; - const char *user; - const char *passwd; -} set_auth_msg_t; - -static err_t pppapi_do_ppp_set_auth(struct tcpip_api_call_data *m) -{ - set_auth_msg_t *msg = (set_auth_msg_t *)m; - ppp_set_auth(msg->ppp, msg->authtype, msg->user, msg->passwd); - return ERR_OK; -} - -void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) -{ - set_auth_msg_t msg = { .ppp = pcb, .authtype = authtype, .user = user, .passwd = passwd}; - tcpip_api_call(pppapi_do_ppp_set_auth, &msg.call); -} - -#endif // PPP_SUPPORT && PPP_AUTH_SUPPORT - -#ifdef CONFIG_LWIP_GARP_TMR_INTERVAL -void netif_send_garp(void *arg) -{ - struct netif *netif = arg; - etharp_gratuitous(netif); - sys_timeout(CONFIG_LWIP_GARP_TMR_INTERVAL*1000, netif_send_garp, netif); -} - -void netif_set_garp_flag(struct netif *netif) -{ - sys_timeout(CONFIG_LWIP_GARP_TMR_INTERVAL*1000, netif_send_garp, netif); -} - -void netif_unset_garp_flag(struct netif *netif) -{ - sys_untimeout(netif_send_garp, netif); -} -#endif // CONFIG_LWIP_GARP_TMR_INTERVAL diff --git a/components/esp_netif/lwip/esp_netif_lwip_orig.h b/components/esp_netif/lwip/esp_netif_lwip_orig.h deleted file mode 100644 index f5560e055e..0000000000 --- a/components/esp_netif/lwip/esp_netif_lwip_orig.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include "esp_netif_lwip_internal.h" - - -#if defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) - -#if PPP_SUPPORT -typedef struct ppp_pcb_s ppp_pcb; -#endif - -/** - * @brief Sets one extended lwip netif callbacks for all esp-netif - */ -void set_lwip_netif_callback(void); - -void remove_lwip_netif_callback(void); - -void esp_netif_internal_dhcpc_cb(struct netif *netif); - -void esp_netif_internal_nd6_cb(struct netif *netif, uint8_t index); - -static inline void dhcp_set_cb(struct netif *netif, void (*cb)(struct netif*)) { } - -static inline void nd6_set_cb(struct netif *netif, void (*cb)(struct netif *netif, u8_t ip_index)) { } - -void dns_clear_servers(bool keep_fallback); - -#if PPP_SUPPORT && PPP_AUTH_SUPPORT -void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd); -#endif - -#if ESP_GRATUITOUS_ARP - -void netif_set_garp_flag(struct netif *netif); - -void netif_unset_garp_flag(struct netif *netif); - -#endif // ESP_GRATUITOUS_ARP - -#else // !CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP and !CONFIG_ESP_NETIF_TCPIP_LWIP - -static inline void set_lwip_netif_callback(void) { } - -static inline void remove_lwip_netif_callback(void) { } - -static inline void netif_unset_garp_flag(struct netif *netif) {} - -#endif // CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP or CONFIG_ESP_NETIF_TCPIP_LWIP diff --git a/components/esp_netif/lwip/esp_netif_lwip_ppp.c b/components/esp_netif/lwip/esp_netif_lwip_ppp.c index 858603f69c..e7860aefbb 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_ppp.c +++ b/components/esp_netif/lwip/esp_netif_lwip_ppp.c @@ -17,7 +17,6 @@ #include "esp_event.h" #include "esp_netif_ppp.h" #include "esp_netif_lwip_internal.h" -#include "esp_netif_lwip_orig.h" #include #include "lwip/ip6_addr.h" @@ -37,6 +36,29 @@ typedef struct lwip_peer2peer_ctx { ppp_pcb *ppp; } lwip_peer2peer_ctx_t; +#if PPP_SUPPORT && PPP_AUTH_SUPPORT +typedef struct { + struct tcpip_api_call_data call; + ppp_pcb *ppp; + u8_t authtype; + const char *user; + const char *passwd; +} set_auth_msg_t; + +static err_t pppapi_do_ppp_set_auth(struct tcpip_api_call_data *m) +{ + set_auth_msg_t *msg = (set_auth_msg_t *)m; + ppp_set_auth(msg->ppp, msg->authtype, msg->user, msg->passwd); + return ERR_OK; +} + +static void pppapi_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) +{ + set_auth_msg_t msg = { .ppp = pcb, .authtype = authtype, .user = user, .passwd = passwd}; + tcpip_api_call(pppapi_do_ppp_set_auth, &msg.call); +} +#endif // PPP_SUPPORT && PPP_AUTH_SUPPORT + /** * @brief lwip callback from PPP client used here to produce PPP error related events, * as well as some IP events diff --git a/components/lwip/include/lwip/netdb.h b/components/lwip/include/lwip/netdb.h index c058e5354b..326fea1ff5 100644 --- a/components/lwip/include/lwip/netdb.h +++ b/components/lwip/include/lwip/netdb.h @@ -13,8 +13,6 @@ extern "C" { #endif -#if defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) - static inline int gethostbyname_r(const char *name, struct hostent *ret, char *buf, size_t buflen, struct hostent **result, int *h_errnop) { return lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop); } static inline struct hostent *gethostbyname(const char *name) @@ -24,8 +22,6 @@ static inline void freeaddrinfo(struct addrinfo *ai) static inline int getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { return lwip_getaddrinfo(nodename, servname, hints, res); } -#endif // CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP || CONFIG_ESP_NETIF_TCPIP_LWIP - #ifdef __cplusplus } #endif diff --git a/components/lwip/include/lwip/sockets.h b/components/lwip/include/lwip/sockets.h index cbb1f66bc2..b0f3a6febe 100644 --- a/components/lwip/include/lwip/sockets.h +++ b/components/lwip/include/lwip/sockets.h @@ -12,8 +12,6 @@ extern "C" { #endif -#if defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) - static inline int accept(int s,struct sockaddr *addr,socklen_t *addrlen) { return lwip_accept(s,addr,addrlen); } static inline int bind(int s,const struct sockaddr *name, socklen_t namelen) @@ -53,8 +51,6 @@ static inline const char *inet_ntop(int af, const void *src, char *dst, socklen_ static inline int inet_pton(int af, const char *src, void *dst) { return lwip_inet_pton(af, src, dst); } -#endif // CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP || CONFIG_ESP_NETIF_TCPIP_LWIP - #ifdef __cplusplus } #endif diff --git a/components/lwip/port/esp32/include/lwipopts.h b/components/lwip/port/esp32/include/lwipopts.h index f66c4db1b6..7d20a98f79 100644 --- a/components/lwip/port/esp32/include/lwipopts.h +++ b/components/lwip/port/esp32/include/lwipopts.h @@ -632,7 +632,6 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) #define LWIP_NETIF_STATUS_CALLBACK 0 #endif -#if defined(CONFIG_ESP_NETIF_TCPIP_VANILLA_LWIP) || defined(CONFIG_ESP_NETIF_TCPIP_LWIP) /** * LWIP_NETIF_EXT_STATUS_CALLBACK==1: Support an extended callback function * for several netif related event that supports multiple subscribers. @@ -641,8 +640,6 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) * to provide netif related events on IP4/IP6 address/status changes */ #define LWIP_NETIF_EXT_STATUS_CALLBACK 1 -#endif - /** * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP *tries* to put all data @@ -1440,13 +1437,13 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min) * allocate memory for lwip in SPIRAM firstly. If failed, try to allocate * internal memory then. */ -#if CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST +#if CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP #define mem_clib_malloc(size) heap_caps_malloc_prefer(size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL) #define mem_clib_calloc(n, size) heap_caps_calloc_prefer(n, size, 2, MALLOC_CAP_DEFAULT|MALLOC_CAP_SPIRAM, MALLOC_CAP_DEFAULT|MALLOC_CAP_INTERNAL) -#else /* !CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST */ +#else /* !CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP */ #define mem_clib_malloc malloc #define mem_clib_calloc calloc -#endif /* CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST */ +#endif /* CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP */ #ifdef __cplusplus } diff --git a/components/lwip/port/esp32/include/netif/wlanif.h b/components/lwip/port/esp32/include/netif/wlanif.h index b8e9c8b32e..49bb423b2b 100644 --- a/components/lwip/port/esp32/include/netif/wlanif.h +++ b/components/lwip/port/esp32/include/netif/wlanif.h @@ -21,8 +21,8 @@ extern "C" { err_t wlanif_init_ap(struct netif *netif); err_t wlanif_init_sta(struct netif *netif); err_t set_wifi_netif(int wifi_inx, void* netif); -esp_err_t wifi_rxcb_sta(void *buffer, uint16_t len, void *eb); -esp_err_t wifi_rxcb_ap(void *buffer, uint16_t len, void *eb); +esp_err_t wifi_rxcb_sta(void *buffer, uint16_t len, void *l2_buff); +esp_err_t wifi_rxcb_ap(void *buffer, uint16_t len, void *l2_buff); void wlanif_input(void *netif, void *buffer, size_t len, void* eb); diff --git a/components/lwip/port/esp32/netif/wlanif.c b/components/lwip/port/esp32/netif/wlanif.c index 4824f13751..3c7c8ade85 100644 --- a/components/lwip/port/esp32/netif/wlanif.c +++ b/components/lwip/port/esp32/netif/wlanif.c @@ -244,9 +244,9 @@ sta_output(struct netif *netif, struct pbuf *p) LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug")); q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM); if (q != NULL) { - pbuf_copy(q, p); + pbuf_copy(q, p); } else { - return ERR_MEM; + return ERR_MEM; } ret = esp_wifi_internal_tx(WIFI_IF_STA, q->payload, q->len); pbuf_free(q); @@ -276,9 +276,9 @@ ap_output(struct netif *netif, struct pbuf *p) LWIP_DEBUGF(PBUF_DEBUG, ("low_level_output: pbuf is a list, application may has bug")); q = pbuf_alloc(PBUF_RAW_TX, p->tot_len, PBUF_RAM); if (q != NULL) { - pbuf_copy(q, p); + pbuf_copy(q, p); } else { - return ERR_MEM; + return ERR_MEM; } ret = esp_wifi_internal_tx(WIFI_IF_AP, q->payload, q->len); pbuf_free(q); diff --git a/components/lwip/port/esp32/vfs_lwip.c b/components/lwip/port/esp32/vfs_lwip.c index ad50fee327..e9fa7a7ec9 100644 --- a/components/lwip/port/esp32/vfs_lwip.c +++ b/components/lwip/port/esp32/vfs_lwip.c @@ -24,6 +24,13 @@ _Static_assert(MAX_FDS >= CONFIG_LWIP_MAX_SOCKETS, "MAX_FDS < CONFIG_LWIP_MAX_SO #ifdef CONFIG_VFS_SUPPORT_SELECT +/** + * @brief This function is implemented only in FreeRTOS port (ingroup sys_sem) + * and has no official API counterpart in lwip's sys.h declarations + * Signals a semaphore from ISR + * @param sem the semaphore to signal + * @return 1 if the signal has caused a high-prio task to unblock (pxHigherPriorityTaskWoken) + */ int sys_sem_signal_isr(sys_sem_t *sem); static void lwip_stop_socket_select(void *sem)