mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-16 18:13:49 +01:00
Merge pull request #20371 from xnumad/nib-next-hop-addr
gnrc_ipv6_nib: Force unspecified next hop addresses
This commit is contained in:
commit
73e90c5049
@ -84,8 +84,11 @@ void _nib_release(void)
|
|||||||
static inline bool _addr_equals(const ipv6_addr_t *addr,
|
static inline bool _addr_equals(const ipv6_addr_t *addr,
|
||||||
const _nib_onl_entry_t *node)
|
const _nib_onl_entry_t *node)
|
||||||
{
|
{
|
||||||
return (addr == NULL) || ipv6_addr_is_unspecified(&node->ipv6) ||
|
if (addr == NULL) {
|
||||||
(ipv6_addr_equal(addr, &node->ipv6));
|
return ipv6_addr_is_unspecified(&node->ipv6);
|
||||||
|
} else {
|
||||||
|
return ipv6_addr_equal(addr, &node->ipv6);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_nib_onl_entry_t *_nib_onl_alloc(const ipv6_addr_t *addr, unsigned iface)
|
_nib_onl_entry_t *_nib_onl_alloc(const ipv6_addr_t *addr, unsigned iface)
|
||||||
@ -501,28 +504,34 @@ _nib_offl_entry_t *_nib_offl_alloc(const ipv6_addr_t *next_hop, unsigned iface,
|
|||||||
_nib_offl_entry_t *tmp = &_dsts[i];
|
_nib_offl_entry_t *tmp = &_dsts[i];
|
||||||
_nib_onl_entry_t *tmp_node = tmp->next_hop;
|
_nib_onl_entry_t *tmp_node = tmp->next_hop;
|
||||||
|
|
||||||
if ((tmp->pfx_len == pfx_len) && /* prefix length matches and */
|
if (tmp->mode == _EMPTY) {
|
||||||
(tmp_node != NULL) && /* there is a next hop that */
|
if (dst == NULL) {
|
||||||
(_nib_onl_get_if(tmp_node) == iface) && /* has a matching interface and */
|
dst = tmp;
|
||||||
_addr_equals(next_hop, tmp_node) && /* equal address to next_hop, also */
|
|
||||||
(ipv6_addr_match_prefix(&tmp->pfx, pfx) >= pfx_len)) { /* the prefix matches */
|
|
||||||
/* exact match (or next hop address was previously unset) */
|
|
||||||
DEBUG(" %p is an exact match\n", (void *)tmp);
|
|
||||||
if (next_hop != NULL) {
|
|
||||||
memcpy(&tmp_node->ipv6, next_hop, sizeof(tmp_node->ipv6));
|
|
||||||
}
|
}
|
||||||
tmp->next_hop->mode |= _DST;
|
continue;
|
||||||
return tmp;
|
|
||||||
}
|
}
|
||||||
if ((dst == NULL) && (tmp_node == NULL)) {
|
|
||||||
dst = tmp;
|
/* else: offlink entry not empty, potential match */
|
||||||
|
if (tmp->pfx_len == pfx_len && ipv6_addr_match_prefix(&tmp->pfx, pfx) >= pfx_len) {
|
||||||
|
/* prefix matches */
|
||||||
|
assert(tmp_node);
|
||||||
|
if (_nib_onl_get_if(tmp_node) == iface && (ipv6_addr_is_unspecified(&tmp_node->ipv6)
|
||||||
|
|| _addr_equals(next_hop, tmp_node))) {
|
||||||
|
/* next hop matches or is unspecified */
|
||||||
|
DEBUG(" %p is an exact match\n", (void *)tmp);
|
||||||
|
if (next_hop != NULL) {
|
||||||
|
/* sets next_hop if it was previously unspecified */
|
||||||
|
memcpy(&tmp_node->ipv6, next_hop, sizeof(tmp_node->ipv6));
|
||||||
|
}
|
||||||
|
/*mark that this NCE is used by an offl_entry*/
|
||||||
|
tmp->next_hop->mode |= _DST;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (dst != NULL) {
|
if (dst != NULL) {
|
||||||
DEBUG(" using %p\n", (void *)dst);
|
DEBUG(" using %p\n", (void *)dst);
|
||||||
dst->next_hop = _nib_onl_alloc(next_hop, iface);
|
if (!dst->next_hop && !(dst->next_hop = _nib_onl_alloc(next_hop, iface))) {
|
||||||
|
|
||||||
if (dst->next_hop == NULL) {
|
|
||||||
memset(dst, 0, sizeof(_nib_offl_entry_t));
|
memset(dst, 0, sizeof(_nib_offl_entry_t));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1449,6 +1449,60 @@ static void test_nib_offl_alloc__success_overwrite_unspecified(void)
|
|||||||
TEST_ASSERT(ipv6_addr_equal(&next_hop, &dst1->next_hop->ipv6));
|
TEST_ASSERT(ipv6_addr_equal(&next_hop, &dst1->next_hop->ipv6));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates an off-link entry (to a next hop) and an on-link entry on the same interface.
|
||||||
|
* Then proceeds to delete the off-link entries to this next hop
|
||||||
|
* by only comparing the next hop, not checking the _PFX_ON_LINK flag.
|
||||||
|
*
|
||||||
|
* Expected results: Only off-link entries are deleted.
|
||||||
|
* On-link entries on the same interface are unaffected by the deletion.
|
||||||
|
*/
|
||||||
|
static void test_nib_offl_alloc__next_hop_indicates_whether_onl(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 } } };
|
||||||
|
|
||||||
|
/*are in practice different prefixes actually*/
|
||||||
|
static const ipv6_addr_t *onl_pfx = &pfx;
|
||||||
|
static const ipv6_addr_t *offl_pfx = &pfx;
|
||||||
|
|
||||||
|
/* Add off-link entry */
|
||||||
|
_nib_offl_entry_t *dst1;
|
||||||
|
TEST_ASSERT_NOT_NULL((dst1 = _nib_ft_add(&next_hop, IFACE, offl_pfx, GLOBAL_PREFIX_LEN)));
|
||||||
|
|
||||||
|
/* Add on-link entry */
|
||||||
|
const unsigned pfx_len = GLOBAL_PREFIX_LEN; /* arbitrary */
|
||||||
|
|
||||||
|
/* (calls _nib_offl_alloc) */
|
||||||
|
_nib_offl_entry_t *dst;
|
||||||
|
TEST_ASSERT_NOT_NULL((dst = _nib_pl_add(IFACE, onl_pfx, pfx_len, UINT32_MAX, UINT32_MAX)));
|
||||||
|
TEST_ASSERT(ipv6_addr_is_unspecified(&dst->next_hop->ipv6));
|
||||||
|
/* would normally be set by PIO flags in Router Advertisement */
|
||||||
|
dst->flags |= _PFX_ON_LINK;
|
||||||
|
|
||||||
|
/* Delete all off-link entries to next_hop */
|
||||||
|
_nib_offl_entry_t *route = NULL;
|
||||||
|
while ((route = _nib_offl_iter(route))) {
|
||||||
|
if ((_nib_onl_get_if(route->next_hop) == IFACE) &&
|
||||||
|
(route->next_hop != NULL) &&
|
||||||
|
ipv6_addr_equal(&route->next_hop->ipv6, &next_hop) /*off-link, to this next hop*/
|
||||||
|
/*should not need to be checked for when next hop is already checked:*/
|
||||||
|
/*&& !(route->flags & _PFX_ON_LINK)*/
|
||||||
|
) {
|
||||||
|
_nib_ft_remove(route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Expected result: On-link entries remain unaffected */
|
||||||
|
gnrc_ipv6_nib_pl_t prefix;
|
||||||
|
void *state = NULL;
|
||||||
|
TEST_ASSERT_MESSAGE(gnrc_ipv6_nib_pl_iter(IFACE, &state, &prefix),
|
||||||
|
"No prefix list entry found");
|
||||||
|
TEST_ASSERT_MESSAGE(ipv6_addr_match_prefix(onl_pfx, &prefix.pfx) >= pfx_len,
|
||||||
|
"Unexpected prefix configured");
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creates an off-link entry.
|
* Creates an off-link entry.
|
||||||
* Expected result: new entry should contain the given prefix, address and
|
* Expected result: new entry should contain the given prefix, address and
|
||||||
@ -2069,6 +2123,7 @@ Test *tests_gnrc_ipv6_nib_internal_tests(void)
|
|||||||
new_TestFixture(test_nib_offl_alloc__no_space_left_diff_next_hop_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_duplicate),
|
||||||
new_TestFixture(test_nib_offl_alloc__success_overwrite_unspecified),
|
new_TestFixture(test_nib_offl_alloc__success_overwrite_unspecified),
|
||||||
|
new_TestFixture(test_nib_offl_alloc__next_hop_indicates_whether_onl),
|
||||||
new_TestFixture(test_nib_offl_alloc__success),
|
new_TestFixture(test_nib_offl_alloc__success),
|
||||||
new_TestFixture(test_nib_offl_clear__uncleared),
|
new_TestFixture(test_nib_offl_clear__uncleared),
|
||||||
new_TestFixture(test_nib_offl_clear__same_next_hop),
|
new_TestFixture(test_nib_offl_clear__same_next_hop),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user