mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-27 15:31:17 +01:00
Merge pull request #3044 from Lotterleben/ipv6_ifs_no_duplicates
ng_ipv6_netif: no more duplicates if empty entries are found before
This commit is contained in:
commit
486f8dd8e9
@ -38,49 +38,58 @@ static char addr_str[NG_IPV6_ADDR_MAX_STR_LEN];
|
||||
static ng_ipv6_addr_t *_add_addr_to_entry(ng_ipv6_netif_t *entry, const ng_ipv6_addr_t *addr,
|
||||
uint8_t prefix_len, uint8_t flags)
|
||||
{
|
||||
ng_ipv6_netif_addr_t *tmp_addr = NULL;
|
||||
|
||||
for (int i = 0; i < NG_IPV6_NETIF_ADDR_NUMOF; i++) {
|
||||
if (ng_ipv6_addr_equal(&(entry->addrs[i].addr), addr)) {
|
||||
return &(entry->addrs[i].addr);
|
||||
}
|
||||
|
||||
if (ng_ipv6_addr_is_unspecified(&(entry->addrs[i].addr))) {
|
||||
memcpy(&(entry->addrs[i].addr), addr, sizeof(ng_ipv6_addr_t));
|
||||
DEBUG("ipv6 netif: Added %s/%" PRIu8 " to interface %" PRIkernel_pid "\n",
|
||||
ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
|
||||
prefix_len, entry->pid);
|
||||
|
||||
entry->addrs[i].prefix_len = prefix_len;
|
||||
entry->addrs[i].flags = flags;
|
||||
|
||||
if (ng_ipv6_addr_is_multicast(addr)) {
|
||||
entry->addrs[i].flags |= NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST;
|
||||
}
|
||||
else {
|
||||
ng_ipv6_addr_t sol_node;
|
||||
|
||||
if (!ng_ipv6_addr_is_link_local(addr)) {
|
||||
/* add also corresponding link-local address */
|
||||
ng_ipv6_addr_t ll_addr;
|
||||
|
||||
ll_addr.u64[1] = addr->u64[1];
|
||||
ng_ipv6_addr_set_link_local_prefix(&ll_addr);
|
||||
|
||||
_add_addr_to_entry(entry, &ll_addr, 64,
|
||||
flags | NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK);
|
||||
}
|
||||
else {
|
||||
entry->addrs[i].flags |= NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK;
|
||||
}
|
||||
|
||||
ng_ipv6_addr_set_solicited_nodes(&sol_node, addr);
|
||||
_add_addr_to_entry(entry, &sol_node, NG_IPV6_ADDR_BIT_LEN, 0);
|
||||
}
|
||||
|
||||
return &entry->addrs[i].addr;
|
||||
if (ng_ipv6_addr_is_unspecified(&(entry->addrs[i].addr)) && !tmp_addr) {
|
||||
tmp_addr = &(entry->addrs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
if (!tmp_addr) {
|
||||
DEBUG("ipv6 netif: couldn't add %s/%" PRIu8 " to interface %" PRIkernel_pid "\n: No space left.",
|
||||
ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
|
||||
prefix_len, entry->pid);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(&(tmp_addr->addr), addr, sizeof(ng_ipv6_addr_t));
|
||||
DEBUG("ipv6 netif: Added %s/%" PRIu8 " to interface %" PRIkernel_pid "\n",
|
||||
ng_ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
|
||||
prefix_len, entry->pid);
|
||||
|
||||
tmp_addr->prefix_len = prefix_len;
|
||||
tmp_addr->flags = flags;
|
||||
|
||||
if (ng_ipv6_addr_is_multicast(addr)) {
|
||||
tmp_addr->flags |= NG_IPV6_NETIF_ADDR_FLAGS_NON_UNICAST;
|
||||
}
|
||||
else {
|
||||
ng_ipv6_addr_t sol_node;
|
||||
|
||||
if (!ng_ipv6_addr_is_link_local(addr)) {
|
||||
/* add also corresponding link-local address */
|
||||
ng_ipv6_addr_t ll_addr;
|
||||
|
||||
ll_addr.u64[1] = addr->u64[1];
|
||||
ng_ipv6_addr_set_link_local_prefix(&ll_addr);
|
||||
|
||||
_add_addr_to_entry(entry, &ll_addr, 64,
|
||||
flags | NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK);
|
||||
}
|
||||
else {
|
||||
tmp_addr->flags |= NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK;
|
||||
}
|
||||
|
||||
ng_ipv6_addr_set_solicited_nodes(&sol_node, addr);
|
||||
_add_addr_to_entry(entry, &sol_node, NG_IPV6_ADDR_BIT_LEN, 0);
|
||||
}
|
||||
|
||||
return &(tmp_addr->addr);
|
||||
}
|
||||
|
||||
static void _reset_addr_from_entry(ng_ipv6_netif_t *entry)
|
||||
@ -102,37 +111,48 @@ void ng_ipv6_netif_init(void)
|
||||
|
||||
void ng_ipv6_netif_add(kernel_pid_t pid)
|
||||
{
|
||||
ng_ipv6_netif_t *free_entry = NULL;
|
||||
|
||||
for (int i = 0; i < NG_NETIF_NUMOF; i++) {
|
||||
if (ipv6_ifs[i].pid == pid) {
|
||||
return; /* prevent duplicates */
|
||||
}
|
||||
else if (ipv6_ifs[i].pid == KERNEL_PID_UNDEF) {
|
||||
ng_ipv6_addr_t addr = NG_IPV6_ADDR_ALL_NODES_LINK_LOCAL;
|
||||
mutex_lock(&ipv6_ifs[i].mutex);
|
||||
|
||||
DEBUG("ipv6 netif: Add IPv6 interface %" PRIkernel_pid " (i = %d)\n", pid, i);
|
||||
ipv6_ifs[i].pid = pid;
|
||||
ipv6_ifs[i].mtu = NG_IPV6_NETIF_DEFAULT_MTU;
|
||||
ipv6_ifs[i].cur_hl = NG_IPV6_NETIF_DEFAULT_HL;
|
||||
ipv6_ifs[i].flags = 0;
|
||||
|
||||
_add_addr_to_entry(&ipv6_ifs[i], &addr, NG_IPV6_ADDR_BIT_LEN, 0);
|
||||
|
||||
mutex_unlock(&ipv6_ifs[i].mutex);
|
||||
|
||||
#ifdef MODULE_NG_NDP
|
||||
ng_ndp_netif_add(&ipv6_ifs[i]);
|
||||
#endif
|
||||
|
||||
DEBUG(" * pid = %" PRIkernel_pid " ", ipv6_ifs[i].pid);
|
||||
DEBUG("cur_hl = %d ", ipv6_ifs[i].cur_hl);
|
||||
DEBUG("mtu = %d ", ipv6_ifs[i].mtu);
|
||||
DEBUG("flags = %04" PRIx16 "\n", ipv6_ifs[i].flags);
|
||||
/* pid has already been added */
|
||||
return;
|
||||
}
|
||||
|
||||
else if ((ipv6_ifs[i].pid == KERNEL_PID_UNDEF) && !free_entry) {
|
||||
/* found the first free entry */
|
||||
free_entry = &ipv6_ifs[i];
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG("ipv6 netif: Could not add %" PRIkernel_pid " to IPv6: No space left.\n", pid);
|
||||
if (!free_entry) {
|
||||
DEBUG("ipv6 netif: Could not add %" PRIkernel_pid " to IPv6: No space left.\n", pid);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Otherwise, fill the free entry */
|
||||
|
||||
ng_ipv6_addr_t addr = NG_IPV6_ADDR_ALL_NODES_LINK_LOCAL;
|
||||
mutex_lock(&free_entry->mutex);
|
||||
|
||||
DEBUG("ipv6 netif: Add IPv6 interface %" PRIkernel_pid " (i = %d)\n", pid, i);
|
||||
free_entry->pid = pid;
|
||||
free_entry->mtu = NG_IPV6_NETIF_DEFAULT_MTU;
|
||||
free_entry->cur_hl = NG_IPV6_NETIF_DEFAULT_HL;
|
||||
free_entry->flags = 0;
|
||||
|
||||
_add_addr_to_entry(free_entry, &addr, NG_IPV6_ADDR_BIT_LEN, 0);
|
||||
|
||||
mutex_unlock(&free_entry->mutex);
|
||||
|
||||
#ifdef MODULE_NG_NDP
|
||||
ng_ndp_netif_add(free_entry);
|
||||
#endif
|
||||
|
||||
DEBUG(" * pid = %" PRIkernel_pid " ", free_entry->pid);
|
||||
DEBUG("cur_hl = %d ", free_entry->cur_hl);
|
||||
DEBUG("mtu = %d ", free_entry->mtu);
|
||||
DEBUG("flags = %04" PRIx16 "\n", free_entry->flags);
|
||||
}
|
||||
|
||||
void ng_ipv6_netif_remove(kernel_pid_t pid)
|
||||
|
||||
@ -95,6 +95,24 @@ static void test_netif_add__success_with_ipv6(void)
|
||||
TEST_ASSERT_EQUAL_STRING((char *)exp_addr.u8, (char *)entry->addrs[0].addr.u8);
|
||||
}
|
||||
|
||||
static void test_ipv6_netif_add__despite_free_entry(void)
|
||||
{
|
||||
/* Tests for possible duplicates as described in http://github.com/RIOT-OS/RIOT/issues/2965 */
|
||||
|
||||
ng_ipv6_netif_add(OTHER_TEST_NETIF);
|
||||
test_ipv6_netif_add__success(); /* adds DEFAULT_TEST_NETIF as interface */
|
||||
|
||||
/* create space by removing first entry */
|
||||
ng_ipv6_netif_remove(OTHER_TEST_NETIF);
|
||||
|
||||
/* add DEFAULT_TEST_NETIF yet again and remove it */
|
||||
test_ipv6_netif_add__success();
|
||||
ng_ipv6_netif_remove(DEFAULT_TEST_NETIF);
|
||||
|
||||
/* see if there's a duplicate left */
|
||||
TEST_ASSERT_NULL(ng_ipv6_netif_get(DEFAULT_TEST_NETIF));
|
||||
}
|
||||
|
||||
static void test_ipv6_netif_remove__not_allocated(void)
|
||||
{
|
||||
test_ipv6_netif_add__success(); /* adds DEFAULT_TEST_NETIF as interface */
|
||||
@ -169,6 +187,33 @@ static void test_ipv6_netif_add_addr__success(void)
|
||||
TEST_ASSERT_NOT_NULL(ng_ipv6_netif_add_addr(DEFAULT_TEST_NETIF, &addr, DEFAULT_TEST_PREFIX_LEN, 0));
|
||||
}
|
||||
|
||||
static void test_ipv6_netif_add_addr__despite_free_entry(void)
|
||||
{
|
||||
/* Tests for possible duplicates as described in http://github.com/RIOT-OS/RIOT/issues/2965 */
|
||||
ng_ipv6_addr_t *entry_1;
|
||||
ng_ipv6_addr_t *entry_2;
|
||||
|
||||
ng_ipv6_addr_t default_addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
ng_ipv6_addr_t ll_addr;
|
||||
|
||||
test_ipv6_netif_add__success(); /* adds DEFAULT_TEST_NETIF as interface */
|
||||
|
||||
/* add addresses to the interface */
|
||||
TEST_ASSERT_NOT_NULL((entry_1 = ng_ipv6_netif_add_addr(DEFAULT_TEST_NETIF, &default_addr, DEFAULT_TEST_PREFIX_LEN, 0)));
|
||||
|
||||
/* remove default_addr, but not the others (corresponding lla, solicited-node addr)
|
||||
* that came with it */
|
||||
ng_ipv6_netif_remove_addr(DEFAULT_TEST_NETIF, &default_addr);
|
||||
|
||||
/* create and re-add corresponding lla and check that it hasn't taken
|
||||
* the old place of default_addr*/
|
||||
ll_addr.u64[1] = default_addr.u64[1];
|
||||
ng_ipv6_addr_set_link_local_prefix(&ll_addr);
|
||||
TEST_ASSERT_NOT_NULL((entry_2 = ng_ipv6_netif_add_addr(DEFAULT_TEST_NETIF, &ll_addr, DEFAULT_TEST_PREFIX_LEN, 0)));
|
||||
|
||||
TEST_ASSERT(entry_1 != entry_2);
|
||||
}
|
||||
|
||||
static void test_ipv6_netif_remove_addr__not_allocated(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
@ -462,6 +507,7 @@ Test *tests_ipv6_netif_tests(void)
|
||||
EMB_UNIT_TESTFIXTURES(fixtures) {
|
||||
new_TestFixture(test_ipv6_netif_add__success),
|
||||
new_TestFixture(test_netif_add__success_with_ipv6),
|
||||
new_TestFixture(test_ipv6_netif_add__despite_free_entry),
|
||||
new_TestFixture(test_ipv6_netif_remove__not_allocated),
|
||||
new_TestFixture(test_ipv6_netif_remove__success),
|
||||
new_TestFixture(test_ipv6_netif_get__empty),
|
||||
@ -471,6 +517,7 @@ Test *tests_ipv6_netif_tests(void)
|
||||
new_TestFixture(test_ipv6_netif_add_addr__addr_unspecified),
|
||||
new_TestFixture(test_ipv6_netif_add_addr__full),
|
||||
new_TestFixture(test_ipv6_netif_add_addr__success),
|
||||
new_TestFixture(test_ipv6_netif_add_addr__despite_free_entry),
|
||||
new_TestFixture(test_ipv6_netif_remove_addr__not_allocated),
|
||||
new_TestFixture(test_ipv6_netif_remove_addr__success),
|
||||
new_TestFixture(test_ipv6_netif_reset_addr__success),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user