uIP ND6: added option to automatically fill the neighbor cache assuming autoconfigured IPv6 addresses
This commit is contained in:
parent
30bb899f7c
commit
0d0e065456
@ -173,16 +173,25 @@
|
||||
/* UIP_CONF_ND6_SEND_NS enables standard IPv6 Neighbor Discovery Protocol.
|
||||
We enable it by default when IPv6 is used without RPL.
|
||||
With RPL, the neighbor cache (link-local IPv6 <-> MAC address mapping)
|
||||
is fed whenever receiving DIO and DAO messages. This is always sufficient
|
||||
is fed whenever receiving DIO. This is often sufficient
|
||||
for RPL routing, i.e. to send to the preferred parent or any child.
|
||||
Link-local unicast to other neighbors may, however, not be possible if
|
||||
we never receive any DIO from them. This may happen if the link from the
|
||||
neighbor to us is weak, if DIO transmissions are suppressed (Trickle
|
||||
timer) or if the neighbor chooses not to transmit DIOs because it is
|
||||
a leaf node or for any reason. */
|
||||
a leaf node or for any reason.*/
|
||||
#ifndef UIP_CONF_ND6_SEND_NS
|
||||
#define UIP_CONF_ND6_SEND_NS (NETSTACK_CONF_WITH_IPV6 && !UIP_CONF_IPV6_RPL)
|
||||
#endif /* UIP_CONF_ND6_SEND_NS */
|
||||
/* To speed up the neighbor cache construction,
|
||||
enable UIP_CONF_ND6_AUTOFILL_NBR_CACHE. When a node does not the link-layer
|
||||
address of a neighbor, it will infer it from the link-local IPv6, assuming
|
||||
the node used autoconfiguration. Note that RPL uses its own freshness
|
||||
mechanism to select whether neighbors are sitll usable as a parent
|
||||
or not, regardless of the neighbor cache. */
|
||||
#ifndef UIP_CONF_ND6_AUTOFILL_NBR_CACHE
|
||||
#define UIP_CONF_ND6_AUTOFILL_NBR_CACHE (!UIP_CONF_ND6_SEND_NS)
|
||||
#endif /* UIP_CONF_ND6_AUTOFILL_NBR_CACHE */
|
||||
/* UIP_CONF_ND6_SEND_NA allows to still comply with NDP even if the host does
|
||||
not perform NUD or DAD processes. By default it is activated so the host
|
||||
can still communicate with a full NDP peer. */
|
||||
|
@ -668,6 +668,25 @@ tcpip_ipv6_output(void)
|
||||
annotate_transmission(nexthop);
|
||||
|
||||
nbr = uip_ds6_nbr_lookup(nexthop);
|
||||
|
||||
#if UIP_ND6_AUTOFILL_NBR_CACHE
|
||||
if(nbr == NULL) {
|
||||
/* Neighbor not found in cache? Derive its link-layer address from it's
|
||||
link-local IPv6, assuming it used autoconfiguration. This is not
|
||||
standard-compliant but this is a convenient way to keep the
|
||||
neighbor cache out of the way in cases ND is not used */
|
||||
uip_lladdr_t lladdr;
|
||||
uip_ds6_set_lladdr_from_iid(&lladdr, nexthop);
|
||||
if((nbr = uip_ds6_nbr_add(nexthop, &lladdr,
|
||||
0, NBR_REACHABLE, NBR_TABLE_REASON_IPV6_ND, NULL)) == NULL) {
|
||||
PRINTF("tcpip_ipv6_output: failed to autofill neighbor cache for host ");
|
||||
PRINT6ADDR(nexthop);
|
||||
PRINTF("\n");
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
#endif /* UIP_ND6_AUTOFILL_NBR_CACHE */
|
||||
|
||||
if(nbr == NULL) {
|
||||
if(send_nd6_ns(nexthop)) {
|
||||
PRINTF("tcpip_ipv6_output: failed to add neighbor to cache\n");
|
||||
|
@ -558,6 +558,18 @@ uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_ds6_set_lladdr_from_iid(uip_lladdr_t *lladdr, const uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
#if (UIP_LLADDR_LEN == 8)
|
||||
memcpy(lladdr, ipaddr->u8 + 8, UIP_LLADDR_LEN);
|
||||
lladdr->addr[0] ^= 0x02;
|
||||
#else
|
||||
#error uip-ds6.c cannot build lladdr address when UIP_LLADDR_LEN is not 8
|
||||
#endif
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
get_match_length(uip_ipaddr_t *src, uip_ipaddr_t *dst)
|
||||
|
@ -344,6 +344,9 @@ uip_ds6_aaddr_t *uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr);
|
||||
/** \brief set the last 64 bits of an IP address based on the MAC address */
|
||||
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr);
|
||||
|
||||
/** \brief Build a link-layer address from an IPv6 address based on its UUID64 */
|
||||
void uip_ds6_set_lladdr_from_iid(uip_lladdr_t *lladdr, const uip_ipaddr_t *ipaddr);
|
||||
|
||||
/** \brief Get the number of matching bits of two addresses */
|
||||
uint8_t get_match_length(uip_ipaddr_t *src, uip_ipaddr_t *dst);
|
||||
|
||||
|
@ -96,6 +96,15 @@
|
||||
#else
|
||||
#define UIP_ND6_SEND_NA UIP_CONF_ND6_SEND_NA
|
||||
#endif
|
||||
#ifndef UIP_CONF_ND6_AUTOFILL_NBR_CACHE
|
||||
/* Neighbor not found in cache? Derive its link-layer address from it's
|
||||
link-local IPv6, assuming it used autoconfiguration. This is not
|
||||
standard-compliant but this is a convenient way to keep the
|
||||
neighbor cache out of the way in cases ND is not used */
|
||||
#define UIP_ND6_AUTOFILL_NBR_CACHE 0
|
||||
#else
|
||||
#define UIP_ND6_AUTOFILL_NBR_CACHE UIP_CONF_ND6_AUTOFILL_NBR_CACHE
|
||||
#endif
|
||||
#ifndef UIP_CONF_ND6_MAX_RA_INTERVAL
|
||||
#define UIP_ND6_MAX_RA_INTERVAL 600
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user