From 09a67e050d8d50db6dca07b7f5e9f27a78ec8bea Mon Sep 17 00:00:00 2001 From: Lotte Steenbrink Date: Thu, 14 May 2015 07:54:42 -0700 Subject: [PATCH] ipv6_nc: no more duplicates if empty entries are found before --- sys/net/network_layer/ng_ipv6/nc/ng_ipv6_nc.c | 56 +++++++++++-------- tests/unittests/tests-ipv6_nc/tests-ipv6_nc.c | 22 ++++++++ 2 files changed, 54 insertions(+), 24 deletions(-) diff --git a/sys/net/network_layer/ng_ipv6/nc/ng_ipv6_nc.c b/sys/net/network_layer/ng_ipv6/nc/ng_ipv6_nc.c index 40dbf194df..9f7cbe756d 100644 --- a/sys/net/network_layer/ng_ipv6/nc/ng_ipv6_nc.c +++ b/sys/net/network_layer/ng_ipv6/nc/ng_ipv6_nc.c @@ -46,6 +46,8 @@ ng_ipv6_nc_t *_find_free_entry(void) ng_ipv6_nc_t *ng_ipv6_nc_add(kernel_pid_t iface, const ng_ipv6_addr_t *ipv6_addr, const void *l2_addr, size_t l2_addr_len, uint8_t flags) { + ng_ipv6_nc_t *free_entry = NULL; + if (ipv6_addr == NULL) { DEBUG("ipv6_nc: address was NULL\n"); return NULL; @@ -75,34 +77,40 @@ ng_ipv6_nc_t *ng_ipv6_nc_add(kernel_pid_t iface, const ng_ipv6_addr_t *ipv6_addr return &ncache[i]; } - if (ng_ipv6_addr_is_unspecified(&(ncache[i].ipv6_addr))) { - ncache[i].iface = iface; - - ng_pktqueue_init(&(ncache[i].pkts)); - memcpy(&(ncache[i].ipv6_addr), ipv6_addr, sizeof(ng_ipv6_addr_t)); - DEBUG("ipv6_nc: Register %s for interface %" PRIkernel_pid, - ng_ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)), - iface); - - if ((l2_addr != NULL) && (l2_addr_len > 0)) { - DEBUG(" to L2 address %s", - ng_netif_addr_to_str(addr_str, sizeof(addr_str), - l2_addr, l2_addr_len)); - memcpy(&(ncache[i].l2_addr), l2_addr, l2_addr_len); - ncache[i].l2_addr_len = l2_addr_len; - } - - ncache[i].flags = flags; - - DEBUG(" with flags = 0x%0x\n", flags); - - return &ncache[i]; + if (ng_ipv6_addr_is_unspecified(&(ncache[i].ipv6_addr)) && !free_entry) { + /* found the first free entry */ + free_entry = &ncache[i]; } } - DEBUG("ipv6_nc: neighbor cache full.\n"); + if (!free_entry) { + /* reached end of NC without finding updateable or free entry */ + DEBUG("ipv6_nc: neighbor cache full.\n"); + return NULL; + } - return NULL; + /* Otherwise, fill free entry with your fresh information */ + free_entry->iface = iface; + + ng_pktqueue_init(&(free_entry->pkts)); + memcpy(&(free_entry->ipv6_addr), ipv6_addr, sizeof(ng_ipv6_addr_t)); + DEBUG("ipv6_nc: Register %s for interface %" PRIkernel_pid, + ng_ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)), + iface); + + if ((l2_addr != NULL) && (l2_addr_len > 0)) { + DEBUG(" to L2 address %s", + ng_netif_addr_to_str(addr_str, sizeof(addr_str), + l2_addr, l2_addr_len)); + memcpy(&(free_entry->l2_addr), l2_addr, l2_addr_len); + free_entry->l2_addr_len = l2_addr_len; + } + + free_entry->flags = flags; + + DEBUG(" with flags = 0x%0x\n", flags); + + return free_entry; } void ng_ipv6_nc_remove(kernel_pid_t iface, const ng_ipv6_addr_t *ipv6_addr) diff --git a/tests/unittests/tests-ipv6_nc/tests-ipv6_nc.c b/tests/unittests/tests-ipv6_nc/tests-ipv6_nc.c index e4f0d289c1..bc8ef3be17 100644 --- a/tests/unittests/tests-ipv6_nc/tests-ipv6_nc.c +++ b/tests/unittests/tests-ipv6_nc/tests-ipv6_nc.c @@ -123,6 +123,27 @@ static void test_ipv6_nc_add__success(void) TEST_ASSERT(entry1 == entry2); } +static void test_ipv6_nc_add__address_update_despite_free_entry(void) +{ + ng_ipv6_addr_t default_addr = DEFAULT_TEST_IPV6_ADDR; + ng_ipv6_addr_t other_addr = OTHER_TEST_IPV6_ADDR; + ng_ipv6_nc_t *entry1, *entry2; + + TEST_ASSERT_NOT_NULL(ng_ipv6_nc_add(OTHER_TEST_NETIF, &other_addr, + TEST_STRING4, sizeof(TEST_STRING4), + 0)); + TEST_ASSERT_NOT_NULL((entry1 = ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &default_addr, + TEST_STRING4, sizeof(TEST_STRING4), + 0))); + + /* create space by removing first entry and see if duplicate is still detected & updated */ + ng_ipv6_nc_remove(OTHER_TEST_NETIF, &other_addr); + TEST_ASSERT_NOT_NULL((entry2 = ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &default_addr, + TEST_STRING4, sizeof(TEST_STRING4), + 0))); + TEST_ASSERT(entry1 == entry2); +} + static void test_ipv6_nc_remove__no_entry_pid(void) { ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR; @@ -371,6 +392,7 @@ Test *tests_ipv6_nc_tests(void) new_TestFixture(test_ipv6_nc_add__l2addr_too_long), new_TestFixture(test_ipv6_nc_add__full), new_TestFixture(test_ipv6_nc_add__success), + new_TestFixture(test_ipv6_nc_add__address_update_despite_free_entry), new_TestFixture(test_ipv6_nc_remove__no_entry_pid), new_TestFixture(test_ipv6_nc_remove__no_entry_addr1), new_TestFixture(test_ipv6_nc_remove__no_entry_addr2),