Пример #1
0
static void test_ipv6_netif_find_best_src_addr__success(void)
{
    ipv6_addr_t ll_addr1 = IPV6_ADDR_UNSPECIFIED;
    ipv6_addr_t ll_addr2 = IPV6_ADDR_UNSPECIFIED;
    ipv6_addr_t mc_addr = IPV6_ADDR_ALL_NODES_LINK_LOCAL;
    ipv6_addr_t *out = NULL;

    ll_addr1.u8[15] = 1;
    ipv6_addr_set_link_local_prefix(&ll_addr1);
    ll_addr2.u8[15] = 2;
    ipv6_addr_set_link_local_prefix(&ll_addr2);

    TEST_ASSERT_EQUAL_INT(126, ipv6_addr_match_prefix(&ll_addr2, &ll_addr1));

    test_ipv6_netif_add__success(); /* adds DEFAULT_TEST_NETIF as interface */
    TEST_ASSERT_NOT_NULL(ng_ipv6_netif_add_addr(DEFAULT_TEST_NETIF, &mc_addr, DEFAULT_TEST_PREFIX_LEN,
                         0));
    TEST_ASSERT_NOT_NULL(ng_ipv6_netif_add_addr(DEFAULT_TEST_NETIF, &ll_addr1, DEFAULT_TEST_PREFIX_LEN,
                         0));

    TEST_ASSERT_NOT_NULL((out = ng_ipv6_netif_find_best_src_addr(DEFAULT_TEST_NETIF, &ll_addr2)));
    TEST_ASSERT(out != &ll_addr1);
    TEST_ASSERT(out != &ll_addr2);
    TEST_ASSERT_EQUAL_INT(true, ipv6_addr_equal(out, &ll_addr1));
}
Пример #2
0
gnrc_sixlowpan_ctx_t *gnrc_sixlowpan_ctx_lookup_addr(const ipv6_addr_t *addr)
{
    uint8_t best = 0;
    gnrc_sixlowpan_ctx_t *res = NULL;

    mutex_lock(&_ctx_mutex);

    for (unsigned int id = 0; id < GNRC_SIXLOWPAN_CTX_SIZE; id++) {
        if (_valid(id)) {
            uint8_t match = ipv6_addr_match_prefix(&_ctxs[id].prefix, addr);

            if ((_ctxs[id].prefix_len <= match) && (match > best)) {
                best = match;
                res = &(_ctxs[id]);
            }
        }
    }

    mutex_unlock(&_ctx_mutex);

#if ENABLE_DEBUG
    if (res != NULL) {
        DEBUG("6lo ctx: found context (%u, %s/%" PRIu8 ") ",
              (res->flags_id & GNRC_SIXLOWPAN_CTX_FLAGS_CID_MASK),
              ipv6_addr_to_str(ipv6str, &res->prefix, sizeof(ipv6str)),
              res->prefix_len);
        DEBUG("for address %s\n", ipv6_addr_to_str(ipv6str, addr, sizeof(ipv6str)));
    }
#endif

    return res;
}
Пример #3
0
static inline bool _check_prefixes(gnrc_ipv6_netif_addr_t *a, gnrc_ipv6_netif_addr_t *b)
{
    if ((a->prefix_len == b->prefix_len) &&
        (ipv6_addr_match_prefix(&a->addr, &b->addr) >= a->prefix_len)) {
        return true;
    }

    return false;
}
Пример #4
0
static uint8_t _find_by_prefix_unsafe(ipv6_addr_t **res, gnrc_ipv6_netif_t *iface,
                                      const ipv6_addr_t *addr, uint8_t *only)
{
    uint8_t best_match = 0;

    for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) {
        uint8_t match;

        if ((only != NULL) && !(bf_isset(only, i))) {
            continue;
        }

        if (((only != NULL) &&
             gnrc_ipv6_netif_addr_is_non_unicast(&(iface->addrs[i].addr))) ||
            ipv6_addr_is_unspecified(&(iface->addrs[i].addr))) {
            continue;
        }

        match = ipv6_addr_match_prefix(&(iface->addrs[i].addr), addr);

        if ((only == NULL) && !ipv6_addr_is_multicast(addr) &&
            (match < iface->addrs[i].prefix_len)) {
            /* match but not of same subnet */
            continue;
        }

        if (match > best_match) {
            if (res != NULL) {
                *res = &(iface->addrs[i].addr);
            }

            best_match = match;
        }
    }

