From b15660033a42b2ea029ff4211ec4d4272bc09030 Mon Sep 17 00:00:00 2001 From: Oleg Hahm Date: Wed, 16 Sep 2015 03:07:05 +0200 Subject: [PATCH] sixlowpan nd: send actually router advertisements --- sys/include/net/gnrc/ndp.h | 26 +++++++++++++------ sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c | 6 +++++ sys/net/gnrc/network_layer/ndp/gnrc_ndp.c | 12 +++++++++ .../ndp/internal/gnrc_ndp_internal.c | 2 ++ 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/sys/include/net/gnrc/ndp.h b/sys/include/net/gnrc/ndp.h index 5315a2c4c5..83b5106fc7 100644 --- a/sys/include/net/gnrc/ndp.h +++ b/sys/include/net/gnrc/ndp.h @@ -41,14 +41,24 @@ extern "C" { #endif -#define GNRC_NDP_MSG_RTR_TIMEOUT (0x0210) /**< Message type for router timeouts */ -#define GNRC_NDP_MSG_ADDR_TIMEOUT (0x0211) /**< Message type for address timeouts */ -#define GNRC_NDP_MSG_NBR_SOL_RETRANS (0x0212) /**< Message type for multicast - * neighbor solicitation retransmissions */ -#define GNRC_NDP_MSG_RTR_ADV_RETRANS (0x0213) /**< Message type for periodic router advertisements */ -#define GNRC_NDP_MSG_RTR_ADV_DELAY (0x0214) /**< Message type for delayed router advertisements */ -#define GNRC_NDP_MSG_RTR_SOL_RETRANS (0x0215) /**< Message type for periodic router solicitations */ -#define GNRC_NDP_MSG_NC_STATE_TIMEOUT (0x0216) /**< Message type for neighbor cache state timeouts */ +/** Message type for router timeouts */ +#define GNRC_NDP_MSG_RTR_TIMEOUT (0x0210) +/** Message type for address timeouts */ +#define GNRC_NDP_MSG_ADDR_TIMEOUT (0x0211) +/** Message type for multicast neighbor solicitation retransmissions */ +#define GNRC_NDP_MSG_NBR_SOL_RETRANS (0x0212) +/** Message type for periodic router advertisements */ +#define GNRC_NDP_MSG_RTR_ADV_RETRANS (0x0213) +/** Message type for delayed router advertisements */ +#define GNRC_NDP_MSG_RTR_ADV_DELAY (0x0214) +/** Message type for delayed router advertisements in a 6LoWPAN + * 6LoWPAN needs a special handling, because router advertisements are only + * sent after a short randomized delay, but not periodically. */ +#define GNRC_NDP_MSG_RTR_ADV_SIXLOWPAN_DELAY (0x0215) +/** Message type for periodic router solicitations */ +#define GNRC_NDP_MSG_RTR_SOL_RETRANS (0x0216) +/** Message type for neighbor cache state timeouts */ +#define GNRC_NDP_MSG_NC_STATE_TIMEOUT (0x0217) /** * @name Host constants diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index ddfce4be36..c3a7061ea1 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -255,6 +255,12 @@ static void *_event_loop(void *args) DEBUG("ipv6: address registration timeout received\n"); gnrc_sixlowpan_nd_router_gc_nc((gnrc_ipv6_nc_t *)msg.content.ptr); break; + case GNRC_NDP_MSG_RTR_ADV_SIXLOWPAN_DELAY: + DEBUG("ipv6: Delayed router advertisement event received\n"); + gnrc_ipv6_nc_t *nc_entry = (gnrc_ipv6_nc_t *)msg.content.ptr; + gnrc_ndp_internal_send_rtr_adv(nc_entry->iface, NULL, + &(nc_entry->ipv6_addr), false); + break; #endif default: break; diff --git a/sys/net/gnrc/network_layer/ndp/gnrc_ndp.c b/sys/net/gnrc/network_layer/ndp/gnrc_ndp.c index ed68300248..5c3ac01876 100644 --- a/sys/net/gnrc/network_layer/ndp/gnrc_ndp.c +++ b/sys/net/gnrc/network_layer/ndp/gnrc_ndp.c @@ -414,6 +414,17 @@ void gnrc_ndp_rtr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, #endif delay = timex_set(0, genrand_uint32_range(0, ms)); vtimer_remove(&if_entry->rtr_adv_timer); +#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER + /* in case of a 6LBR we have to check if the interface is actually + * the 6lo interface */ + if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) { + gnrc_ipv6_nc_t *nc_entry = gnrc_ipv6_nc_get(iface, &ipv6->src); + if (nc_entry != NULL) { + vtimer_set_msg(&if_entry->rtr_adv_timer, delay, gnrc_ipv6_pid, + GNRC_NDP_MSG_RTR_ADV_SIXLOWPAN_DELAY, nc_entry); + } + } +#elif defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER) if (ipv6_addr_is_unspecified(&ipv6->src)) { /* either multicast, if source unspecified */ vtimer_set_msg(&if_entry->rtr_adv_timer, delay, gnrc_ipv6_pid, @@ -427,6 +438,7 @@ void gnrc_ndp_rtr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, vtimer_set_msg(&if_entry->rtr_adv_timer, delay, gnrc_ipv6_pid, GNRC_NDP_MSG_RTR_ADV_DELAY, nc_entry); } +#endif } } /* otherwise ignore silently */ diff --git a/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c b/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c index 4a3158a2cd..4f268549bc 100644 --- a/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c +++ b/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c @@ -462,8 +462,10 @@ void gnrc_ndp_internal_send_rtr_adv(kernel_pid_t iface, ipv6_addr_t *src, ipv6_a pkt = hdr; } if (src == NULL) { + mutex_unlock(&ipv6_iface->mutex); /* get address from source selection algorithm */ src = gnrc_ipv6_netif_find_best_src_addr(iface, dst); + mutex_lock(&ipv6_iface->mutex); } /* add SL2A for source address */ if (src != NULL) {