mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-29 00:11:16 +01:00
Merge pull request #2461 from authmillenon/ng_ipv6_nc/feat/initial
net: initial import of an IPv6 neighbor cache
This commit is contained in:
commit
99e810e9b5
@ -48,6 +48,10 @@ ifneq (,$(filter sixlowpan,$(USEMODULE)))
|
||||
USEMODULE += vtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter ng_ipv6_nc,$(USEMODULE)))
|
||||
USEMODULE += ng_ipv6_addr
|
||||
endif
|
||||
|
||||
ifneq (,$(filter aodvv2,$(USEMODULE)))
|
||||
USEMODULE += vtimer
|
||||
USEMODULE += sixlowpan
|
||||
|
||||
@ -65,6 +65,9 @@ endif
|
||||
ifneq (,$(filter ng_ipv6_addr,$(USEMODULE)))
|
||||
DIRS += net/network_layer/ng_ipv6/addr
|
||||
endif
|
||||
ifneq (,$(filter ng_ipv6_nc,$(USEMODULE)))
|
||||
DIRS += net/network_layer/ng_ipv6/nc
|
||||
endif
|
||||
ifneq (,$(filter ng_netapi,$(USEMODULE)))
|
||||
DIRS += net/crosslayer/ng_netapi
|
||||
endif
|
||||
|
||||
220
sys/include/net/ng_ipv6/nc.h
Normal file
220
sys/include/net/ng_ipv6/nc.h
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*
|
||||
* 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_ng_ipv6_nc IPv6 neighbor cache
|
||||
* @ingroup net_ng_ipv6
|
||||
* @brief Translates IPv6 addresses to link layer addresses.
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Neighbor cache definitions.
|
||||
*
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef NG_IPV6_NC_H_
|
||||
#define NG_IPV6_NC_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "kernel_types.h"
|
||||
#include "net/ng_ipv6/addr.h"
|
||||
#include "net/ng_netif.h"
|
||||
#include "net/ng_pktqueue.h"
|
||||
#include "timex.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef NG_IPV6_NC_SIZE
|
||||
/**
|
||||
* @brief The size of the neighbor cache
|
||||
*/
|
||||
#define NG_IPV6_NC_SIZE (NG_NETIF_NUMOF * 8)
|
||||
#endif
|
||||
|
||||
#ifndef NG_IPV6_NC_L2_ADDR_MAX
|
||||
/**
|
||||
* @brief The maximum size of a link layer address
|
||||
*/
|
||||
#define NG_IPV6_NC_L2_ADDR_MAX (8)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @name Flag definitions for ng_ipv6_nc_t
|
||||
*/
|
||||
/**
|
||||
* @{
|
||||
* @brief States of a neighbor cache entry.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-7.3.2">
|
||||
* RFC 4861, section 7.3.2
|
||||
* </a>
|
||||
*/
|
||||
#define NG_IPV6_NC_STATE_MASK (0x07) /**< Mask for neighbor cache state */
|
||||
#define NG_IPV6_NC_STATE_POS (0) /**< Shift of neighbor cache state */
|
||||
|
||||
#define NG_IPV6_NC_STATE_UNMANAGED (0x00) /**< The entry is not manage by NDP */
|
||||
|
||||
/**
|
||||
* @brief The entry is unreachable
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc7048#section-3">
|
||||
* RFC 7048, section 3
|
||||
* </a>
|
||||
*/
|
||||
#define NG_IPV6_NC_STATE_UNREACHABLE (0x01)
|
||||
#define NG_IPV6_NC_STATE_INCOMPLETE (0x02) /**< Address resolution is performed */
|
||||
#define NG_IPV6_NC_STATE_STALE (0x03) /**< The entry is stale */
|
||||
#define NG_IPV6_NC_STATE_DELAY (0x04) /**< The entry was stale but packet was sent out */
|
||||
#define NG_IPV6_NC_STATE_PROBE (0x05) /**< Periodic reachabality confirmation */
|
||||
#define NG_IPV6_NC_STATE_REACHABLE (0x07) /**< The entry is reachable */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#define NG_IPV6_NC_IS_ROUTER (0x08) /**< The neighbor is a router */
|
||||
|
||||
#define NG_IPV6_NC_TYPE_MASK (0x30) /**< Mask for neighbor cache state */
|
||||
#define NG_IPV6_NC_TYPE_POS (4) /**< Shift of neighbor cache state */
|
||||
|
||||
/**
|
||||
* @{
|
||||
* @brief States of a neighbor cache entry.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc6775#section-3.5">
|
||||
* RFC 6775, section 3.5
|
||||
* </a>
|
||||
*/
|
||||
/**
|
||||
* @brief The entry has no type
|
||||
*
|
||||
* @details The node sents multicast Neighbor Solicitations for hosts.
|
||||
*/
|
||||
#define NG_IPV6_NC_TYPE_NONE (0x00)
|
||||
#define NG_IPV6_NC_TYPE_GC (0x10) /**< The entry is marked for removal */
|
||||
#define NG_IPV6_NC_TYPE_TENTATIVE (0x20) /**< The entry is temporary */
|
||||
#define NG_IPV6_NC_TYPE_REGISTERED (0x30) /**< The entry is registered */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Neighbor cache entry as defined in
|
||||
* <a href="http://tools.ietf.org/html/rfc4861#section-5.1">
|
||||
* RFC 4861, section 5.1
|
||||
* </a>.
|
||||
*/
|
||||
typedef struct {
|
||||
ng_pktqueue_t pkts; /**< Packets waiting for address resolution */
|
||||
ng_ipv6_addr_t ipv6_addr; /**< IPv6 address of the neighbor */
|
||||
uint8_t l2_addr[NG_IPV6_NC_L2_ADDR_MAX];/**< Link layer address of the neighbor */
|
||||
uint8_t l2_addr_len; /**< Length of ng_ipv6_nc_t::l2_addr */
|
||||
uint8_t flags; /**< Flags as defined above */
|
||||
kernel_pid_t iface; /**< PID to the interface where the neighbor is */
|
||||
} ng_ipv6_nc_t;
|
||||
|
||||
/**
|
||||
* @brief Initializes neighbor cache
|
||||
*/
|
||||
void ng_ipv6_nc_init(void);
|
||||
|
||||
/**
|
||||
* @brief Adds a neighbor to the neighbor cache
|
||||
*
|
||||
* @param[in] iface PID to the interface where the neighbor is.
|
||||
* Must not be KERNEL_PID_UNDEF.
|
||||
* @param[in] ipv6_addr IPv6 address of the neighbor. Must not be NULL.
|
||||
* @param[in] l2_addr Link layer address of the neighbor. NULL if unknown.
|
||||
* @param[in] l2_addr_len Length of @p l2_addr, must be lesser than or equal
|
||||
* to NG_IPV6_L2_ADDR_MAX. 0 if unknown.
|
||||
* @param[in] flags Flags for the entry
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -EADDRINUSE, if @p ipv6_addr is already registered to the neighbor
|
||||
* cache.
|
||||
* @return -EFAULT, if @p ipv6_addr was NULL.
|
||||
* @return -EINVAL, if @p l2_addr_len is greater then @ref NG_IPV6_NC_L2_ADDR_MAX,
|
||||
* @p ipv6_addr is unspecified or @p iface is KERNEL_PID_UNDEF.
|
||||
* @return -ENOMEM, if no space is left to store entry.
|
||||
*/
|
||||
int 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);
|
||||
|
||||
/**
|
||||
* @brief Removes a neighbor from the neighbor cache
|
||||
*
|
||||
* @param[in] iface PID to the interface where the neighbor is. If it
|
||||
* is KERNEL_PID_UNDEF it will be removed for all
|
||||
* interfaces.
|
||||
* @param[in] ipv6_addr IPv6 address of the neighbor
|
||||
*/
|
||||
void ng_ipv6_nc_remove(kernel_pid_t iface, const ng_ipv6_addr_t *ipv6_addr);
|
||||
|
||||
/**
|
||||
* @brief Searches for any neighbor cache entry fitting the @p ipv6_addr.
|
||||
*
|
||||
* @param[in] iface PID to the interface where the neighbor is. If it
|
||||
* is KERNEL_PID_UNDEF it will be searched on all
|
||||
* interfaces.
|
||||
* @param[in] ipv6_addr An IPv6 address
|
||||
*
|
||||
* @return The neighbor cache entry, if one is found.
|
||||
* @return NULL, if none is found.
|
||||
*/
|
||||
ng_ipv6_nc_t *ng_ipv6_nc_get(kernel_pid_t iface, const ng_ipv6_addr_t *ipv6_addr);
|
||||
|
||||
/**
|
||||
* @brief Searches for any neighbor cache entry fitting the @p ipv6_addr,
|
||||
* where you currently can send a packet to (do not confuse with
|
||||
* NG_IPV6_NC_STATE_REACHABLE).
|
||||
*
|
||||
* @param[in] iface PID to the interface where the neighbor is. If it
|
||||
* is KERNEL_PID_UNDEF it will be searched on all
|
||||
* interfaces.
|
||||
* @param[in] ipv6_addr An IPv6 address
|
||||
*
|
||||
* @return The neighbor cache entry, if one is found.
|
||||
* @return NULL, if none is found.
|
||||
*/
|
||||
ng_ipv6_nc_t *ng_ipv6_nc_get_reachable(kernel_pid_t iface,
|
||||
const ng_ipv6_addr_t *ipv6_addr);
|
||||
|
||||
/**
|
||||
* @brief Marks an entry as still reachable, if one with a fitting @p ipv6_addr
|
||||
* can be found.
|
||||
*
|
||||
* @details This function can be used by upper layer protocols for neighbor
|
||||
* discovery optimization to confirm that there was a reachability
|
||||
* confirmation (e. g. an ACK in TCP) from the neighbor.
|
||||
*
|
||||
* @see <a href="http://tools.ietf.org/html/rfc4861#section-7.3.1">
|
||||
* RFC 4861, section 7.3.1
|
||||
* </a>
|
||||
*
|
||||
* @param[in] ipv6_addr An IPv6 address
|
||||
*
|
||||
* @return The neighbor cache entry, if one is found.
|
||||
* @return NULL, if none is found.
|
||||
*/
|
||||
ng_ipv6_nc_t *ng_ipv6_nc_still_reachable(const ng_ipv6_addr_t *ipv6_addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NG_IPV6_NC_H_ */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
3
sys/net/network_layer/ng_ipv6/nc/Makefile
Normal file
3
sys/net/network_layer/ng_ipv6/nc/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = ng_ipv6_nc
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
185
sys/net/network_layer/ng_ipv6/nc/ng_ipv6_nc.c
Normal file
185
sys/net/network_layer/ng_ipv6/nc/ng_ipv6_nc.c
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "net/ng_ipv6/addr.h"
|
||||
#include "net/ng_ipv6/nc.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
static char addr_str[NG_IPV6_ADDR_MAX_STR_LEN];
|
||||
#endif
|
||||
|
||||
static ng_ipv6_nc_t ncache[NG_IPV6_NC_SIZE];
|
||||
|
||||
void ng_ipv6_nc_init(void)
|
||||
{
|
||||
memset(ncache, 0, sizeof(ncache));
|
||||
}
|
||||
|
||||
ng_ipv6_nc_t *_find_free_entry(void)
|
||||
{
|
||||
for (int i = 0; i < NG_IPV6_NC_SIZE; i++) {
|
||||
if (ng_ipv6_addr_is_unspecified(&(ncache[i].ipv6_addr))) {
|
||||
return ncache + i;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int 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)
|
||||
{
|
||||
if (ipv6_addr == NULL) {
|
||||
DEBUG("ipv6_nc: address was NULL\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if ((l2_addr_len > NG_IPV6_NC_L2_ADDR_MAX) || (iface == KERNEL_PID_UNDEF) ||
|
||||
ng_ipv6_addr_is_unspecified(ipv6_addr)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < NG_IPV6_NC_SIZE; i++) {
|
||||
if (ng_ipv6_addr_equal(&(ncache[i].ipv6_addr), ipv6_addr)) {
|
||||
DEBUG("ipv6_nc: Address %s already registered\n",
|
||||
ng_ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)));
|
||||
return -EADDRINUSE;
|
||||
}
|
||||
|
||||
if (ncache[i].iface == KERNEL_PID_UNDEF) {
|
||||
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)) {
|
||||
#if ENABLE_DEBUG
|
||||
DEBUG(" to L2 address ");
|
||||
|
||||
for (size_t i = 0; i < l2_addr_len; i++) {
|
||||
if (i > 0) {
|
||||
putchar(':');
|
||||
}
|
||||
|
||||
DEBUG("%02x", ((uint8_t *)l2_addr)[i]);
|
||||
}
|
||||
|
||||
#endif
|
||||
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 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void ng_ipv6_nc_remove(kernel_pid_t iface, const ng_ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
ng_ipv6_nc_t *entry = ng_ipv6_nc_get(iface, ipv6_addr);
|
||||
|
||||
if (entry != NULL) {
|
||||
DEBUG("ipv6_nc: Remove %s for interface %" PRIkernel_pid "\n",
|
||||
ng_ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)),
|
||||
iface);
|
||||
|
||||
ng_ipv6_addr_set_unspecified(&(entry->ipv6_addr));
|
||||
entry->iface = KERNEL_PID_UNDEF;
|
||||
entry->flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ng_ipv6_nc_t *ng_ipv6_nc_get(kernel_pid_t iface, const ng_ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
if (ipv6_addr == NULL) {
|
||||
DEBUG("ipv6_nc: address was NULL\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < NG_IPV6_NC_SIZE; i++) {
|
||||
if (((iface == KERNEL_PID_UNDEF) || (iface == ncache[i].iface)) &&
|
||||
ng_ipv6_addr_equal(&(ncache[i].ipv6_addr), ipv6_addr)) {
|
||||
DEBUG("ipv6_nc: Found entry for %s on interface %" PRIkernel_pid
|
||||
" (0 = all interfaces) [%p]\n",
|
||||
ng_ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)),
|
||||
iface, (void *)(ncache + i));
|
||||
|
||||
return ncache + i;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ng_ipv6_nc_t *ng_ipv6_nc_get_reachable(kernel_pid_t iface,
|
||||
const ng_ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
ng_ipv6_nc_t *entry = ng_ipv6_nc_get(iface, ipv6_addr);
|
||||
|
||||
if (entry == NULL) {
|
||||
DEBUG("ipv6_nc: No entry found for %s on interface %" PRIkernel_pid "\n",
|
||||
ng_ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)),
|
||||
iface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch ((entry->flags & NG_IPV6_NC_STATE_MASK) >> NG_IPV6_NC_STATE_POS) {
|
||||
case NG_IPV6_NC_STATE_UNREACHABLE:
|
||||
case NG_IPV6_NC_STATE_INCOMPLETE:
|
||||
DEBUG("ipv6_nc: Entry %s is unreachable (flags = 0x%02x)\n",
|
||||
ng_ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)),
|
||||
entry->flags);
|
||||
return NULL;
|
||||
|
||||
default:
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
ng_ipv6_nc_t *ng_ipv6_nc_still_reachable(const ng_ipv6_addr_t *ipv6_addr)
|
||||
{
|
||||
ng_ipv6_nc_t *entry = ng_ipv6_nc_get(KERNEL_PID_UNDEF, ipv6_addr);
|
||||
|
||||
if (entry == NULL) {
|
||||
DEBUG("ipv6_nc: No entry found for %s\n",
|
||||
ng_ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (((entry->flags & NG_IPV6_NC_STATE_MASK) >> NG_IPV6_NC_STATE_POS) !=
|
||||
NG_IPV6_NC_STATE_INCOMPLETE) {
|
||||
DEBUG("ipv6_nc: Marking entry %s as reachable\n",
|
||||
ng_ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str)));
|
||||
entry->flags &= ~(NG_IPV6_NC_STATE_MASK >> NG_IPV6_NC_STATE_POS);
|
||||
entry->flags |= (NG_IPV6_NC_STATE_REACHABLE >> NG_IPV6_NC_STATE_POS);
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
1
tests/unittests/tests-ipv6_nc/Makefile
Normal file
1
tests/unittests/tests-ipv6_nc/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
1
tests/unittests/tests-ipv6_nc/Makefile.include
Normal file
1
tests/unittests/tests-ipv6_nc/Makefile.include
Normal file
@ -0,0 +1 @@
|
||||
USEMODULE += ng_ipv6_nc
|
||||
337
tests/unittests/tests-ipv6_nc/tests-ipv6_nc.c
Normal file
337
tests/unittests/tests-ipv6_nc/tests-ipv6_nc.c
Normal file
@ -0,0 +1,337 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "embUnit.h"
|
||||
|
||||
#include "net/ng_ipv6/addr.h"
|
||||
#include "net/ng_ipv6/nc.h"
|
||||
|
||||
#include "tests-ipv6_nc.h"
|
||||
|
||||
/* default interface for testing */
|
||||
#define DEFAULT_TEST_NETIF (TEST_UINT16)
|
||||
/* default IPv6 addr for testing */
|
||||
#define DEFAULT_TEST_IPV6_ADDR { { \
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f \
|
||||
} \
|
||||
}
|
||||
|
||||
/* another interface for testing */
|
||||
#define OTHER_TEST_NETIF (TEST_UINT16 + TEST_UINT8)
|
||||
/* another IPv6 addr for testing */
|
||||
#define OTHER_TEST_IPV6_ADDR { { \
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f \
|
||||
} \
|
||||
}
|
||||
|
||||
static void set_up(void)
|
||||
{
|
||||
ng_ipv6_nc_init();
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_add__EADDRINUSE(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(0, ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr,
|
||||
TEST_STRING4, sizeof(TEST_STRING4),
|
||||
0));
|
||||
TEST_ASSERT_EQUAL_INT(-EADDRINUSE, ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr,
|
||||
TEST_STRING4, sizeof(TEST_STRING4), 0));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_add__EFAULT(void)
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(-EFAULT, ng_ipv6_nc_add(DEFAULT_TEST_NETIF, NULL,
|
||||
TEST_STRING4, sizeof(TEST_STRING4), 0));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_add__EINVAL_KERNEL_PID_UNDEF(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(-EINVAL, ng_ipv6_nc_add(KERNEL_PID_UNDEF, &addr,
|
||||
TEST_STRING4, sizeof(TEST_STRING4), 0));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_add__EINVAL_ipv6_addr_unspecified(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = NG_IPV6_ADDR_UNSPECIFIED;
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(-EINVAL, ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr,
|
||||
TEST_STRING4, sizeof(TEST_STRING4), 0));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_add__EINVAL_l2addr_too_long(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(-EINVAL, ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr,
|
||||
TEST_STRING4, NG_IPV6_NC_L2_ADDR_MAX + TEST_UINT8, 0));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_add__ENOMEM(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
|
||||
for (int i = 0; i < NG_IPV6_NC_SIZE; i++) {
|
||||
TEST_ASSERT_EQUAL_INT(0, ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr,
|
||||
TEST_STRING4, sizeof(TEST_STRING4), 0));
|
||||
addr.u16[7].u16++;
|
||||
}
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(-ENOMEM, ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr,
|
||||
TEST_STRING4, sizeof(TEST_STRING4), 0));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_add__success(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(0, ng_ipv6_nc_add(DEFAULT_TEST_NETIF, &addr,
|
||||
TEST_STRING4, sizeof(TEST_STRING4), 0));
|
||||
|
||||
TEST_ASSERT_NOT_NULL(ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_remove__no_entry_pid(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
|
||||
test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
|
||||
ng_ipv6_nc_remove(OTHER_TEST_NETIF, &addr);
|
||||
TEST_ASSERT_NOT_NULL(ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr));
|
||||
TEST_ASSERT_NULL(ng_ipv6_nc_get(OTHER_TEST_NETIF, &addr));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_remove__no_entry_addr1(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = OTHER_TEST_IPV6_ADDR;
|
||||
ng_ipv6_addr_t exp_addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
|
||||
test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
|
||||
ng_ipv6_nc_remove(DEFAULT_TEST_NETIF, &addr);
|
||||
TEST_ASSERT_NOT_NULL(ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &exp_addr));
|
||||
TEST_ASSERT_NULL(ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_remove__no_entry_addr2(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = NG_IPV6_ADDR_UNSPECIFIED;
|
||||
ng_ipv6_addr_t exp_addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
|
||||
test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
|
||||
ng_ipv6_nc_remove(DEFAULT_TEST_NETIF, &addr);
|
||||
TEST_ASSERT_NOT_NULL(ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &exp_addr));
|
||||
TEST_ASSERT_NULL(ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_remove__success(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
|
||||
test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
|
||||
TEST_ASSERT_NOT_NULL(ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr));
|
||||
ng_ipv6_nc_remove(DEFAULT_TEST_NETIF, &addr);
|
||||
TEST_ASSERT_NULL(ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_get__empty(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
|
||||
TEST_ASSERT_NULL(ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_get__different_if(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
|
||||
test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
|
||||
|
||||
TEST_ASSERT_NULL(ng_ipv6_nc_get(OTHER_TEST_NETIF, &addr));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_get__different_addr(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = OTHER_TEST_IPV6_ADDR;
|
||||
|
||||
test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
|
||||
|
||||
TEST_ASSERT_NULL(ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_get__success_if_local(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
ng_ipv6_nc_t *entry = NULL;
|
||||
|
||||
test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
|
||||
|
||||
TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr)));
|
||||
TEST_ASSERT_EQUAL_INT(DEFAULT_TEST_NETIF, entry->iface);
|
||||
TEST_ASSERT(ng_ipv6_addr_equal(&(entry->ipv6_addr), &addr));
|
||||
TEST_ASSERT_EQUAL_STRING(TEST_STRING4, (char *)entry->l2_addr);
|
||||
TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING4), entry->l2_addr_len);
|
||||
TEST_ASSERT_EQUAL_INT(0, entry->flags);
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_get__success_if_global(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
ng_ipv6_nc_t *entry = NULL;
|
||||
|
||||
test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
|
||||
|
||||
TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get(KERNEL_PID_UNDEF, &addr)));
|
||||
TEST_ASSERT_EQUAL_INT(DEFAULT_TEST_NETIF, entry->iface);
|
||||
TEST_ASSERT(ng_ipv6_addr_equal(&(entry->ipv6_addr), &addr));
|
||||
TEST_ASSERT_EQUAL_STRING(TEST_STRING4, (char *)entry->l2_addr);
|
||||
TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING4), entry->l2_addr_len);
|
||||
TEST_ASSERT_EQUAL_INT(0, entry->flags);
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_get_reachable__incomplete_if_local(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
ng_ipv6_nc_t *entry = NULL;
|
||||
|
||||
test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
|
||||
|
||||
TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr)));
|
||||
entry->flags = (NG_IPV6_NC_STATE_INCOMPLETE << NG_IPV6_NC_STATE_POS);
|
||||
TEST_ASSERT_NULL(ng_ipv6_nc_get_reachable(DEFAULT_TEST_NETIF, &addr));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_get_reachable__incomplete_if_global(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
ng_ipv6_nc_t *entry = NULL;
|
||||
|
||||
test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
|
||||
|
||||
TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get(KERNEL_PID_UNDEF, &addr)));
|
||||
entry->flags = (NG_IPV6_NC_STATE_INCOMPLETE << NG_IPV6_NC_STATE_POS);
|
||||
TEST_ASSERT_NULL(ng_ipv6_nc_get_reachable(KERNEL_PID_UNDEF, &addr));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_get_reachable__reachable_if_local(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
ng_ipv6_nc_t *entry = NULL;
|
||||
|
||||
test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
|
||||
|
||||
TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get(DEFAULT_TEST_NETIF, &addr)));
|
||||
entry->flags = (NG_IPV6_NC_STATE_REACHABLE << NG_IPV6_NC_STATE_POS);
|
||||
TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_reachable(DEFAULT_TEST_NETIF, &addr)));
|
||||
TEST_ASSERT_EQUAL_INT(DEFAULT_TEST_NETIF, entry->iface);
|
||||
TEST_ASSERT(ng_ipv6_addr_equal(&(entry->ipv6_addr), &addr));
|
||||
TEST_ASSERT_EQUAL_STRING(TEST_STRING4, (char *)entry->l2_addr);
|
||||
TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING4), entry->l2_addr_len);
|
||||
TEST_ASSERT_EQUAL_INT((NG_IPV6_NC_STATE_REACHABLE << NG_IPV6_NC_STATE_POS),
|
||||
entry->flags);
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_get_reachable__reachable_if_global(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
ng_ipv6_nc_t *entry = NULL;
|
||||
|
||||
test_ipv6_nc_add__success(); /* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF */
|
||||
|
||||
TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get(KERNEL_PID_UNDEF, &addr)));
|
||||
entry->flags = (NG_IPV6_NC_STATE_REACHABLE << NG_IPV6_NC_STATE_POS);
|
||||
TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_reachable(KERNEL_PID_UNDEF, &addr)));
|
||||
TEST_ASSERT_EQUAL_INT(DEFAULT_TEST_NETIF, entry->iface);
|
||||
TEST_ASSERT(ng_ipv6_addr_equal(&(entry->ipv6_addr), &addr));
|
||||
TEST_ASSERT_EQUAL_STRING(TEST_STRING4, (char *)entry->l2_addr);
|
||||
TEST_ASSERT_EQUAL_INT(sizeof(TEST_STRING4), entry->l2_addr_len);
|
||||
TEST_ASSERT_EQUAL_INT((NG_IPV6_NC_STATE_REACHABLE << NG_IPV6_NC_STATE_POS),
|
||||
entry->flags);
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_still_reachable__incomplete(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
|
||||
/* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF and sets flags to
|
||||
* (NG_IPV6_NC_STATE_INCOMPLETE << NG_IPV6_NC_STATE_POS) */
|
||||
test_ipv6_nc_get_reachable__incomplete_if_global();
|
||||
|
||||
TEST_ASSERT_NULL(ng_ipv6_nc_get_reachable(KERNEL_PID_UNDEF, &addr));
|
||||
TEST_ASSERT_NOT_NULL(ng_ipv6_nc_still_reachable(&addr));
|
||||
TEST_ASSERT_NULL(ng_ipv6_nc_get_reachable(KERNEL_PID_UNDEF, &addr));
|
||||
}
|
||||
|
||||
static void test_ipv6_nc_still_reachable__success(void)
|
||||
{
|
||||
ng_ipv6_addr_t addr = DEFAULT_TEST_IPV6_ADDR;
|
||||
ng_ipv6_nc_t *entry = NULL;
|
||||
|
||||
/* adds DEFAULT_TEST_IPV6_ADDR to DEFAULT_TEST_NETIF and sets flags to
|
||||
* (NG_IPV6_NC_STATE_REACHABLE << NG_IPV6_NC_STATE_POS) */
|
||||
test_ipv6_nc_get_reachable__reachable_if_global();
|
||||
|
||||
TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_reachable(KERNEL_PID_UNDEF, &addr)));
|
||||
|
||||
entry->flags = (NG_IPV6_NC_STATE_STALE << NG_IPV6_NC_STATE_POS);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(ng_ipv6_nc_still_reachable(&addr));
|
||||
TEST_ASSERT_NOT_NULL((entry = ng_ipv6_nc_get_reachable(KERNEL_PID_UNDEF, &addr)));
|
||||
TEST_ASSERT_EQUAL_INT((NG_IPV6_NC_STATE_REACHABLE << NG_IPV6_NC_STATE_POS),
|
||||
entry->flags);
|
||||
}
|
||||
|
||||
Test *tests_ipv6_nc_tests(void)
|
||||
{
|
||||
EMB_UNIT_TESTFIXTURES(fixtures) {
|
||||
new_TestFixture(test_ipv6_nc_add__EADDRINUSE),
|
||||
new_TestFixture(test_ipv6_nc_add__EFAULT),
|
||||
new_TestFixture(test_ipv6_nc_add__EINVAL_KERNEL_PID_UNDEF),
|
||||
new_TestFixture(test_ipv6_nc_add__EINVAL_ipv6_addr_unspecified),
|
||||
new_TestFixture(test_ipv6_nc_add__EINVAL_l2addr_too_long),
|
||||
new_TestFixture(test_ipv6_nc_add__ENOMEM),
|
||||
new_TestFixture(test_ipv6_nc_add__success),
|
||||
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),
|
||||
new_TestFixture(test_ipv6_nc_remove__success),
|
||||
new_TestFixture(test_ipv6_nc_get__empty),
|
||||
new_TestFixture(test_ipv6_nc_get__different_if),
|
||||
new_TestFixture(test_ipv6_nc_get__different_addr),
|
||||
new_TestFixture(test_ipv6_nc_get__success_if_local),
|
||||
new_TestFixture(test_ipv6_nc_get__success_if_global),
|
||||
new_TestFixture(test_ipv6_nc_get_reachable__incomplete_if_local),
|
||||
new_TestFixture(test_ipv6_nc_get_reachable__incomplete_if_global),
|
||||
new_TestFixture(test_ipv6_nc_get_reachable__reachable_if_local),
|
||||
new_TestFixture(test_ipv6_nc_get_reachable__reachable_if_global),
|
||||
new_TestFixture(test_ipv6_nc_still_reachable__incomplete),
|
||||
new_TestFixture(test_ipv6_nc_still_reachable__success),
|
||||
};
|
||||
|
||||
EMB_UNIT_TESTCALLER(ipv6_nc_tests, set_up, NULL, fixtures);
|
||||
|
||||
return (Test *)&ipv6_nc_tests;
|
||||
}
|
||||
|
||||
void tests_ipv6_nc(void)
|
||||
{
|
||||
TESTS_RUN(tests_ipv6_nc_tests());
|
||||
}
|
||||
/** @} */
|
||||
37
tests/unittests/tests-ipv6_nc/tests-ipv6_nc.h
Normal file
37
tests/unittests/tests-ipv6_nc/tests-ipv6_nc.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Martin Lenders
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup unittests
|
||||
* @{
|
||||
*
|
||||
* @file tests-ipv6_nc.h
|
||||
* @brief Unittests for the ``ipv6_nc`` module
|
||||
*
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*/
|
||||
#ifndef __TESTS_NETREG_H_
|
||||
#define __TESTS_NETREG_H_
|
||||
|
||||
#include "embUnit.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The entry point of this test suite.
|
||||
*/
|
||||
void tests_ipv6_nc(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __TESTS_NETREG_H_ */
|
||||
/** @} */
|
||||
Loading…
x
Reference in New Issue
Block a user