Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gnrc_sixlowpan_nd_border_router: initial import of border router behavior of 6LoWPAN-ND #3134

Merged
merged 2 commits into from
Sep 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 2 additions & 0 deletions Makefile.pseudomodules
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions doc/doxygen/riot.doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
11 changes: 11 additions & 0 deletions sys/include/net/gnrc/sixlowpan/nd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
* @{
Expand Down
43 changes: 43 additions & 0 deletions sys/include/net/gnrc/sixlowpan/nd/border_router.h
Original file line number Diff line number Diff line change
@@ -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_ */
/** @} */
65 changes: 65 additions & 0 deletions sys/include/net/gnrc/sixlowpan/nd/router.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
21 changes: 21 additions & 0 deletions sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ static ipv6_addr_t *_add_addr_to_entry(gnrc_ipv6_netif_t *entry, const ipv6_addr
gnrc_ndp_router_retrans_rtr_adv(entry);
mutex_lock(&entry->mutex); /* relock mutex */
}
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
gnrc_sixlowpan_nd_router_abr_t *abr = gnrc_sixlowpan_nd_router_abr_get();
if (gnrc_sixlowpan_nd_router_abr_add_prf(abr, entry, tmp_addr) < 0) {
DEBUG("ipv6_netif: error adding prefix to 6LoWPAN-ND management\n");
}
#endif
}
else {
Expand Down Expand Up @@ -303,6 +309,10 @@ static void _remove_addr_from_entry(gnrc_ipv6_netif_t *entry, ipv6_addr_t *addr)
return;
}
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
gnrc_sixlowpan_nd_router_abr_t *abr = gnrc_sixlowpan_nd_router_abr_get();
gnrc_sixlowpan_nd_router_abr_rem_prf(abr, entry, &entry->addrs[i]);
#endif

mutex_unlock(&entry->mutex);
return;
Expand Down Expand Up @@ -752,6 +762,9 @@ void gnrc_ipv6_netif_init_by_dev(void)
{
kernel_pid_t ifs[GNRC_NETIF_NUMOF];
size_t ifnum = gnrc_netif_get(ifs);
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
bool abr_init = false;
#endif

for (size_t i = 0; i < ifnum; i++) {
ipv6_addr_t addr;
Expand Down Expand Up @@ -826,6 +839,14 @@ void gnrc_ipv6_netif_init_by_dev(void)
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_ND
if (ipv6_if->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) {
#ifdef MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER
/* first interface wins */
if (!abr_init) {
gnrc_sixlowpan_nd_router_abr_create(&addr, 0);
gnrc_ipv6_netif_set_rtr_adv(ipv6_if, true);
abr_init = true;
}
#endif
gnrc_sixlowpan_nd_init(ipv6_if);
continue; /* skip gnrc_ndp_host_init() */
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,6 @@ gnrc_sixlowpan_ctx_t *gnrc_sixlowpan_ctx_update(uint8_t id, const ipv6_addr_t *p
_ctx_inval_times[id] = ltime + _current_minute();

mutex_unlock(&_ctx_mutex);

return &(_ctxs[id]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand All @@ -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;
}

Expand Down Expand Up @@ -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
/** @} */