diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index e7ec5ebd7a6645..3c099437ad9813 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -186,6 +186,17 @@ menu "CHIP Core" help Enable this option to use LwIP default IPv6 route hook for Route Information Option(RIO) feature. + config ENABLE_LWIP_THREAD_SAFETY + bool "Enable LwIP Thread safety options" + default y + select LWIP_TCPIP_CORE_LOCKING + select LWIP_CHECK_THREAD_SAFETY + help + CHIP SDK performs LwIP core locking before calling an LwIP API. + To make the calls thread safe we have to enable LWIP_TCPIP_CORE_LOCKING. + Here, we are also enabling LWIP_CHECK_THREAD_SAFETY which will assert when + LwIP code gets called from any other context or without holding the LwIP lock. + endmenu # "Networking Options" menu "System Options" diff --git a/src/inet/UDPEndPointImplLwIP.cpp b/src/inet/UDPEndPointImplLwIP.cpp index d3e87e1dd0ca42..8690fb3839377c 100644 --- a/src/inet/UDPEndPointImplLwIP.cpp +++ b/src/inet/UDPEndPointImplLwIP.cpp @@ -41,6 +41,11 @@ static_assert(LWIP_VERSION_MAJOR > 1, "CHIP requires LwIP 2.0 or later"); +#if !(CHIP_DEVICE_LAYER_TARGET_BL602 || CHIP_DEVICE_LAYER_TARGET_BL702 || CHIP_DEVICE_LAYER_TARGET_BL702L || \ + CHIP_DEVICE_LAYER_TARGET_ASR) +static_assert(LWIP_TCPIP_CORE_LOCKING, "CHIP requires config LWIP_TCPIP_CORE_LOCKING enabled"); +#endif + #if !defined(RAW_FLAGS_MULTICAST_LOOP) || !defined(UDP_FLAGS_MULTICAST_LOOP) || !defined(raw_clear_flags) || \ !defined(raw_set_flags) || !defined(udp_clear_flags) || !defined(udp_set_flags) #define HAVE_LWIP_MULTICAST_LOOP 0 diff --git a/src/platform/ESP32/route_hook/ESP32RouteHook.c b/src/platform/ESP32/route_hook/ESP32RouteHook.c index df19adf1de13e8..f19cf59ebf90b2 100644 --- a/src/platform/ESP32/route_hook/ESP32RouteHook.c +++ b/src/platform/ESP32/route_hook/ESP32RouteHook.c @@ -17,10 +17,12 @@ #include "lwip/icmp6.h" #include "lwip/mld6.h" #include "lwip/netif.h" +#include "lwip/opt.h" #include "lwip/prot/icmp6.h" #include "lwip/prot/ip6.h" #include "lwip/prot/nd6.h" #include "lwip/raw.h" +#include "lwip/tcpip.h" #define HOPLIM_MAX 255 #define PIO_FLAG_ON_LINK (1 << 7) @@ -155,25 +157,41 @@ esp_err_t esp_route_hook_init(esp_netif_t * netif) esp_err_t ret = ESP_OK; ESP_RETURN_ON_FALSE(netif != NULL, ESP_ERR_INVALID_ARG, TAG, "Invalid network interface"); + + LOCK_TCPIP_CORE(); + int netif_idx = esp_netif_get_netif_impl_index(netif); if (netif_idx < 0 || netif_idx > UINT8_MAX) { + UNLOCK_TCPIP_CORE(); return ESP_ERR_INVALID_SIZE; } lwip_netif = netif_get_by_index((uint8_t) netif_idx); - ESP_RETURN_ON_FALSE(lwip_netif != NULL, ESP_ERR_INVALID_ARG, TAG, "Invalid network interface"); + + if (lwip_netif == NULL) + { + UNLOCK_TCPIP_CORE(); + ESP_LOGE(TAG, "Invalid network interface"); + return ESP_ERR_INVALID_ARG; + } for (esp_route_hook_t * iter = s_hooks; iter != NULL; iter = iter->next) { if (iter->netif == lwip_netif) { + UNLOCK_TCPIP_CORE(); ESP_LOGI(TAG, "Hook already installed on netif, skip..."); return ESP_OK; } } hook = (esp_route_hook_t *) malloc(sizeof(esp_route_hook_t)); - ESP_RETURN_ON_FALSE(hook != NULL, ESP_ERR_NO_MEM, TAG, "Cannot allocate hook"); + if (hook == NULL) + { + UNLOCK_TCPIP_CORE(); + ESP_LOGE(TAG, "Cannot allocate hook"); + return ESP_ERR_NO_MEM; + } ESP_GOTO_ON_FALSE(mld6_joingroup_netif(lwip_netif, ip_2_ip6(&router_group)) == ESP_OK, ESP_FAIL, exit, TAG, "Failed to join multicast group"); @@ -189,6 +207,9 @@ esp_err_t esp_route_hook_init(esp_netif_t * netif) s_hooks = hook; exit: + + UNLOCK_TCPIP_CORE(); + if (ret != ESP_OK && hook != NULL) { free(hook);