Beispiel #1
0
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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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);
}