mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #6325 from miri64/gnrc_ipv6_nib/feat/internal
gnrc_ipv6_nib: initial import of internal NIB functions
This commit is contained in:
commit
72c3c9cf6a
@ -315,6 +315,11 @@ ifneq (,$(filter gnrc_ipv6_nc,$(USEMODULE)))
|
||||
USEMODULE += ipv6_addr
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_ipv6_nib,$(USEMODULE)))
|
||||
USEMODULE += ipv6_addr
|
||||
USEMODULE += random
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_ipv6_netif,$(USEMODULE)))
|
||||
USEMODULE += ipv6_addr
|
||||
USEMODULE += gnrc_netif
|
||||
|
186
sys/include/net/gnrc/ipv6/nib.h
Normal file
186
sys/include/net/gnrc/ipv6/nib.h
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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 Neighbor Information Base for IPv6
|
||||
* @ingroup net_gnrc_ipv6
|
||||
* @brief Neighbor Information Base (NIB) for IPv6
|
||||
*
|
||||
* @todo Add detailed description
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief NIB definitions
|
||||
*
|
||||
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||
*/
|
||||
#ifndef NET_GNRC_IPV6_NIB_H
|
||||
#define NET_GNRC_IPV6_NIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Timer event message types
|
||||
* @anchor net_gnrc_ipv6_nib_msg
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief (Re-)transmit unicast Neighbor Solicitation event.
|
||||
*
|
||||
* This message type is for the event of (re-)transmitting of unicast Neighbor
|
||||
* Solicitation. The expected message context is a pointer to a valid on-link
|
||||
* entry representing the neighbor to which the Neighbor Solicitation is
|
||||
* supposed to be sent.
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_SND_UC_NS (0x4fc0U)
|
||||
|
||||
/**
|
||||
* @brief (Re-)transmit multicast Neighbor Solicitation event.
|
||||
*
|
||||
* This message type is for the event of (re-)transmitting of multicast Neighbor
|
||||
* Solicitation. The expected message context is a pointer to a valid on-link
|
||||
* entry representing the neighbor to which [solicited
|
||||
* nodes](https://tools.ietf.org/html/rfc4291#section-2.7.1) group
|
||||
* the Neighbor Solicitation is supposed to be sent.
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_SND_MC_NS (0x4fc1U)
|
||||
|
||||
/**
|
||||
* @brief Send delayed Neighbor Advertisement event.
|
||||
*
|
||||
* This message type is for the event of sending delayed Neighbor
|
||||
* Advertisements. The expected message context is a pointer to a valid
|
||||
* [packet snip](@ref gnrc_pktsnip_t) in *sending order*, representing the
|
||||
* Neighbor Advertisement.
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_SND_NA (0x4fc2U)
|
||||
|
||||
/**
|
||||
* @brief Search router event.
|
||||
*
|
||||
* This message type is for the event of searching a (new) router (which
|
||||
* implies sending a multicast Router Solicitation). The expected message
|
||||
* context is a pointer to a valid interface behind which the router is
|
||||
* searched.
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_SEARCH_RTR (0x4fc3U)
|
||||
|
||||
/**
|
||||
* @brief Reconfirm router event.
|
||||
*
|
||||
* This message type is for the event the reconfirmation of a router (which
|
||||
* implies sending a unicast Router Solicitation). The expected message context
|
||||
* is a pointer to a valid on-link entry representing the router that is to be
|
||||
* confirmed.
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_RECONFIRM_RTR (0x4fc4U)
|
||||
|
||||
/**
|
||||
* @brief Reply Router Solicitation event.
|
||||
*
|
||||
* This message type is for the event of the delayed reply to a Router
|
||||
* Solicitaion with a Router Advertisement. The expected message context is a
|
||||
* pointer to a valid on-link entry representing the neighbor that sent the
|
||||
* Router Solicitation.
|
||||
*
|
||||
* @note Only handled with @ref GNRC_IPV6_NIB_CONF_ROUTER != 0
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_REPLY_RS (0x4fc5U)
|
||||
|
||||
/**
|
||||
* @brief (Re-)transmit multicast Router Advertisement event.
|
||||
*
|
||||
* This message type is for the event of (Re)transmit Advertisements
|
||||
* event. The expected message context is a pointer to a valid interface over
|
||||
* which the Router Advertisement will be sent and by which parameters it will
|
||||
* be configured.
|
||||
*
|
||||
* @note Only handled with @ref GNRC_IPV6_NIB_CONF_ROUTER != 0
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_SND_MC_RA (0x4fc6U)
|
||||
|
||||
/**
|
||||
* @brief Reachability timeout event.
|
||||
*
|
||||
* This message type is for the event of a REACHABLE state timeout.
|
||||
* The expected message context is a pointer to a valid on-link entry
|
||||
* representing the neighbor cache entry that faces a state change.
|
||||
*
|
||||
* @note Only handled with @ref GNRC_IPV6_NIB_CONF_ARSM != 0
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_REACH_TIMEOUT (0x4fc7U)
|
||||
|
||||
/**
|
||||
* @brief Delay timeout event.
|
||||
*
|
||||
* This message type is for the event of the DELAY state timeout.
|
||||
* The expected message context is a pointer to a valid on-link entry
|
||||
* representing the neighbor cache entry that faces a state change.
|
||||
*
|
||||
* @note Only handled with @ref GNRC_IPV6_NIB_CONF_ARSM != 0
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_DELAY_TIMEOUT (0x4fc8U)
|
||||
|
||||
/**
|
||||
* @brief Address registration timeout event.
|
||||
*
|
||||
* This message type is for the event of a 6LoWPAN address registration state
|
||||
* timeout. The expected message context is a pointer to a valid on-link entry
|
||||
* representing the neighbor which faces a timeout of its address registration.
|
||||
*
|
||||
* @note Only handled with @ref GNRC_IPV6_NIB_CONF_6LR != 0
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_ADDR_REG_TIMEOUT (0x4fc9U)
|
||||
|
||||
/**
|
||||
* @brief 6LoWPAN context timeout event.
|
||||
*
|
||||
* This message type is for the event of a 6LoWPAN compression context timeout.
|
||||
* The expected message context is the compression context's numerical
|
||||
* identifier.
|
||||
*
|
||||
* @note Only handled with @ref GNRC_IPV6_NIB_CONF_6LN != 0
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_6LO_CTX_TIMEOUT (0x4fcaU)
|
||||
|
||||
/**
|
||||
* @brief Authoritative border router timeout event.
|
||||
*
|
||||
* This message type is for the event of an Authoritative border router timeout.
|
||||
* The expected message context is the NIB-internal state of the authoritative
|
||||
* border router.
|
||||
*
|
||||
* @note Only handled with @ref GNRC_IPV6_NIB_CONF_MULTIHOP_P6C != 0
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_ABR_TIMEOUT (0x4fcbU)
|
||||
|
||||
/**
|
||||
* @brief Prefix timeout event.
|
||||
*
|
||||
* This message type is for the event of a prefix timeout. The expected message
|
||||
* context is a valid off-link entry representing the prefix.
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_PFX_TIMEOUT (0x4fccU)
|
||||
|
||||
/**
|
||||
* @brief Router timeout event.
|
||||
*
|
||||
* This message type is for the event of a router timeout. The expected message
|
||||
* context is a valid default router entry representing the router.
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_RTR_TIMEOUT (0x4fcdU)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_GNRC_IPV6_NIB_H */
|
||||
/** @} */
|
192
sys/include/net/gnrc/ipv6/nib/conf.h
Normal file
192
sys/include/net/gnrc/ipv6/nib/conf.h
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* 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_conf Configuration macros
|
||||
* @ingroup net_gnrc_ipv6_nib
|
||||
* @brief Configuration macros for network information base
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Configuration macro definitions for network information base
|
||||
*
|
||||
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
|
||||
*/
|
||||
#ifndef NET_GNRC_IPV6_NIB_CONF_H
|
||||
#define NET_GNRC_IPV6_NIB_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Compile flags
|
||||
* @brief Compile flags to (de-)activate certain features for NIB
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief enable features for 6Lo border router
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_CONF_6LBR
|
||||
#define GNRC_IPV6_NIB_CONF_6LBR (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief enable features for 6Lo router
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_CONF_6LR
|
||||
#if GNRC_IPV6_NIB_CONF_6LBR
|
||||
#define GNRC_IPV6_NIB_CONF_6LR (1)
|
||||
#else
|
||||
#define GNRC_IPV6_NIB_CONF_6LR (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief enable features for 6Lo node
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_CONF_6LN
|
||||
#if GNRC_IPV6_NIB_CONF_6LR
|
||||
#define GNRC_IPV6_NIB_CONF_6LN (1)
|
||||
#else
|
||||
#define GNRC_IPV6_NIB_CONF_6LN (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief enable features for IPv6 routers
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_CONF_ROUTER
|
||||
#if GNRC_IPV6_NIB_CONF_6LR
|
||||
#define GNRC_IPV6_NIB_CONF_ROUTER (1)
|
||||
#else
|
||||
#define GNRC_IPV6_NIB_CONF_ROUTER (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief (de-)activate router advertising at interface start-up
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_CONF_ADV_ROUTER
|
||||
#if GNRC_IPV6_NIB_CONF_ROUTER && \
|
||||
(!GNRC_IPV6_NIB_CONF_6LR || GNRC_IPV6_NIB_CONF_6LBR)
|
||||
#define GNRC_IPV6_NIB_CONF_ADV_ROUTER (1)
|
||||
#else
|
||||
#define GNRC_IPV6_NIB_CONF_ADV_ROUTER (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief (de-)activate NDP address resolution state-machine
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_CONF_ARSM
|
||||
#define GNRC_IPV6_NIB_CONF_ARSM (1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief queue packets for address resolution
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_CONF_QUEUE_PKT
|
||||
#if GNRC_IPV6_NIB_CONF_6LN
|
||||
#define GNRC_IPV6_NIB_CONF_QUEUE_PKT (0)
|
||||
#else
|
||||
#define GNRC_IPV6_NIB_CONF_QUEUE_PKT (1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief handle NDP messages according for stateless address
|
||||
* auto-configuration (if activated on interface)
|
||||
*
|
||||
* @see [RFC 4862](https://tools.ietf.org/html/rfc4862)
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_CONF_SLAAC
|
||||
#define GNRC_IPV6_NIB_CONF_SLAAC (1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief handle Redirect Messages
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_CONF_REDIRECT
|
||||
#define GNRC_IPV6_NIB_CONF_REDIRECT (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief (de-)activate destination cache
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_CONF_DC
|
||||
#if GNRC_IPV6_NIB_CONF_REDIRECT
|
||||
#define GNRC_IPV6_NIB_CONF_DC (1)
|
||||
#else
|
||||
#define GNRC_IPV6_NIB_CONF_DC (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Multihop prefix and 6LoWPAN context distribution
|
||||
*
|
||||
* @see [RFC 6775, section 8.1](https://tools.ietf.org/html/rfc6775#section-8.1)
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
|
||||
#define GNRC_IPV6_NIB_CONF_MULTIHOP_P6C (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Multihop duplicate address detection
|
||||
*
|
||||
* @see [RFC 6775, section 8.2](https://tools.ietf.org/html/rfc6775#section-8.2)
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_CONF_MULTIHOP_DAD
|
||||
#define GNRC_IPV6_NIB_CONF_MULTIHOP_DAD (0)
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Reset time in milliseconds for the reachability time
|
||||
*
|
||||
* @see [RFC 4861, section 6.3.4](https://tools.ietf.org/html/rfc4861#section-6.3.4)
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_CONF_REACH_TIME_RESET
|
||||
#define GNRC_IPV6_NIB_CONF_REACH_TIME_RESET (7200000U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Maximum link-layer address length (aligned)
|
||||
*/
|
||||
#if (GNRC_NETIF_HDR_L2ADDR_MAX_LEN % 8)
|
||||
#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (((GNRC_NETIF_HDR_L2ADDR_MAX_LEN >> 3) + 1) << 3)
|
||||
#else
|
||||
#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (GNRC_NETIF_HDR_L2ADDR_MAX_LEN)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of default routers in the default router list.
|
||||
*
|
||||
* @note **This number has direct influence on the maximum number of
|
||||
* default routers**
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_DEFAULT_ROUTER_NUMOF
|
||||
#define GNRC_IPV6_NIB_DEFAULT_ROUTER_NUMOF (1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of entries in NIB
|
||||
*
|
||||
* @note **This number has direct influence on the maximum number of
|
||||
* neighbors and duplicate address detection table entries**
|
||||
*/
|
||||
#ifndef GNRC_IPV6_NIB_NUMOF
|
||||
#define GNRC_IPV6_NIB_NUMOF (4)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_GNRC_IPV6_NIB_CONF_H */
|
||||
/** @} */
|
134
sys/include/net/gnrc/ipv6/nib/nc.h
Normal file
134
sys/include/net/gnrc/ipv6/nib/nc.h
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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_nc Neighbor Cache
|
||||
* @ingroup net_gnrc_ipv6_nib
|
||||
* @brief Neighbor cache component of network information base
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Neighbor cache definitions
|
||||
*
|
||||
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||
*/
|
||||
#ifndef NET_GNRC_IPV6_NIB_NC_H
|
||||
#define NET_GNRC_IPV6_NIB_NC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "net/eui64.h"
|
||||
#include "net/gnrc/netif/hdr.h"
|
||||
#include "net/gnrc/ipv6/nib/conf.h"
|
||||
#include "net/ipv6/addr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Values for gnrc_ipv6_nib_nc_t::info
|
||||
* @anchor net_gnrc_ipv6_nib_nc_info
|
||||
* @name Info values
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Mask for neighbor unreachability detection (NUD) states
|
||||
*
|
||||
* @see [RFC 4861, section 7.3.2](https://tools.ietf.org/html/rfc4861#section-7.3.2)
|
||||
* @see [RFC 7048](https://tools.ietf.org/html/rfc7048)
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK (0x0007)
|
||||
|
||||
/**
|
||||
* @brief not managed by NUD
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED (0x0000)
|
||||
|
||||
/**
|
||||
* @brief entry is not reachable
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE (0x0001)
|
||||
|
||||
/**
|
||||
* @brief address resolution is currently performed
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE (0x0002)
|
||||
|
||||
/**
|
||||
* @brief address might not be reachable
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE (0x0003)
|
||||
|
||||
/**
|
||||
* @brief NUD will be performed in a moment
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY (0x0004)
|
||||
|
||||
/**
|
||||
* @brief NUD is performed
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE (0x0005)
|
||||
|
||||
/**
|
||||
* @brief entry is reachable
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE (0x0006)
|
||||
|
||||
/**
|
||||
* @brief gnrc_ipv6_nib_t::next_hop is router
|
||||
*
|
||||
* This flag indicates that gnrc_ipv6_nib_t::next_hop is a router, but it does
|
||||
* not necessarily indicate that it is in the default router list! A neighbor
|
||||
* that has this flag unset however **must not** appear in the default router
|
||||
* list.
|
||||
*
|
||||
* @see [RFC 4861, Appendix D](https://tools.ietf.org/html/rfc4861#page-91)
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_IS_ROUTER (0x0008)
|
||||
|
||||
/**
|
||||
* @brief Mask for interface identifier
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_IFACE_MASK (0x01f0)
|
||||
|
||||
/**
|
||||
* @brief Shift position of interface identifier
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_IFACE_POS (4)
|
||||
|
||||
/**
|
||||
* @brief Mask for 6LoWPAN address registration (6Lo-AR) states
|
||||
*
|
||||
* @see [RFC 6775, section 3.5](https://tools.ietf.org/html/rfc6775#section-3.5)
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_AR_STATE_MASK (0x0600)
|
||||
|
||||
/**
|
||||
* @brief not managed by 6Lo-AR (address can be removed when memory is low
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_AR_STATE_GC (0x0000)
|
||||
|
||||
/**
|
||||
* @brief address registration still pending at upstream router
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_AR_STATE_TENTATIVE (0x0200)
|
||||
|
||||
/**
|
||||
* @brief address is registered
|
||||
*/
|
||||
#define GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED (0x0600)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NET_GNRC_IPV6_NIB_NC_H */
|
||||
/** @} */
|
@ -22,6 +22,9 @@ endif
|
||||
ifneq (,$(filter gnrc_ipv6_netif,$(USEMODULE)))
|
||||
DIRS += network_layer/ipv6/netif
|
||||
endif
|
||||
ifneq (,$(filter gnrc_ipv6_nib,$(USEMODULE)))
|
||||
DIRS += network_layer/ipv6/nib
|
||||
endif
|
||||
ifneq (,$(filter gnrc_ipv6_whitelist,$(USEMODULE)))
|
||||
DIRS += network_layer/ipv6/whitelist
|
||||
endif
|
||||
|
3
sys/net/gnrc/network_layer/ipv6/nib/Makefile
Normal file
3
sys/net/gnrc/network_layer/ipv6/nib/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = gnrc_ipv6_nib
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
387
sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c
Normal file
387
sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c
Normal file
@ -0,0 +1,387 @@
|
||||
/*
|
||||
* 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 <m.lenders@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "net/gnrc/ipv6.h"
|
||||
#include "net/gnrc/ipv6/nib/conf.h"
|
||||
#include "net/gnrc/ipv6/nib/nc.h"
|
||||
#include "net/gnrc/ipv6/nib.h"
|
||||
#include "net/gnrc/netif.h"
|
||||
#include "random.h"
|
||||
|
||||
#include "_nib-internal.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
/* pointers for default router selection */
|
||||
static _nib_dr_entry_t *_prime_def_router = NULL;
|
||||
static clist_node_t _next_removable = { NULL };
|
||||
|
||||
static _nib_onl_entry_t _nodes[GNRC_IPV6_NIB_NUMOF];
|
||||
static _nib_dr_entry_t _def_routers[GNRC_IPV6_NIB_DEFAULT_ROUTER_NUMOF];
|
||||
static _nib_iface_t _nis[GNRC_NETIF_NUMOF];
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
static char addr_str[IPV6_ADDR_MAX_STR_LEN];
|
||||
#endif
|
||||
|
||||
mutex_t _nib_mutex = MUTEX_INIT;
|
||||
|
||||
static void _override_node(const ipv6_addr_t *addr, unsigned iface,
|
||||
_nib_onl_entry_t *node);
|
||||
static inline bool _node_unreachable(_nib_onl_entry_t *node);
|
||||
|
||||
void _nib_init(void)
|
||||
{
|
||||
#ifdef TEST_SUITES
|
||||
_prime_def_router = NULL;
|
||||
_next_removable.next = NULL;
|
||||
memset(_nodes, 0, sizeof(_nodes));
|
||||
memset(_def_routers, 0, sizeof(_def_routers));
|
||||
memset(_nis, 0, sizeof(_nis));
|
||||
#endif
|
||||
/* TODO: load ABR information from persistent memory */
|
||||
}
|
||||
|
||||
_nib_onl_entry_t *_nib_onl_alloc(const ipv6_addr_t *addr, unsigned iface)
|
||||
{
|
||||
_nib_onl_entry_t *node = NULL;
|
||||
|
||||
assert(addr != NULL);
|
||||
DEBUG("nib: Allocating on-link node entry (addr = %s, iface = %u)\n",
|
||||
ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), iface);
|
||||
for (unsigned i = 0; i < GNRC_IPV6_NIB_NUMOF; i++) {
|
||||
_nib_onl_entry_t *tmp = &_nodes[i];
|
||||
|
||||
if ((_nib_onl_get_if(tmp) == iface) &&
|
||||
(ipv6_addr_equal(addr, &tmp->ipv6))) {
|
||||
/* exact match */
|
||||
DEBUG(" %p is an exact match\n", (void *)tmp);
|
||||
return tmp;
|
||||
}
|
||||
if ((node == NULL) && (tmp->mode == _EMPTY)) {
|
||||
node = tmp;
|
||||
}
|
||||
}
|
||||
if (node != NULL) {
|
||||
DEBUG(" using %p\n", (void *)node);
|
||||
_override_node(addr, iface, node);
|
||||
}
|
||||
#if ENABLE_DEBUG
|
||||
else {
|
||||
DEBUG(" NIB full\n");
|
||||
}
|
||||
#endif
|
||||
return node;
|
||||
}
|
||||
|
||||
static inline bool _is_gc(_nib_onl_entry_t *node)
|
||||
{
|
||||
return ((node->mode & ~(_NC)) == 0) &&
|
||||
((node->info & GNRC_IPV6_NIB_NC_INFO_AR_STATE_MASK) ==
|
||||
GNRC_IPV6_NIB_NC_INFO_AR_STATE_GC);
|
||||
}
|
||||
|
||||
static inline _nib_onl_entry_t *_cache_out_onl_entry(const ipv6_addr_t *addr,
|
||||
unsigned iface,
|
||||
uint16_t cstate)
|
||||
{
|
||||
/* Use clist as FIFO for caching */
|
||||
_nib_onl_entry_t *first = (_nib_onl_entry_t *)clist_lpop(&_next_removable);
|
||||
_nib_onl_entry_t *tmp = first, *res = NULL;
|
||||
|
||||
DEBUG("nib: Searching for replaceable entries (addr = %s, iface = %u)\n",
|
||||
ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), iface);
|
||||
if (tmp == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
do {
|
||||
if (_is_gc(tmp)) {
|
||||
DEBUG("nib: Removing neighbor cache entry (addr = %s, "
|
||||
"iface = %u) ",
|
||||
ipv6_addr_to_str(addr_str, &tmp->ipv6,
|
||||
sizeof(addr_str)),
|
||||
_nib_onl_get_if(tmp));
|
||||
DEBUG("for (addr = %s, iface = %u)\n",
|
||||
ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)),
|
||||
iface);
|
||||
res = tmp;
|
||||
res->mode = _EMPTY;
|
||||
_override_node(addr, iface, res);
|
||||
/* cstate masked above already */
|
||||
res->info = cstate;
|
||||
res->mode = _NC;
|
||||
break;
|
||||
}
|
||||
/* requeue if not garbage collectible at the moment */
|
||||
DEBUG("nib: Requeing (addr = %s, iface = %u)\n",
|
||||
ipv6_addr_to_str(addr_str, &tmp->ipv6,
|
||||
sizeof(addr_str)),
|
||||
_nib_onl_get_if(tmp));
|
||||
clist_rpush(&_next_removable, (clist_node_t *)tmp);
|
||||
tmp = (_nib_onl_entry_t *)clist_lpop(&_next_removable);
|
||||
} while (tmp != first);
|
||||
return res;
|
||||
}
|
||||
|
||||
_nib_onl_entry_t *_nib_nc_add(const ipv6_addr_t *addr, unsigned iface,
|
||||
uint16_t cstate)
|
||||
{
|
||||
cstate &= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK;
|
||||
assert(cstate != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY);
|
||||
assert(cstate != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE);
|
||||
assert(cstate != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE);
|
||||
_nib_onl_entry_t *node = _nib_onl_alloc(addr, iface);
|
||||
if (node == NULL) {
|
||||
return _cache_out_onl_entry(addr, iface, cstate);
|
||||
}
|
||||
DEBUG("nib: Adding to neighbor cache (addr = %s, iface = %u)\n",
|
||||
ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), iface);
|
||||
if (!(node->mode & _NC)) {
|
||||
node->info &= ~GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK;
|
||||
/* masked above already */
|
||||
node->info |= cstate;
|
||||
node->mode |= _NC;
|
||||
}
|
||||
if (node->next == NULL) {
|
||||
DEBUG("nib: queueing (addr = %s, iface = %u) for potential removal\n",
|
||||
ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), iface);
|
||||
/* add to next removable list, if not already in it */
|
||||
clist_rpush(&_next_removable, (clist_node_t *)node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
_nib_onl_entry_t *_nib_onl_iter(const _nib_onl_entry_t *last)
|
||||
{
|
||||
for (const _nib_onl_entry_t *node = (last) ? last + 1 : _nodes;
|
||||
node < (_nodes + GNRC_IPV6_NIB_NUMOF);
|
||||
node++) {
|
||||
if (node->mode != _EMPTY) {
|
||||
/* const modifier provided to assure internal consistency.
|
||||
* Can now be discarded. */
|
||||
return (_nib_onl_entry_t *)node;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_nib_onl_entry_t *_nib_onl_get(const ipv6_addr_t *addr, unsigned iface)
|
||||
{
|
||||
assert(addr != NULL);
|
||||
DEBUG("nib: Getting on-link node entry (addr = %s, iface = %u)\n",
|
||||
ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), iface);
|
||||
for (unsigned i = 0; i < GNRC_IPV6_NIB_NUMOF; i++) {
|
||||
_nib_onl_entry_t *node = &_nodes[i];
|
||||
|
||||
if ((node->mode != _EMPTY) &&
|
||||
/* either requested or current interface undefined or
|
||||
* interfaces equal */
|
||||
((_nib_onl_get_if(node) == 0) || (iface == 0) ||
|
||||
(_nib_onl_get_if(node) == iface)) &&
|
||||
ipv6_addr_equal(&node->ipv6, addr)) {
|
||||
DEBUG(" Found %p\n", (void *)node);
|
||||
return node;
|
||||
}
|
||||
}
|
||||
DEBUG(" No suitable entry found\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void _nib_nc_set_reachable(_nib_onl_entry_t *node)
|
||||
{
|
||||
_nib_iface_t *iface = _nib_iface_get(_nib_onl_get_if(node));
|
||||
|
||||
DEBUG("nib: set %s%%%u reachable (reachable time = %u)\n",
|
||||
ipv6_addr_to_str(addr_str, &node->ipv6, sizeof(addr_str)),
|
||||
_nib_onl_get_if(node), iface->reach_time);
|
||||
node->info &= ~GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK;
|
||||
node->info |= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE;
|
||||
/* TODO add event for state change to STALE to event timer*/
|
||||
(void)iface;
|
||||
}
|
||||
|
||||
void _nib_nc_remove(_nib_onl_entry_t *node)
|
||||
{
|
||||
DEBUG("nib: remove from neighbor cache (addr = %s, iface = %u)\n",
|
||||
ipv6_addr_to_str(addr_str, &node->ipv6, sizeof(addr_str)),
|
||||
_nib_onl_get_if(node));
|
||||
node->mode &= ~(_NC);
|
||||
/* TODO: remove NC related timers */
|
||||
_nib_onl_clear(node);
|
||||
}
|
||||
|
||||
_nib_dr_entry_t *_nib_drl_add(const ipv6_addr_t *router_addr, unsigned iface)
|
||||
{
|
||||
_nib_dr_entry_t *def_router = NULL;
|
||||
|
||||
DEBUG("nib: Allocating default router list entry "
|
||||
"(router_addr = %s, iface = %u)\n",
|
||||
ipv6_addr_to_str(addr_str, router_addr, sizeof(addr_str)), iface);
|
||||
for (unsigned i = 0; i < GNRC_IPV6_NIB_DEFAULT_ROUTER_NUMOF; i++) {
|
||||
_nib_dr_entry_t *tmp = &_def_routers[i];
|
||||
_nib_onl_entry_t *tmp_node = tmp->next_hop;
|
||||
|
||||
if ((tmp_node != NULL) &&
|
||||
(_nib_onl_get_if(tmp_node) == iface) &&
|
||||
(ipv6_addr_equal(router_addr, &tmp_node->ipv6))) {
|
||||
/* exact match */
|
||||
DEBUG(" %p is an exact match\n", (void *)tmp);
|
||||
tmp_node->mode |= _DRL;
|
||||
return tmp;
|
||||
}
|
||||
if ((def_router == NULL) && (tmp_node == NULL)) {
|
||||
def_router = tmp;
|
||||
}
|
||||
}
|
||||
if (def_router != NULL) {
|
||||
DEBUG(" using %p\n", (void *)def_router);
|
||||
def_router->next_hop = _nib_onl_alloc(router_addr, iface);
|
||||
|
||||
if (def_router->next_hop == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
_override_node(router_addr, iface, def_router->next_hop);
|
||||
def_router->next_hop->mode |= _DRL;
|
||||
}
|
||||
return def_router;
|
||||
}
|
||||
|
||||
void _nib_drl_remove(_nib_dr_entry_t *nib_dr)
|
||||
{
|
||||
if (nib_dr->next_hop != NULL) {
|
||||
nib_dr->next_hop->mode &= ~(_DRL);
|
||||
_nib_onl_clear(nib_dr->next_hop);
|
||||
memset(nib_dr, 0, sizeof(_nib_dr_entry_t));
|
||||
}
|
||||
if (nib_dr == _prime_def_router) {
|
||||
_prime_def_router = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
_nib_dr_entry_t *_nib_drl_iter(const _nib_dr_entry_t *last)
|
||||
{
|
||||
for (const _nib_dr_entry_t *def_router = (last) ? (last + 1) : _def_routers;
|
||||
def_router < (_def_routers + GNRC_IPV6_NIB_DEFAULT_ROUTER_NUMOF);
|
||||
def_router++) {
|
||||
_nib_onl_entry_t *node = def_router->next_hop;
|
||||
if ((node != NULL) && (node->mode != _EMPTY)) {
|
||||
/* const modifier provided to assure internal consistency.
|
||||
* Can now be discarded. */
|
||||
return (_nib_dr_entry_t *)def_router;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_nib_dr_entry_t *_nib_drl_get(const ipv6_addr_t *router_addr, unsigned iface)
|
||||
{
|
||||
for (unsigned i = 0; i < GNRC_IPV6_NIB_DEFAULT_ROUTER_NUMOF; i++) {
|
||||
_nib_dr_entry_t *def_router = &_def_routers[i];
|
||||
_nib_onl_entry_t *node = def_router->next_hop;
|
||||
|
||||
if ((node != NULL) &&
|
||||
(_nib_onl_get_if(node) == iface) &&
|
||||
(ipv6_addr_equal(router_addr, &node->ipv6))) {
|
||||
/* It is linked to the default router list so it *should* be set */
|
||||
assert(node->mode & _DRL);
|
||||
return def_router;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_nib_dr_entry_t *_nib_drl_get_dr(void)
|
||||
{
|
||||
_nib_dr_entry_t *ptr = NULL;
|
||||
|
||||
/* if there is already a default router selected or
|
||||
* its reachability is not suspect */
|
||||
if (!((_prime_def_router == NULL) ||
|
||||
(_node_unreachable(_prime_def_router->next_hop)))) {
|
||||
/* take it */
|
||||
return _prime_def_router;
|
||||
}
|
||||
/* else search next reachable router */
|
||||
do {
|
||||
ptr = _nib_drl_iter(ptr);
|
||||
/* if there is no reachable router */
|
||||
if (ptr == NULL) {
|
||||
_nib_dr_entry_t *next = _nib_drl_iter(_prime_def_router);
|
||||
/* if first time called or last selected router is last in
|
||||
* router list */
|
||||
if ((_prime_def_router == NULL) || (next == NULL)) {
|
||||
/* wrap around to first (potentially unreachable) route
|
||||
* to trigger NUD for it */
|
||||
_prime_def_router = _nib_drl_iter(NULL);
|
||||
}
|
||||
/* there is another default router, choose it regardless of
|
||||
* reachability to potentially trigger NUD for it */
|
||||
else if (next != NULL) {
|
||||
_prime_def_router = next;
|
||||
}
|
||||
return _prime_def_router;
|
||||
}
|
||||
} while (_node_unreachable(ptr->next_hop));
|
||||
_prime_def_router = ptr;
|
||||
return _prime_def_router;
|
||||
}
|
||||
|
||||
_nib_iface_t *_nib_iface_get(unsigned iface)
|
||||
{
|
||||
_nib_iface_t *ni = NULL;
|
||||
|
||||
assert(iface <= _NIB_IF_MAX);
|
||||
for (unsigned i = 0; i < GNRC_NETIF_NUMOF; i++) {
|
||||
_nib_iface_t *tmp = &_nis[i];
|
||||
if (((unsigned)tmp->pid) == iface) {
|
||||
return tmp;
|
||||
}
|
||||
if ((ni == NULL) && (tmp->pid == KERNEL_PID_UNDEF)) {
|
||||
ni = tmp;
|
||||
}
|
||||
}
|
||||
if (ni != NULL) {
|
||||
memset(ni, 0, sizeof(_nib_iface_t));
|
||||
/* TODO: set random reachable time using constants from #6220 */
|
||||
ni->pid = (kernel_pid_t)iface;
|
||||
}
|
||||
return ni;
|
||||
}
|
||||
|
||||
static void _override_node(const ipv6_addr_t *addr, unsigned iface,
|
||||
_nib_onl_entry_t *node)
|
||||
{
|
||||
_nib_onl_clear(node);
|
||||
memcpy(&node->ipv6, addr, sizeof(node->ipv6));
|
||||
_nib_onl_set_if(node, iface);
|
||||
}
|
||||
|
||||
static inline bool _node_unreachable(_nib_onl_entry_t *node)
|
||||
{
|
||||
switch (node->info & GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK) {
|
||||
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE:
|
||||
/* Falls through. */
|
||||
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
633
sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.h
Normal file
633
sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.h
Normal file
@ -0,0 +1,633 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup net_gnrc_ipv6_nib
|
||||
* @internal
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Internal definitions
|
||||
*
|
||||
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||
*/
|
||||
#ifndef PRIV_NIB_INTERNAL_H
|
||||
#define PRIV_NIB_INTERNAL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "kernel_types.h"
|
||||
#include "mutex.h"
|
||||
#include "net/eui64.h"
|
||||
#include "net/ipv6/addr.h"
|
||||
#include "net/gnrc/ipv6/nib/nc.h"
|
||||
#include "net/gnrc/ipv6/nib/conf.h"
|
||||
#include "net/gnrc/pktqueue.h"
|
||||
#include "net/ndp.h"
|
||||
#include "random.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Mode flags for entries
|
||||
* @anchor net_gnrc_ipv6_nib_mode
|
||||
* @{
|
||||
*/
|
||||
#define _EMPTY (0x00) /**< empty */
|
||||
#define _NC (0x01) /**< neighbor cache */
|
||||
#define _DC (0x02) /**< destination cache */
|
||||
#define _PL (0x04) /**< prefix list */
|
||||
#define _DRL (0x08) /**< default router list */
|
||||
#define _FT (0x10) /**< forwarding table */
|
||||
#define _DAD (0x20) /**< 6LoWPAN duplicate address detection table */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Shorter name for convenience ;-)
|
||||
*/
|
||||
#define _NIB_IF_MASK (GNRC_IPV6_NIB_NC_INFO_IFACE_MASK)
|
||||
|
||||
/**
|
||||
* @brief Shorter name for convenience ;-)
|
||||
*/
|
||||
#define _NIB_IF_POS (GNRC_IPV6_NIB_NC_INFO_IFACE_POS)
|
||||
|
||||
/**
|
||||
* @brief Maximum identifier for the interface
|
||||
*/
|
||||
#define _NIB_IF_MAX (_NIB_IF_MASK >> _NIB_IF_POS)
|
||||
|
||||
/**
|
||||
* @brief On-link NIB entry
|
||||
* @anchor _nib_onl_entry_t
|
||||
*/
|
||||
typedef struct _nib_onl_entry {
|
||||
struct _nib_onl_entry *next; /**< next removable entry */
|
||||
#if GNRC_IPV6_NIB_CONF_QUEUE_PKT || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief queue for packets currently in address resolution
|
||||
*
|
||||
* @note Only available if @ref GNRC_IPV6_NIB_CONF_QUEUE_PKT != 0.
|
||||
*/
|
||||
gnrc_pktqueue_t *pktqueue;
|
||||
#endif
|
||||
/**
|
||||
* @brief Neighbors IPv6 address
|
||||
*/
|
||||
ipv6_addr_t ipv6;
|
||||
#if GNRC_IPV6_NIB_CONF_6LR || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief The neighbors EUI-64 (used for DAD)
|
||||
*
|
||||
* @note Only available if @ref GNRC_IPV6_NIB_CONF_6LR != 0.
|
||||
*/
|
||||
eui64_t eui64;
|
||||
#endif
|
||||
#if GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Link-layer address of _nib_onl_entry_t::next_hop
|
||||
*
|
||||
* @note Only available if @ref GNRC_IPV6_NIB_CONF_ARSM != 0.
|
||||
*/
|
||||
uint8_t l2addr[GNRC_IPV6_NIB_L2ADDR_MAX_LEN];
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Information flags
|
||||
*
|
||||
* @see [NC info values](@ref net_gnrc_ipv6_nib_nc_info)
|
||||
*/
|
||||
uint16_t info;
|
||||
|
||||
/**
|
||||
* @brief NIB entry mode
|
||||
*
|
||||
* This field identifies which "views" of the NIB the entry belongs to.
|
||||
*
|
||||
* @see [Mode flags for entries](@ref net_gnrc_ipv6_nib_mode).
|
||||
*/
|
||||
uint8_t mode;
|
||||
#if GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Neighbor solicitations sent for probing
|
||||
*
|
||||
* @note Only available if @ref GNRC_IPV6_NIB_CONF_ARSM != 0.
|
||||
*/
|
||||
uint8_t ns_sent;
|
||||
|
||||
/**
|
||||
* @brief length in bytes of _nib_onl_entry_t::l2addr
|
||||
*
|
||||
* @note Only available if @ref GNRC_IPV6_NIB_CONF_ARSM != 0.
|
||||
*/
|
||||
uint8_t l2addr_len;
|
||||
#endif
|
||||
} _nib_onl_entry_t;
|
||||
|
||||
/**
|
||||
* @brief Default route NIB entry
|
||||
*/
|
||||
typedef struct {
|
||||
_nib_onl_entry_t *next_hop; /**< next hop to destination */
|
||||
uint16_t ltime; /**< lifetime in seconds */
|
||||
} _nib_dr_entry_t;
|
||||
|
||||
/**
|
||||
* @brief Off-link NIB entry
|
||||
*/
|
||||
typedef struct {
|
||||
_nib_onl_entry_t *next_hop; /**< next hop to destination */
|
||||
ipv6_addr_t pfx; /**< prefix to the destination */
|
||||
unsigned pfx_len; /**< prefix-length in bits of
|
||||
* _nib_onl_entry_t::pfx */
|
||||
} _nib_offl_entry_t;
|
||||
|
||||
/**
|
||||
* @brief Interface specific information for Neighbor Discovery
|
||||
*/
|
||||
typedef struct {
|
||||
#if GNRC_IPV6_NIB_CONF_ARSM
|
||||
/**
|
||||
* @brief base for random reachable time calculation
|
||||
*/
|
||||
uint32_t reach_time_base;
|
||||
uint32_t reach_time; /**< reachable time (in ms) */
|
||||
uint32_t retrans_time; /**< retransmission time (in ms) */
|
||||
#endif
|
||||
#if GNRC_IPV6_NIB_CONF_ROUTER || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief timestamp in milliseconds of last unsolicited router
|
||||
* advertisement
|
||||
*
|
||||
* @note Only available if @ref GNRC_IPV6_NIB_CONF_ROUTER.
|
||||
*/
|
||||
uint32_t last_ra;
|
||||
#endif
|
||||
kernel_pid_t pid; /**< identifier of the interface */
|
||||
#if GNRC_IPV6_NIB_CONF_ROUTER || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief number of unsolicited router advertisements sent
|
||||
*
|
||||
* This only counts up to the first @ref NDP_MAX_INIT_RA_NUMOF on interface
|
||||
* initialization. The last @ref NDP_MAX_FIN_RA_NUMOF of an advertising
|
||||
* interface are counted from UINT8_MAX - @ref NDP_MAX_FIN_RA_NUMOF + 1.
|
||||
*
|
||||
* @note Only available if @ref GNRC_IPV6_NIB_CONF_ROUTER.
|
||||
*/
|
||||
uint8_t ra_sent;
|
||||
#endif
|
||||
/**
|
||||
* @brief number of unsolicited router solicitations scheduled
|
||||
*/
|
||||
uint8_t rs_sent;
|
||||
/**
|
||||
* @brief number of unsolicited neighbor advertisements scheduled
|
||||
*/
|
||||
uint8_t na_sent;
|
||||
} _nib_iface_t;
|
||||
|
||||
/**
|
||||
* @brief Mutex for locking the NIB
|
||||
*/
|
||||
extern mutex_t _nib_mutex;
|
||||
|
||||
/**
|
||||
* @brief Initializes NIB internally
|
||||
*/
|
||||
void _nib_init(void);
|
||||
|
||||
/**
|
||||
* @brief Gets interface identifier from a NIB entry
|
||||
*
|
||||
* @param[in] node A NIB entry.
|
||||
*
|
||||
* @return The NIB entry's interface identifier.
|
||||
*/
|
||||
static inline unsigned _nib_onl_get_if(const _nib_onl_entry_t *node)
|
||||
{
|
||||
return (node->info & _NIB_IF_MASK) >> _NIB_IF_POS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets interface for a NIB entry
|
||||
*
|
||||
* @param[in,out] node A NIB entry.
|
||||
* @param[in] iface An interface identifier.
|
||||
*/
|
||||
static inline void _nib_onl_set_if(_nib_onl_entry_t *node, unsigned iface)
|
||||
{
|
||||
assert(iface <= _NIB_IF_MAX);
|
||||
node->info &= ~(_NIB_IF_MASK);
|
||||
node->info |= ((iface << _NIB_IF_POS) & _NIB_IF_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates or gets an existing on-link entry by address
|
||||
*
|
||||
* @pre `(addr != NULL)`.
|
||||
*
|
||||
* @param[in] addr An IPv6 address. May not be NULL.
|
||||
* *May also be a global address!*
|
||||
* @param[in] iface The interface to the node.
|
||||
*
|
||||
* @return A new or existing on-link entry with _nib_onl_entry_t::ipv6 set to
|
||||
* @p addr.
|
||||
* @return NULL, if no space is left.
|
||||
*/
|
||||
_nib_onl_entry_t *_nib_onl_alloc(const ipv6_addr_t *addr, unsigned iface);
|
||||
|
||||
/**
|
||||
* @brief Clears out a NIB entry (on-link version)
|
||||
*
|
||||
* @param[in,out] node An entry.
|
||||
*
|
||||
* @return true, if entry was cleared.
|
||||
* @return false, if entry was not cleared.
|
||||
*/
|
||||
static inline bool _nib_onl_clear(_nib_onl_entry_t *node)
|
||||
{
|
||||
if (node->mode == _EMPTY) {
|
||||
memset(node, 0, sizeof(_nib_onl_entry_t));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Iterates over on-link entries
|
||||
*
|
||||
* @param[in] last Last entry (NULL to start).
|
||||
*
|
||||
* @return entry after @p last.
|
||||
*/
|
||||
_nib_onl_entry_t *_nib_onl_iter(const _nib_onl_entry_t *last);
|
||||
|
||||
/**
|
||||
* @brief Gets a node by IPv6 address and interface
|
||||
*
|
||||
* @pre `(addr != NULL)`
|
||||
*
|
||||
* @param[in] addr The address of a node. May not be NULL.
|
||||
* @param[in] iface The interface to the node. May be 0 for any interface.
|
||||
*
|
||||
* @return The NIB entry for node with @p addr and @p iface on success.
|
||||
* @return NULL, if there is no such entry.
|
||||
*/
|
||||
_nib_onl_entry_t *_nib_onl_get(const ipv6_addr_t *addr, unsigned iface);
|
||||
|
||||
/**
|
||||
* @brief Creates or gets an existing node from the neighbor cache by address
|
||||
*
|
||||
* @pre `(addr != NULL)`
|
||||
* @pre `((cstate & GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK) !=
|
||||
* GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY)`
|
||||
* @pre `((cstate & GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK) !=
|
||||
* GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE)`
|
||||
* @pre `((cstate & GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK) !=
|
||||
* GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE)`
|
||||
*
|
||||
* @param[in] addr The address of a node. May not be NULL.
|
||||
* @param[in] iface The interface to the node.
|
||||
* @param[in] cstate Creation state. State of the entry *if* the entry is
|
||||
* newly created.
|
||||
*
|
||||
* @return The NIB entry for the new neighbor cache entry on success.
|
||||
* @return NULL, if there is no space left.
|
||||
*/
|
||||
_nib_onl_entry_t *_nib_nc_add(const ipv6_addr_t *addr, unsigned iface,
|
||||
uint16_t cstate);
|
||||
|
||||
/**
|
||||
* @brief Removes a node from the neighbor cache
|
||||
*
|
||||
* @param[in,out] node A node.
|
||||
*/
|
||||
void _nib_nc_remove(_nib_onl_entry_t *node);
|
||||
|
||||
/**
|
||||
* @brief Sets a NUD-managed neighbor cache entry to reachable and sets the
|
||||
* respective event in @ref _nib_evtimer "event timer"
|
||||
* (@ref GNRC_IPV6_NIB_MSG_NUD_SET_STALE)
|
||||
*
|
||||
* @param[in,out] node A node.
|
||||
*/
|
||||
void _nib_nc_set_reachable(_nib_onl_entry_t *node);
|
||||
|
||||
/**
|
||||
* @brief Creates or gets an existing node from the DAD table by address
|
||||
*
|
||||
* @pre `addr != NULL`
|
||||
*
|
||||
* @param[in] addr The address of a node. May not be NULL.
|
||||
*
|
||||
* @return The NIB entry for the new DAD table entry on success.
|
||||
* @return NULL, if there is no space left.
|
||||
*/
|
||||
static inline _nib_onl_entry_t *_nib_dad_add(const ipv6_addr_t *addr)
|
||||
{
|
||||
_nib_onl_entry_t *node = _nib_onl_alloc(addr, 0);
|
||||
|
||||
if (node != NULL) {
|
||||
node->mode |= (_DAD);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes a node from the DAD table
|
||||
*
|
||||
* @param[in] node A node.
|
||||
*/
|
||||
static inline void _nib_dad_remove(_nib_onl_entry_t *node)
|
||||
{
|
||||
node->mode &= ~(_DAD);
|
||||
_nib_onl_clear(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates or gets an existing default router list entry by address
|
||||
*
|
||||
* @pre `(router_addr != NULL)`
|
||||
*
|
||||
* @param[in] addr An IPv6 address. May not be NULL.
|
||||
* *May also be a global address!*
|
||||
* @param[in] iface The interface to the router.
|
||||
*
|
||||
* @return A new or existing default router entry with _nib_onl_entry_t::ipv6
|
||||
* of _nib_dr_entry_t::next_hop set to @p router_addr.
|
||||
* @return NULL, if no space is left.
|
||||
*/
|
||||
_nib_dr_entry_t *_nib_drl_add(const ipv6_addr_t *router_addr, unsigned iface);
|
||||
|
||||
/**
|
||||
* @brief Removes a default router list entry
|
||||
*
|
||||
* @param[in,out] nib_dr An entry.
|
||||
*
|
||||
* Corresponding on-link entry is removed, too.
|
||||
*/
|
||||
void _nib_drl_remove(_nib_dr_entry_t *nib_dr);
|
||||
|
||||
/**
|
||||
* @brief Iterates over default router list
|
||||
*
|
||||
* @param[in] last Last entry (NULL to start).
|
||||
*
|
||||
* @return entry after @p last.
|
||||
*/
|
||||
_nib_dr_entry_t *_nib_drl_iter(const _nib_dr_entry_t *last);
|
||||
|
||||
/**
|
||||
* @brief Gets a default router by IPv6 address and interface
|
||||
*
|
||||
* @pre `(router_addr != NULL)`
|
||||
*
|
||||
* @param[in] router_addr The address of a default router. May not be NULL.
|
||||
* @param[in] iface The interface to the node. May be 0 for any
|
||||
* interface.
|
||||
*
|
||||
* @return The NIB entry for node with @p router_addr and @p iface onsuccess.
|
||||
* @return NULL, if there is no such entry.
|
||||
*/
|
||||
_nib_dr_entry_t *_nib_drl_get(const ipv6_addr_t *router_addr, unsigned iface);
|
||||
|
||||
/**
|
||||
* @brief Gets *the* default router
|
||||
*
|
||||
* @see [RFC 4861, section 6.3.6](https://tools.ietf.org/html/rfc4861#section-6.3.6)
|
||||
*
|
||||
* @return The current default router, on success.
|
||||
* @return NULL, if there is no default router in the list.
|
||||
*/
|
||||
_nib_dr_entry_t *_nib_drl_get_dr(void);
|
||||
|
||||
/**
|
||||
* @brief Creates or gets an existing off-link entry by next hop and prefix
|
||||
*
|
||||
* @pre `(next_hop != NULL)`
|
||||
* @pre `(pfx != NULL) && (pfx != "::") && (pfx_len != 0) && (pfx_len <= 128)`
|
||||
*
|
||||
* @param[in] next_hop An IPv6 address to next hop. May not be NULL.
|
||||
* *May also be a global address!*
|
||||
* @param[in] iface The interface to @p next_hop.
|
||||
* @param[in] pfx The IPv6 prefix or address of the destination.
|
||||
* May not be NULL or unspecified address. Use
|
||||
* @ref _nib_drl_add() for default route destinations.
|
||||
* @param[in] pfx_len The length in bits of @p pfx in bits.
|
||||
*
|
||||
* @return A new or existing off-link entry with _nib_dr_entry_t::pfx set to
|
||||
* @p pfx.
|
||||
* @return NULL, if no space is left.
|
||||
*/
|
||||
_nib_offl_entry_t *_nib_dst_alloc(const ipv6_addr_t *next_hop, unsigned iface,
|
||||
const ipv6_addr_t *pfx, unsigned pfx_len);
|
||||
|
||||
/**
|
||||
* @brief Clears out a NIB entry (off-link version)
|
||||
*
|
||||
* @param[in,out] dst An entry.
|
||||
*/
|
||||
void _nib_dst_clear(_nib_offl_entry_t *dst);
|
||||
|
||||
/**
|
||||
* @brief Iterates over off-link entries
|
||||
*
|
||||
* @param[in] last Last entry (NULL to start).
|
||||
*
|
||||
* @return entry after @p last.
|
||||
*/
|
||||
_nib_offl_entry_t *_nib_dst_iter(const _nib_offl_entry_t *last);
|
||||
|
||||
/**
|
||||
* @brief Helper function for view-level add-functions below
|
||||
*
|
||||
* @pre `(next_hop != NULL)`
|
||||
* @pre `(pfx != NULL) && (pfx != "::") && (pfx_len != 0) && (pfx_len <= 128)`
|
||||
*
|
||||
* @param[in] next_hop Next hop to the destination. May not be NULL.
|
||||
* *May also be a global address!*
|
||||
* @param[in] iface The interface to the destination.
|
||||
* @param[in] pfx The IPv6 prefix or address of the destination.
|
||||
* May not be NULL or unspecified address. Use
|
||||
* @ref _nib_drl_add() for default route destinations.
|
||||
* @param[in] pfx_len The length in bits of @p pfx in bits.
|
||||
* @param[in] mode [NIB-mode](_nib_onl_entry_t::mode).
|
||||
*
|
||||
* @return A new or existing off-link entry with _nib_dr_entry_t::pfx set to
|
||||
* @p pfx.
|
||||
* @return NULL, if no space is left.
|
||||
*/
|
||||
static inline _nib_offl_entry_t *_nib_dst_add(const ipv6_addr_t *next_hop,
|
||||
unsigned iface,
|
||||
const ipv6_addr_t *pfx,
|
||||
unsigned pfx_len, uint8_t mode)
|
||||
{
|
||||
_nib_offl_entry_t *nib_offl = _nib_dst_alloc(next_hop, iface, pfx, pfx_len);
|
||||
|
||||
if (nib_offl != NULL) {
|
||||
nib_offl->next_hop->mode |= (mode);
|
||||
}
|
||||
return nib_offl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function for the view-level remove-functions below
|
||||
*
|
||||
* @param[in,out] nib_offl An entry.
|
||||
*/
|
||||
static inline void _nib_dst_remove(_nib_offl_entry_t *nib_offl, uint8_t mode)
|
||||
{
|
||||
_nib_onl_entry_t *node = nib_offl->next_hop;
|
||||
|
||||
if (node != NULL) {
|
||||
node->mode &= ~mode;
|
||||
}
|
||||
_nib_dst_clear(nib_offl);
|
||||
}
|
||||
|
||||
#if defined(GNRC_IPV6_NIB_CONF_DC) || DOXYGEN
|
||||
/**
|
||||
* @brief Creates or gets an existing destination cache entry by its addresses
|
||||
*
|
||||
* @pre `(next_hop != NULL)`
|
||||
* @pre `(dst != NULL)`
|
||||
*
|
||||
* @param[in] next_hop Next hop to the destination. May not be NULL.
|
||||
* *May also be a global address!*
|
||||
* @param[in] iface The interface to the destination.
|
||||
*
|
||||
* @note Only available if @ref GNRC_IPV6_NIB_CONF_DC.
|
||||
*
|
||||
* @return A new or existing destination cache entry with
|
||||
* _nib_onl_entry_t::ipv6 of _nib_dr_entry_t::next_hop set to
|
||||
* @p next_hop.
|
||||
* @return NULL, if no space is left.
|
||||
*/
|
||||
static inline _nib_offl_entry_t *_nib_dc_add(const ipv6_addr_t *next_hop,
|
||||
unsigned iface,
|
||||
const ipv6_addr_t *dst)
|
||||
{
|
||||
return _nib_dst_add(next_hop, iface, dst, IPV6_ADDR_BIT_LEN, _DC);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes a destination cache entry
|
||||
*
|
||||
* @param[in,out] nib_dr An entry.
|
||||
*
|
||||
* Corresponding on-link entry is removed, too.
|
||||
*
|
||||
* @note Only available if @ref GNRC_IPV6_NIB_CONF_DC.
|
||||
*/
|
||||
static inline void _nib_dc_remove(_nib_offl_entry_t *nib_offl)
|
||||
{
|
||||
_nib_dst_remove(nib_offl, _DC);
|
||||
}
|
||||
#endif /* GNRC_IPV6_NIB_CONF_DC */
|
||||
|
||||
/**
|
||||
* @brief Creates or gets an existing prefix list entry by its prefix
|
||||
*
|
||||
* @pre `(next_hop != NULL)`
|
||||
* @pre `(pfx != NULL) && (pfx != "::") && (pfx_len != 0) && (pfx_len <= 128)`
|
||||
*
|
||||
* @param[in] iface The interface to the prefix is added to.
|
||||
* @param[in] pfx The IPv6 prefix or address of the destination.
|
||||
* May not be NULL or unspecified address. Use
|
||||
* @ref _nib_drl_add() for default route destinations.
|
||||
* @param[in] pfx_len The length in bits of @p pfx in bits.
|
||||
*
|
||||
* @return A new or existing prefix list entry with _nib_dr_entry_t::pfx set to
|
||||
* @p pfx.
|
||||
* @return NULL, if no space is left.
|
||||
*/
|
||||
static inline _nib_offl_entry_t *_nib_pl_add(unsigned iface,
|
||||
const ipv6_addr_t *pfx,
|
||||
unsigned pfx_len)
|
||||
{
|
||||
return _nib_dst_add(NULL, iface, pfx, pfx_len, _PL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes a prefix list entry
|
||||
*
|
||||
* @param[in,out] nib_offl An entry.
|
||||
*
|
||||
* Corresponding on-link entry is removed, too.
|
||||
*/
|
||||
static inline void _nib_pl_remove(_nib_offl_entry_t *nib_offl)
|
||||
{
|
||||
_nib_dst_remove(nib_offl, _PL);
|
||||
}
|
||||
|
||||
#if defined(GNRC_IPV6_NIB_CONF_ROUTER) || DOXYGEN
|
||||
/**
|
||||
* @brief Creates or gets an existing forwarding table entry by its prefix
|
||||
*
|
||||
* @pre `(next_hop != NULL)`
|
||||
* @pre `(pfx != NULL) && (pfx != "::") && (pfx_len != 0) && (pfx_len <= 128)`
|
||||
*
|
||||
* @param[in] next_hop Next hop to the destination. May not be NULL.
|
||||
* *May also be a global address!*
|
||||
* @param[in] iface The interface to the destination.
|
||||
* @param[in] pfx The IPv6 prefix or address of the destination.
|
||||
* May not be NULL or unspecified address. Use
|
||||
* @ref _nib_drl_add() for default route destinations.
|
||||
* @param[in] pfx_len The length in bits of @p pfx in bits.
|
||||
*
|
||||
* @note Only available if @ref GNRC_IPV6_NIB_CONF_ROUTER.
|
||||
*
|
||||
* @return A new or existing forwarding table entry with _nib_dr_entry_t::pfx
|
||||
* set to @p pfx.
|
||||
* @return NULL, if no space is left.
|
||||
*/
|
||||
static inline _nib_offl_entry_t *_nib_ft_add(const ipv6_addr_t *next_hop,
|
||||
unsigned iface,
|
||||
const ipv6_addr_t *pfx,
|
||||
unsigned pfx_len)
|
||||
{
|
||||
return _nib_dst_add(next_hop, iface, pfx, pfx_len, _FT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes a forwarding table entry
|
||||
*
|
||||
* @param[in,out] nib_offl An entry.
|
||||
*
|
||||
* Corresponding on-link entry is removed, too.
|
||||
*
|
||||
* @note Only available if @ref GNRC_IPV6_NIB_CONF_ROUTER.
|
||||
*/
|
||||
static inline void _nib_ft_remove(_nib_offl_entry_t *nib_offl)
|
||||
{
|
||||
_nib_dst_remove(nib_offl, _FT);
|
||||
}
|
||||
#endif /* GNRC_IPV6_NIB_CONF_ROUTER */
|
||||
|
||||
/**
|
||||
* @brief Gets (or creates if it not exists) interface information for
|
||||
* neighbor discovery
|
||||
*
|
||||
* @pre `(iface <= _NIB_IF_MAX)`
|
||||
*
|
||||
* @param[in] iface Interface identifier to get information for.
|
||||
*
|
||||
* @return Interface information on @p iface.
|
||||
* @return NULL, if no space left for interface.
|
||||
*/
|
||||
_nib_iface_t *_nib_iface_get(unsigned iface);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PRIV_NIB_INTERNAL_H */
|
||||
/** @} */
|
1
tests/unittests/tests-gnrc_ipv6_nib/Makefile
Normal file
1
tests/unittests/tests-gnrc_ipv6_nib/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
6
tests/unittests/tests-gnrc_ipv6_nib/Makefile.include
Normal file
6
tests/unittests/tests-gnrc_ipv6_nib/Makefile.include
Normal file
@ -0,0 +1,6 @@
|
||||
USEMODULE += gnrc_ipv6_nib
|
||||
|
||||
CFLAGS += -DGNRC_IPV6_NIB_NUMOF=16
|
||||
CFLAGS += -DGNRC_IPV6_NIB_DEFAULT_ROUTER_NUMOF=4
|
||||
|
||||
INCLUDES += -I$(RIOTBASE)/sys/net/gnrc/network_layer/ipv6/nib
|
1060
tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-internal.c
Normal file
1060
tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-internal.c
Normal file
File diff suppressed because it is too large
Load Diff
21
tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib.c
Normal file
21
tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib.c
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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 <m.lenders@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#include "tests-gnrc_ipv6_nib.h"
|
||||
|
||||
void tests_gnrc_ipv6_nib(void)
|
||||
{
|
||||
TESTS_RUN(tests_gnrc_ipv6_nib_internal_tests());
|
||||
}
|
44
tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib.h
Normal file
44
tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup unittests
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Unittests for the ``gnrc_ipv6_nib`` module
|
||||
*
|
||||
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||
*/
|
||||
#ifndef TESTS_GNRC_IPV6_NIB_H
|
||||
#define TESTS_GNRC_IPV6_NIB_H
|
||||
|
||||
#include "embUnit.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The entry point of this test suite.
|
||||
*/
|
||||
void tests_gnrc_ipv6_nib(void);
|
||||
|
||||
/**
|
||||
* @brief Generates tests for internal layer
|
||||
*
|
||||
* @return embUnit tests if successful, NULL if not.
|
||||
*/
|
||||
Test *tests_gnrc_ipv6_nib_internal_tests(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* TESTS_GNRC_IPV6_NIB_H */
|
||||
/** @} */
|
Loading…
Reference in New Issue
Block a user