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

gnrc_sixlowpan_nd_border_router: initial import

This commit is contained in:
Martine Lenders 2015-08-31 00:23:27 +02:00 committed by Martine Lenders
parent 81a8d0e3b3
commit e6c96cde53
7 changed files with 248 additions and 2 deletions

View File

@ -64,6 +64,14 @@ ifneq (,$(filter gnrc_sixlowpan_router_default,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_iphc
endif
ifneq (,$(filter gnrc_sixlowpan_border_router_default,$(USEMODULE)))
USEMODULE += gnrc_ipv6_router_default
USEMODULE += gnrc_sixlowpan_nd_border_router
USEMODULE += gnrc_sixlowpan_router
USEMODULE += gnrc_sixlowpan_frag
USEMODULE += gnrc_sixlowpan_iphc
endif
ifneq (,$(filter gnrc_sixlowpan_router,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan
endif
@ -89,6 +97,10 @@ ifneq (,$(filter gnrc_sixlowpan_ctx,$(USEMODULE)))
USEMODULE += vtimer
endif
ifneq (,$(filter gnrc_sixlowpan_nd_border_router,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_nd_router
endif
ifneq (,$(filter gnrc_sixlowpan_nd_router,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_nd
endif

View File

@ -3,6 +3,8 @@ PSEUDOMODULES += gnrc_ipv6_default
PSEUDOMODULES += gnrc_ipv6_router
PSEUDOMODULES += gnrc_ipv6_router_default
PSEUDOMODULES += gnrc_sixlowpan_default
PSEUDOMODULES += gnrc_sixlowpan_border_router_default
PSEUDOMODULES += gnrc_sixlowpan_nd_border_router
PSEUDOMODULES += gnrc_sixlowpan_router
PSEUDOMODULES += gnrc_sixlowpan_router_default
PSEUDOMODULES += gnrc_pktbuf

View File

@ -2005,6 +2005,7 @@ PREDEFINED = DOXYGEN \
MODULE_GNRC_NDP_ROUTER \
MODULE_GNRC_SIXLOWPAN \
MODULE_GNRC_SIXLOWPAN_ND_ROUTER \
MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER \
MODULE_GNRC_UDP

View File

@ -33,6 +33,7 @@
#include "net/sixlowpan/nd.h"
#include "timex.h"
#include "net/gnrc/sixlowpan/nd/border_router.h"
#include "net/gnrc/sixlowpan/nd/router.h"
#ifdef __cplusplus
@ -78,6 +79,16 @@ extern "C" {
#define GNRC_SIXLOWPAN_ND_AR_LTIME (15U)
#endif
/**
* @name Border router constants
* @{
* @see <a href="https://tools.ietf.org/html/rfc6775#section-9">
* RFC 6775, section 9
* </a>
*/
#define GNRC_SIXLOWPAN_ND_RTR_MIN_CTX_DELAY (300U) /**< minimum delay between context change and
* stop of C=0 dissimination in seconds */
/** @} */
/**
* @name Host constants
* @{

View File

@ -0,0 +1,43 @@
/*
* 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 gnrc_sixlowpan_nd_border_router Border router part of 6LoWPAN-ND
* @ingroup gnrc_sixlowpan_nd
* @brief Border router part of 6LoWPAN-ND
* @{
*
* @file
* @brief Border router definitions for 6LoWPAN.
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef GNRC_SIXLOWPAN_BORDER_ROUTER_H_
#define GNRC_SIXLOWPAN_BORDER_ROUTER_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Default lifetime in minutes for 6LoWPAN border router information.
*
* @see <a href="https://tools.ietf.org/html/rfc6775#section-4.3">
* RFC 6775, section 4.3
* </a>
*/
#ifndef GNRC_SIXLOWPAN_ND_BORDER_ROUTER_DEFAULT_LTIME
#define GNRC_SIXLOWPAN_ND_BORDER_ROUTER_DEFAULT_LTIME (10000U)
#endif
#ifdef __cplusplus
}
#endif
#endif /* GNRC_SIXLOWPAN_BORDER_ROUTER_H_ */
/** @} */

View File

@ -156,6 +156,71 @@ bool gnrc_sixlowpan_nd_router_abr_older(sixlowpan_nd_opt_abr_t *abr_opt);
*/
void gnrc_sixlowpan_nd_router_abr_remove(gnrc_sixlowpan_nd_router_abr_t *abr);
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
/**
* @brief Makes this node a new border router.
*
* @per addr != NULL
*
* @param[in] addr The local address to use in the ABROs
* @param[in] ltime The lifetime to advertise in the ABROs. 0 assumes a default value of
* @ref GNRC_SIXLOWPAN_ND_BORDER_ROUTER_DEFAULT_LTIME
*
* @return The new border router object.
* @return NULL, on error.
*/
gnrc_sixlowpan_nd_router_abr_t *gnrc_sixlowpan_nd_router_abr_create(ipv6_addr_t *addr,
unsigned int ltime);
/**
* @brief Adds a prefix for this border router to manage.
*
* @pre iface != NULL && prefix != NULL
*
* @param[in] abr The local border router
* @param[in] iface The IPv6 interface the prefix was added to.
* @param[in] prefix The prefix.
*
* @return 0, on success
* @return -ENOMEM, if no space for the new prefix is available.
* @return -ENOENT, if @p abr is not registered.
*/
int gnrc_sixlowpan_nd_router_abr_add_prf(gnrc_sixlowpan_nd_router_abr_t* abr,
gnrc_ipv6_netif_t *iface, gnrc_ipv6_netif_addr_t *prefix);
/**
* @brief Removes a prefix from this border router.
*
* @param[in] abr The local border router
* @param[in] iface The IPv6 interface the prefix was added to.
* @param[in] prefix The prefix.
*/
void gnrc_sixlowpan_nd_router_abr_rem_prf(gnrc_sixlowpan_nd_router_abr_t *abr,
gnrc_ipv6_netif_t *iface, gnrc_ipv6_netif_addr_t *prefix);
/**
* @brief Adds a context for this border router to manage.
*
* @param[in] abr The local border router
* @param[in] ctx The context to be add.
*
* @return 0, on success
* @return -EINVAL, if @p ctx is greater than 15.
* @return -ENOENT, if @p abr is not registered.
*/
int gnrc_sixlowpan_nd_router_abr_add_ctx(gnrc_sixlowpan_nd_router_abr_t *abr, uint8_t cid);
/**
* @brief Removes a context from this border router.
*
* @param[in] abr The local border router
* @param[in] ctx The context to be remove.
*/
void gnrc_sixlowpan_nd_router_abr_rem_ctx(gnrc_sixlowpan_nd_router_abr_t *abr, uint8_t cid);
#else
#define gnrc_sixlowpan_nd_router_abr_create(addr, ltime) (NULL)
#endif
#ifdef __cplusplus
}
#endif

View File

@ -95,6 +95,17 @@ static void _add_ctx(gnrc_sixlowpan_nd_router_abr_t *abr, sixlowpan_nd_opt_6ctx_
bf_set(abr->ctxs, sixlowpan_nd_opt_6ctx_get_cid(ctx_opt));
}
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
static inline bool _is_me(ipv6_addr_t *addr)
{
ipv6_addr_t *res;
return (gnrc_ipv6_netif_find_by_addr(&res, addr) != KERNEL_PID_UNDEF);
}
#else
#define _is_me(ignore) (false)
#endif
gnrc_sixlowpan_nd_router_abr_t *gnrc_sixlowpan_nd_router_abr_get(void)
{
if (ipv6_addr_is_unspecified(&_abrs[0].addr)) {
@ -113,6 +124,10 @@ bool gnrc_sixlowpan_nd_router_abr_older(sixlowpan_nd_opt_abr_t *abr_opt)
return true;
}
if (_is_me(&abr_opt->braddr)) {
return false;
}
abr = _get_abr(&abr_opt->braddr);
if (abr == NULL) {
@ -155,9 +170,11 @@ void gnrc_sixlowpan_nd_opt_abr_handle(kernel_pid_t iface, ndp_rtr_adv_t *rtr_adv
gnrc_sixlowpan_nd_router_abr_t *abr;
timex_t t = { 0, 0 };
if (_is_me(&abr_opt->braddr)) {
return;
}
/* validity and version was checked in previously called
* gnrc_sixlowpan_nd_router_abr_older() */
abr = _get_abr(&abr_opt->braddr);
if (abr == NULL) {
@ -167,7 +184,7 @@ void gnrc_sixlowpan_nd_opt_abr_handle(kernel_pid_t iface, ndp_rtr_adv_t *rtr_adv
abr->ltime = byteorder_ntohs(abr_opt->ltime);
if (abr->ltime == 0) {
gnrc_sixlowpan_nd_router_abr_remove(abr);
abr->ltime = GNRC_SIXLOWPAN_ND_BORDER_ROUTER_DEFAULT_LTIME;
return;
}
@ -242,4 +259,99 @@ gnrc_pktsnip_t *gnrc_sixlowpan_nd_opt_abr_build(uint32_t version, uint16_t ltime
return pkt;
}
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
gnrc_sixlowpan_nd_router_abr_t *gnrc_sixlowpan_nd_router_abr_create(ipv6_addr_t *addr,
unsigned int ltime)
{
assert(addr != NULL);
gnrc_sixlowpan_nd_router_abr_t *abr = _get_abr(addr);
if (abr == NULL) {
return NULL;
}
/* TODO: store and get this somewhere stable */
abr->version = 0;
abr->ltime = (uint16_t)ltime;
abr->addr.u64[0] = addr->u64[0];
abr->addr.u64[1] = addr->u64[1];
memset(abr->ctxs, 0, sizeof(abr->ctxs));
abr->prfs = NULL;
return abr;
}
int gnrc_sixlowpan_nd_router_abr_add_prf(gnrc_sixlowpan_nd_router_abr_t* abr,
gnrc_ipv6_netif_t *iface, gnrc_ipv6_netif_addr_t *prefix)
{
assert((iface != NULL) && (prefix != NULL));
gnrc_sixlowpan_nd_router_prf_t *prf_ent;
if ((abr < _abrs) || (abr > (_abrs + GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF))) {
return -ENOENT;
}
prf_ent = _get_free_prefix(&prefix->addr, prefix->prefix_len);
if (prf_ent == NULL) {
return -ENOMEM;
}
prf_ent->iface = iface;
prf_ent->prefix = prefix;
LL_PREPEND(abr->prfs, prf_ent);
abr->version++; /* TODO: store somewhere stable */
return 0;
}
void gnrc_sixlowpan_nd_router_abr_rem_prf(gnrc_sixlowpan_nd_router_abr_t *abr,
gnrc_ipv6_netif_t *iface, gnrc_ipv6_netif_addr_t *prefix)
{
assert((iface != NULL) && (prefix != NULL));
gnrc_sixlowpan_nd_router_prf_t *prf_ent = abr->prfs, *prev = NULL;
if ((abr < _abrs) || (abr > (_abrs + GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF))) {
return;
}
while (prf_ent) {
if (prf_ent->prefix == prefix) {
if (prev == NULL) {
abr->prfs = prf_ent->next;
}
else {
prev->next = prf_ent->next;
}
prf_ent->next = NULL;
prf_ent->iface = NULL;
prf_ent->prefix = NULL;
abr->version++; /* TODO: store somewhere stable */
break;
}
prev = prf_ent;
prf_ent = prf_ent->next;
}
}
int gnrc_sixlowpan_nd_router_abr_add_ctx(gnrc_sixlowpan_nd_router_abr_t *abr, uint8_t cid)
{
if ((abr < _abrs) || (abr > (_abrs + GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF))) {
return -ENOENT;
}
if (cid >= GNRC_SIXLOWPAN_CTX_SIZE) {
return -EINVAL;
}
if (bf_isset(abr->ctxs, cid)) {
return -EADDRINUSE;
}
bf_set(abr->ctxs, cid);
abr->version++; /* TODO: store somewhere stable */
return 0;
}
void gnrc_sixlowpan_nd_router_abr_rem_ctx(gnrc_sixlowpan_nd_router_abr_t *abr, uint8_t cid)
{
if ((abr < _abrs) || (abr > (_abrs + GNRC_SIXLOWPAN_ND_ROUTER_ABR_NUMOF))) {
return;
}
if (cid >= GNRC_SIXLOWPAN_CTX_SIZE) {
return;
}
bf_unset(abr->ctxs, cid);
abr->version++; /* TODO: store somewhere stable */
return;
}
#endif
/** @} */