diff --git a/components/esp_netif/esp_netif_objects.c b/components/esp_netif/esp_netif_objects.c index 490a91c7e05..7741b208de3 100644 --- a/components/esp_netif/esp_netif_objects.c +++ b/components/esp_netif/esp_netif_objects.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,8 +7,6 @@ #include "esp_netif.h" #include "sys/queue.h" #include "esp_log.h" -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" #include "esp_netif_private.h" #include @@ -28,65 +26,31 @@ struct slist_netifs_s { SLIST_HEAD(slisthead, slist_netifs_s) s_head = { .slh_first = NULL, }; static size_t s_esp_netif_counter = 0; -static SemaphoreHandle_t s_list_lock = NULL; ESP_EVENT_DEFINE_BASE(IP_EVENT); -esp_err_t esp_netif_list_lock(void) -{ - if (s_list_lock == NULL) { - s_list_lock = xSemaphoreCreateMutex(); - if (s_list_lock == NULL) { - return ESP_ERR_NO_MEM; - } - } - xSemaphoreTake(s_list_lock, portMAX_DELAY); - return ESP_OK; -} - -void esp_netif_list_unlock(void) -{ - assert(s_list_lock); - xSemaphoreGive(s_list_lock); - if (s_esp_netif_counter == 0) { - vQueueDelete(s_list_lock); - s_list_lock = NULL; - } -} - // // List manipulation functions // -esp_err_t esp_netif_add_to_list(esp_netif_t *netif) +esp_err_t esp_netif_add_to_list_unsafe(esp_netif_t *netif) { - esp_err_t ret; struct slist_netifs_s *item = calloc(1, sizeof(struct slist_netifs_s)); - ESP_LOGD(TAG, "%s %p", __func__, netif); + ESP_LOGV(TAG, "%s %p", __func__, netif); if (item == NULL) { return ESP_ERR_NO_MEM; } item->netif = netif; - if ((ret = esp_netif_list_lock()) != ESP_OK) { - free(item); - return ret; - } - SLIST_INSERT_HEAD(&s_head, item, next); ++s_esp_netif_counter; - ESP_LOGD(TAG, "%s netif added successfully (total netifs: %d)", __func__, s_esp_netif_counter); - esp_netif_list_unlock(); + ESP_LOGD(TAG, "%s netif added successfully (total netifs: %" PRIu32 ")", __func__, (uint32_t)s_esp_netif_counter); return ESP_OK; } -esp_err_t esp_netif_remove_from_list(esp_netif_t *netif) +esp_err_t esp_netif_remove_from_list_unsafe(esp_netif_t *netif) { struct slist_netifs_s *item; - esp_err_t ret; - if ((ret = esp_netif_list_lock()) != ESP_OK) { - return ret; - } ESP_LOGV(TAG, "%s %p", __func__, netif); SLIST_FOREACH(item, &s_head, next) { @@ -96,11 +60,9 @@ esp_err_t esp_netif_remove_from_list(esp_netif_t *netif) --s_esp_netif_counter; ESP_LOGD(TAG, "%s netif successfully removed (total netifs: %d)", __func__, s_esp_netif_counter); free(item); - esp_netif_list_unlock(); return ESP_OK; } } - esp_netif_list_unlock(); return ESP_ERR_NOT_FOUND; } @@ -109,17 +71,11 @@ size_t esp_netif_get_nr_of_ifs(void) return s_esp_netif_counter; } +// This API is inherently unsafe +// suggest that users call from esp_netif_tcpip_exec() esp_netif_t* esp_netif_next(esp_netif_t* netif) { - esp_err_t ret; - esp_netif_t* result; - if ((ret = esp_netif_list_lock()) != ESP_OK) { - ESP_LOGE(TAG, "Failed to lock esp-netif list with %d", ret); - return NULL; - } - result = esp_netif_next_unsafe(netif); - esp_netif_list_unlock(); - return result; + return esp_netif_next_unsafe(netif); } esp_netif_t* esp_netif_next_unsafe(esp_netif_t* netif) @@ -144,38 +100,23 @@ esp_netif_t* esp_netif_next_unsafe(esp_netif_t* netif) bool esp_netif_is_netif_listed(esp_netif_t *esp_netif) { struct slist_netifs_s *item; - esp_err_t ret; - if ((ret = esp_netif_list_lock()) != ESP_OK) { - ESP_LOGE(TAG, "Failed to lock esp-netif list with %d", ret); - return false; - } - SLIST_FOREACH(item, &s_head, next) { if (item->netif == esp_netif) { - esp_netif_list_unlock(); return true; } } - esp_netif_list_unlock(); return false; } -esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key) +esp_netif_t *esp_netif_get_handle_from_ifkey_unsafe(const char *if_key) { struct slist_netifs_s *item; - esp_err_t ret; - if ((ret = esp_netif_list_lock()) != ESP_OK) { - ESP_LOGE(TAG, "Failed to lock esp-netif list with %d", ret); - return NULL; - } SLIST_FOREACH(item, &s_head, next) { esp_netif_t *esp_netif = item->netif; if (strcmp(if_key, esp_netif_get_ifkey(esp_netif)) == 0) { - esp_netif_list_unlock(); return esp_netif; } } - esp_netif_list_unlock(); return NULL; } diff --git a/components/esp_netif/include/esp_netif.h b/components/esp_netif/include/esp_netif.h index 2510a1eefee..df4beee605a 100644 --- a/components/esp_netif/include/esp_netif.h +++ b/components/esp_netif/include/esp_netif.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -975,12 +975,49 @@ int32_t esp_netif_get_event_id(esp_netif_t *esp_netif, esp_netif_ip_event_type_t /** * @brief Iterates over list of interfaces. Returns first netif if NULL given as parameter * + * @note This API doesn't lock the list, nor the TCPIP context, as this it's usually required + * to get atomic access between iteration steps rather that within a single iteration. + * Therefore it is recommended to iterate over the interfaces inside esp_netif_tcpip_exec() + * + * You can use esp_netif_next_unsafe() directly if all the system + * interfaces are under your control and you can safely iterate over them. + * Otherwise, iterate over interfaces using esp_netif_tcpip_exec(), or use esp_netif_find_if() + * to search in the list of netifs with defined predicate. + * * @param[in] esp_netif Handle to esp-netif instance * * @return First netif from the list if supplied parameter is NULL, next one otherwise */ esp_netif_t *esp_netif_next(esp_netif_t *esp_netif); +/** + * @brief Iterates over list of interfaces without list locking. Returns first netif if NULL given as parameter + * + * Used for bulk search loops within TCPIP context, e.g. using esp_netif_tcpip_exec(), or if we're sure + * that the iteration is safe from our application perspective (e.g. no interface is removed between iterations) + * + * @param[in] esp_netif Handle to esp-netif instance + * + * @return First netif from the list if supplied parameter is NULL, next one otherwise + */ +esp_netif_t* esp_netif_next_unsafe(esp_netif_t* esp_netif); + +/** + * @brief Predicate callback for esp_netif_find_if() used to find interface + * which meets defined criteria + */ +typedef bool (*esp_netif_find_predicate_t)(esp_netif_t *netif, void *ctx); + +/** + * @brief Return a netif pointer for the first interface that meets criteria defined + * by the callback + * + * @param fn Predicate function returning true for the desired interface + * @param ctx Context pointer passed to the predicate, typically a descriptor to compare with + * @return valid netif pointer if found, NULL if not + */ +esp_netif_t *esp_netif_find_if(esp_netif_find_predicate_t fn, void *ctx); + /** * @brief Returns number of registered esp_netif objects * diff --git a/components/esp_netif/loopback/esp_netif_loopback.c b/components/esp_netif/loopback/esp_netif_loopback.c index e3fbb71921b..0721fcce580 100644 --- a/components/esp_netif/loopback/esp_netif_loopback.c +++ b/components/esp_netif/loopback/esp_netif_loopback.c @@ -187,7 +187,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) } esp_netif->ip_info_old = ip_info; - esp_netif_add_to_list(esp_netif); + esp_netif_add_to_list_unsafe(esp_netif); // Configure the created object with provided configuration esp_err_t ret = esp_netif_init_configuration(esp_netif, esp_netif_config); @@ -203,7 +203,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) void esp_netif_destroy(esp_netif_t *esp_netif) { if (esp_netif) { - esp_netif_remove_from_list(esp_netif); + esp_netif_remove_from_list_unsafe(esp_netif); free(esp_netif->ip_info); free(esp_netif->ip_info_old); free(esp_netif->if_key); diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index fa2579d6b84..df1a19f062c 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -143,6 +143,8 @@ static void netif_set_mldv6_flag(struct netif *netif); static void netif_unset_mldv6_flag(struct netif *netif); #endif /* LWIP_IPV6 */ +static esp_err_t esp_netif_destroy_api(esp_netif_api_msg_t *msg); + static void netif_callback_fn(struct netif* netif, netif_nsc_reason_t reason, const netif_ext_callback_args_t* args) { #if LWIP_IPV4 @@ -161,30 +163,6 @@ static void netif_callback_fn(struct netif* netif, netif_nsc_reason_t reason, co #endif /* #if LWIP_IPV6 */ } -#if LWIP_ESP_NETIF_DATA -static esp_err_t alloc_client_data_id(esp_netif_api_msg_t *msg) -{ - uint8_t *client_data_id = msg->data; - *client_data_id = netif_alloc_client_data_id(); - return ESP_OK; -} -#endif // LWIP_ESP_NETIF_DATA - -static esp_err_t set_lwip_netif_callback(struct esp_netif_api_msg_s *msg) -{ - (void)msg; - netif_add_ext_callback(&netif_callback, netif_callback_fn); - return ESP_OK; -} - -static esp_err_t remove_lwip_netif_callback(struct esp_netif_api_msg_s *msg) -{ - (void)msg; - netif_remove_ext_callback(&netif_callback); - memset(&netif_callback, 0, sizeof(netif_callback)); - return ESP_OK; -} - #ifdef CONFIG_LWIP_GARP_TMR_INTERVAL static void netif_send_garp(void *arg) @@ -275,6 +253,16 @@ static inline esp_err_t esp_netif_lwip_ipc_call_fn(esp_netif_api_fn fn, esp_neti return esp_netif_lwip_ipc_call_msg(&msg); } +static inline esp_err_t esp_netif_lwip_ipc_call_get_netif(esp_netif_api_fn fn, esp_netif_t **netif, void *ctx) +{ + esp_netif_api_msg_t msg = { + .p_esp_netif = netif, + .data = ctx, + .api_fn = fn + }; + return esp_netif_lwip_ipc_call_msg(&msg); +} + static inline esp_err_t esp_netif_lwip_ipc_no_args(esp_netif_api_fn fn) { esp_netif_api_msg_t msg = { @@ -363,7 +351,6 @@ static esp_err_t esp_netif_update_default_netif_lwip(esp_netif_api_msg_t *msg) case ESP_NETIF_STOPPED: { s_last_default_esp_netif = NULL; - esp_netif_list_lock(); esp_netif_t *netif = esp_netif_next_unsafe(NULL); while (netif) { if (esp_netif_is_netif_up(netif)) { @@ -378,7 +365,6 @@ static esp_err_t esp_netif_update_default_netif_lwip(esp_netif_api_msg_t *msg) } netif = esp_netif_next_unsafe(netif); } - esp_netif_list_unlock(); if (s_last_default_esp_netif && esp_netif_is_netif_up(s_last_default_esp_netif)) { esp_netif_set_default_netif_internal(s_last_default_esp_netif); } @@ -518,6 +504,13 @@ void* esp_netif_get_netif_impl(esp_netif_t *esp_netif) static void tcpip_init_done(void *arg) { sys_sem_t *init_sem = arg; + +#if LWIP_ESP_NETIF_DATA + if (lwip_netif_client_id == 0xFF) { + lwip_netif_client_id = netif_alloc_client_data_id(); + } +#endif + sys_sem_signal(init_sem); } @@ -569,11 +562,6 @@ esp_err_t esp_netif_init(void) } #endif -#if LWIP_ESP_NETIF_DATA - if (lwip_netif_client_id == 0xFF) { - esp_netif_lwip_ipc_call(alloc_client_data_id, NULL, &lwip_netif_client_id); - } -#endif ESP_LOGD(TAG, "esp-netif has been successfully initialized"); return ESP_OK; } @@ -697,15 +685,16 @@ esp_err_t esp_netif_tcpip_exec(esp_netif_callback_fn fn, void*ctx) return esp_netif_lwip_ipc_call_fn(tcpip_exec_api, fn, ctx); } -esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) +static esp_err_t esp_netif_new_api(esp_netif_api_msg_t *msg) { + const esp_netif_config_t *esp_netif_config = msg->data; // mandatory configuration must be provided when creating esp_netif object if (esp_netif_config == NULL || esp_netif_config->base->if_key == NULL || - NULL != esp_netif_get_handle_from_ifkey(esp_netif_config->base->if_key)) { + NULL != esp_netif_get_handle_from_ifkey_unsafe(esp_netif_config->base->if_key)) { ESP_LOGE(TAG, "%s: Failed to configure netif with config=%p (config or if_key is NULL or duplicate key)", __func__, esp_netif_config); - return NULL; + return ESP_FAIL; } #if ESP_DHCPS @@ -714,7 +703,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) (esp_netif_config->base->flags & ESP_NETIF_DHCP_CLIENT)) { ESP_LOGE(TAG, "%s: Failed to configure netif with config=%p (DHCP server and client cannot be configured together)", __func__, esp_netif_config); - return NULL; + return ESP_FAIL; } #endif @@ -723,7 +712,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) if (!esp_netif) { ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(struct esp_netif_obj), esp_get_free_heap_size()); - return NULL; + return ESP_FAIL; } // Create ip info @@ -732,7 +721,7 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) 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; + return ESP_FAIL; } esp_netif->ip_info = ip_info; @@ -743,19 +732,11 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) esp_get_free_heap_size()); free(esp_netif->ip_info); free(esp_netif); - return NULL; + return ESP_FAIL; } esp_netif->ip_info_old = ip_info; // Create underlying lwip netif -#if LWIP_ESP_NETIF_DATA - // Optionally allocate netif client data for esp-netif ptr - // to allow for running esp_netif_new() before esp_netif_init() - if (lwip_netif_client_id == 0xFF) { - esp_netif_lwip_ipc_call(alloc_client_data_id, NULL, &lwip_netif_client_id); - } -#endif - struct netif * lwip_netif = calloc(1, sizeof(struct netif)); if (!lwip_netif) { ESP_LOGE(TAG, "Failed to allocate %d bytes (free heap size %d)", sizeof(struct netif), @@ -763,12 +744,12 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) free(esp_netif->ip_info_old); free(esp_netif->ip_info); free(esp_netif); - return NULL; + return ESP_FAIL; } esp_netif->lwip_netif = lwip_netif; - esp_netif_add_to_list(esp_netif); + esp_netif_add_to_list_unsafe(esp_netif); #if ESP_DHCPS // Create DHCP server structure @@ -776,8 +757,9 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) esp_netif->dhcps = dhcps_new(); if (esp_netif->dhcps == NULL) { ESP_LOGE(TAG, "Failed to create dhcp server handle"); - esp_netif_destroy(esp_netif); - return NULL; + esp_netif_api_msg_t to_destroy = { .esp_netif = esp_netif}; + esp_netif_destroy_api(&to_destroy); + return ESP_FAIL; } } #endif @@ -786,16 +768,66 @@ esp_netif_t *esp_netif_new(const esp_netif_config_t *esp_netif_config) esp_err_t ret = esp_netif_init_configuration(esp_netif, esp_netif_config); if (ret != ESP_OK) { ESP_LOGE(TAG, "Initial configuration of esp_netif failed with %d", ret); - esp_netif_destroy(esp_netif); - return NULL; + esp_netif_api_msg_t to_destroy = { .esp_netif = esp_netif}; + esp_netif_destroy_api(&to_destroy); + return ESP_FAIL; } lwip_set_esp_netif(lwip_netif, esp_netif); if (netif_callback.callback_fn == NULL ) { - esp_netif_lwip_ipc_no_args(set_lwip_netif_callback); + netif_add_ext_callback(&netif_callback, netif_callback_fn); } - return esp_netif; + *msg->p_esp_netif = esp_netif; + return ESP_OK; +} + +esp_netif_t *esp_netif_new(const esp_netif_config_t *config) +{ + esp_netif_t *netif = NULL; + esp_netif_lwip_ipc_call_get_netif(esp_netif_new_api, &netif, (void *)config); + return netif; +} + +static esp_err_t get_handle_from_ifkey_api(esp_netif_api_msg_t *msg) +{ + *msg->p_esp_netif = esp_netif_get_handle_from_ifkey_unsafe(msg->data); + return ESP_OK; +} + +esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key) +{ + esp_netif_t *netif = NULL; + esp_netif_lwip_ipc_call_get_netif(get_handle_from_ifkey_api, &netif, (void*)if_key); + return netif; +} + +typedef struct find_if_api { + esp_netif_find_predicate_t fn; + void *ctx; +} find_if_api_t; + +static esp_err_t esp_netif_find_if_api(esp_netif_api_msg_t *msg) +{ + find_if_api_t *find_if_api = msg->data; + esp_netif_t *esp_netif = NULL; + while ((esp_netif = esp_netif_next_unsafe(esp_netif)) != NULL) { + if (find_if_api->fn(esp_netif, find_if_api->ctx)) { + *msg->p_esp_netif = esp_netif; + return ESP_OK; + } + } + return ESP_FAIL; +} + +esp_netif_t *esp_netif_find_if(esp_netif_find_predicate_t fn, void *ctx) +{ + esp_netif_t *netif = NULL; + find_if_api_t find_if_api = { .fn = fn, .ctx = ctx }; + if (esp_netif_lwip_ipc_call_get_netif(esp_netif_find_if_api, &netif, &find_if_api) == ESP_OK) { + return netif; + } + return NULL; } static void esp_netif_lwip_remove(esp_netif_t *esp_netif) @@ -886,33 +918,36 @@ static void esp_netif_destroy_related(esp_netif_t *esp_netif) } } -static esp_err_t esp_netif_lwip_remove_api(esp_netif_api_msg_t *msg) +static esp_err_t esp_netif_destroy_api(esp_netif_api_msg_t *msg) { - esp_netif_lwip_remove(msg->esp_netif); + esp_netif_t *esp_netif = msg->esp_netif; + esp_netif_remove_from_list_unsafe(esp_netif); + if (esp_netif_get_nr_of_ifs() == 0) { + netif_remove_ext_callback(&netif_callback); + netif_callback.callback_fn = NULL; + } + free(esp_netif->ip_info); + free(esp_netif->ip_info_old); + free(esp_netif->if_key); + free(esp_netif->if_desc); + esp_netif_lwip_remove(esp_netif); + esp_netif_destroy_related(esp_netif); + free(esp_netif->lwip_netif); + free(esp_netif->hostname); + esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED); +#if ESP_DHCPS + dhcps_delete(esp_netif->dhcps); +#endif + free(esp_netif); return ESP_OK; } 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) { - esp_netif_lwip_ipc_no_args(remove_lwip_netif_callback); - } - free(esp_netif->ip_info); - free(esp_netif->ip_info_old); - free(esp_netif->if_key); - free(esp_netif->if_desc); - esp_netif_lwip_ipc_call(esp_netif_lwip_remove_api, esp_netif, NULL); - esp_netif_destroy_related(esp_netif); - free(esp_netif->lwip_netif); - free(esp_netif->hostname); - esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED); -#if ESP_DHCPS - dhcps_delete(esp_netif->dhcps); -#endif - free(esp_netif); + if (esp_netif == NULL) { + return; } + esp_netif_lwip_ipc_call(esp_netif_destroy_api, esp_netif, NULL); } esp_err_t esp_netif_attach(esp_netif_t *esp_netif, esp_netif_iodriver_handle driver_handle) @@ -1033,6 +1068,15 @@ static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg) esp_netif_t * esp_netif = msg->esp_netif; ESP_LOGD(TAG, "%s %p", __func__, esp_netif); + if (ESP_NETIF_IS_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) { +#if CONFIG_PPP_SUPPORT + esp_err_t ret = esp_netif_start_ppp(esp_netif); + if (ret == ESP_OK) { + esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED); + } + return ret; +#endif + } ESP_ERROR_CHECK(esp_netif_config_sanity_check(esp_netif)); @@ -1115,22 +1159,22 @@ static esp_err_t esp_netif_start_api(esp_netif_api_msg_t *msg) esp_err_t esp_netif_start(esp_netif_t *esp_netif) { + return esp_netif_lwip_ipc_call(esp_netif_start_api, esp_netif, NULL); +} + +static esp_err_t esp_netif_stop_api(esp_netif_api_msg_t *msg) +{ + esp_netif_t *esp_netif = msg->esp_netif; + if (ESP_NETIF_IS_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) { #if CONFIG_PPP_SUPPORT - // No need to start PPP interface in lwip thread - esp_err_t ret = esp_netif_start_ppp(esp_netif); + esp_err_t ret = esp_netif_stop_ppp(esp_netif->related_data); if (ret == ESP_OK) { - esp_netif_update_default_netif(esp_netif, ESP_NETIF_STARTED); + esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED); } return ret; #endif } - return esp_netif_lwip_ipc_call(esp_netif_start_api, esp_netif, NULL); -} - -static esp_err_t esp_netif_stop_api(esp_netif_api_msg_t *msg) -{ - esp_netif_t *esp_netif = msg->esp_netif; struct netif *lwip_netif = esp_netif->lwip_netif; if (lwip_netif == NULL) { @@ -1174,16 +1218,6 @@ static esp_err_t esp_netif_stop_api(esp_netif_api_msg_t *msg) esp_err_t esp_netif_stop(esp_netif_t *esp_netif) { - if (ESP_NETIF_IS_POINT2POINT_TYPE(esp_netif, PPP_LWIP_NETIF)) { -#if CONFIG_PPP_SUPPORT - // No need to stop PPP interface in lwip thread - esp_err_t ret = esp_netif_stop_ppp(esp_netif->related_data); - if (ret == ESP_OK) { - esp_netif_update_default_netif(esp_netif, ESP_NETIF_STOPPED); - } - return ret; -#endif - } return esp_netif_lwip_ipc_call(esp_netif_stop_api, esp_netif, NULL); } @@ -2411,11 +2445,11 @@ esp_err_t esp_netif_get_netif_impl_name(esp_netif_t *esp_netif, char* name) return esp_netif_lwip_ipc_call(esp_netif_get_netif_impl_name_api, esp_netif, name); } -esp_err_t esp_netif_napt_enable(esp_netif_t *esp_netif) +#if IP_NAPT +static esp_err_t esp_netif_napt_control_api(esp_netif_api_msg_t *msg) { -#if !IP_NAPT - return ESP_ERR_NOT_SUPPORTED; -#else + bool enable = (bool)msg->data; + esp_netif_t *esp_netif = msg->esp_netif; ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif); /* Check if the interface is up */ @@ -2423,44 +2457,74 @@ esp_err_t esp_netif_napt_enable(esp_netif_t *esp_netif) return ESP_FAIL; } - esp_netif_list_lock(); - /* Disable napt on all other interface */ - esp_netif_t *netif = esp_netif_next_unsafe(NULL); - while (netif) { - if (netif != esp_netif) { - ip_napt_enable_netif(netif->lwip_netif, 0); // Fails only if netif is down - ESP_LOGW(TAG, "napt disabled on esp_netif:%p", esp_netif); + if (enable) { + /* Disable napt on all other interface */ + esp_netif_t *netif = esp_netif_next_unsafe(NULL); + while (netif) { + if (netif != esp_netif) { + ip_napt_enable_netif(netif->lwip_netif, 0); // Fails only if netif is down + ESP_LOGW(TAG, "napt disabled on esp_netif:%p", esp_netif); + } + netif = esp_netif_next_unsafe(netif); } - netif = esp_netif_next_unsafe(netif); - } - int ret = ip_napt_enable_netif(esp_netif->lwip_netif, 1); - esp_netif_list_unlock(); + int ret = ip_napt_enable_netif(esp_netif->lwip_netif, 1); - if (ret == 0) { - return ESP_FAIL; - } + if (ret == 0) { + return ESP_FAIL; + } + return ESP_OK; + } else { + ip_napt_enable_netif(esp_netif->lwip_netif, 0); // Fails only if netif is down + ESP_LOGD(TAG, "napt disabled on esp_netif:%p", esp_netif); - return ESP_OK; -#endif /* IP_NAPT */ + return ESP_OK; + } } +#endif // !IP_NAPT -esp_err_t esp_netif_napt_disable(esp_netif_t *esp_netif) +esp_err_t esp_netif_napt_enable(esp_netif_t *esp_netif) { #if !IP_NAPT return ESP_ERR_NOT_SUPPORTED; #else - /* Check if the interface is up */ - if (!netif_is_up(esp_netif->lwip_netif)) { - return ESP_FAIL; - } + return esp_netif_lwip_ipc_call(esp_netif_napt_control_api, esp_netif, (void*)true /* Enable */); +#endif /* IP_NAPT */ +} - esp_netif_list_lock(); - ip_napt_enable_netif(esp_netif->lwip_netif, 0); // Fails only if netif is down - ESP_LOGD(TAG, "napt disabled on esp_netif:%p", esp_netif); - esp_netif_list_unlock(); +typedef struct { + u8_t authtype; + const char *user; + const char *passwd; +} set_auth_msg_t; +static esp_err_t esp_netif_ppp_set_auth_api(esp_netif_api_msg_t *msg) +{ + set_auth_msg_t *params = msg->data; + return esp_netif_ppp_set_auth_internal(msg->esp_netif, params->authtype, params->user, params->passwd); +} + +esp_err_t esp_netif_ppp_set_auth(esp_netif_t *esp_netif, esp_netif_auth_type_t authtype, const char *user, const char *passwd) +{ + set_auth_msg_t msg = { .authtype = authtype, .user = user, .passwd = passwd }; + return esp_netif_lwip_ipc_call(esp_netif_ppp_set_auth_api, esp_netif, &msg); +#if PPP_AUTH_SUPPORT + lwip_peer2peer_ctx_t *ppp_ctx = (lwip_peer2peer_ctx_t *)netif->related_data; + assert(ppp_ctx->base.netif_type == PPP_LWIP_NETIF); + pppapi_set_auth(ppp_ctx->ppp, authtype, user, passwd); return ESP_OK; +#else + ESP_LOGE(TAG, "%s failed: No authorisation enabled in menuconfig", __func__); + return ESP_ERR_ESP_NETIF_IF_NOT_READY; +#endif +} + +esp_err_t esp_netif_napt_disable(esp_netif_t *esp_netif) +{ +#if !IP_NAPT + return ESP_ERR_NOT_SUPPORTED; +#else + return esp_netif_lwip_ipc_call(esp_netif_napt_control_api, esp_netif, (void*)false /* Disable */); #endif /* IP_NAPT */ } diff --git a/components/esp_netif/lwip/esp_netif_lwip_internal.h b/components/esp_netif/lwip/esp_netif_lwip_internal.h index 5f749c03068..f1fc1f8bf8b 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-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,9 +23,10 @@ typedef struct esp_netif_api_msg_s { int ret; esp_netif_api_fn api_fn; union { - esp_netif_t *esp_netif; - esp_netif_callback_fn user_fn; - }; + esp_netif_t *esp_netif; /* esp_netif as input param */ + esp_netif_t **p_esp_netif; /* esp_netif as output */ + esp_netif_callback_fn user_fn; /* user callback */ + }; /* Commonly used parameters what calling api_fn */ void *data; } esp_netif_api_msg_t; diff --git a/components/esp_netif/lwip/esp_netif_lwip_ppp.c b/components/esp_netif/lwip/esp_netif_lwip_ppp.c index 4bf697bc278..25a3db6ef16 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_ppp.c +++ b/components/esp_netif/lwip/esp_netif_lwip_ppp.c @@ -8,7 +8,6 @@ #include "esp_netif.h" #include "lwip/dns.h" -#include "netif/ppp/pppapi.h" #include "netif/ppp/pppos.h" #include "esp_log.h" #include "esp_netif_net_stack.h" @@ -34,29 +33,6 @@ 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 @@ -199,15 +175,14 @@ static uint32_t pppos_low_level_output(ppp_pcb *pcb, uint8_t *data, uint32_t len return 0; } -esp_err_t esp_netif_ppp_set_auth(esp_netif_t *netif, esp_netif_auth_type_t authtype, const char *user, const char *passwd) +esp_err_t esp_netif_ppp_set_auth_internal(esp_netif_t *netif, esp_netif_auth_type_t authtype, const char *user, const char *passwd) { if (!ESP_NETIF_IS_POINT2POINT_TYPE(netif, PPP_LWIP_NETIF)) { return ESP_ERR_ESP_NETIF_INVALID_PARAMS; } #if PPP_AUTH_SUPPORT lwip_peer2peer_ctx_t *ppp_ctx = (lwip_peer2peer_ctx_t *)netif->related_data; - assert(ppp_ctx->base.netif_type == PPP_LWIP_NETIF); - pppapi_set_auth(ppp_ctx->ppp, authtype, user, passwd); + ppp_set_auth(ppp_ctx->ppp, authtype, user, passwd); return ESP_OK; #else ESP_LOGE(TAG, "%s failed: No authorisation enabled in menuconfig", __func__); @@ -235,10 +210,11 @@ netif_related_data_t * esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif ppp_obj->base.is_point2point = true; ppp_obj->base.netif_type = PPP_LWIP_NETIF; - ppp_obj->ppp = pppapi_pppos_create(netif_impl, pppos_low_level_output, on_ppp_status_changed, esp_netif); + ppp_obj->ppp = pppos_create(netif_impl, pppos_low_level_output, on_ppp_status_changed, esp_netif); ESP_LOGD(TAG, "%s: PPP connection created: %p", __func__, ppp_obj->ppp); if (!ppp_obj->ppp) { ESP_LOGE(TAG, "%s: lwIP PPP connection cannot be created", __func__); + return NULL; } // Set the related data here, since the phase callback could be triggered before this function exits @@ -258,7 +234,7 @@ esp_err_t esp_netif_start_ppp(esp_netif_t *esp_netif) assert(ppp_ctx->base.netif_type == PPP_LWIP_NETIF); ESP_LOGD(TAG, "%s: Starting PPP connection: %p", __func__, ppp_ctx->ppp); - esp_err_t err = pppapi_connect(ppp_ctx->ppp, 0); + err_t err = ppp_connect(ppp_ctx->ppp, 0); if (err != ESP_OK) { ESP_LOGE(TAG, "%s: PPP connection cannot be started", __func__); if (ppp_ctx->ppp_error_event_enabled) { @@ -285,9 +261,9 @@ esp_err_t esp_netif_stop_ppp(netif_related_data_t *netif_related) lwip_peer2peer_ctx_t *ppp_ctx = (lwip_peer2peer_ctx_t *)netif_related; assert(ppp_ctx->base.netif_type == PPP_LWIP_NETIF); ESP_LOGD(TAG, "%s: Stopped PPP connection: %p", __func__, ppp_ctx->ppp); - err_t ret = pppapi_close(ppp_ctx->ppp, 0); + err_t ret = ppp_close(ppp_ctx->ppp, 0); if (ret != ERR_OK) { - ESP_LOGE(TAG, "pppapi_close failed with %d", ret); + ESP_LOGE(TAG, "ppp_close failed with %d", ret); return ESP_FAIL; } return ESP_OK; @@ -298,7 +274,7 @@ void esp_netif_destroy_ppp(netif_related_data_t *netif_related) lwip_peer2peer_ctx_t *ppp_ctx = (lwip_peer2peer_ctx_t *)netif_related; assert(ppp_ctx->base.netif_type == PPP_LWIP_NETIF); - pppapi_free(ppp_ctx->ppp); + ppp_free(ppp_ctx->ppp); free(netif_related); } diff --git a/components/esp_netif/lwip/esp_netif_lwip_ppp.h b/components/esp_netif/lwip/esp_netif_lwip_ppp.h index 9fb2be025d3..035dc03fad3 100644 --- a/components/esp_netif/lwip/esp_netif_lwip_ppp.h +++ b/components/esp_netif/lwip/esp_netif_lwip_ppp.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -9,6 +9,7 @@ /** * @brief Creates new PPP related structure + * This needs to be called withing lwIP context * * @param[in] esp_netif pointer esp-netif instance * @param[in] stack_config TCP/IP stack configuration structure @@ -21,6 +22,7 @@ netif_related_data_t * esp_netif_new_ppp(esp_netif_t *esp_netif, const esp_netif /** * @brief Creates new PPP related structure + * This needs to be called withing lwIP context * * @param[in] esp_netif pointer esp-netif instance * @@ -44,6 +46,7 @@ esp_netif_recv_ret_t esp_netif_lwip_ppp_input(void *ppp, void *buffer, size_t le /** * @brief Destroys the ppp netif object + * This needs to be called withing lwIP context * * @param[in] netif_related pointer to internal ppp context instance */ @@ -51,6 +54,7 @@ void esp_netif_destroy_ppp(netif_related_data_t *netif_related); /** * @brief Stops the PPP interface + * This needs to be called withing lwIP context * * @param[in] netif_related pointer to internal ppp context instance * @@ -61,11 +65,19 @@ esp_err_t esp_netif_stop_ppp(netif_related_data_t *netif_related); /** * @brief Sets default netif for routing priority config + * This needs to be called withing lwIP context * * @note: This function must be called from lwip thread * */ void esp_netif_ppp_set_default_netif(netif_related_data_t *netif_related); +/** + * @brief Set PPP auth internal version (TCPIP context must be locked) + * This needs to be called withing lwIP context + * + * For params/return value description, please @refitem esp_netif_ppp_set_auth() + */ +esp_err_t esp_netif_ppp_set_auth_internal(esp_netif_t *netif, esp_netif_auth_type_t authtype, const char *user, const char *passwd); #endif // _ESP_NETIF_LWIP_PPP_H_ diff --git a/components/esp_netif/private_include/esp_netif_private.h b/components/esp_netif/private_include/esp_netif_private.h index b7fcfa6ef10..8c80fe1451f 100644 --- a/components/esp_netif/private_include/esp_netif_private.h +++ b/components/esp_netif/private_include/esp_netif_private.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -82,7 +82,9 @@ esp_err_t esp_netif_down(esp_netif_t *esp_netif); bool esp_netif_is_valid_static_ip(esp_netif_ip_info_t *ip_info); /** - * @brief Adds created interface to the list of netifs + * @brief Adds created interface to the list of netifs. + * This function doesn't lock the list, so you need to call esp_netif_list_lock/unlock + * manually before and after the call. * * @param[in] esp_netif Handle to esp-netif instance * @@ -90,10 +92,12 @@ bool esp_netif_is_valid_static_ip(esp_netif_ip_info_t *ip_info); * - ESP_OK -- Success * - ESP_ERR_NO_MEM -- Cannot be added due to memory allocation failure */ -esp_err_t esp_netif_add_to_list(esp_netif_t* netif); +esp_err_t esp_netif_add_to_list_unsafe(esp_netif_t* netif); /** * @brief Removes interface to be destroyed from the list of netifs + * This function doesn't lock the list, so you need to call esp_netif_list_lock/unlock + * manually before and after the call. * * @param[in] esp_netif Handle to esp-netif instance * @@ -101,32 +105,7 @@ esp_err_t esp_netif_add_to_list(esp_netif_t* netif); * - ESP_OK -- Success * - ESP_ERR_NOT_FOUND -- This netif was not found in the netif list */ -esp_err_t esp_netif_remove_from_list(esp_netif_t* netif); - -/** - * @brief Iterates over list of interfaces without list locking. Returns first netif if NULL given as parameter - * - * Used for bulk search loops to avoid locking and unlocking every iteration. esp_netif_list_lock and esp_netif_list_unlock - * must be used to guard the search loop - * - * @param[in] esp_netif Handle to esp-netif instance - * - * @return First netif from the list if supplied parameter is NULL, next one otherwise - */ -esp_netif_t* esp_netif_next_unsafe(esp_netif_t* netif); - -/** - * @brief Locking network interface list. Use only in connection with esp_netif_next_unsafe - * - * @return ESP_OK on success, specific mutex error if failed to lock - */ -esp_err_t esp_netif_list_lock(void); - -/** - * @brief Unlocking network interface list. Use only in connection with esp_netif_next_unsafe - * - */ -void esp_netif_list_unlock(void); +esp_err_t esp_netif_remove_from_list_unsafe(esp_netif_t* netif); /** * @brief Iterates over list of registered interfaces to check if supplied netif is listed @@ -165,4 +144,13 @@ esp_err_t esp_netif_add_ip6_address(esp_netif_t *esp_netif, const ip_event_add_i */ esp_err_t esp_netif_remove_ip6_address(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr); +/** + * @brief Get esp_netif handle based on the if_key + * This doesn't lock the list nor TCPIP context + * + * @param if_key + * @return esp_netif handle if found, NULL otherwise + */ +esp_netif_t *esp_netif_get_handle_from_ifkey_unsafe(const char *if_key); + #endif //_ESP_NETIF_PRIVATE_H_ diff --git a/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c index 18b4ee92e5d..472a8de7adf 100644 --- a/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c +++ b/components/esp_netif/test_apps/test_app_esp_netif/main/esp_netif_test.c @@ -129,6 +129,44 @@ TEST(esp_netif, create_delete_multiple_netifs) } +static bool desc_matches_with(esp_netif_t *netif, void *ctx) +{ + return strcmp(ctx, esp_netif_get_desc(netif)) == 0; +} + +TEST(esp_netif, find_netifs) +{ + // Create some interfaces + const char* if_keys[] = { "if1", "if2", "if3", "if4", "if5"}; + const int nr_of_netifs = sizeof(if_keys)/sizeof(char*); + esp_netif_t *netifs[nr_of_netifs]; + + for (int i=0; i0 : Successfully found an interface with Global/Unique local IPv6 address. - * -1 : Unable to to find a valid interface with Global/Unique local IPv6 address. + * ESP_OK : Successfully found an interface with Global/Unique local IPv6 address. + * ESP_FAIL : Unable to to find a valid interface with Global/Unique local IPv6 address. */ -bool get_src_iface(char *interface, char *src_addr_str) +static esp_err_t get_src_iface(void* ctx) { + src_iface_api_t *api = ctx; esp_netif_t *netif = NULL; int ip6_addrs_count = 0; esp_ip6_addr_t ip6[LWIP_IPV6_NUM_ADDRESSES]; - esp_err_t ret = ESP_FAIL; // Get interface details and own global ipv6 address - for (int i = 0; i < esp_netif_get_nr_of_ifs(); ++i) { - netif = esp_netif_next(netif); - ret = esp_netif_get_netif_impl_name(netif, interface); + while ((netif = esp_netif_next_unsafe(netif)) != NULL) { + esp_err_t ret = esp_netif_get_netif_impl_name(netif, api->interface); if ((ESP_FAIL == ret) || (NULL == netif)) { ESP_LOGE(TAG, "No interface available"); - return false; + return ESP_FAIL; } - ESP_LOGI(TAG, "Interface: %s", interface); + ESP_LOGI(TAG, "Interface: %s", api->interface); ip6_addrs_count = esp_netif_get_all_ip6(netif, ip6); for (int j = 0; j < ip6_addrs_count; ++j) { @@ -252,13 +259,13 @@ bool get_src_iface(char *interface, char *src_addr_str) if ((ESP_IP6_ADDR_IS_GLOBAL == ipv6_type) || (ESP_IP6_ADDR_IS_UNIQUE_LOCAL == ipv6_type)) { // Break as we have the source address - sprintf(src_addr_str, IPV6STR, IPV62STR(ip6[j])); - return true; + sprintf(api->src_addr_str, IPV6STR, IPV62STR(ip6[j])); + return ESP_OK; } } } - return false; + return ESP_FAIL; } @@ -268,7 +275,8 @@ static void ping6_test_task(void *pvParameters) char interface[10]; char dst_addr_str[] = CONFIG_EXAMPLE_DST_IPV6_ADDR; - if (true == get_src_iface(interface, src_addr_str)) { + src_iface_api_t api = { .interface = interface, .src_addr_str = src_addr_str }; + if (esp_netif_tcpip_exec(get_src_iface, &api) == ESP_OK) { ESP_LOGI(TAG, "Source address: %s", src_addr_str); ESP_LOGI(TAG, "Destination address: %s", dst_addr_str); ESP_LOGI(TAG, "Interface name: %s", interface); diff --git a/examples/protocols/sockets/tcp_client/main/tcp_client_v6.c b/examples/protocols/sockets/tcp_client/main/tcp_client_v6.c index 73acd117e23..231eb886892 100644 --- a/examples/protocols/sockets/tcp_client/main/tcp_client_v6.c +++ b/examples/protocols/sockets/tcp_client/main/tcp_client_v6.c @@ -84,78 +84,48 @@ static int get_src_iface(char *interface) } #else -static esp_netif_t *get_esp_netif_from_iface(char *interface_i) -{ - esp_netif_t *netif = NULL; - esp_err_t ret = ESP_FAIL; - char iface[10]; - - // Get interface details and own global ipv6 address - for (int i = 0; i < esp_netif_get_nr_of_ifs(); ++i) { - netif = esp_netif_next(netif); - ret = esp_netif_get_netif_impl_name(netif, iface); - if ((ESP_FAIL == ret) || (NULL == netif)) { - ESP_LOGE(TAG, "No interface available"); - return NULL; - } - - if (0 == strcmp(interface_i, iface)) { - return netif; - } - } - - return NULL; -} - - /** * @brief In case of Auto mode returns the interface name with a valid IPv6 address or * In case the user has specified interface, validates and returns the interface name. * - * @param[out] interface Name of the interface in as a string. + * This function is a predicate for esp_netif_find_if() API, and it uses the underlying + * network interface name as a context parameter * - * @return 0 incase of success. + * @return true if we found the appropriate interface, false if not */ -static int get_src_iface(char *interface) +static bool choose_netif(esp_netif_t *netif, void* ctx) { - esp_netif_t *netif = NULL; - esp_err_t ret = ESP_FAIL; - int ip6_addrs_count = 0; + char *interface = ctx; esp_ip6_addr_t ip6[LWIP_IPV6_NUM_ADDRESSES]; - // Get interface details and own global ipv6 address - for (int i = 0; i < esp_netif_get_nr_of_ifs(); ++i) { - netif = esp_netif_next(netif); - ret = esp_netif_get_netif_impl_name(netif, interface); - - if ((ESP_FAIL == ret) || (NULL == netif)) { - ESP_LOGE(TAG, "No interface available"); - return -1; - } + esp_err_t ret = esp_netif_get_netif_impl_name(netif, interface); + if ((ESP_FAIL == ret) || (NULL == netif)) { + ESP_LOGE(TAG, "No interface available"); + return false; + } #if defined(CONFIG_EXAMPLE_USER_SPECIFIED_IFACE) - if (!strcmp(CONFIG_EXAMPLE_USER_SPECIFIED_IFACE_NAME, interface)) { + if (!strcmp(CONFIG_EXAMPLE_USER_SPECIFIED_IFACE_NAME, interface)) { ESP_LOGI(TAG, "Interface: %s", interface); - return 0; + return true; } #else - ip6_addrs_count = esp_netif_get_all_ip6(netif, ip6); - for (int j = 0; j < ip6_addrs_count; ++j) { - esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&(ip6[j])); - - if ((ESP_IP6_ADDR_IS_GLOBAL == ipv6_type) || - (ESP_IP6_ADDR_IS_UNIQUE_LOCAL == ipv6_type) || - (ESP_IP6_ADDR_IS_LINK_LOCAL == ipv6_type)) { - // Break as we have the source address - ESP_LOGI(TAG, "Interface: %s", interface); - return 0; - } + int ip6_addrs_count = esp_netif_get_all_ip6(netif, ip6); + for (int j = 0; j < ip6_addrs_count; ++j) { + esp_ip6_addr_type_t ipv6_type = esp_netif_ip6_get_addr_type(&(ip6[j])); + + if ((ESP_IP6_ADDR_IS_GLOBAL == ipv6_type) || + (ESP_IP6_ADDR_IS_UNIQUE_LOCAL == ipv6_type) || + (ESP_IP6_ADDR_IS_LINK_LOCAL == ipv6_type)) { + // Break as we have the source address + ESP_LOGI(TAG, "Interface: %s", interface); + return true; } -#endif // #if defined(CONFIG_EXAMPLE_USER_SPECIFIED_IFACE) } - - return -1; +#endif // #if defined(CONFIG_EXAMPLE_USER_SPECIFIED_IFACE) + return false; } + #endif // #if defined(CONFIG_IDF_TARGET_LINUX) @@ -191,12 +161,11 @@ void tcp_client(void) } ESP_LOGI(TAG, "Socket created, connecting to %s:%d", host_ip, PORT); +#if defined(CONFIG_IDF_TARGET_LINUX) if (0 != get_src_iface(interface)) { ESP_LOGE(TAG, "Interface: Unavailable\n"); break; } - -#if defined(CONFIG_IDF_TARGET_LINUX) memset (&ifr, 0, sizeof(ifr)); snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", interface); if (ioctl (sock, SIOCGIFINDEX, &ifr) < 0) { @@ -208,7 +177,7 @@ void tcp_client(void) ESP_LOGI(TAG, "Interface index: %d\n", dest_addr.sin6_scope_id); #endif #else - if (NULL == (netif = get_esp_netif_from_iface(interface))) { + if (NULL == (netif = esp_netif_find_if(choose_netif, interface))) { ESP_LOGE(TAG, "Failed to find interface "); break; }