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:
commit
7af0f916fe
@ -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"
|
||||
|
||||
|
55
sys/include/net/gnrc/ipv6/nib/abr.h
Normal file
55
sys/include/net/gnrc/ipv6/nib/abr.h
Normal 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 */
|
||||
/** @} */
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
57
sys/net/gnrc/network_layer/ipv6/nib/nib_abr.c
Normal file
57
sys/net/gnrc/network_layer/ipv6/nib/nib_abr.c
Normal 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
|
||||
|
||||
/** @} */
|
@ -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
|
||||
|
102
tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-abr.c
Normal file
102
tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-abr.c
Normal 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;
|
||||
}
|
@ -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),
|
||||
};
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user