void gnrc_sixlowpan_nd_init(gnrc_ipv6_netif_t *iface) { assert(iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN); mutex_lock(&iface->mutex); iface->rtr_sol_count = 0; /* first will be sent immediately */ DEBUG("6lo nd: retransmit multicast rtr sol in 10 sec\n"); _rtr_sol_reschedule(iface, GNRC_SIXLOWPAN_ND_RTR_SOL_INT); mutex_unlock(&iface->mutex); gnrc_ndp_internal_send_rtr_sol(iface->pid, NULL); }
void gnrc_ndp_host_retrans_rtr_sol(gnrc_ipv6_netif_t *iface) { mutex_lock(&iface->mutex); if (iface->rtr_sol_count > 1) { /* regard off-by-one error */ DEBUG("ndp hst: retransmit rtr sol in %d sec\n", GNRC_NDP_MAX_RTR_SOL_INT); iface->rtr_sol_count--; _reschedule_rtr_sol(iface, GNRC_NDP_MAX_RTR_SOL_INT * US_PER_SEC); } mutex_unlock(&iface->mutex); gnrc_ndp_internal_send_rtr_sol(iface->pid, NULL); }
void gnrc_sixlowpan_nd_uc_rtr_sol(gnrc_ipv6_nc_t *nce) { assert(gnrc_ipv6_netif_get(nce->iface)->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN); /* neighbor is not a router anymore */ if (!(nce->flags & GNRC_IPV6_NC_IS_ROUTER) || ipv6_addr_is_unspecified(&nce->ipv6_addr)) { /* and there are no routers anymore */ if (gnrc_ipv6_nc_get_next_router(NULL) == NULL) { /* start search for routers */ gnrc_sixlowpan_nd_init(gnrc_ipv6_netif_get(nce->iface)); } /* otherwise ignore this call */ return; } /* next RS is rescheduled by RA handle function */ gnrc_ndp_internal_send_rtr_sol(nce->iface, &nce->ipv6_addr); }
void gnrc_sixlowpan_nd_mc_rtr_sol(gnrc_ipv6_netif_t *iface) { uint32_t interval; assert(iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN); mutex_lock(&iface->mutex); if (iface->rtr_sol_count < GNRC_NDP_MAX_RTR_SOL_NUMOF) { DEBUG("6lo nd: retransmit multicast rtr sol in 10 sec\n"); iface->rtr_sol_count++; interval = GNRC_SIXLOWPAN_ND_RTR_SOL_INT; } else { unsigned int exp = (unsigned int)(iface->rtr_sol_count - GNRC_NDP_MAX_RTR_SOL_NUMOF); interval = _binary_exp_backoff(1, exp); if ((1U << exp) < GNRC_SIXLOWPAN_ND_MAX_RTR_SOL_INT) { /* XXX Not sure if this is the correct interpretation of the truncation described in * https://tools.ietf.org/html/rfc6775#section-5.3. In every source I've read the * truncating value was the exponent, not the target value, so I'm very confused * about this sentencing. Anyway, since 60 sec is a maximum value this should only * affect the energy consumption of the implementation by sending the next RS too fast * but not its interoperability. */ iface->rtr_sol_count++; } /* RFC6775, section 5.3 (https://tools.ietf.org/html/rfc6775#section-5.3) * states that router solicitation should be sent slower after the * initial 3 retransmissions (i.e. >= 10 secondes) and truncate "the * increase of the retransmission timer at 60 seconds". */ if (interval < GNRC_SIXLOWPAN_ND_RTR_SOL_INT) { interval = GNRC_SIXLOWPAN_ND_RTR_SOL_INT; } else if (interval > GNRC_SIXLOWPAN_ND_MAX_RTR_SOL_INT) { interval = GNRC_SIXLOWPAN_ND_MAX_RTR_SOL_INT; } DEBUG("6lo nd: retransmit multicast rtr sol in %" PRIu32 " sec\n", interval); } _rtr_sol_reschedule(iface, interval); mutex_unlock(&iface->mutex); gnrc_ndp_internal_send_rtr_sol(iface->pid, NULL); }