1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

Merge pull request #8093 from miri64/gnrc_ipv6_nib/fix/unreachable-behavior

gnrc_ipv6_nib: various fixes regarding UNREACHABLE state
This commit is contained in:
Koen Zandberg 2017-11-21 17:41:55 +01:00 committed by GitHub
commit 8158a273c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 42 additions and 21 deletions

View File

@ -170,6 +170,15 @@ extern "C" {
* @see [RFC 7048](https://tools.ietf.org/html/rfc7048)
*/
#define NDP_MAX_RETRANS_TIMER_MS (60000U)
/**
* @brief Maximum retransmission of neighbor solicitations when UNREACHABLE
*
* With more than this number the backoff will always be larger than
* @ref NDP_MAX_RETRANS_TIMER_MS, even if the random factor is 0.5 and the
* retransmission time is 1ms.
*/
#define NDP_MAX_NS_NUMOF (17U)
#define NDP_DELAY_FIRST_PROBE_MS (5000U) /**< DELAY_FIRST_PROBE_TIME (in ms) */
#define NDP_MIN_RANDOM_FACTOR (500U) /**< MIN_RANDOM_FACTOR (x 1000) */
#define NDP_MAX_RANDOM_FACTOR (1500U) /**< MAX_RANDOM_FACTOR (x 1000) */

View File

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

View File

@ -352,8 +352,9 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset)
_snd_ns(&nbr->ipv6, netif, NULL, &sol_nodes);
_evtimer_add(nbr, GNRC_IPV6_NIB_SND_MC_NS, &nbr->nud_timeout,
retrans_time);
if (nbr->ns_sent < UINT8_MAX) {
/* cap ns_sent at UINT8_MAX to prevent backoff reset */
if (nbr->ns_sent < (NDP_MAX_NS_NUMOF + 2)) {
/* cap ns_sent at NDP_MAX_NS_NUMOF to prevent backoff
* overflow */
nbr->ns_sent++;
}
}
@ -495,6 +496,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 +559,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 */
/** @} */

View File

@ -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
@ -185,12 +196,13 @@ void _set_nud_state(gnrc_netif_t *netif, _nib_onl_entry_t *nbr,
#define _init_iface_arsm(netif) (void)netif
#define _handle_adv_l2(netif, nce, icmpv6, tl2ao) (void)netif; (void)nce; \
(void)icmpv6; (void)tl2ao
#define _recalc_reach_time(netif) (void)netif;
#define _recalc_reach_time(netif) (void)netif
#define _set_reachable(netif, nce) (void)netif; (void)nce
#define _init_iface_arsm(netif) (void)netif
#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

View File

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