#if ENABLE_DEBUG
    if (*res != NULL) {
        DEBUG("ipv6 netif: Found %s on interface %" PRIkernel_pid " matching ",
              ipv6_addr_to_str(addr_str, *res, sizeof(addr_str)),
              iface->pid);
        DEBUG("%s by %" PRIu8 " bits (used as source address = %s)\n",
              ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
              best_match,
              (only != NULL) ? "true" : "false");
    }
    else {
        DEBUG("ipv6 netif: Did not found any address on interface %" PRIkernel_pid
              " matching %s (used as source address = %s)\n",
              iface->pid,
              ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
              (only != NULL) ? "true" : "false");
    }
#endif

    return best_match;
}
Пример #5
0
static void test_ipv6_netif_match_prefix__success3(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_PREFIX64;
    ipv6_addr_t *out = NULL;

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

    TEST_ASSERT_NOT_NULL((out = ng_ipv6_netif_match_prefix(DEFAULT_TEST_NETIF, &addr)));
    TEST_ASSERT(out != &addr);
    TEST_ASSERT_EQUAL_INT(64, ipv6_addr_match_prefix(out, &addr));
}
Пример #6
0
static void test_ipv6_netif_find_by_prefix__success2(void)
{
    ipv6_addr_t addr = DEFAULT_TEST_IPV6_PREFIX18;
    ipv6_addr_t *out = NULL;

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

    TEST_ASSERT_EQUAL_INT(DEFAULT_TEST_NETIF, ng_ipv6_netif_find_by_prefix(&out, &addr));
    TEST_ASSERT_NOT_NULL(out);
    TEST_ASSERT(out != &addr);
    TEST_ASSERT_EQUAL_INT(18, ipv6_addr_match_prefix(out, &addr));
}
Пример #7
0
static gnrc_sixlowpan_nd_router_prf_t *_get_free_prefix(ipv6_addr_t *prefix, size_t prefix_len)
{
    gnrc_sixlowpan_nd_router_prf_t *prf = NULL;

    for (int i = 0; i < GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF; i++) {
        if ((ipv6_addr_match_prefix(&_prefixes[i].prefix->addr, prefix) >= prefix_len) &&
            (_prefixes[i].prefix->prefix_len == prefix_len)) {
            return &_prefixes[i];
        }

        if ((prf == NULL) && ipv6_addr_is_unspecified(&_prefixes[i].prefix->addr)) {
            prf = &_prefixes[i];
        }
    }

    return prf;
}
Пример #8
0
static unsigned _match(const gnrc_netif_t *netif, const ipv6_addr_t *addr,
                       const uint8_t *filter, int *idx)
{
    unsigned best_match = 0;

    assert(idx != NULL);
    *idx = -1;
    for (int i = 0; i < GNRC_NETIF_IPV6_ADDRS_NUMOF; i++) {
        unsigned match;

        if ((netif->ipv6.addrs_flags[i] == 0) ||
            ((filter != NULL) && _addr_anycast(netif, i)) ||
            /* discard const intentionally */
            ((filter != NULL) && !(bf_isset((uint8_t *)filter, i)))) {
            continue;
        }
        match = ipv6_addr_match_prefix(&(netif->ipv6.addrs[i]), addr);
        if (((match > 64U) || !ipv6_addr_is_link_local(&(netif->ipv6.addrs[i]))) &&
            (match >= best_match)) {
            if (idx != NULL) {
                *idx = i;
            }
            best_match = match;
        }
    }
    if (*idx >= 0) {
        DEBUG("gnrc_netif: Found %s on interface %" PRIkernel_pid " matching ",
              ipv6_addr_to_str(addr_str, &netif->ipv6.addrs[*idx],
                               sizeof(addr_str)),
              netif->pid);
        DEBUG("%s by %u bits (used as source address = %s)\n",
              ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
              best_match,
              (filter != NULL) ? "true" : "false");
    }
    else {
        DEBUG("gnrc_netif: Did not found any address on interface %" PRIkernel_pid
              " matching %s (used as source address = %s)\n",
              netif->pid,
              ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
              (filter != NULL) ? "true" : "false");
    }
    return best_match;
}
Пример #9
0
static void test_ipv6_netif_find_best_src_addr__no_unicast(void)
{
    ipv6_addr_t ll_addr1 = IPV6_ADDR_UNSPECIFIED;
    ipv6_addr_t ll_addr2 = IPV6_ADDR_UNSPECIFIED;
    ipv6_addr_t mc_addr = IPV6_ADDR_ALL_NODES_LINK_LOCAL;

    ll_addr1.u8[15] = 1;
    ipv6_addr_set_link_local_prefix(&ll_addr1);
    ll_addr2.u8[15] = 2;
    ipv6_addr_set_link_local_prefix(&ll_addr2);

    TEST_ASSERT_EQUAL_INT(126, ipv6_addr_match_prefix(&ll_addr2, &ll_addr1));

    test_ipv6_netif_add__success(); /* adds DEFAULT_TEST_NETIF as interface */
    TEST_ASSERT_NOT_NULL(ng_ipv6_netif_add_addr(DEFAULT_TEST_NETIF, &mc_addr, DEFAULT_TEST_PREFIX_LEN,
                         0));
    TEST_ASSERT_NOT_NULL(ng_ipv6_netif_add_addr(DEFAULT_TEST_NETIF, &ll_addr1, DEFAULT_TEST_PREFIX_LEN,
                         NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST));

    TEST_ASSERT_NULL(ng_ipv6_netif_find_best_src_addr(DEFAULT_TEST_NETIF, &ll_addr2));
}
Пример #10
0
int gnrc_netif_ipv6_addr_add_internal(gnrc_netif_t *netif,
                                      const ipv6_addr_t *addr,
                                      unsigned pfx_len, uint8_t flags)
{
    unsigned idx = UINT_MAX;

    assert((netif != NULL) && (addr != NULL));
    assert(!(ipv6_addr_is_multicast(addr) || ipv6_addr_is_unspecified(addr) ||
             ipv6_addr_is_loopback(addr)));
    assert((pfx_len > 0) && (pfx_len <= 128));
    gnrc_netif_acquire(netif);
    if ((flags & GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_MASK) ==
        GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_TENTATIVE) {
        /* set to first retransmission */
        flags &= ~GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_TENTATIVE;
        flags |= 0x1;
    }
    for (unsigned i = 0; i < GNRC_NETIF_IPV6_ADDRS_NUMOF; i++) {
        if (ipv6_addr_equal(&netif->ipv6.addrs[i], addr)) {
            gnrc_netif_release(netif);
            return i;
        }
        if ((idx == UINT_MAX) && (netif->ipv6.addrs_flags[i] == 0)) {
            idx = i;
        }
    }
    if (idx == UINT_MAX) {
        gnrc_netif_release(netif);
        return -ENOMEM;
    }
    netif->ipv6.addrs_flags[idx] = flags;
    memcpy(&netif->ipv6.addrs[idx], addr, sizeof(netif->ipv6.addrs[idx]));
#ifdef MODULE_GNRC_IPV6_NIB
#if GNRC_IPV6_NIB_CONF_ARSM
    ipv6_addr_t sol_nodes;
    int res;

    /* TODO: SHOULD delay join between 0 and MAX_RTR_SOLICITATION_DELAY
     * for SLAAC */
    ipv6_addr_set_solicited_nodes(&sol_nodes, addr);
    res = gnrc_netif_ipv6_group_join_internal(netif, &sol_nodes);
    if (res < 0) {
        DEBUG("nib: Can't join solicited-nodes of %s on interface %u\n",
              ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
              netif->pid);
    }
#endif /* GNRC_IPV6_NIB_CONF_ARSM */
    if (_get_state(netif, idx) == GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_VALID) {
        void *state = NULL;
        gnrc_ipv6_nib_pl_t ple;
        bool in_pl = false;

        while (gnrc_ipv6_nib_pl_iter(netif->pid, &state, &ple)) {
            if (ipv6_addr_match_prefix(&ple.pfx, addr) >= pfx_len) {
                in_pl = true;
            }
        }
        if (!in_pl) {
            gnrc_ipv6_nib_pl_set(netif->pid, addr, pfx_len,
                                 UINT32_MAX, UINT32_MAX);
        }
    }
#if GNRC_IPV6_NIB_CONF_SLAAC
    else {
        /* TODO: send out NS to solicited nodes for DAD probing */
    }
#endif
#else
    (void)pfx_len;
#endif
    gnrc_netif_release(netif);
    return idx;
}