Merge pull request #33 from simonduq/pr/nd6-autofill

ND6 autofill
This commit is contained in:
Simon Duquennoy 2017-06-21 17:09:13 +02:00 committed by GitHub
commit c65d060669
6 changed files with 60 additions and 3 deletions

View File

@ -170,10 +170,10 @@
#define UIP_CONF_ND6_SEND_RA (NETSTACK_CONF_WITH_IPV6 && !UIP_CONF_IPV6_RPL)
#endif /* UIP_CONF_ND6_SEND_RA */
/* UIP_CONF_ND6_SEND_NS enables standard IPv6 Neighbor Discovery Protocol.
We enable it by default when IPv6 is used without RPL.
/* UIP_CONF_ND6_SEND_NS enables standard IPv6 Neighbor Discovery Protocol
(RFC 4861). 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
@ -183,6 +183,17 @@
#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 still usable as a parent
or not, regardless of the neighbor cache. Note that this is not
standard-compliant (RFC 4861), as neighbors will be added regardless of
their reachability and liveness. */
#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. */

View File

@ -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_AUTOFILL, 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");

View File

@ -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)

View File

@ -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);

View File

@ -96,6 +96,17 @@
#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.
Note that this is not standard-compliant (RFC 4861), as neighbors will
be added regardless of their reachability and liveness. */
#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

View File

@ -82,6 +82,7 @@ typedef enum {
NBR_TABLE_REASON_RPL_DIS,
NBR_TABLE_REASON_ROUTE,
NBR_TABLE_REASON_IPV6_ND,
NBR_TABLE_REASON_IPV6_ND_AUTOFILL,
NBR_TABLE_REASON_MAC,
NBR_TABLE_REASON_LLSEC,
NBR_TABLE_REASON_LINK_STATS,