From c1f9b15c3ab84bde76700bee126c1278fc8b0ef4 Mon Sep 17 00:00:00 2001 From: Martine Lenders <m.lenders@fu-berlin.de> Date: Tue, 20 Jun 2017 15:20:00 +0200 Subject: [PATCH] tests: extend nib-internal unittests for off-link entry handling --- .../tests-gnrc_ipv6_nib/Makefile.include | 2 + .../tests-gnrc_ipv6_nib-internal.c | 783 +++++++++++++++++- 2 files changed, 784 insertions(+), 1 deletion(-) diff --git a/tests/unittests/tests-gnrc_ipv6_nib/Makefile.include b/tests/unittests/tests-gnrc_ipv6_nib/Makefile.include index ccae089522..269d2c903a 100644 --- a/tests/unittests/tests-gnrc_ipv6_nib/Makefile.include +++ b/tests/unittests/tests-gnrc_ipv6_nib/Makefile.include @@ -1,6 +1,8 @@ USEMODULE += gnrc_ipv6_nib +CFLAGS += -DGNRC_IPV6_NIB_CONF_ROUTER=1 CFLAGS += -DGNRC_IPV6_NIB_NUMOF=16 +CFLAGS += -DGNRC_IPV6_NIB_OFFL_NUMOF=25 CFLAGS += -DGNRC_IPV6_NIB_DEFAULT_ROUTER_NUMOF=4 INCLUDES += -I$(RIOTBASE)/sys/net/gnrc/network_layer/ipv6/nib diff --git a/tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-internal.c b/tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-internal.c index 2b9c7ebb7f..494acdb2c4 100644 --- a/tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-internal.c +++ b/tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-internal.c @@ -29,7 +29,8 @@ #define LINK_LOCAL_PREFIX { 0xfe, 0x08, 0, 0, 0, 0, 0, 0 } #define GLOBAL_PREFIX { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0 } -#define IFACE (26) +#define GLOBAL_PREFIX_LEN (30) +#define IFACE (6) static void set_up(void) { @@ -121,6 +122,23 @@ static void test_nib_alloc__success_duplicate(void) TEST_ASSERT(node == _nib_onl_alloc(&addr, iface)); } +/* + * Creates a persistent on-link entry with no IPv6 address and then tries to + * create another one with the same interface, but with an address + * Expected result: entries should be identical + */ +static void test_nib_alloc__success_noaddr_override(void) +{ + _nib_onl_entry_t *node1, *node2; + const ipv6_addr_t addr = { .u64 = { { .u8 = GLOBAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + + TEST_ASSERT_NOT_NULL((node1 = _nib_onl_alloc(NULL, IFACE))); + TEST_ASSERT_NOT_NULL((node2 = _nib_onl_alloc(&addr, IFACE))); + TEST_ASSERT(node1 == node2); + TEST_ASSERT(ipv6_addr_equal(&addr, &node1->ipv6)); +} + /* * Creates an non-persistent entry. * Expected result: new entry should contain the given address and interface @@ -964,6 +982,735 @@ static void test_nib_drl_get_dr__success4(void) TEST_ASSERT(nib_res != node2); } +#if GNRC_IPV6_NIB_NUMOF < GNRC_IPV6_NIB_OFFL_NUMOF +#define MAX_NUMOF (GNRC_IPV6_NIB_NUMOF) +#else /* GNRC_IPV6_NIB_NUMOF < GNRC_IPV6_NIB_OFFL_NUMOF */ +#define MAX_NUMOF (GNRC_IPV6_NIB_OFFL_NUMOF) +#endif + +/* + * Creates MAX_NUMOF off-link entries with different next-hop addresses and + * then tries to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_next_hop(void) +{ + ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + for (int i = 0; i < MAX_NUMOF; i++) { + _nib_offl_entry_t *dst; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _FT; + next_hop.u64[1].u64++; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, IFACE, &pfx, GLOBAL_PREFIX_LEN)); +} + +/* + * Creates MAX_NUMOF off-link entries with different interfaces and then tries + * to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_iface(void) +{ + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + unsigned iface = IFACE; + + for (int i = 0; i < MAX_NUMOF; i++) { + _nib_offl_entry_t *dst; + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, iface, &pfx, + GLOBAL_PREFIX_LEN))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _PL; + iface++; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, iface, &pfx, GLOBAL_PREFIX_LEN)); +} + +/* + * Creates MAX_NUMOF off-link entries with different next-hop addresses and + * interfaces and then tries to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_next_hop_iface(void) +{ + ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + unsigned iface = IFACE; + + for (int i = 0; i < MAX_NUMOF; i++) { + _nib_offl_entry_t *dst; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, iface, &pfx, + GLOBAL_PREFIX_LEN))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _DC; + next_hop.u64[1].u64++; + iface++; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, iface, &pfx, GLOBAL_PREFIX_LEN)); +} + +/* + * Creates GNRC_IPV6_NIB_OFFL_NUMOF off-link entries with different prefixes + * of the same length and then tries to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_pfx(void) +{ + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + for (int i = 0; i < GNRC_IPV6_NIB_OFFL_NUMOF; i++) { + _nib_offl_entry_t *dst; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _FT; + pfx.u16[0].u16++; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, IFACE, &pfx, GLOBAL_PREFIX_LEN)); +} + +/* + * Creates MAX_NUMOF off-link entries with different prefixes of the same + * length and different next-hop addresses and then tries to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_next_hop_pfx(void) +{ + ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + for (int i = 0; i < MAX_NUMOF; i++) { + _nib_offl_entry_t *dst; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _FT; + next_hop.u64[1].u64++; + pfx.u16[0].u16++; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, IFACE, &pfx, GLOBAL_PREFIX_LEN)); +} + +/* + * Creates MAX_NUMOF off-link entries with different prefixes of the same + * length and different interfaces and then tries to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_iface_pfx(void) +{ + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + unsigned iface = IFACE; + + for (int i = 0; i < MAX_NUMOF; i++) { + _nib_offl_entry_t *dst; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, iface, &pfx, + GLOBAL_PREFIX_LEN))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _FT; + iface++; + pfx.u16[0].u16++; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, iface, &pfx, GLOBAL_PREFIX_LEN)); +} + +/* + * Creates MAX_NUMOF off-link entries with different prefixes of the same + * length, different interfaces, and different next hop addresses and then + * tries to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_next_hop_iface_pfx(void) +{ + ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + unsigned iface = IFACE; + + for (int i = 0; i < MAX_NUMOF; i++) { + _nib_offl_entry_t *dst; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, iface, &pfx, + GLOBAL_PREFIX_LEN))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _FT; + next_hop.u64[1].u64++; + iface++; + pfx.u16[0].u16++; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, iface, &pfx, GLOBAL_PREFIX_LEN)); +} + +/* + * Creates GNRC_IPV6_NIB_OFFL_NUMOF off-link entries with different prefix + * lengths and then tries to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_pfx_len(void) +{ + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + unsigned pfx_len = GLOBAL_PREFIX_LEN; + + for (int i = 0; i < GNRC_IPV6_NIB_OFFL_NUMOF; i++) { + _nib_offl_entry_t *dst; + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, IFACE, &pfx, + pfx_len))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _PL; + pfx_len--; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, IFACE, &pfx, pfx_len)); +} + +/* + * Creates MAX_NUMOF off-link entries with different prefixes and then tries to + * add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_next_hop_pfx_len(void) +{ + ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + unsigned pfx_len = GLOBAL_PREFIX_LEN; + + for (int i = 0; i < MAX_NUMOF; i++) { + _nib_offl_entry_t *dst; + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, IFACE, &pfx, + pfx_len))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _PL; + next_hop.u64[1].u64++; + pfx_len--; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, IFACE, &pfx, pfx_len)); +} + +/* + * Creates MAX_NUMOF off-link entries with different prefix lengths and + * interfaces and then tries to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_iface_pfx_len(void) +{ + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + unsigned pfx_len = GLOBAL_PREFIX_LEN, iface = IFACE; + + for (int i = 0; i < MAX_NUMOF; i++) { + _nib_offl_entry_t *dst; + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, iface, &pfx, + pfx_len))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _PL; + iface++; + pfx_len--; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, iface, &pfx, pfx_len)); +} + +/* + * Creates MAX_NUMOF off-link entries with different prefix lengths, + * interfaces, and next hop addresses and then tries to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_next_hop_iface_pfx_len(void) +{ + ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + unsigned pfx_len = GLOBAL_PREFIX_LEN, iface = IFACE; + + for (int i = 0; i < MAX_NUMOF; i++) { + _nib_offl_entry_t *dst; + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, iface, &pfx, + pfx_len))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _PL; + next_hop.u64[1].u64++; + iface++; + pfx_len--; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, iface, &pfx, pfx_len)); +} + +/* + * Creates GNRC_IPV6_NIB_OFFL_NUMOF off-link entries with different prefixes + * and then tries to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_pfx_pfx_len(void) +{ + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + unsigned pfx_len = GLOBAL_PREFIX_LEN; + + for (int i = 0; i < GNRC_IPV6_NIB_OFFL_NUMOF; i++) { + _nib_offl_entry_t *dst; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, IFACE, &pfx, + pfx_len))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _FT; + pfx.u16[0].u16++; + pfx_len--; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, IFACE, &pfx, pfx_len)); +} + +/* + * Creates MAX_NUMOF off-link entries with different prefixes and different + * next-hop addresses and then tries to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_next_hop_pfx_pfx_len(void) +{ + ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + unsigned pfx_len = GLOBAL_PREFIX_LEN; + + for (int i = 0; i < MAX_NUMOF; i++) { + _nib_offl_entry_t *dst; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, IFACE, &pfx, + pfx_len))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _FT; + next_hop.u64[1].u64++; + pfx.u16[0].u16++; + pfx_len--; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, IFACE, &pfx, pfx_len)); +} + +/* + * Creates MAX_NUMOF off-link entries with different prefixes and different + * interfaces and then tries to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_iface_pfx_pfx_len(void) +{ + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + unsigned pfx_len = GLOBAL_PREFIX_LEN, iface = IFACE; + + for (int i = 0; i < MAX_NUMOF; i++) { + _nib_offl_entry_t *dst; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, iface, &pfx, + pfx_len))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _FT; + iface++; + pfx.u16[0].u16++; + pfx_len--; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, iface, &pfx, pfx_len)); +} + +/* + * Creates MAX_NUMOF off-link entries with different prefixes, different + * interfaces, and different next hop addresses and then tries to add another. + * Expected result: should return NULL + */ +static void test_nib_offl_alloc__no_space_left_diff_next_hop_iface_pfx_pfx_len(void) +{ + ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + unsigned pfx_len = GLOBAL_PREFIX_LEN, iface = IFACE; + + for (int i = 0; i < MAX_NUMOF; i++) { + _nib_offl_entry_t *dst; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, iface, &pfx, + pfx_len))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _FT; + next_hop.u64[1].u64++; + iface++; + pfx.u16[0].u16++; + pfx_len--; + } + TEST_ASSERT_NULL(_nib_offl_alloc(&next_hop, iface, &pfx, pfx_len)); +} + +/* + * Creates MAX_NUMOF off-link entries with different prefixes, different + * interfaces, and different next hop addresses and then tries to add another + * equal to the last. + * Expected result: should return not NULL (the last) + */ +static void test_nib_offl_alloc__success_duplicate(void) +{ + ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + unsigned pfx_len = GLOBAL_PREFIX_LEN, iface = IFACE; + + for (int i = 0; i < MAX_NUMOF; i++) { + _nib_offl_entry_t *dst; + + next_hop.u64[1].u64++; + iface++; + pfx.u16[0].u16++; + pfx_len--; + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, iface, &pfx, + pfx_len))); + TEST_ASSERT_NOT_NULL(dst->next_hop); + dst->mode |= _FT; + } + TEST_ASSERT_NOT_NULL(_nib_offl_alloc(&next_hop, iface, &pfx, pfx_len)); +} + +/* + * Creates an off-link entry with no next hop address and then adds another + * with equal prefix and interface to the last, but with a next hop address + * Expected result: the first entry should be equal to the second and both + * have the same next hop address + */ +static void test_nib_offl_alloc__success_overwrite_unspecified(void) +{ + _nib_offl_entry_t *dst1, *dst2; + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + TEST_ASSERT_NOT_NULL((dst1 = _nib_offl_alloc(NULL, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + dst1->mode |= _PL; + TEST_ASSERT_NOT_NULL((dst2 = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + TEST_ASSERT_NOT_NULL(dst1->next_hop); + TEST_ASSERT_EQUAL_INT(_PL, dst1->mode); + TEST_ASSERT(dst1 == dst2); + TEST_ASSERT(ipv6_addr_equal(&next_hop, &dst1->next_hop->ipv6)); +} + +/* + * Creates an off-link entry. + * Expected result: new entry should contain the given prefix, address and + * interface + */ +static void test_nib_offl_alloc__success(void) +{ + _nib_offl_entry_t *dst; + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + TEST_ASSERT_EQUAL_INT(GLOBAL_PREFIX_LEN, dst->pfx_len); + TEST_ASSERT(GLOBAL_PREFIX_LEN <= ipv6_addr_match_prefix(&pfx, &dst->pfx)); + TEST_ASSERT_NOT_NULL(dst->next_hop); + TEST_ASSERT_EQUAL_INT(_DST, dst->next_hop->mode); + TEST_ASSERT(ipv6_addr_equal(&next_hop, &dst->next_hop->ipv6)); + TEST_ASSERT_EQUAL_INT(IFACE, _nib_onl_get_if(dst->next_hop)); +} + +/* + * Creates an off-link entry, sets a neighbor cache flag, and tries to remove + * it. + * Expected result: The off-link entry is removed, but the on-link entry should + * still exist + */ +static void test_nib_offl_clear__uncleared(void) +{ + _nib_offl_entry_t *dst; + _nib_onl_entry_t *node; + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + node = dst->next_hop; + node->mode |= _NC; + _nib_offl_clear(dst); + TEST_ASSERT_NULL(_nib_offl_iter(NULL)); + TEST_ASSERT(node == _nib_onl_iter(NULL)); +} + +/* + * Creates two off-link entry off-link entries and tries to remove one of them. + * Expected result: The NIB should only contain the one removed, the on-link + * entry should still exist + */ +static void test_nib_offl_clear__same_next_hop(void) +{ + _nib_offl_entry_t *dst1, *dst2, *res; + _nib_onl_entry_t *node; + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + TEST_ASSERT_NOT_NULL((dst1 = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + dst1->mode |= _FT; + pfx.u16[0].u16++; + TEST_ASSERT_NOT_NULL((dst2 = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + TEST_ASSERT(dst1->next_hop == dst2->next_hop); + node = dst2->next_hop; + TEST_ASSERT_NOT_NULL(node); + _nib_offl_clear(dst2); + TEST_ASSERT_NOT_NULL((res = _nib_offl_iter(NULL))); + TEST_ASSERT(dst1 == res); + TEST_ASSERT_NULL(_nib_offl_iter(res)); + TEST_ASSERT(node == _nib_onl_iter(NULL)); +} + +/* + * Creates an off-link entry and tries to remove it. + * Expected result: The NIB should be empty + */ +static void test_nib_offl_clear__cleared(void) +{ + _nib_offl_entry_t *dst; + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + _nib_offl_clear(dst); + TEST_ASSERT_NULL(_nib_offl_iter(NULL)); + TEST_ASSERT_NULL(_nib_onl_iter(NULL)); +} + +/* + * Iterates over empty off-link entries + * Expected result: _nib_drl_iter returns NULL + */ +static void test_nib_offl_iter__empty(void) +{ + TEST_ASSERT_NULL(_nib_offl_iter(NULL)); +} + +/* + * Iterates over off-link entries with one element + * Expected result: _nib_offl_iter returns element with NULL, and with that + * element NULL. + */ +static void test_nib_offl_iter__one_elem(void) +{ + _nib_offl_entry_t *dst, *res; + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + TEST_ASSERT_NOT_NULL((dst = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + dst->mode |= _FT; + TEST_ASSERT_NOT_NULL((res = _nib_offl_iter(NULL))); + TEST_ASSERT(res == dst); + TEST_ASSERT_NULL(_nib_offl_iter(res)); +} + +/* + * Iterates over off-link entries with three element + * Expected result: _nib_offl_iter returns element with NULL, with that element + * another, with that element yet another and with the last NULL. + */ +static void test_nib_offl_iter__three_elem(void) +{ + _nib_offl_entry_t *dst1, *dst2, *dst3, *res; + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + TEST_ASSERT_NOT_NULL((dst1 = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + dst1->mode |= _FT; + pfx.u16[0].u16++; + TEST_ASSERT_NOT_NULL((dst2 = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + dst2->mode |= _FT; + pfx.u16[0].u16++; + TEST_ASSERT_NOT_NULL((dst3 = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + dst3->mode |= _FT; + TEST_ASSERT_NOT_NULL((res = _nib_offl_iter(NULL))); + TEST_ASSERT(res == dst1); + TEST_ASSERT_NOT_NULL((res = _nib_offl_iter(res))); + TEST_ASSERT(res == dst2); + TEST_ASSERT_NOT_NULL((res = _nib_offl_iter(res))); + TEST_ASSERT(res == dst3); + TEST_ASSERT_NULL(_nib_offl_iter(res)); +} + +/* + * Iterates over off-link entries with two elements, where there is a whole in + * the internal array + * Expected result: _nib_offl_iter returns element with NULL, with that element + * another, and with the last NULL. + */ +static void test_nib_offl_iter__three_elem_middle_removed(void) +{ + _nib_offl_entry_t *dst1, *dst2, *dst3, *res; + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + TEST_ASSERT_NOT_NULL((dst1 = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + dst1->mode |= _FT; + pfx.u16[0].u16++; + TEST_ASSERT_NOT_NULL((dst2 = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + dst2->mode |= _FT; + pfx.u16[0].u16++; + TEST_ASSERT_NOT_NULL((dst3 = _nib_offl_alloc(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + dst3->mode |= _FT; + dst2->mode = _EMPTY; + _nib_offl_clear(dst2); + TEST_ASSERT_NOT_NULL((res = _nib_offl_iter(NULL))); + TEST_ASSERT(res == dst1); + TEST_ASSERT_NOT_NULL((res = _nib_offl_iter(res))); + TEST_ASSERT(res == dst3); + TEST_ASSERT_NULL(_nib_offl_iter(res)); +} + +#if GNRC_IPV6_NIB_CONF_DC +/* + * Creates a destination cache entry. + * Expected result: new entry should contain the given address and interface + */ +static void test_nib_dc_add__success(void) +{ + _nib_offl_entry_t *dst; + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t dst_addr = { .u64 = { { .u8 = GLOBAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + + TEST_ASSERT_NOT_NULL((dst = _nib_dc_add(&next_hop, IFACE, &dst_addr))); + TEST_ASSERT(dst->mode & _DC); + TEST_ASSERT_EQUAL_INT(IPV6_ADDR_BIT_LEN, dst->pfx_len); + TEST_ASSERT(ipv6_addr_equal(&dst_addr, &dst->pfx)); + TEST_ASSERT_NOT_NULL(dst->next_hop); + TEST_ASSERT_EQUAL_INT(_DST, dst->next_hop->mode); + TEST_ASSERT(ipv6_addr_equal(&next_hop, &dst->next_hop->ipv6)); + TEST_ASSERT_EQUAL_INT(IFACE, _nib_onl_get_if(dst->next_hop)); +} + +/* + * Creates a destination cache entry and removes it. + * Expected result: The destination cache should be empty + */ +static void test_nib_dc_remove(void) +{ + + _nib_offl_entry_t *dst; + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t dst_addr = { .u64 = { { .u8 = GLOBAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + + TEST_ASSERT_NOT_NULL((dst = _nib_dc_add(&next_hop, IFACE, &dst_addr))); + _nib_dc_remove(dst); + TEST_ASSERT_NULL(_nib_offl_iter(NULL)); +} +#endif + +/* + * Creates a prefix list entry. + * Expected result: new entry should contain the given address and interface + */ +static void test_nib_pl_add__success(void) +{ + _nib_offl_entry_t *dst; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + TEST_ASSERT_NOT_NULL((dst = _nib_pl_add(IFACE, &pfx, GLOBAL_PREFIX_LEN))); + TEST_ASSERT(dst->mode & _PL); + TEST_ASSERT_EQUAL_INT(GLOBAL_PREFIX_LEN, dst->pfx_len); + TEST_ASSERT(GLOBAL_PREFIX_LEN <= ipv6_addr_match_prefix(&pfx, &dst->pfx)); + TEST_ASSERT_NOT_NULL(dst->next_hop); + TEST_ASSERT_EQUAL_INT(_DST, dst->next_hop->mode); + TEST_ASSERT_EQUAL_INT(IFACE, _nib_onl_get_if(dst->next_hop)); +} + +/* + * Creates a prefix list entry and removes it. + * Expected result: The prefix list should be empty + */ +static void test_nib_pl_remove(void) +{ + + _nib_offl_entry_t *dst; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + TEST_ASSERT_NOT_NULL((dst = _nib_pl_add(IFACE, &pfx, GLOBAL_PREFIX_LEN))); + _nib_pl_remove(dst); + TEST_ASSERT_NULL(_nib_offl_iter(NULL)); +} + +/* + * Creates a forwarding table entry. + * Expected result: new entry should contain the given address and interface + */ +static void test_nib_ft_add__success(void) +{ + _nib_offl_entry_t *dst; + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + TEST_ASSERT_NOT_NULL((dst = _nib_ft_add(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + TEST_ASSERT(dst->mode & _FT); + TEST_ASSERT_EQUAL_INT(GLOBAL_PREFIX_LEN, dst->pfx_len); + TEST_ASSERT(GLOBAL_PREFIX_LEN <= ipv6_addr_match_prefix(&pfx, &dst->pfx)); + TEST_ASSERT_NOT_NULL(dst->next_hop); + TEST_ASSERT_EQUAL_INT(_DST, dst->next_hop->mode); + TEST_ASSERT(ipv6_addr_equal(&next_hop, &dst->next_hop->ipv6)); + TEST_ASSERT_EQUAL_INT(IFACE, _nib_onl_get_if(dst->next_hop)); +} + +/* + * Creates a forwarding table entry and removes it. + * Expected result: The forwarding table should be empty + */ +static void test_nib_ft_remove(void) +{ + + _nib_offl_entry_t *dst; + static const ipv6_addr_t next_hop = { .u64 = { { .u8 = LINK_LOCAL_PREFIX }, + { .u64 = TEST_UINT64 } } }; + static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } }; + + TEST_ASSERT_NOT_NULL((dst = _nib_ft_add(&next_hop, IFACE, &pfx, + GLOBAL_PREFIX_LEN))); + _nib_ft_remove(dst); + TEST_ASSERT_NULL(_nib_offl_iter(NULL)); +} + /* * Creates GNRC_NETIF_NUMOF interfaces and then tries to add another. * Expected result: should return NULL @@ -998,6 +1745,7 @@ Test *tests_gnrc_ipv6_nib_internal_tests(void) new_TestFixture(test_nib_alloc__no_space_left_diff_iface), new_TestFixture(test_nib_alloc__no_space_left_diff_addr_iface), new_TestFixture(test_nib_alloc__success_duplicate), + new_TestFixture(test_nib_alloc__success_noaddr_override), new_TestFixture(test_nib_alloc__success), new_TestFixture(test_nib_clear__persistent), new_TestFixture(test_nib_clear__non_persistent_but_content), @@ -1041,6 +1789,39 @@ Test *tests_gnrc_ipv6_nib_internal_tests(void) new_TestFixture(test_nib_drl_get_dr__success2), new_TestFixture(test_nib_drl_get_dr__success3), new_TestFixture(test_nib_drl_get_dr__success4), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_next_hop), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_iface), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_next_hop_iface), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_pfx), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_next_hop_pfx), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_iface_pfx), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_next_hop_iface_pfx), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_pfx_len), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_next_hop_pfx_len), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_iface_pfx_len), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_next_hop_iface_pfx_len), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_pfx_pfx_len), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_next_hop_pfx_pfx_len), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_iface_pfx_pfx_len), + new_TestFixture(test_nib_offl_alloc__no_space_left_diff_next_hop_iface_pfx_pfx_len), + new_TestFixture(test_nib_offl_alloc__success_duplicate), + new_TestFixture(test_nib_offl_alloc__success_overwrite_unspecified), + new_TestFixture(test_nib_offl_alloc__success), + new_TestFixture(test_nib_offl_clear__uncleared), + new_TestFixture(test_nib_offl_clear__same_next_hop), + new_TestFixture(test_nib_offl_clear__cleared), + new_TestFixture(test_nib_offl_iter__empty), + new_TestFixture(test_nib_offl_iter__one_elem), + new_TestFixture(test_nib_offl_iter__three_elem), + new_TestFixture(test_nib_offl_iter__three_elem_middle_removed), +#if GNRC_IPV6_NIB_CONF_DC + new_TestFixture(test_nib_dc_add__success), + new_TestFixture(test_nib_dc_remove), +#endif + new_TestFixture(test_nib_pl_add__success), + new_TestFixture(test_nib_pl_remove), + new_TestFixture(test_nib_ft_add__success), + new_TestFixture(test_nib_ft_remove), new_TestFixture(test_nib_iface_get__no_space_left), new_TestFixture(test_nib_iface_get__success), }; -- GitLab