Exemple #1
0
static void test_ipv6_nc_still_reachable__incomplete(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
    ng_ipv6_nc_t *entry = NULL;

    /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF and sets flags to
     * (NG_IPV6_NC_STATE_INCOMPLETE << NG_IPV6_NC_STATE_POS) */
    test_ipv6_nc_is_reachable__incomplete();

    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get(KERNEL_PID_UNDEF, &addr)));
    TEST_ASSERT(!ng_ipv6_nc_is_reachable(entry));
    TEST_ASSERT_NOT_NULL(ng_ipv6_nc_still_reachable(&addr));
    TEST_ASSERT(!ng_ipv6_nc_is_reachable(entry));
}
Exemple #2
0
static void test_ipv6_nc_still_reachable__success(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
    ng_ipv6_nc_t *entry = NULL;

    /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF and sets flags to
     * (NG_IPV6_NC_STATE_REACHABLE << NG_IPV6_NC_STATE_POS) */
    test_ipv6_nc_is_reachable__reachable();

    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get(KERNEL_PID_UNDEF, &addr)));
    TEST_ASSERT(ng_ipv6_nc_is_reachable(entry));

    entry->flags = (NG_IPV6_NC_STATE_STALE << NG_IPV6_NC_STATE_POS);

    TEST_ASSERT_NOT_NULL(ng_ipv6_nc_still_reachable(&addr));
    TEST_ASSERT(ng_ipv6_nc_is_reachable(entry));
}
Exemple #3
0
static void test_ipv6_nc_is_reachable__reachable(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
    ng_ipv6_nc_t *entry = NULL;

    test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */

    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr)));
    entry->flags = (NG_IPV6_NC_STATE_REACHABLE << NG_IPV6_NC_STATE_POS);
    TEST_ASSERT(ng_ipv6_nc_is_reachable(entry));
}
Exemple #4
0
static void test_ipv6_nc_is_reachable__incomplete(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
    ng_ipv6_nc_t *entry = NULL;

    test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */

    TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get(KERNEL_PID_UNDEF, &addr)));
    entry->flags = (NG_IPV6_NC_STATE_INCOMPLETE << NG_IPV6_NC_STATE_POS);
    TEST_ASSERT(!ng_ipv6_nc_is_reachable(entry));
}
Exemple #5
0
kernel_pid_t ng_ndp_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
                                    kernel_pid_t iface, ng_ipv6_addr_t *dst,
                                    ng_pktsnip_t *pkt)
{
    ng_ipv6_addr_t *next_hop_ip = NULL, *prefix = NULL;

#ifdef MODULE_NG_IPV6_EXT_RH
    next_hop_ip = ng_ipv6_ext_rh_next_hop(hdr);
#endif
#ifdef MODULE_FIB
    size_t next_hop_size = sizeof(ng_ipv6_addr_t);
    uint32_t next_hop_flags = 0;
    ng_ipv6_addr_t next_hop_actual; /* FIB copies address into this variable */

    if ((next_hop_ip == NULL) &&
        (fib_get_next_hop(&iface, next_hop_actual.u8, &next_hop_size,
                          &next_hop_flags, (uint8_t *)dst,
                          sizeof(ng_ipv6_addr_t), 0) >= 0) &&
        (next_hop_size == sizeof(ng_ipv6_addr_t))) {
        next_hop_ip = &next_hop_actual;
    }

#endif

    if (next_hop_ip == NULL) {            /* no route to host */
        if (iface == KERNEL_PID_UNDEF) {
            /* ng_ipv6_netif_t doubles as prefix list */
            iface = ng_ipv6_netif_find_by_prefix(&prefix, dst);
        }
        else {
            /* ng_ipv6_netif_t doubles as prefix list */
            prefix = ng_ipv6_netif_match_prefix(iface, dst);
        }

        if ((prefix != NULL) &&             /* prefix is on-link */
            (ng_ipv6_netif_addr_get(prefix)->flags &
             NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK)) {
            next_hop_ip = dst;
#ifdef MODULE_FIB
            /* We don't care if FIB is full, this is just for efficiency
             * for later sends */
            fib_add_entry(iface, (uint8_t *)dst, sizeof(ng_ipv6_addr_t), 0,
                          (uint8_t *)next_hop_ip, sizeof(ng_ipv6_addr_t), 0,
                          FIB_LIFETIME_NO_EXPIRE);
#endif
        }
    }

    if (next_hop_ip == NULL) {
        next_hop_ip = _default_router();
#ifdef MODULE_FIB
        /* We don't care if FIB is full, this is just for efficiency for later
         * sends */
        fib_add_entry(iface, (uint8_t *)dst, sizeof(ng_ipv6_addr_t), 0,
                      (uint8_t *)next_hop_ip, sizeof(ng_ipv6_addr_t), 0,
                      FIB_LIFETIME_NO_EXPIRE);
#endif
    }

    if (next_hop_ip != NULL) {
        ng_ipv6_nc_t *nc_entry = ng_ipv6_nc_get(iface, next_hop_ip);

        if ((nc_entry != NULL) && ng_ipv6_nc_is_reachable(nc_entry)) {
            DEBUG("ndp: found reachable neighbor (%s => ",
                  ng_ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str)));
            DEBUG("%s)\n",
                  ng_netif_addr_to_str(addr_str, sizeof(addr_str),
                                       nc_entry->l2_addr, nc_entry->l2_addr_len));

            if (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_STALE) {
                _set_state(nc_entry, NG_IPV6_NC_STATE_DELAY);
            }

            memcpy(l2addr, nc_entry->l2_addr, nc_entry->l2_addr_len);
            *l2addr_len = nc_entry->l2_addr_len;
            /* TODO: unreachability check */
            return nc_entry->iface;
        }
        else if (nc_entry == NULL) {
            ng_pktqueue_t *pkt_node;
            ng_ipv6_addr_t dst_sol;

            nc_entry = ng_ipv6_nc_add(iface, next_hop_ip, NULL, 0,
                                      NG_IPV6_NC_STATE_INCOMPLETE << NG_IPV6_NC_STATE_POS);

            if (nc_entry == NULL) {
                DEBUG("ndp: could not create neighbor cache entry\n");
                return KERNEL_PID_UNDEF;
            }

            pkt_node = _alloc_pkt_node(pkt);

            if (pkt_node == NULL) {
                DEBUG("ndp: could not add packet to packet queue\n");
            }
            else {
                /* prevent packet from being released by IPv6 */
                ng_pktbuf_hold(pkt_node->pkt, 1);
                ng_pktqueue_add(&nc_entry->pkts, pkt_node);
            }

            /* address resolution */
            ng_ipv6_addr_set_solicited_nodes(&dst_sol, next_hop_ip);

            if (iface == KERNEL_PID_UNDEF) {
                timex_t t = { 0, NG_NDP_RETRANS_TIMER };
                kernel_pid_t ifs[NG_NETIF_NUMOF];
                size_t ifnum = ng_netif_get(ifs);

                for (size_t i = 0; i < ifnum; i++) {
                    _send_nbr_sol(ifs[i], next_hop_ip, &dst_sol);
                }

                vtimer_remove(&nc_entry->nbr_sol_timer);
                vtimer_set_msg(&nc_entry->nbr_sol_timer, t, ng_ipv6_pid,
                               NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry);
            }
            else {
                ng_ipv6_netif_t *ipv6_iface = ng_ipv6_netif_get(iface);

                _send_nbr_sol(iface, next_hop_ip, &dst_sol);

                mutex_lock(&ipv6_iface->mutex);
                vtimer_remove(&nc_entry->nbr_sol_timer);
                vtimer_set_msg(&nc_entry->nbr_sol_timer,
                               ipv6_iface->retrans_timer, ng_ipv6_pid,
                               NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry);
                mutex_unlock(&ipv6_iface->mutex);
            }
        }
    }

    return KERNEL_PID_UNDEF;
}