gnrc_ipv6_nib: fallback to SLAAC if ARO is ignored by upstream

Linux doesn't have ARO support at the moment so this is a workaround to
try to speak 6Lo-ND while still being able to do DAD with a border
router that doesn't.

(cherry picked from commit 4f87883ab8)
This commit is contained in:
Martine Lenders 2018-07-06 16:39:48 +02:00 committed by Martine Lenders
parent 710afe3a1a
commit cbd1e027a8
2 changed files with 27 additions and 2 deletions

View File

@ -52,6 +52,16 @@ static inline uint32_t _now_min(void)
*/ */
#define _ADDR_REG_STATUS_IGNORE (4) #define _ADDR_REG_STATUS_IGNORE (4)
/**
* @brief Additional (local) status to ARO status values to signify that ARO
* is not available in NA
*
* Can be assigned to the variable that receives the return value of
* @ref _handle_aro(), so that the case that an NA does not contain an ARO
* (e.g. because upstream router does not support it) can be dealt with.
*/
#define _ADDR_REG_STATUS_UNAVAIL (255)
/** /**
* @brief Resolves address statically from destination address using reverse * @brief Resolves address statically from destination address using reverse
* translation of the IID * translation of the IID

View File

@ -1015,6 +1015,9 @@ static void _handle_nbr_adv(gnrc_netif_t *netif, const ipv6_hdr_t *ipv6,
#if GNRC_IPV6_NIB_CONF_ARSM #if GNRC_IPV6_NIB_CONF_ARSM
bool tl2ao_avail = false; bool tl2ao_avail = false;
#endif /* GNRC_IPV6_NIB_CONF_ARSM */ #endif /* GNRC_IPV6_NIB_CONF_ARSM */
#if GNRC_IPV6_NIB_CONF_6LN
uint8_t aro_status = _ADDR_REG_STATUS_UNAVAIL;
#endif
tmp_len = icmpv6_len - sizeof(ndp_nbr_adv_t); tmp_len = icmpv6_len - sizeof(ndp_nbr_adv_t);
FOREACH_OPT(nbr_adv, opt, tmp_len) { FOREACH_OPT(nbr_adv, opt, tmp_len) {
@ -1027,8 +1030,10 @@ static void _handle_nbr_adv(gnrc_netif_t *netif, const ipv6_hdr_t *ipv6,
#endif /* GNRC_IPV6_NIB_CONF_ARSM */ #endif /* GNRC_IPV6_NIB_CONF_ARSM */
#if GNRC_IPV6_NIB_CONF_6LN #if GNRC_IPV6_NIB_CONF_6LN
case NDP_OPT_AR: case NDP_OPT_AR:
_handle_aro(netif, ipv6, (const icmpv6_hdr_t *)nbr_adv, aro_status = _handle_aro(netif, ipv6,
(const sixlowpan_nd_opt_ar_t *)opt, opt, nce); (const icmpv6_hdr_t *)nbr_adv,
(const sixlowpan_nd_opt_ar_t *)opt,
opt, nce);
break; break;
#endif /* GNRC_IPV6_NIB_CONF_6LN */ #endif /* GNRC_IPV6_NIB_CONF_6LN */
default: default:
@ -1046,6 +1051,16 @@ static void _handle_nbr_adv(gnrc_netif_t *netif, const ipv6_hdr_t *ipv6,
_handle_adv_l2(netif, nce, (icmpv6_hdr_t *)nbr_adv, NULL); _handle_adv_l2(netif, nce, (icmpv6_hdr_t *)nbr_adv, NULL);
} }
#endif /* GNRC_IPV6_NIB_CONF_ARSM */ #endif /* GNRC_IPV6_NIB_CONF_ARSM */
#if GNRC_IPV6_NIB_CONF_SLAAC && GNRC_IPV6_NIB_CONF_6LN
/* 6Lo-ND duplicate address detection (DAD) was ignored by neighbor, try
* traditional DAD */
if ((aro_status == _ADDR_REG_STATUS_UNAVAIL) &&
gnrc_netif_is_6ln(netif)) {
_handle_dad(&ipv6->dst);
}
#elif GNRC_IPV6_NIB_CONF_6LN
(void)aro_status;
#endif
} }
} }