From d7fcba02804993aa8af0e67e242f2721ccd7c022 Mon Sep 17 00:00:00 2001 From: zwx Date: Wed, 23 Jul 2025 17:51:31 +0800 Subject: [PATCH 1/2] fix(openthread): fix the preference of the ip6 address set to lwip --- .../openthread/src/esp_openthread_netif_glue.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/components/openthread/src/esp_openthread_netif_glue.c b/components/openthread/src/esp_openthread_netif_glue.c index dd623aa5f7..ff37ce1fb3 100644 --- a/components/openthread/src/esp_openthread_netif_glue.c +++ b/components/openthread/src/esp_openthread_netif_glue.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -106,9 +106,13 @@ static void process_thread_address(const otIp6AddressInfo *address_info, bool is } else { ip_event_add_ip6_t add_addr; add_addr.addr = addr; - // if an address is not mesh local or link local, we set preferred for this address. - add_addr.preferred = - is_mesh_local_addr(address_info->mAddress) || is_link_local_addr(address_info->mAddress) ? 0 : 1; + // Only mark the address as preferred if + // it is marked preferred by OpenThread and it is neither a mesh-local nor a link-local address. + if (address_info->mPreferred == 0 || is_mesh_local_addr(address_info->mAddress) || is_link_local_addr(address_info->mAddress)) { + add_addr.preferred = 0; + } else { + add_addr.preferred = 1; + } if (esp_event_post(OPENTHREAD_EVENT, OPENTHREAD_EVENT_GOT_IP6, &add_addr, sizeof(add_addr), 0) != ESP_OK) { ESP_LOGE(OT_PLAT_LOG_TAG, "Failed to post OpenThread got ip6 address event"); } From 9215751334c20d3296bf565e99b08049980c6273 Mon Sep 17 00:00:00 2001 From: zwx Date: Wed, 23 Jul 2025 17:52:30 +0800 Subject: [PATCH 2/2] fix(openthread): use OpenThread API in lwIP source address selection hook --- .../src/esp_openthread_lwip_netif.c | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/components/openthread/src/esp_openthread_lwip_netif.c b/components/openthread/src/esp_openthread_lwip_netif.c index 94c8e16861..f8969cb01f 100644 --- a/components/openthread/src/esp_openthread_lwip_netif.c +++ b/components/openthread/src/esp_openthread_lwip_netif.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -153,21 +153,29 @@ static err_t openthread_netif_init(struct netif *netif) const ip_addr_t *lwip_hook_ip6_select_source_address(struct netif *netif, const ip6_addr_t *dest) { - const ip6_addr_t *cur_addr; + ip6_addr_t cand_addr = { 0 }; uint8_t idx = 0; + otError err = OT_ERROR_NONE; // Only process with ot netif. if (!(netif->name[0] == 'o' && netif->name[1] == 't')) { return NULL; } - // Currently, prefer the address with the same prefix of the destination address. - // If no address found, return NULL for selection source address using the default algorithm. - for (idx = 0; idx < LWIP_IPV6_NUM_ADDRESSES; idx++) { - if (!ip6_addr_isvalid(netif_ip6_addr_state(netif, idx))) { - continue; - } - cur_addr = netif_ip6_addr(netif, idx); - if (ip6_addr_netcmp_zoneless(cur_addr, dest)) { - return netif_ip_addr6(netif, idx); + otMessageInfo message_info = { 0 }; + memcpy(message_info.mPeerAddr.mFields.m32, dest->addr, sizeof(message_info.mPeerAddr.mFields.m32)); + otInstance *instance = esp_openthread_get_instance(); + esp_openthread_task_switching_lock_acquire(portMAX_DELAY); + err = otIp6SelectSourceAddress(instance, &message_info); + esp_openthread_task_switching_lock_release(); + if (err == OT_ERROR_NONE) { + // If a Src address was selected by the OT stack, use this address. + memcpy(cand_addr.addr, message_info.mSockAddr.mFields.m32, sizeof(cand_addr.addr)); + for (idx = 0; idx < LWIP_IPV6_NUM_ADDRESSES; idx++) { + if (!ip6_addr_isvalid(netif_ip6_addr_state(netif, idx))) { + continue; + } + if (ip6_addr_zoneless_eq(netif_ip6_addr(netif, idx), &cand_addr)) { + return netif_ip_addr6(netif, idx); + } } } return NULL;