1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #7270 from miri64/gnrc_ipv6_nib/feat/abr-component

gnrc_ipv6_nib: provide component to handle ABRO
This commit is contained in:
Cenk Gündoğan 2017-10-06 22:16:17 +02:00 committed by GitHub
commit 7af0f916fe
11 changed files with 667 additions and 5 deletions

View File

@ -22,6 +22,7 @@
#ifndef NET_GNRC_IPV6_NIB_H
#define NET_GNRC_IPV6_NIB_H
#include "net/gnrc/ipv6/nib/abr.h"
#include "net/gnrc/ipv6/nib/nc.h"
#include "net/gnrc/ipv6/nib/pl.h"

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_gnrc_ipv6_nib_abr Authoritative border router list
* @ingroup net_gnrc_ipv6_nib
* @brief Authoritative border router list component of neighbor
* information base
* @{
*
* @file
* @brief Authoritative border router list definitions
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NET_GNRC_IPV6_NIB_ABR_H
#define NET_GNRC_IPV6_NIB_ABR_H
#include "net/ipv6/addr.h"
#include "net/gnrc/ipv6/nib/conf.h"
#ifdef __cplusplus
extern "C" {
#endif
#if (GNRC_IPV6_NIB_CONF_6LBR && GNRC_IPV6_NIB_CONF_MULTIHOP_P6C) || defined(DOXYGEN)
/**
* @brief Adds the address of an authoritative border router to the NIB
*
* @param[in] addr The address of an authoritative border router.
*
* @return 0 on success.
* @return -ENOMEM, if no space is left in the neighbor cache.
*/
int gnrc_ipv6_nib_abr_add(const ipv6_addr_t *addr);
/**
* @brief Removes an authoritative border router from the NIB
*
* @param[in] addr The address of an authoritative border router.
*/
void gnrc_ipv6_nib_abr_del(const ipv6_addr_t *addr);
#endif /* (GNRC_IPV6_NIB_CONF_6LBR && GNRC_IPV6_NIB_CONF_MULTIHOP_P6C) || defined(DOXYGEN) */
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_IPV6_NIB_ABR_H */
/** @} */

View File

@ -194,6 +194,15 @@ extern "C" {
#define GNRC_IPV6_NIB_OFFL_NUMOF (8)
#endif
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C || defined(DOXYGEN)
/**
* @brief Number of authoritative border router entries in NIB
*/
#ifndef GNRC_IPV6_NIB_ABR_NUMOF
#define GNRC_IPV6_NIB_ABR_NUMOF (1)
#endif
#endif
#ifdef __cplusplus
}
#endif

View File

@ -37,6 +37,10 @@ static _nib_offl_entry_t _dsts[GNRC_IPV6_NIB_OFFL_NUMOF];
static _nib_dr_entry_t _def_routers[GNRC_IPV6_NIB_DEFAULT_ROUTER_NUMOF];
static _nib_iface_t _nis[GNRC_NETIF_NUMOF];
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
static _nib_abr_entry_t _abrs[GNRC_IPV6_NIB_ABR_NUMOF];
#endif
#if ENABLE_DEBUG
static char addr_str[IPV6_ADDR_MAX_STR_LEN];
#endif
@ -57,6 +61,9 @@ void _nib_init(void)
memset(_def_routers, 0, sizeof(_def_routers));
memset(_dsts, 0, sizeof(_dsts));
memset(_nis, 0, sizeof(_nis));
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
memset(_abrs, 0, sizeof(_abrs));
#endif
#endif
evtimer_init_msg(&_nib_evtimer);
/* TODO: load ABR information from persistent memory */
@ -450,6 +457,13 @@ static inline bool _in_dsts(const _nib_offl_entry_t *dst)
return (dst < (_dsts + GNRC_IPV6_NIB_OFFL_NUMOF));
}
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
static inline bool _in_abrs(const _nib_abr_entry_t *abr)
{
return (abr < (_abrs + GNRC_IPV6_NIB_ABR_NUMOF));
}
#endif
void _nib_offl_clear(_nib_offl_entry_t *dst)
{
if (dst->next_hop != NULL) {
@ -483,6 +497,131 @@ _nib_offl_entry_t *_nib_offl_iter(const _nib_offl_entry_t *last)
return NULL;
}
void _nib_pl_remove(_nib_offl_entry_t *nib_offl)
{
_nib_offl_remove(nib_offl, _PL);
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
unsigned idx = nib_offl - _dsts;
if (idx < GNRC_IPV6_NIB_OFFL_NUMOF) {
for (_nib_abr_entry_t *abr = _abrs; _in_abrs(abr); abr++) {
if (bf_isset(abr->pfxs, idx)) {
DEBUG("nib: Removing prefix %s/%u ",
ipv6_addr_to_str(addr_str, &nib_offl->pfx,
sizeof(addr_str)),
nib_offl->pfx_len);
DEBUG("from border router %s\n",
ipv6_addr_to_str(addr_str, &abr->addr, sizeof(addr_str)));
bf_unset(abr->pfxs, idx);
}
}
}
#endif
}
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
_nib_abr_entry_t *_nib_abr_add(const ipv6_addr_t *addr)
{
_nib_abr_entry_t *abr = NULL;
assert(addr != NULL);
DEBUG("nib: Allocating authoritative border router entry (addr = %s)\n",
ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)));
for (unsigned i = 0; i < GNRC_IPV6_NIB_ABR_NUMOF; i++) {
_nib_abr_entry_t *tmp = &_abrs[i];
if (ipv6_addr_equal(addr, &tmp->addr)) {
/* exact match */
DEBUG(" %p is an exact match\n", (void *)tmp);
return tmp;
}
if ((abr == NULL) && (ipv6_addr_is_unspecified(&tmp->addr))) {
abr = tmp;
}
}
if (abr != NULL) {
DEBUG(" using %p\n", (void *)abr);
memcpy(&abr->addr, addr, sizeof(abr->addr));
}
#if ENABLE_DEBUG
else {
DEBUG(" NIB full\n");
}
#endif
return abr;
}
void _nib_abr_remove(const ipv6_addr_t *addr)
{
assert(addr != NULL);
DEBUG("nib: Removing border router %s\n", ipv6_addr_to_str(addr_str, addr,
sizeof(addr_str)));
for (_nib_abr_entry_t *abr = _abrs; _in_abrs(abr); abr++) {
if (ipv6_addr_equal(addr, &abr->addr)) {
for (int i = 0; i < GNRC_IPV6_NIB_OFFL_NUMOF; i++) {
if (bf_isset(abr->pfxs, i)) {
_nib_pl_remove(&_dsts[i]);
}
}
#if MODULE_GNRC_SIXLOWPAN_CTX
for (int i = 0; i < GNRC_SIXLOWPAN_CTX_SIZE; i++) {
if (bf_isset(abr->ctxs, i)) {
gnrc_sixlowpan_ctx_remove(i);
}
}
#endif
memset(abr, 0, sizeof(_nib_abr_entry_t));
}
}
}
void _nib_abr_add_pfx(_nib_abr_entry_t *abr, const _nib_offl_entry_t *offl)
{
assert((abr != NULL) && (offl != NULL) && (offl->mode & _PL));
unsigned idx = (unsigned)(_dsts - offl);
DEBUG("nib: Prefix %s/%u ",
ipv6_addr_to_str(addr_str, &offl->pfx, sizeof(addr_str)),
offl->pfx_len);
DEBUG("came from border router %s\n", ipv6_addr_to_str(addr_str, &abr->addr,
sizeof(addr_str)));
if (idx < GNRC_IPV6_NIB_OFFL_NUMOF) {
bf_set(abr->pfxs, idx);
}
}
_nib_offl_entry_t *_nib_abr_iter_pfx(const _nib_abr_entry_t *abr,
const _nib_offl_entry_t *last)
{
if ((last == NULL) ||
(((unsigned)(_dsts - last)) < GNRC_IPV6_NIB_OFFL_NUMOF)) {
/* we don't change `ptr`, so dropping const qualifier for now is okay */
_nib_offl_entry_t *ptr = (_nib_offl_entry_t *)last;
while ((ptr = _nib_offl_iter(ptr))) {
/* bf_isset() discards const, but doesn't change the array, so
* discarding it on purpose */
if ((ptr->mode & _PL) && (bf_isset((uint8_t *)abr->pfxs, ptr - _dsts))) {
return ptr;
}
}
}
return NULL;
}
_nib_abr_entry_t *_nib_abr_iter(const _nib_abr_entry_t *last)
{
for (const _nib_abr_entry_t *abr = (last) ? (last + 1) : _abrs;
_in_abrs(abr); abr++) {
if (!ipv6_addr_is_unspecified(&abr->addr)) {
/* const modifier provided to assure internal consistency.
* Can now be discarded. */
return (_nib_abr_entry_t *)abr;
}
}
return NULL;
}
#endif /* GNRC_IPV6_NIB_CONF_MULTIHOP_P6C */
_nib_offl_entry_t *_nib_pl_add(unsigned iface,
const ipv6_addr_t *pfx,
unsigned pfx_len,

View File

@ -23,6 +23,7 @@
#include <stdbool.h>
#include <stdint.h>
#include "bitfield.h"
#include "evtimer_msg.h"
#include "kernel_types.h"
#include "mutex.h"
@ -34,6 +35,7 @@
#include "net/gnrc/ipv6/nib/nc.h"
#include "net/gnrc/ipv6/nib/conf.h"
#include "net/gnrc/pktqueue.h"
#include "net/gnrc/sixlowpan/ctx.h"
#include "net/ndp.h"
#include "random.h"
@ -221,6 +223,27 @@ typedef struct {
uint8_t na_sent;
} _nib_iface_t;
/**
* @brief Internal NIB-representation of the authoritative border router
* for multihop prefix and 6LoWPAN context dissemination
*/
typedef struct {
ipv6_addr_t addr; /**< The address of the border router */
uint32_t version; /**< last received version of the info of
* the _nib_abr_entry_t::addr */
evtimer_msg_event_t timeout; /**< timeout of the information */
/**
* @brief Bitfield marking the prefixes in the NIB's off-link entries
* disseminated by _nib_abr_entry_t::addr
*/
BITFIELD(pfxs, GNRC_IPV6_NIB_OFFL_NUMOF);
/**
* @brief Bitfield marking the contexts disseminated by
* _nib_abr_entry_t::addr
*/
BITFIELD(ctxs, GNRC_SIXLOWPAN_CTX_SIZE);
} _nib_abr_entry_t;
/**
* @brief Mutex for locking the NIB
*/
@ -598,11 +621,7 @@ _nib_offl_entry_t *_nib_pl_add(unsigned iface,
*
* Corresponding on-link entry is removed, too.
*/
static inline void _nib_pl_remove(_nib_offl_entry_t *nib_offl)
{
evtimer_del(&_nib_evtimer, &nib_offl->pfx_timeout.event);
_nib_offl_remove(nib_offl, _PL);
}
void _nib_pl_remove(_nib_offl_entry_t *nib_offl);
#if GNRC_IPV6_NIB_CONF_ROUTER || DOXYGEN
/**
@ -648,6 +667,65 @@ static inline void _nib_ft_remove(_nib_offl_entry_t *nib_offl)
}
#endif /* GNRC_IPV6_NIB_CONF_ROUTER */
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C || defined(DOXYGEN)
/**
* @brief Creates or gets an existing authoritative border router.
*
* @pre `addr != NULL`
*
* @param[in] addr Address of the authoritative border router.
*
* @return An authoritative border router entry, on success.
* @return NULL, if no space is left.
*/
_nib_abr_entry_t *_nib_abr_add(const ipv6_addr_t *addr);
/**
* @brief Removes an authoritative border router
*
* @pre `addr != NULL`
*
* @param[in] addr Address of the authoritative border router.
*/
void _nib_abr_remove(const ipv6_addr_t *addr);
/**
* @brief Adds a prefix to the managed prefix of the authoritative border
* router
*
* @pre `(abr != NULL) && (offl != NULL) && (offl->mode & _PL)`
*
* @param[in] abr The border router.
* @param[in] offl The prefix to add.
*/
void _nib_abr_add_pfx(_nib_abr_entry_t *abr, const _nib_offl_entry_t *offl);
/**
* @brief Iterates over an authoritative border router's prefixes
*
* @pre `(abr != NULL)`
*
* @param[in] abr The border router
* @param[in] last Last prefix (NULL to start)
*
* @return entry after @p last.
* @return NULL, if @p last is the last prefix of @p abr or if @p last
* wasn't in NIB (and != NULL).
*/
_nib_offl_entry_t *_nib_abr_iter_pfx(const _nib_abr_entry_t *abr,
const _nib_offl_entry_t *last);
/**
* @brief Iterates over authoritative border router entries
*
* @param[in] last Last entry (NULL to start).
*
* @return entry after @p last.
* @return NULL, if @p last is the last ABR in the NIB.
*/
_nib_abr_entry_t *_nib_abr_iter(const _nib_abr_entry_t *last);
#endif
/**
* @brief Gets (or creates if it not exists) interface information for
* neighbor discovery

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2017 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @{
*
* @file
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#include "net/gnrc/ipv6/nib/abr.h"
#include "_nib-internal.h"
#if GNRC_IPV6_NIB_CONF_6LBR && GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
int gnrc_ipv6_nib_abr_add(const ipv6_addr_t *addr)
{
_nib_abr_entry_t *abr;
_nib_offl_entry_t *offl = NULL;
mutex_lock(&_nib_mutex);
if ((abr = _nib_abr_add(addr)) == NULL) {
mutex_unlock(&_nib_mutex);
return -ENOMEM;
}
while ((offl = _nib_offl_iter(offl))) {
if (offl->mode & _PL) {
_nib_abr_add_pfx(abr, offl);
}
}
#ifdef MODULE_GNRC_SIXLOWPAN_CTX /* included optionally for NIB testing */
for (uint8_t id = 0; id < GNRC_SIXLOWPAN_CTX_SIZE; id++) {
if (gnrc_sixlowpan_ctx_lookup_id(id) != NULL) {
bf_set(abr->ctxs, id);
}
}
#endif
mutex_unlock(&_nib_mutex);
return 0;
}
void gnrc_ipv6_nib_abr_del(const ipv6_addr_t *addr)
{
mutex_lock(&_nib_mutex);
_nib_abr_remove(addr);
mutex_unlock(&_nib_mutex);
}
#else
typedef int dont_be_pedantic;
#endif
/** @} */

View File

@ -5,5 +5,9 @@ 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
CFLAGS += -DGNRC_IPV6_NIB_ABR_NUMOF=4
CFLAGS += -DGNRC_IPV6_NIB_CONF_6LBR=1
CFLAGS += -DGNRC_IPV6_NIB_CONF_MULTIHOP_P6C=1
CFLAGS += -DGNRC_IPV6_NIB_CONF_DC=1
INCLUDES += -I$(RIOTBASE)/sys/net/gnrc/network_layer/ipv6/nib

View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2016 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @{
*
* @file
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#include <inttypes.h>
#include "net/ipv6/addr.h"
#include "net/gnrc/ipv6/nib.h"
#include "net/gnrc/ipv6/nib/abr.h"
#include "_nib-internal.h"
#include "unittests-constants.h"
#include "tests-gnrc_ipv6_nib.h"
#define GLOBAL_PREFIX { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0 }
static void set_up(void)
{
evtimer_event_t *tmp;
for (evtimer_event_t *ptr = _nib_evtimer.events;
(ptr != NULL) && (tmp = (ptr->next), 1);
ptr = tmp) {
evtimer_del((evtimer_t *)(&_nib_evtimer), ptr);
}
_nib_init();
}
/*
* Creates GNRC_IPV6_NIB_ABR_NUMOF authoritative border router list entries with
* different addresses and then tries to create another one
* Expected result: gnrc_ipv6_nib_abr_add() returns -ENOMEM
*/
static void test_nib_abr_add__ENOMEM(void)
{
ipv6_addr_t addr = { .u64 = { { .u8 = GLOBAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
for (unsigned i = 0; i < GNRC_IPV6_NIB_ABR_NUMOF; i++) {
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_abr_add(&addr));
addr.u16[0].u16++;
}
TEST_ASSERT_EQUAL_INT(-ENOMEM, gnrc_ipv6_nib_abr_add(&addr));
}
/*
* Creates GNRC_IPV6_NIB_ABR_NUMOF authoritative border router list entries with
* different addresses and then tries to add another equal to the last.
* Expected result: should return 0.
*/
static void test_nib_abr_add__success(void)
{
ipv6_addr_t addr = { .u64 = { { .u8 = GLOBAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
for (unsigned i = 0; i < GNRC_IPV6_NIB_ABR_NUMOF; i++) {
addr.u16[0].u16++;
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_abr_add(&addr));
}
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_abr_add(&addr));
}
/*
* Creates an authoritative border router list entry and removes it.
* Expected result: system does not crash ;-)
*/
static void test_nib_abr_del__success(void)
{
ipv6_addr_t addr = { .u64 = { { .u8 = GLOBAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_abr_add(&addr));
gnrc_ipv6_nib_abr_del(&addr);
}
Test *tests_gnrc_ipv6_nib_abr_tests(void)
{
EMB_UNIT_TESTFIXTURES(fixtures) {
new_TestFixture(test_nib_abr_add__ENOMEM),
new_TestFixture(test_nib_abr_add__success),
new_TestFixture(test_nib_abr_del__success),
/* gnrc_ipv6_nib_pl_iter() is tested during all the tests above */
};
EMB_UNIT_TESTCALLER(tests, set_up, NULL,
fixtures);
return (Test *)&tests;
}

View File

@ -1715,6 +1715,201 @@ static void test_nib_ft_remove(void)
TEST_ASSERT_NULL(_nib_offl_iter(NULL));
}
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
/*
* Creates GNRC_IPV6_NIB_ABR_NUMOF ABR entries with different addresses and
* then tries to add another.
* Expected result: should return NULL
*/
static void test_nib_abr_add__no_space_left(void)
{
ipv6_addr_t addr = { .u64 = { { .u8 = LINK_LOCAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
for (int i = 0; i < GNRC_IPV6_NIB_ABR_NUMOF; i++) {
TEST_ASSERT_NOT_NULL(_nib_abr_add(&addr));
addr.u64[1].u64++;
}
TEST_ASSERT_NULL(_nib_abr_add(&addr));
}
/*
* Creates GNRC_IPV6_NIB_ABR_NUMOF ABR entries with different addresses and then
* tries to add another that is equal to the last.
* Expected result: should return not NULL (the last)
*/
static void test_nib_abr_add__success_duplicate(void)
{
_nib_abr_entry_t *abr;
ipv6_addr_t addr = { .u64 = { { .u8 = GLOBAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
for (int i = 0; i < GNRC_IPV6_NIB_ABR_NUMOF; i++) {
addr.u64[1].u64++;
TEST_ASSERT_NOT_NULL((abr = _nib_abr_add(&addr)));
}
TEST_ASSERT(abr == _nib_abr_add(&addr));
}
/*
* Creates an ABR entry.
* Expected result: new entry should contain the given address
*/
static void test_nib_abr_add__success(void)
{
_nib_abr_entry_t *abr;
static const ipv6_addr_t addr = { .u64 = { { .u8 = GLOBAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
TEST_ASSERT_NOT_NULL((abr = _nib_abr_add(&addr)));
TEST_ASSERT(ipv6_addr_equal(&addr, &abr->addr));
}
/*
* Creates an ABR entry and then removes the entry.
* Expected result: the ABR list should be empty
*/
static void test_nib_abr_remove__success(void)
{
_nib_abr_entry_t *abr = NULL;
static const ipv6_addr_t addr = { .u64 = { { .u8 = GLOBAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
TEST_ASSERT_NOT_NULL(_nib_abr_add(&addr));
_nib_abr_remove(&addr);
TEST_ASSERT_NULL(_nib_abr_iter(abr));
}
/*
* Creates an ABR entry and tries to add a prefix, that is not in the NIB.
* Expected result: the ABR's prefix list should be unchanged.
*/
static void test_nib_abr_add_pfx__pfx_not_in_nib(void)
{
_nib_abr_entry_t *abr;
static const ipv6_addr_t addr = { .u64 = { { .u8 = GLOBAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
_nib_offl_entry_t offl;
TEST_ASSERT_NOT_NULL((abr = _nib_abr_add(&addr)));
TEST_ASSERT_NULL(_nib_abr_iter_pfx(abr, NULL));
_nib_abr_add_pfx(abr, &offl);
TEST_ASSERT_NULL(_nib_abr_iter_pfx(abr, NULL));
}
/*
* Creates an ABR entry and a prefix and tries to add that prefix.
* Expected result: the ABR's prefix list should be changed.
*/
static void test_nib_abr_add_pfx__pfx_in_nib(void)
{
_nib_abr_entry_t *abr;
_nib_offl_entry_t *dst;
static const ipv6_addr_t addr = { .u64 = { { .u8 = GLOBAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
static const ipv6_addr_t pfx = { .u64 = { { .u8 = GLOBAL_PREFIX } } };
TEST_ASSERT_NOT_NULL((abr = _nib_abr_add(&addr)));
TEST_ASSERT_NOT_NULL((dst = _nib_pl_add(IFACE, &pfx, GLOBAL_PREFIX_LEN,
UINT32_MAX, UINT32_MAX)));
TEST_ASSERT_NULL(_nib_abr_iter_pfx(abr, NULL));
_nib_abr_add_pfx(abr, dst);
TEST_ASSERT_NOT_NULL(_nib_abr_iter_pfx(abr, NULL));
}
/*
* Iterates over prefixes of ABR with no prefix entries
* Expected result: _nib_abr_pfx_iter returns NULL
*/
static void test_nib_abr_iter_pfx__empty(void)
{
_nib_abr_entry_t *abr;
static const ipv6_addr_t addr = { .u64 = { { .u8 = GLOBAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
TEST_ASSERT_NOT_NULL((abr = _nib_abr_add(&addr)));
TEST_ASSERT_NULL(_nib_abr_iter_pfx(abr, NULL));
}
/*
* Iterates over empty ABR entries
* Expected result: _nib_abr_iter returns NULL
*/
static void test_nib_abr_iter__empty(void)
{
TEST_ASSERT_NULL(_nib_abr_iter(NULL));
}
/*
* Iterates over ABR entries with one element
* Expected result: _nib_abr_iter returns element with NULL, and with that
* element NULL.
*/
static void test_nib_abr_iter__one_elem(void)
{
_nib_abr_entry_t *abr, *res;
static const ipv6_addr_t addr = { .u64 = { { .u8 = LINK_LOCAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
TEST_ASSERT_NOT_NULL((abr = _nib_abr_add(&addr)));
TEST_ASSERT_NOT_NULL((res = _nib_abr_iter(NULL)));
TEST_ASSERT(res == abr);
TEST_ASSERT_NULL(_nib_abr_iter(res));
}
/*
* Iterates over ABR entries with three element
* Expected result: _nib_abr_iter returns element with NULL, with that element
* another, with that element yet another and with the last NULL.
*/
static void test_nib_abr_iter__three_elem(void)
{
_nib_abr_entry_t *abr1, *abr2, *abr3, *res;
ipv6_addr_t addr = { .u64 = { { .u8 = LINK_LOCAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
TEST_ASSERT_NOT_NULL((abr1 = _nib_abr_add(&addr)));
addr.u64[1].u64++;
TEST_ASSERT_NOT_NULL((abr2 = _nib_abr_add(&addr)));
addr.u64[1].u64++;
TEST_ASSERT_NOT_NULL((abr3 = _nib_abr_add(&addr)));
TEST_ASSERT_NOT_NULL((res = _nib_abr_iter(NULL)));
TEST_ASSERT(res == abr1);
TEST_ASSERT_NOT_NULL((res = _nib_abr_iter(res)));
TEST_ASSERT(res == abr2);
TEST_ASSERT_NOT_NULL((res = _nib_abr_iter(res)));
TEST_ASSERT(res == abr3);
TEST_ASSERT_NULL(_nib_abr_iter(res));
}
/*
* Iterates over ABR entries with two elements, where there is a hole in the
* internal array
* Expected result: _nib_abr_iter returns element with NULL, with that element
* another, and with the last NULL.
*/
static void test_nib_abr_iter__three_elem_middle_removed(void)
{
_nib_abr_entry_t *abr1, *abr2, *res;
ipv6_addr_t addr = { .u64 = { { .u8 = LINK_LOCAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
TEST_ASSERT_NOT_NULL((abr1 = _nib_abr_add(&addr)));
addr.u64[1].u64++;
TEST_ASSERT_NOT_NULL(_nib_abr_add(&addr));
addr.u64[1].u64++;
TEST_ASSERT_NOT_NULL((abr2 = _nib_abr_add(&addr)));
addr.u64[1].u64--;
_nib_abr_remove(&addr);
TEST_ASSERT_NOT_NULL((res = _nib_abr_iter(NULL)));
TEST_ASSERT(res == abr1);
TEST_ASSERT_NOT_NULL((res = _nib_abr_iter(res)));
TEST_ASSERT(res == abr2);
TEST_ASSERT_NULL(_nib_abr_iter(res));
}
#endif
/*
* Creates GNRC_NETIF_NUMOF interfaces and then tries to add another.
* Expected result: should return NULL
@ -1826,6 +2021,20 @@ Test *tests_gnrc_ipv6_nib_internal_tests(void)
new_TestFixture(test_nib_pl_remove),
new_TestFixture(test_nib_ft_add__success),
new_TestFixture(test_nib_ft_remove),
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
new_TestFixture(test_nib_abr_add__no_space_left),
new_TestFixture(test_nib_abr_add__success_duplicate),
new_TestFixture(test_nib_abr_add__success),
new_TestFixture(test_nib_abr_remove__success),
new_TestFixture(test_nib_abr_add_pfx__pfx_not_in_nib),
new_TestFixture(test_nib_abr_add_pfx__pfx_in_nib),
new_TestFixture(test_nib_abr_iter_pfx__empty),
/* rest of _nib_abr_iter_pfx() tested through _nib_abr_add_pfx() tests */
new_TestFixture(test_nib_abr_iter__empty),
new_TestFixture(test_nib_abr_iter__one_elem),
new_TestFixture(test_nib_abr_iter__three_elem),
new_TestFixture(test_nib_abr_iter__three_elem_middle_removed),
#endif
new_TestFixture(test_nib_iface_get__no_space_left),
new_TestFixture(test_nib_iface_get__success),
};

View File

@ -18,6 +18,7 @@
void tests_gnrc_ipv6_nib(void)
{
TESTS_RUN(tests_gnrc_ipv6_nib_internal_tests());
TESTS_RUN(tests_gnrc_ipv6_nib_abr_tests());
TESTS_RUN(tests_gnrc_ipv6_nib_nc_tests());
TESTS_RUN(tests_gnrc_ipv6_nib_pl_tests());
}

View File

@ -36,6 +36,13 @@ void tests_gnrc_ipv6_nib(void);
*/
Test *tests_gnrc_ipv6_nib_internal_tests(void);
/**
* @brief Generates tests for authoritative border router list view
*
* @return embUnit tests if successful, NULL if not.
*/
Test *tests_gnrc_ipv6_nib_abr_tests(void);
/**
* @brief Generates tests for neighbor cache view
*