Neighbor discovery and stateless address autoconfiguration for IPv6.
Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 (Address autoconfiguration).
#include "lwip/opt.h"
#include "lwip/nd6.h"
#include "lwip/pbuf.h"
#include "lwip/mem.h"
#include "lwip/memp.h"
#include "lwip/ip6.h"
#include "lwip/ip6_addr.h"
#include "lwip/inet_chksum.h"
#include "lwip/netif.h"
#include "lwip/icmp6.h"
#include "lwip/mld6.h"
#include "lwip/ip.h"
#include "lwip/stats.h"
#include <string.h>
Macros | |
#define | ND6_SEND_FLAG_ALLNODES_DEST 0x02 |
#define | ND6_SEND_FLAG_MULTICAST_DEST 0x01 |
Functions | |
static s8_t | nd6_find_destination_cache_entry (ip6_addr_t *ip6addr) |
Search for a destination cache entry. More... | |
static s8_t | nd6_find_neighbor_cache_entry (ip6_addr_t *ip6addr) |
Search for a neighbor cache entry. More... | |
static void | nd6_free_neighbor_cache_entry (s8_t i) |
Will free any resources associated with a neighbor cache entry, and will mark it as unused. More... | |
static void | nd6_free_q (struct nd6_q_entry *q) |
Free a complete queue of nd6 q entries. More... | |
u16_t | nd6_get_destination_mtu (ip6_addr_t *ip6addr, struct netif *netif) |
Get the Path MTU for a destination. More... | |
s8_t | nd6_get_next_hop_entry (ip6_addr_t *ip6addr, struct netif *netif) |
Determine the next hop for a destination. More... | |
static s8_t | nd6_get_onlink_prefix (ip6_addr_t *prefix, struct netif *netif) |
Find the cached entry for an on-link prefix. More... | |
static s8_t | nd6_get_router (ip6_addr_t *router_addr, struct netif *netif) |
Find an entry for a default router. More... | |
void | nd6_input (struct pbuf *p, struct netif *inp) |
Process an incoming neighbor discovery message. More... | |
static s8_t | nd6_is_prefix_in_netif (ip6_addr_t *ip6addr, struct netif *netif) |
Determine whether an address matches an on-link prefix. More... | |
static s8_t | nd6_new_destination_cache_entry (void) |
Create a new destination cache entry. More... | |
static s8_t | nd6_new_neighbor_cache_entry (void) |
Create a new neighbor cache entry. More... | |
static s8_t | nd6_new_onlink_prefix (ip6_addr_t *prefix, struct netif *netif) |
Creates a new entry for an on-link prefix. More... | |
static s8_t | nd6_new_router (ip6_addr_t *router_addr, struct netif *netif) |
Create a new entry for a default router. More... | |
err_t | nd6_queue_packet (s8_t neighbor_index, struct pbuf *q) |
Queue a packet for a neighbor. More... | |
void | nd6_reachability_hint (ip6_addr_t *ip6addr) |
Provide the Neighbor discovery process with a hint that a destination is reachable. More... | |
s8_t | nd6_select_router (ip6_addr_t *ip6addr, struct netif *netif) |
Select a default router for a destination. More... | |
static void | nd6_send_na (struct netif *netif, ip6_addr_t *target_addr, u8_t flags) |
Send a neighbor advertisement message. More... | |
static void | nd6_send_ns (struct netif *netif, ip6_addr_t *target_addr, u8_t flags) |
Send a neighbor solicitation message. More... | |
static void | nd6_send_q (s8_t i) |
Send queued packets for a neighbor. More... | |
static void | nd6_send_rs (struct netif *netif) |
Send a router solicitation message. More... | |
void | nd6_tmr (void) |
Periodic timer for Neighbor discovery functions: More... | |
Variables | |
struct nd6_router_list_entry | default_router_list [LWIP_ND6_NUM_ROUTERS] |
struct nd6_destination_cache_entry | destination_cache [LWIP_ND6_NUM_DESTINATIONS] |
static ip6_addr_t | multicast_address |
static u8_t | nd6_cached_destination_index |
static u8_t | nd6_cached_neighbor_index |
static u8_t | nd6_ra_buffer [sizeof(struct prefix_option)] |
struct nd6_neighbor_cache_entry | neighbor_cache [LWIP_ND6_NUM_NEIGHBORS] |
struct nd6_prefix_list_entry | prefix_list [LWIP_ND6_NUM_PREFIXES] |
u32_t | reachable_time = LWIP_ND6_REACHABLE_TIME |
u32_t | retrans_timer = LWIP_ND6_RETRANS_TIMER |
#define ND6_SEND_FLAG_ALLNODES_DEST 0x02 |
Referenced by nd6_input(), and nd6_send_na().
#define ND6_SEND_FLAG_MULTICAST_DEST 0x01 |
Referenced by nd6_send_na(), nd6_send_ns(), and nd6_tmr().
|
static |
Search for a destination cache entry.
ip6addr | the IPv6 address of the destination |
References destination_cache, and ip6_addr_cmp.
Referenced by nd6_get_destination_mtu(), nd6_get_next_hop_entry(), nd6_input(), and nd6_reachability_hint().
|
static |
Search for a neighbor cache entry.
ip6addr | the IPv6 address of the neighbor |
References ip6_addr_cmp, and neighbor_cache.
Referenced by nd6_get_next_hop_entry(), nd6_input(), nd6_new_router(), and nd6_reachability_hint().
Will free any resources associated with a neighbor cache entry, and will mark it as unused.
i | the neighbor cache entry index to free |
References nd6_neighbor_cache_entry::counter, ip6_addr_set_zero, nd6_neighbor_cache_entry::isrouter, nd6_free_q(), ND6_NO_ENTRY, neighbor_cache, nd6_neighbor_cache_entry::netif, NULL, nd6_neighbor_cache_entry::q, nd6_neighbor_cache_entry::reachable_time, and nd6_neighbor_cache_entry::state.
Referenced by nd6_new_neighbor_cache_entry(), and nd6_tmr().
|
static |
Free a complete queue of nd6 q entries.
q | a queue of nd6_q_entry to free |
References LWIP_ASSERT, memp_free(), nd6_q_entry::next, NULL, nd6_q_entry::p, and pbuf_free().
Referenced by nd6_free_neighbor_cache_entry(), and nd6_queue_packet().
u16_t nd6_get_destination_mtu | ( | ip6_addr_t * | ip6addr, |
struct netif * | netif | ||
) |
Get the Path MTU for a destination.
ip6addr | the destination address |
netif | the netif on which the packet will be sent |
References destination_cache, netif::mtu, nd6_find_destination_cache_entry(), NULL, and nd6_destination_cache_entry::pmtu.
Referenced by ip6_output_if_src(), and tcp_eff_send_mss_impl().
s8_t nd6_get_next_hop_entry | ( | ip6_addr_t * | ip6addr, |
struct netif * | netif | ||
) |
Determine the next hop for a destination.
Will determine if the destination is on-link, else a suitable on-link router is selected.
The last entry index is cached for fast entry search.
ip6addr | the destination address |
netif | the netif on which the packet will be sent |
References nd6_destination_cache_entry::age, nd6_neighbor_cache_entry::counter, default_router_list, destination_cache, ERR_MEM, ERR_RTE, ip6_addr_cmp, ip6_addr_copy, ip6_addr_islinklocal, ip6_addr_set, ip6_addr_set_any, nd6_neighbor_cache_entry::isrouter, netif::mtu, nd6_cached_destination_index, nd6_cached_neighbor_index, nd6_find_destination_cache_entry(), nd6_find_neighbor_cache_entry(), ND6_INCOMPLETE, nd6_is_prefix_in_netif(), nd6_new_destination_cache_entry(), nd6_new_neighbor_cache_entry(), nd6_select_router(), ND6_STATS_INC, neighbor_cache, nd6_neighbor_cache_entry::netif, NULL, nd6_destination_cache_entry::pmtu, nd6_neighbor_cache_entry::probes_sent, and nd6_neighbor_cache_entry::state.
Referenced by ethip6_output().
|
static |
Find the cached entry for an on-link prefix.
prefix | the IPv6 prefix that is on-link |
netif | the netif on which the prefix is on-link |
References ip6_addr_netcmp, and prefix_list.
Referenced by nd6_input().
|
static |
Find an entry for a default router.
router_addr | the IPv6 address of the router |
netif | the netif on which the router is found, if known |
References default_router_list, ip6_addr_cmp, and NULL.
Referenced by nd6_input().
Process an incoming neighbor discovery message.
p | the nd packet, p->payload pointing to the icmpv6 header |
inp | the netif on which this packet was received |
References buffer, nd6_neighbor_cache_entry::counter, default_router_list, nd6_neighbor_cache_entry::delay_time, destination_cache, nd6_prefix_list_entry::flags, nd6_router_list_entry::flags, netif::hwaddr_len, ICMP6_TYPE_NA, ICMP6_TYPE_NS, ICMP6_TYPE_PTB, ICMP6_TYPE_RA, ICMP6_TYPE_RD, if(), nd6_prefix_list_entry::invalidation_timer, nd6_router_list_entry::invalidation_timer, ip6_addr_cmp, IP6_ADDR_INVALID, ip6_addr_isany, ip6_addr_islinklocal, ip6_addr_ismulticast, ip6_addr_istentative, ip6_addr_isvalid, ip6_addr_set, ip6_addr_set_solicitednode, ip6_current_dest_addr, ip6_current_src_addr, IP6_HLEN, pbuf::len, mld6_leavegroup(), netif::mtu, multicast_address, ND6_DELAY, nd6_find_destination_cache_entry(), nd6_find_neighbor_cache_entry(), ND6_FLAG_OVERRIDE, ND6_FLAG_SOLICITED, nd6_get_onlink_prefix(), nd6_get_router(), ND6_INCOMPLETE, nd6_new_neighbor_cache_entry(), nd6_new_onlink_prefix(), nd6_new_router(), ND6_OPTION_TYPE_MTU, ND6_OPTION_TYPE_PREFIX_INFO, ND6_OPTION_TYPE_ROUTE_INFO, ND6_OPTION_TYPE_SOURCE_LLADDR, ND6_OPTION_TYPE_TARGET_LLADDR, ND6_PREFIX_AUTOCONFIG_ADDRESS_DUPLICATE, ND6_PREFIX_AUTOCONFIG_AUTONOMOUS, ND6_PREFIX_FLAG_AUTONOMOUS, ND6_PREFIX_FLAG_ON_LINK, nd6_ra_buffer, ND6_REACHABLE, ND6_SEND_FLAG_ALLNODES_DEST, nd6_send_na(), nd6_send_q(), ND6_STATS_INC, neighbor_cache, nd6_router_list_entry::neighbor_entry, nd6_neighbor_cache_entry::netif, netif_ip6_addr, netif_ip6_addr_set_state, netif_ip6_addr_state, NULL, pbuf::payload, pbuf_copy_partial(), pbuf_free(), nd6_destination_cache_entry::pmtu, prefix_list, reachable_time, nd6_neighbor_cache_entry::reachable_time, retrans_timer, netif::rs_count, nd6_neighbor_cache_entry::state, and pbuf::tot_len.
Referenced by icmp6_input().
|
static |
Determine whether an address matches an on-link prefix.
ip6addr | the IPv6 address to match |
References ip6_addr_isvalid, ip6_addr_netcmp, netif_ip6_addr, netif_ip6_addr_state, and prefix_list.
Referenced by nd6_get_next_hop_entry().
Create a new destination cache entry.
If no unused entry is found, will recycle oldest entry.
References destination_cache, and ip6_addr_isany.
Referenced by nd6_get_next_hop_entry().
Create a new neighbor cache entry.
If no unused entry is found, will try to recycle an old entry according to ad-hoc "age" heuristic.
References nd6_neighbor_cache_entry::counter, ND6_DELAY, nd6_free_neighbor_cache_entry(), ND6_INCOMPLETE, ND6_NO_ENTRY, ND6_PROBE, ND6_REACHABLE, ND6_STALE, neighbor_cache, NULL, nd6_neighbor_cache_entry::probes_sent, nd6_neighbor_cache_entry::reachable_time, and time.
Referenced by nd6_get_next_hop_entry(), nd6_input(), and nd6_new_router().
|
static |
Creates a new entry for an on-link prefix.
prefix | the IPv6 prefix that is on-link |
netif | the netif on which the prefix is on-link |
References nd6_prefix_list_entry::flags, ip6_addr_set, nd6_prefix_list_entry::netif, NULL, and prefix_list.
Referenced by nd6_input().
|
static |
Create a new entry for a default router.
router_addr | the IPv6 address of the router |
netif | the netif on which the router is connected, if known |
References nd6_neighbor_cache_entry::counter, default_router_list, ip6_addr_set, nd6_neighbor_cache_entry::isrouter, nd6_find_neighbor_cache_entry(), ND6_INCOMPLETE, nd6_new_neighbor_cache_entry(), neighbor_cache, nd6_router_list_entry::neighbor_entry, nd6_neighbor_cache_entry::netif, NULL, nd6_neighbor_cache_entry::probes_sent, nd6_neighbor_cache_entry::q, and nd6_neighbor_cache_entry::state.
Referenced by nd6_input().
Queue a packet for a neighbor.
neighbor_index | the index in the neighbor cache table |
q | packet to be queued |
References ERR_ARG, ERR_MEM, ERR_OK, LWIP_DBG_TRACE, LWIP_DEBUGF, memp_malloc(), nd6_free_q(), neighbor_cache, pbuf::next, nd6_q_entry::next, NULL, nd6_q_entry::p, pbuf_alloc(), pbuf_copy(), pbuf_free(), PBUF_LINK, PBUF_RAM, pbuf_ref(), PBUF_ROM, nd6_neighbor_cache_entry::q, S16_F, pbuf::tot_len, and pbuf::type.
Referenced by ethip6_output().
void nd6_reachability_hint | ( | ip6_addr_t * | ip6addr | ) |
Provide the Neighbor discovery process with a hint that a destination is reachable.
Called by tcp_receive when ACKs are received or sent (as per RFC). This is useful to avoid sending NS messages every 30 seconds.
ip6addr | the destination address which is know to be reachable by an upper layer protocol (TCP) |
References nd6_neighbor_cache_entry::counter, destination_cache, ip6_addr_cmp, nd6_cached_destination_index, nd6_cached_neighbor_index, nd6_find_destination_cache_entry(), nd6_find_neighbor_cache_entry(), ND6_REACHABLE, ND6_STATS_INC, neighbor_cache, reachable_time, nd6_neighbor_cache_entry::reachable_time, and nd6_neighbor_cache_entry::state.
Referenced by tcp_receive().
s8_t nd6_select_router | ( | ip6_addr_t * | ip6addr, |
struct netif * | netif | ||
) |
Select a default router for a destination.
ip6addr | the destination address |
netif | the netif for the outgoing packet, if known |
References default_router_list, ND6_REACHABLE, nd6_router_list_entry::neighbor_entry, nd6_neighbor_cache_entry::netif, NULL, nd6_neighbor_cache_entry::state, and void.
Referenced by ip6_route(), and nd6_get_next_hop_entry().
|
static |
Send a neighbor advertisement message.
netif | the netif on which to send the message |
target_addr | the IPv6 target address for the ND message |
flags | one of ND6_SEND_FLAG_* |
References netif::hwaddr, netif::hwaddr_len, ICMP6_TYPE_NA, ip6_addr_set, ip6_addr_set_allnodes_linklocal, ip6_addr_set_solicitednode, ip6_chksum_pseudo(), ip6_current_src_addr, IP6_NEXTH_ICMP6, ip6_output_if(), pbuf::len, multicast_address, ND6_OPTION_TYPE_TARGET_LLADDR, ND6_SEND_FLAG_ALLNODES_DEST, ND6_SEND_FLAG_MULTICAST_DEST, ND6_STATS_INC, NULL, pbuf::payload, pbuf_alloc(), pbuf_free(), PBUF_IP, and PBUF_RAM.
Referenced by nd6_input().
|
static |
Send a neighbor solicitation message.
netif | the netif on which to send the message |
target_addr | the IPv6 target address for the ND message |
flags | one of ND6_SEND_FLAG_* |
References netif::hwaddr, netif::hwaddr_len, ICMP6_TYPE_NS, IP6_ADDR_ANY, ip6_addr_isvalid, ip6_addr_set, ip6_addr_set_solicitednode, ip6_chksum_pseudo(), IP6_NEXTH_ICMP6, ip6_output_if(), pbuf::len, multicast_address, ND6_OPTION_TYPE_SOURCE_LLADDR, ND6_SEND_FLAG_MULTICAST_DEST, ND6_STATS_INC, netif_ip6_addr, netif_ip6_addr_state, NULL, pbuf::payload, pbuf_alloc(), pbuf_free(), PBUF_IP, and PBUF_RAM.
Referenced by nd6_tmr().
Send queued packets for a neighbor.
i | the neighbor to send packets to |
References ip6_addr_set, ip6_current_dest_addr, memp_free(), neighbor_cache, nd6_neighbor_cache_entry::netif, nd6_q_entry::next, NULL, nd6_q_entry::p, pbuf::payload, pbuf_free(), and nd6_neighbor_cache_entry::q.
Referenced by nd6_input(), and nd6_tmr().
Send a router solicitation message.
netif | the netif on which to send the message |
References netif::hwaddr, netif::hwaddr_len, ICMP6_TYPE_RS, if(), IP6_ADDR_ANY, ip6_addr_isvalid, ip6_addr_set_allrouters_linklocal, ip6_chksum_pseudo(), IP6_NEXTH_ICMP6, ip6_output_if(), pbuf::len, multicast_address, ND6_OPTION_TYPE_SOURCE_LLADDR, ND6_STATS_INC, netif_ip6_addr, netif_ip6_addr_state, NULL, pbuf::payload, pbuf_alloc(), pbuf_free(), PBUF_IP, and PBUF_RAM.
Referenced by nd6_tmr().
Periodic timer for Neighbor discovery functions:
References nd6_destination_cache_entry::age, nd6_neighbor_cache_entry::counter, default_router_list, nd6_neighbor_cache_entry::delay_time, destination_cache, nd6_prefix_list_entry::flags, nd6_router_list_entry::flags, netif::flags, nd6_prefix_list_entry::invalidation_timer, nd6_router_list_entry::invalidation_timer, netif::ip6_addr, IP6_ADDR_INVALID, ip6_addr_istentative, IP6_ADDR_PREFERRED, ip6_addr_set_solicitednode, netif::ip6_addr_state, IP6_ADDR_TENTATIVE, netif::ip6_autoconfig_enabled, nd6_neighbor_cache_entry::isrouter, mld6_joingroup(), multicast_address, ND6_DELAY, nd6_free_neighbor_cache_entry(), ND6_INCOMPLETE, ND6_NO_ENTRY, ND6_PREFIX_AUTOCONFIG_ADDRESS_GENERATED, ND6_PREFIX_AUTOCONFIG_AUTONOMOUS, ND6_PROBE, ND6_REACHABLE, ND6_SEND_FLAG_MULTICAST_DEST, nd6_send_ns(), nd6_send_q(), nd6_send_rs(), ND6_STALE, ND6_TMR_INTERVAL, neighbor_cache, nd6_router_list_entry::neighbor_entry, nd6_prefix_list_entry::netif, NETIF_FLAG_UP, netif_ip6_addr, netif_ip6_addr_set_state, netif_ip6_addr_state, netif_list, netif::next, NULL, nd6_prefix_list_entry::prefix, prefix_list, nd6_neighbor_cache_entry::probes_sent, nd6_neighbor_cache_entry::reachable_time, netif::rs_count, nd6_neighbor_cache_entry::stale_time, nd6_neighbor_cache_entry::state, and netif::state.
Referenced by nd6_timer().
struct nd6_router_list_entry default_router_list[LWIP_ND6_NUM_ROUTERS] |
Referenced by ip6_route(), nd6_get_next_hop_entry(), nd6_get_router(), nd6_input(), nd6_new_router(), nd6_select_router(), and nd6_tmr().
struct nd6_destination_cache_entry destination_cache[LWIP_ND6_NUM_DESTINATIONS] |
|
static |
Referenced by nd6_input(), nd6_send_na(), nd6_send_ns(), nd6_send_rs(), and nd6_tmr().
|
static |
Referenced by nd6_get_next_hop_entry(), and nd6_reachability_hint().
|
static |
Referenced by nd6_get_next_hop_entry(), and nd6_reachability_hint().
|
static |
Referenced by nd6_input().
struct nd6_neighbor_cache_entry neighbor_cache[LWIP_ND6_NUM_NEIGHBORS] |
struct nd6_prefix_list_entry prefix_list[LWIP_ND6_NUM_PREFIXES] |
Referenced by nd6_get_onlink_prefix(), nd6_input(), nd6_is_prefix_in_netif(), nd6_new_onlink_prefix(), and nd6_tmr().
u32_t reachable_time = LWIP_ND6_REACHABLE_TIME |
Referenced by nd6_input(), and nd6_reachability_hint().
u32_t retrans_timer = LWIP_ND6_RETRANS_TIMER |
Referenced by nd6_input().