mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-24 22:13:52 +01:00
gnrc: adapt for gnrc_sixlowpan_nd_router
This commit is contained in:
parent
132f5e1b9c
commit
40912d3d66
@ -244,6 +244,17 @@ static void *_event_loop(void *args)
|
||||
gnrc_sixlowpan_ctx_remove(((((gnrc_sixlowpan_ctx_t *)msg.content.ptr)->flags_id) &
|
||||
GNRC_SIXLOWPAN_CTX_FLAGS_CID_MASK));
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
|
||||
case GNRC_SIXLOWPAN_ND_MSG_ABR_TIMEOUT:
|
||||
DEBUG("ipv6: border router timeout event received\n");
|
||||
gnrc_sixlowpan_nd_router_abr_remove(
|
||||
(gnrc_sixlowpan_nd_router_abr_t *)msg.content.ptr);
|
||||
break;
|
||||
case GNRC_SIXLOWPAN_ND_MSG_AR_TIMEOUT:
|
||||
DEBUG("ipv6: address registration timeout received\n");
|
||||
gnrc_sixlowpan_nd_router_gc_nc((gnrc_ipv6_nc_t *)msg.content.ptr);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -116,7 +116,7 @@ static ipv6_addr_t *_add_addr_to_entry(gnrc_ipv6_netif_t *entry, const ipv6_addr
|
||||
else {
|
||||
tmp_addr->flags |= GNRC_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK;
|
||||
}
|
||||
#if defined(MODULE_GNRC_NDP_NODE) || defined(MODULE_GNRC_SIXLOWPAN_ND)
|
||||
#if defined(MODULE_GNRC_NDP_NODE) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)
|
||||
/* add solicited-nodes multicast address for new address if interface is not a
|
||||
* 6LoWPAN host interface (see: https://tools.ietf.org/html/rfc6775#section-5.2) */
|
||||
if (!(entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) ||
|
||||
@ -235,14 +235,26 @@ gnrc_ipv6_netif_t *gnrc_ipv6_netif_get(kernel_pid_t pid)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(MODULE_GNRC_NDP_ROUTER)
|
||||
#if defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)
|
||||
void gnrc_ipv6_netif_set_router(gnrc_ipv6_netif_t *netif, bool enable)
|
||||
{
|
||||
#if defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)
|
||||
if (netif->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) {
|
||||
gnrc_sixlowpan_nd_router_set_router(netif, enable);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
gnrc_ndp_router_set_router(netif, enable);
|
||||
}
|
||||
|
||||
void gnrc_ipv6_netif_set_rtr_adv(gnrc_ipv6_netif_t *netif, bool enable)
|
||||
{
|
||||
#if defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)
|
||||
if (netif->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) {
|
||||
gnrc_sixlowpan_nd_router_set_rtr_adv(netif, enable);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
gnrc_ndp_router_set_rtr_adv(netif, enable);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
|
||||
#include "byteorder.h"
|
||||
#include "net/fib.h"
|
||||
#include "net/ieee802154.h"
|
||||
#include "net/ipv6/ext/rh.h"
|
||||
#include "net/gnrc/icmpv6.h"
|
||||
#include "net/gnrc/ipv6.h"
|
||||
@ -53,6 +54,19 @@ static void _stale_nc(kernel_pid_t iface, ipv6_addr_t *ipaddr, uint8_t *l2addr,
|
||||
if (l2addr_len != -ENOTSUP) {
|
||||
gnrc_ipv6_nc_t *nc_entry = gnrc_ipv6_nc_get(iface, ipaddr);
|
||||
if (nc_entry == NULL) {
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
|
||||
/* tentative type see https://tools.ietf.org/html/rfc6775#section-6.3 */
|
||||
gnrc_ipv6_netif_t *ipv6_iface = gnrc_ipv6_netif_get(iface);
|
||||
if ((ipv6_iface == NULL) || (ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER)) {
|
||||
timex_t t = { GNRC_SIXLOWPAN_ND_TENTATIVE_NCE_LIFETIME, 0 };
|
||||
gnrc_ipv6_nc_add(iface, ipaddr, l2addr, (uint16_t)l2addr_len,
|
||||
GNRC_IPV6_NC_STATE_STALE | GNRC_IPV6_NC_TYPE_TENTATIVE);
|
||||
vtimer_remove(&nc_entry->type_timeout);
|
||||
vtimer_set_msg(&nc_entry->type_timeout, t, gnrc_ipv6_pid,
|
||||
GNRC_SIXLOWPAN_ND_MSG_AR_TIMEOUT, nc_entry);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
gnrc_ipv6_nc_add(iface, ipaddr, l2addr, (uint16_t)l2addr_len,
|
||||
GNRC_IPV6_NC_STATE_STALE);
|
||||
}
|
||||
@ -73,7 +87,12 @@ void gnrc_ndp_nbr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
|
||||
uint16_t opt_offset = 0;
|
||||
uint8_t l2src[GNRC_IPV6_NC_L2_ADDR_MAX];
|
||||
uint8_t *buf = ((uint8_t *)nbr_sol) + sizeof(ndp_nbr_sol_t);
|
||||
ipv6_addr_t *tgt;
|
||||
ipv6_addr_t *tgt, nbr_adv_dst;
|
||||
gnrc_pktsnip_t *nbr_adv_opts = NULL;
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
|
||||
ndp_opt_t *sl2a_opt = NULL;
|
||||
sixlowpan_nd_opt_ar_t *ar_opt = NULL;
|
||||
#endif
|
||||
int sicmpv6_size = (int)icmpv6_size, l2src_len = 0;
|
||||
DEBUG("ndp: received neighbor solicitation (src: %s, ",
|
||||
ipv6_addr_to_str(addr_str, &ipv6->src, sizeof(addr_str)));
|
||||
@ -111,6 +130,13 @@ void gnrc_ndp_nbr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
|
||||
* is invalid. */
|
||||
return;
|
||||
}
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
|
||||
sl2a_opt = opt;
|
||||
break;
|
||||
case NDP_OPT_AR:
|
||||
/* actually handling at the end of the function (see below) */
|
||||
ar_opt = (sixlowpan_nd_opt_ar_t *)opt;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
/* silently discard all other options */
|
||||
@ -119,9 +145,38 @@ void gnrc_ndp_nbr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
|
||||
opt_offset += (opt->len * 8);
|
||||
sicmpv6_size -= (opt->len * 8);
|
||||
}
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
|
||||
gnrc_ipv6_netif_t *ipv6_iface = gnrc_ipv6_netif_get(iface);
|
||||
assert(ipv6_iface != NULL);
|
||||
if ((sl2a_opt != NULL) && (ar_opt != NULL) &&
|
||||
(ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) &&
|
||||
(ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER)) {
|
||||
uint8_t status = gnrc_sixlowpan_nd_opt_ar_handle(iface, ipv6, nbr_sol->type, ar_opt,
|
||||
l2src, l2src_len);
|
||||
/* check for multihop DAD return */
|
||||
nbr_adv_opts = gnrc_sixlowpan_nd_opt_ar_build(status, GNRC_SIXLOWPAN_ND_AR_LTIME,
|
||||
&ar_opt->eui64, NULL);
|
||||
if (status == 0) {
|
||||
memcpy(&nbr_adv_dst, &ipv6->src, sizeof(ipv6_addr_t));
|
||||
}
|
||||
else {
|
||||
/* see https://tools.ietf.org/html/rfc6775#section-6.5.2 */
|
||||
eui64_t iid;
|
||||
ieee802154_get_iid(&iid, ar_opt->eui64.uint8, sizeof(eui64_t));
|
||||
ipv6_addr_set_iid(&nbr_adv_dst, iid.uint64.u64);
|
||||
ipv6_addr_set_link_local_prefix(&nbr_adv_dst);
|
||||
}
|
||||
}
|
||||
else { /* gnrc_sixlowpan_nd_opt_ar_handle updates neighbor cache */
|
||||
_stale_nc(iface, &ipv6->src, l2src, l2src_len);
|
||||
memcpy(&nbr_adv_dst, &ipv6->src, sizeof(ipv6_addr_t));
|
||||
}
|
||||
#else
|
||||
_stale_nc(iface, &ipv6->src, l2src, l2src_len);
|
||||
gnrc_ndp_internal_send_nbr_adv(iface, tgt, &ipv6->src, ipv6_addr_is_multicast(&ipv6->dst),
|
||||
NULL);
|
||||
memcpy(&nbr_adv_dst, &ipv6->src, sizeof(ipv6_addr_t));
|
||||
#endif
|
||||
gnrc_ndp_internal_send_nbr_adv(iface, tgt, &nbr_adv_dst, ipv6_addr_is_multicast(&ipv6->dst),
|
||||
nbr_adv_opts);
|
||||
}
|
||||
|
||||
static inline bool _pkt_has_l2addr(gnrc_netif_hdr_t *netif_hdr)
|
||||
@ -332,7 +387,14 @@ void gnrc_ndp_rtr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
|
||||
_stale_nc(iface, &ipv6->src, l2src, l2src_len);
|
||||
/* send delayed */
|
||||
if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV) {
|
||||
timex_t delay = timex_set(0, genrand_uint32_range(0, GNRC_NDP_MAX_RTR_ADV_DELAY));
|
||||
timex_t delay;
|
||||
uint32_t ms = GNRC_NDP_MAX_RTR_ADV_DELAY;
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
|
||||
if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) {
|
||||
ms = GNRC_SIXLOWPAN_ND_MAX_RTR_ADV_DELAY;
|
||||
}
|
||||
#endif
|
||||
delay = timex_set(0, genrand_uint32_range(0, ms));
|
||||
vtimer_remove(&if_entry->rtr_adv_timer);
|
||||
if (ipv6_addr_is_unspecified(&ipv6->src)) {
|
||||
/* either multicast, if source unspecified */
|
||||
@ -477,8 +539,15 @@ void gnrc_ndp_rtr_adv_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, ipv6_hdr_t
|
||||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
|
||||
case NDP_OPT_ABR:
|
||||
gnrc_sixlowpan_nd_opt_abr_handle(iface, rtr_adv, icmpv6_size,
|
||||
(sixlowpan_nd_opt_abr_t *)opt);
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
sicmpv6_size -= (opt->len * 8);
|
||||
}
|
||||
#if ENABLE_DEBUG && defined(MODULE_NG_SIXLOWPAN_ND)
|
||||
if ((if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) && (l2src_len <= 0)) {
|
||||
@ -552,6 +621,18 @@ void gnrc_ndp_retrans_nbr_sol(gnrc_ipv6_nc_t *nc_entry)
|
||||
}
|
||||
}
|
||||
else if (nc_entry->probes_remaining <= 1) {
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
|
||||
if (nc_entry->iface != KERNEL_PID_UNDEF) {
|
||||
gnrc_ipv6_netif_t *ipv6_iface = gnrc_ipv6_netif_get(nc_entry->iface);
|
||||
if ((ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) &&
|
||||
(ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) &&
|
||||
(gnrc_ipv6_nc_get_type(nc_entry) != GNRC_IPV6_NC_TYPE_GC)) {
|
||||
/* don't remove non-gc entrys on 6LRs:
|
||||
* https://tools.ietf.org/html/rfc6775#section-6 */
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
DEBUG("ndp: Remove nc entry %s for interface %" PRIkernel_pid "\n",
|
||||
ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str)),
|
||||
nc_entry->iface);
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include "net/eui64.h"
|
||||
#include "net/gnrc/ipv6.h"
|
||||
#include "net/gnrc/ndp.h"
|
||||
#include "net/gnrc/sixlowpan/ctx.h"
|
||||
#include "net/gnrc/sixlowpan/nd.h"
|
||||
#include "random.h"
|
||||
#include "timex.h"
|
||||
@ -395,6 +396,9 @@ void gnrc_ndp_internal_send_rtr_adv(kernel_pid_t iface, ipv6_addr_t *src, ipv6_a
|
||||
DEBUG("ndp internal: send router advertisement (iface: %" PRIkernel_pid ", dst: %s%s\n",
|
||||
iface, ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), fin ? ", final" : "");
|
||||
mutex_lock(&ipv6_iface->mutex);
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
|
||||
if (!(ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN)) {
|
||||
#endif
|
||||
hdr = _add_pios(ipv6_iface, pkt);
|
||||
if (hdr == NULL) {
|
||||
/* pkt already released in _add_pios */
|
||||
@ -402,6 +406,51 @@ void gnrc_ndp_internal_send_rtr_adv(kernel_pid_t iface, ipv6_addr_t *src, ipv6_a
|
||||
return;
|
||||
}
|
||||
pkt = hdr;
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
|
||||
}
|
||||
else {
|
||||
gnrc_sixlowpan_nd_router_abr_t *abr = gnrc_sixlowpan_nd_router_abr_get();
|
||||
if (abr != NULL) {
|
||||
gnrc_sixlowpan_nd_router_prf_t *prf = abr->prfs;
|
||||
/* add prefixes from border router */
|
||||
while (prf) {
|
||||
if (_pio_from_iface_addr(&hdr, prf->prefix, pkt)) {
|
||||
if (hdr != NULL) {
|
||||
pkt = hdr;
|
||||
}
|
||||
else {
|
||||
DEBUG("ndp rtr: error allocating PIO\n");
|
||||
gnrc_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
prf = prf->next;
|
||||
}
|
||||
for (unsigned int i = 0; i < GNRC_SIXLOWPAN_CTX_SIZE; i++) {
|
||||
gnrc_sixlowpan_ctx_t *ctx;
|
||||
if (!bf_isset(abr->ctxs, i)) {
|
||||
continue;
|
||||
}
|
||||
ctx = gnrc_sixlowpan_ctx_lookup_id(i);
|
||||
hdr = gnrc_sixlowpan_nd_opt_6ctx_build(ctx->prefix_len, ctx->flags_id, ctx->ltime,
|
||||
&ctx->prefix, pkt);
|
||||
if (hdr == NULL) {
|
||||
DEBUG("ndp rtr: error allocating 6CO\n");
|
||||
gnrc_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
pkt = hdr;
|
||||
}
|
||||
hdr = gnrc_sixlowpan_nd_opt_abr_build(abr->version, abr->ltime, &abr->addr, pkt);
|
||||
if (hdr == NULL) {
|
||||
DEBUG("ndp internal: error allocating ABRO.\n");
|
||||
gnrc_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
pkt = hdr;
|
||||
}
|
||||
}
|
||||
#endif /* MODULE_GNRC_SIXLOWPAN_ND_ROUTER */
|
||||
if (ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_ADV_MTU) {
|
||||
if ((hdr = gnrc_ndp_opt_mtu_build(ipv6_iface->mtu, pkt)) == NULL) {
|
||||
DEBUG("ndp rtr: no space left in packet buffer\n");
|
||||
|
||||
@ -79,6 +79,7 @@ void gnrc_ndp_router_retrans_rtr_adv(gnrc_ipv6_netif_t *iface)
|
||||
void gnrc_ndp_router_send_rtr_adv(gnrc_ipv6_nc_t *neighbor)
|
||||
{
|
||||
gnrc_ipv6_netif_t *iface = gnrc_ipv6_netif_get(neighbor->iface);
|
||||
/* TODO: send one router advertisement per ABR: https://tools.ietf.org/html/rfc6775#section-6.3 */
|
||||
_send_rtr_adv(iface, &neighbor->ipv6_addr);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user