Merge branch 'feat/nd6_static_neighbor_entries' into 'master'

feat(lwip): Add IPv6 static neighbor cache entry support

See merge request espressif/esp-idf!49961
This commit is contained in:
Jiang Jiang Jian
2026-06-30 23:34:17 +08:00
5 changed files with 110 additions and 1 deletions
+37
View File
@@ -862,6 +862,43 @@ int esp_netif_get_all_ip6(esp_netif_t *esp_netif, esp_ip6_addr_t if_ip6[]);
*/
int esp_netif_get_all_preferred_ip6(esp_netif_t *esp_netif, esp_ip6_addr_t if_ip6[]);
#if CONFIG_LWIP_ND6_SUPPORT_STATIC_ENTRIES
/**
* @brief Add or update a static (permanent) IPv6 neighbor cache entry
*
* Installs a fixed IPv6 -> link-layer address mapping that bypasses Neighbor
* Discovery: no Neighbor Solicitation/Advertisement is exchanged for this
* address, the entry never ages out and is never overwritten by incoming
* advertisements. Calling again with the same address updates the mapping.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] addr Neighbor's IPv6 address
* @param[in] mac Neighbor's link-layer address (interface hwaddr_len bytes)
*
* @return
* - ESP_OK on success
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS on invalid arguments
* - ESP_FAIL if the entry could not be installed (e.g. neighbor cache full)
*/
esp_err_t esp_netif_add_static_neighbor(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr, const uint8_t *mac);
/**
* @brief Remove a static IPv6 neighbor cache entry
*
* Removes an entry previously added with esp_netif_add_static_neighbor().
* Dynamic (non-static) entries are left untouched.
*
* @param[in] esp_netif Handle to esp-netif instance
* @param[in] addr Neighbor's IPv6 address
*
* @return
* - ESP_OK on success
* - ESP_ERR_ESP_NETIF_INVALID_PARAMS on invalid arguments
* - ESP_FAIL if no matching static entry exists
*/
esp_err_t esp_netif_remove_static_neighbor(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr);
#endif /* CONFIG_LWIP_ND6_SUPPORT_STATIC_ENTRIES */
/**
* @brief Cause the TCP/IP stack to add an IPv6 address to the interface
*
@@ -2483,6 +2483,56 @@ int esp_netif_get_all_preferred_ip6(esp_netif_t *esp_netif, esp_ip6_addr_t if_ip
}
return addr_count;
}
#if CONFIG_LWIP_ND6_SUPPORT_STATIC_ENTRIES
typedef struct {
const esp_ip6_addr_t *addr;
const uint8_t *mac;
} esp_netif_static_neighbor_t;
static esp_err_t esp_netif_add_static_neighbor_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
const esp_netif_static_neighbor_t *nbr = msg->data;
ip6_addr_t ip6;
memcpy(&ip6, nbr->addr, sizeof(ip6_addr_t));
if (nd6_add_static_neighbor(esp_netif->lwip_netif, &ip6, nbr->mac) != ERR_OK) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_netif_add_static_neighbor(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr, const uint8_t *mac)
{
if (esp_netif == NULL || esp_netif->lwip_netif == NULL || addr == NULL || mac == NULL) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}
esp_netif_static_neighbor_t nbr = { .addr = addr, .mac = mac };
return esp_netif_lwip_ipc_call(esp_netif_add_static_neighbor_api, esp_netif, &nbr);
}
static esp_err_t esp_netif_remove_static_neighbor_api(esp_netif_api_msg_t *msg)
{
esp_netif_t *esp_netif = msg->esp_netif;
const esp_ip6_addr_t *addr = msg->data;
ip6_addr_t ip6;
memcpy(&ip6, addr, sizeof(ip6_addr_t));
if (nd6_remove_static_neighbor(esp_netif->lwip_netif, &ip6) != ERR_OK) {
return ESP_FAIL;
}
return ESP_OK;
}
esp_err_t esp_netif_remove_static_neighbor(esp_netif_t *esp_netif, const esp_ip6_addr_t *addr)
{
if (esp_netif == NULL || esp_netif->lwip_netif == NULL || addr == NULL) {
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
}
return esp_netif_lwip_ipc_call(esp_netif_remove_static_neighbor_api, esp_netif, (void *)addr);
}
#endif /* CONFIG_LWIP_ND6_SUPPORT_STATIC_ENTRIES */
#endif
esp_netif_flags_t esp_netif_get_flags(esp_netif_t *esp_netif)
+9
View File
@@ -116,6 +116,15 @@ menu "LWIP"
This option is used to disable the Network Discovery Protocol (NDP) if it is not required.
Please use this option with caution, as the NDP is essential for IPv6 functionality within a local network.
config LWIP_ND6_SUPPORT_STATIC_ENTRIES
bool "Enable API for static IPv6 neighbor cache entries"
default n
depends on LWIP_ND6
help
Enable APIs to add/remove permanent IPv6->MAC neighbor cache entries
that bypass Neighbor Discovery (no NS/NA). IPv6 counterpart of
ETHARP_SUPPORT_STATIC_ENTRIES.
config LWIP_FORCE_ROUTER_FORWARDING
bool "LWIP Force Router Forwarding Enable/Disable"
default n
+13
View File
@@ -1242,6 +1242,19 @@ static inline uint32_t timeout_from_offered(uint32_t lease, uint32_t min)
#define LWIP_ND6 0
#endif
/**
* LWIP_ND6_SUPPORT_STATIC_ENTRIES==1: enable nd6_add_static_neighbor() and
* nd6_remove_static_neighbor() to manage permanent IPv6->MAC neighbor cache
* entries that bypass Neighbor Discovery (no NS/NA). Applied per-(netif,address)
* and does not affect NDP on other interfaces. IPv6 counterpart of
* ETHARP_SUPPORT_STATIC_ENTRIES.
*/
#ifdef CONFIG_LWIP_ND6_SUPPORT_STATIC_ENTRIES
#define LWIP_ND6_SUPPORT_STATIC_ENTRIES 1
#else
#define LWIP_ND6_SUPPORT_STATIC_ENTRIES 0
#endif
/**
* LWIP_FORCE_ROUTER_FORWARDING==1: the router flag in NA packet will always set to 1,
* otherwise, never set router flag for NA packets.