diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-6ln.c b/sys/net/gnrc/network_layer/ipv6/nib/_nib-6ln.c index 2d3036aa20..8dcbfefeff 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-6ln.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-6ln.c @@ -206,8 +206,10 @@ void _handle_rereg_address(const ipv6_addr_t *addr) { gnrc_netif_t *netif = gnrc_netif_get_by_ipv6_addr(addr); _nib_dr_entry_t *router = _nib_drl_get_dr(); + const bool router_reachable = (router != NULL) && + _is_reachable(router->next_hop); - if ((netif != NULL) && (router != NULL)) { + if (router_reachable && (netif != NULL)) { assert((unsigned)netif->pid == _nib_onl_get_if(router->next_hop)); DEBUG("nib: Re-registering %s", ipv6_addr_to_str(addr_str, addr, sizeof(addr_str))); @@ -224,9 +226,10 @@ void _handle_rereg_address(const ipv6_addr_t *addr) if (netif != NULL) { int idx = gnrc_netif_ipv6_addr_idx(netif, addr); - if (_is_valid(netif, idx) || (_is_tentative(netif, idx) && + if (router_reachable && + (_is_valid(netif, idx) || (_is_tentative(netif, idx) && (gnrc_netif_ipv6_addr_dad_trans(netif, idx) < - SIXLOWPAN_ND_REG_TRANSMIT_NUMOF))) { + SIXLOWPAN_ND_REG_TRANSMIT_NUMOF)))) { uint32_t retrans_time; if (_is_valid(netif, idx)) { diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.c b/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.c index 772da2f157..ff66de434f 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.c @@ -495,6 +495,17 @@ void _set_nud_state(gnrc_netif_t *netif, _nib_onl_entry_t *nce, #endif /* GNRC_IPV6_NIB_CONF_ROUTER */ } +bool _is_reachable(_nib_onl_entry_t *entry) +{ + switch (_get_nud_state(entry)) { + case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE: + case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE: + return false; + default: + return true; + } +} + /* internal functions */ static inline uint32_t _exp_backoff_retrans_timer(uint8_t ns_sent, uint32_t retrans_timer) @@ -547,7 +558,6 @@ static inline bool _rflag_set(const ndp_nbr_adv_t *nbr_adv) return (nbr_adv->type == ICMPV6_NBR_ADV) && (nbr_adv->flags & NDP_NBR_ADV_FLAGS_R); } - #endif /* GNRC_IPV6_NIB_CONF_ARSM */ /** @} */ diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.h b/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.h index f2558ff852..aa380c61a5 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.h +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.h @@ -178,6 +178,17 @@ static inline uint16_t _get_nud_state(_nib_onl_entry_t *nbr) void _set_nud_state(gnrc_netif_t *netif, _nib_onl_entry_t *nbr, uint16_t state); +/** + * @brief Checks if a node is in a reachable state + * + * A node is reachable if it is not in NUD state UNREACHABLE or INCOMPLETE + * + * @param[in] entry A node. + * + * @return true, if @p entry is in a reachable state. + * @return false, if @p entry is not in a reachable state. + */ +bool _is_reachable(_nib_onl_entry_t *entry); #else /* GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN) */ #define _handle_snd_ns(ctx) (void)ctx #define _handle_state_timeout(ctx) (void)ctx @@ -191,6 +202,7 @@ void _set_nud_state(gnrc_netif_t *netif, _nib_onl_entry_t *nbr, #define _get_nud_state(nbr) (GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED) #define _set_nud_state(netif, nce, state) (void)netif; (void)nbr; (void)state +#define _is_reachable(entry) (true) #endif /* GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN) */ #ifdef __cplusplus diff --git a/sys/net/gnrc/network_layer/ipv6/nib/nib.c b/sys/net/gnrc/network_layer/ipv6/nib/nib.c index a0d40d516d..b4875faaa2 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/nib.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/nib.c @@ -983,20 +983,6 @@ static void _handle_nbr_adv(gnrc_netif_t *netif, const ipv6_hdr_t *ipv6, } } -#if GNRC_IPV6_NIB_CONF_ARSM -static inline bool _is_reachable(_nib_onl_entry_t *entry) -{ - (void)entry; /* _get_nud_state() might just resolved to UNMANAGED as macro */ - switch (_get_nud_state(entry)) { - case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE: - case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE: - return false; - default: - return true; - } -} -#endif /* GNRC_IPV6_NIB_CONF_ARSM */ - #if GNRC_IPV6_NIB_CONF_QUEUE_PKT static gnrc_pktqueue_t *_alloc_queue_entry(gnrc_pktsnip_t *pkt) {