diff --git a/components/esp_netif/esp_netif_objects.c b/components/esp_netif/esp_netif_objects.c index fbfa45b324..ea831a2c83 100644 --- a/components/esp_netif/esp_netif_objects.c +++ b/components/esp_netif/esp_netif_objects.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -71,13 +71,6 @@ 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) -{ - return esp_netif_next_unsafe(netif); -} - esp_netif_t* esp_netif_next_unsafe(esp_netif_t* netif) { ESP_LOGV(TAG, "%s %p", __func__, netif); diff --git a/components/esp_netif/include/esp_netif.h b/components/esp_netif/include/esp_netif.h index 59b47f9e76..6430881f56 100644 --- a/components/esp_netif/include/esp_netif.h +++ b/components/esp_netif/include/esp_netif.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -981,25 +981,6 @@ int esp_netif_set_route_prio(esp_netif_t *esp_netif, int route_prio); int32_t esp_netif_get_event_id(esp_netif_t *esp_netif, esp_netif_ip_event_type_t event_type); -/** - * @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() - * - * @note This API is deprecated. Please 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) -__attribute__((deprecated("use esp_netif_next_unsafe() either directly or via esp_netif_tcpip_exec"))); - /** * @brief Iterates over list of interfaces without list locking. Returns first netif if NULL given as parameter * diff --git a/docs/en/migration-guides/release-6.x/6.0/networking.rst b/docs/en/migration-guides/release-6.x/6.0/networking.rst index 4aab6c6d4e..c69a73e483 100644 --- a/docs/en/migration-guides/release-6.x/6.0/networking.rst +++ b/docs/en/migration-guides/release-6.x/6.0/networking.rst @@ -42,3 +42,69 @@ Removed the following RMII clock Kconfig options from `components/esp_eth`. Cloc **Impact**: Applications using ``ETH_ESP32_EMAC_DEFAULT_CONFIG()`` continue to work. Custom clock configurations must be set explicitly in the EMAC config structure or use the `Ethernet Init component `_. + +ESP-NETIF +********* + +Removal of deprecated :cpp:func:`esp_netif_next` +------------------------------------------------ + +The deprecated iteration helper :cpp:func:`esp_netif_next` has been removed from :doc:`/api-reference/network/esp_netif`. This API was inherently unsafe because it did not lock the interface list or the TCP/IP context during iteration. + +Use one of the following alternatives: + +- Directly call :cpp:func:`esp_netif_next_unsafe` only in contexts you fully control, or inside :cpp:func:`esp_netif_tcpip_exec` for safe execution within the TCP/IP context. +- Use :cpp:func:`esp_netif_find_if` with a predicate to search for specific interfaces without manual iteration. + +Migration +~~~~~~~~~ + +Before: + +.. code-block:: c + + esp_netif_t *it = NULL; + while ((it = esp_netif_next(it)) != NULL) { + // use "it" + } + +After (iterate unsafely in a controlled context): + +.. code-block:: c + + esp_netif_t *it = NULL; + while ((it = esp_netif_next_unsafe(it)) != NULL) { + // use "it" + } + +Recommended (iterate within TCP/IP context): + +.. code-block:: c + + static esp_err_t iterate_netifs(void *ctx) + { + esp_netif_t *it = NULL; + while ((it = esp_netif_next_unsafe(it)) != NULL) { + // use "it" + } + return ESP_OK; + } + + // Execute iteration safely in TCP/IP context + ESP_ERROR_CHECK(esp_netif_tcpip_exec(iterate_netifs, NULL)); + +Alternative (find with predicate): + +.. code-block:: c + + static bool match_by_key(void *ctx, esp_netif_t *netif) + { + const char *wanted = (const char *)ctx; + const char *key = esp_netif_get_ifkey(netif); + return key && strcmp(key, wanted) == 0; + } + + esp_netif_t *target = esp_netif_find_if(match_by_key, (void *)"WIFI_STA_DEF"); + if (target) { + // use "target" + } diff --git a/docs/zh_CN/migration-guides/release-6.x/6.0/networking.rst b/docs/zh_CN/migration-guides/release-6.x/6.0/networking.rst index ace9bc73e5..9ff614307d 100644 --- a/docs/zh_CN/migration-guides/release-6.x/6.0/networking.rst +++ b/docs/zh_CN/migration-guides/release-6.x/6.0/networking.rst @@ -42,3 +42,69 @@ **影响**:使用 ``ETH_ESP32_EMAC_DEFAULT_CONFIG()`` 的应用程序可继续正常工作。自定义时钟配置需在 EMAC 配置结构体中显式设置,或使用 `Ethernet Init 组件 `_。 + +ESP-NETIF +********* + +移除弃用的 :cpp:func:`esp_netif_next` +------------------------------------- + +已从 :doc:`/api-reference/network/esp_netif` 中移除弃用的迭代辅助函数 :cpp:func:`esp_netif_next`。该 API 在迭代过程中不会对接口列表或 TCP/IP 上下文进行加锁,因而并不安全。 + +请使用以下替代方案: + +- 仅在完全可控的上下文中直接调用 :cpp:func:`esp_netif_next_unsafe`,或在 :cpp:func:`esp_netif_tcpip_exec` 中执行以保证在 TCP/IP 上下文内安全运行。 +- 使用 :cpp:func:`esp_netif_find_if` 并配合谓词查找特定接口,从而避免手动迭代。 + +迁移方式 +~~~~~~~~~ + +之前: + +.. code-block:: c + + esp_netif_t *it = NULL; + while ((it = esp_netif_next(it)) != NULL) { + // 使用 "it" + } + +之后(在可控上下文中进行不加锁迭代): + +.. code-block:: c + + esp_netif_t *it = NULL; + while ((it = esp_netif_next_unsafe(it)) != NULL) { + // 使用 "it" + } + +推荐方式(在 TCP/IP 上下文中迭代): + +.. code-block:: c + + static esp_err_t iterate_netifs(void *ctx) + { + esp_netif_t *it = NULL; + while ((it = esp_netif_next_unsafe(it)) != NULL) { + // 使用 "it" + } + return ESP_OK; + } + + // 在 TCP/IP 上下文中安全执行迭代 + ESP_ERROR_CHECK(esp_netif_tcpip_exec(iterate_netifs, NULL)); + +替代方式(使用谓词查找): + +.. code-block:: c + + static bool match_by_key(void *ctx, esp_netif_t *netif) + { + const char *wanted = (const char *)ctx; + const char *key = esp_netif_get_ifkey(netif); + return key && strcmp(key, wanted) == 0; + } + + esp_netif_t *target = esp_netif_find_if(match_by_key, (void *)"WIFI_STA_DEF"); + if (target) { + // 使用 "target" + }