diff --git a/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c b/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c index c953baf3ee..b750f8be3f 100644 --- a/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c +++ b/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c @@ -87,10 +87,13 @@ void gnrc_icmpv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt) break; #endif +#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)) case ICMPV6_RTR_SOL: DEBUG("icmpv6: router solicitation received\n"); - /* TODO */ + gnrc_ndp_rtr_sol_handle(iface, pkt, ipv6->data, (ndp_rtr_sol_t *)hdr, + icmpv6->size); break; +#endif #ifdef MODULE_GNRC_NDP case ICMPV6_RTR_ADV: diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index 02f3368e09..0f876f2425 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -212,6 +212,16 @@ static void *_event_loop(void *args) gnrc_ndp_state_timeout((gnrc_ipv6_nc_t *)msg.content.ptr); break; #endif +#ifdef MODULE_GNRC_NDP_ROUTER + case GNRC_NDP_MSG_RTR_ADV_RETRANS: + DEBUG("ipv6: Router advertisement retransmission event received\n"); + gnrc_ndp_router_retrans_rtr_adv((gnrc_ipv6_netif_t *)msg.content.ptr); + break; + case GNRC_NDP_MSG_RTR_ADV_DELAY: + DEBUG("ipv6: Delayed router advertisement event received\n"); + gnrc_ndp_router_send_rtr_adv((gnrc_ipv6_nc_t *)msg.content.ptr); + break; +#endif #ifdef MODULE_GNRC_NDP_HOST case GNRC_NDP_MSG_RTR_SOL_RETRANS: DEBUG("ipv6: Router solicitation retransmission event received\n"); diff --git a/sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c b/sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c index 8c8a91084d..2967a07962 100644 --- a/sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c +++ b/sys/net/gnrc/network_layer/ipv6/netif/gnrc_ipv6_netif.c @@ -101,6 +101,18 @@ static ipv6_addr_t *_add_addr_to_entry(gnrc_ipv6_netif_t *entry, const ipv6_addr _add_addr_to_entry(entry, &ll_addr, 64, flags | GNRC_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK); +#ifdef MODULE_GNRC_NDP_ROUTER + /* New prefixes MAY allow the router to retransmit up to + * GNRC_NDP_MAX_INIT_RTR_ADV_NUMOF unsolicited RA + * (see https://tools.ietf.org/html/rfc4861#section-6.2.4) */ + if ((entry->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) && + (entry->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV)) { + entry->rtr_adv_count = GNRC_NDP_MAX_INIT_RTR_ADV_NUMOF; + mutex_unlock(&entry->mutex); /* function below relocks mutex */ + gnrc_ndp_router_retrans_rtr_adv(entry); + mutex_lock(&entry->mutex); /* relock mutex */ + } +#endif } else { tmp_addr->flags |= GNRC_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK; @@ -215,6 +227,18 @@ gnrc_ipv6_netif_t *gnrc_ipv6_netif_get(kernel_pid_t pid) return NULL; } +#if defined(MODULE_GNRC_NDP_ROUTER) +void gnrc_ipv6_netif_set_router(gnrc_ipv6_netif_t *netif, bool enable) +{ + gnrc_ndp_router_set_router(netif, enable); +} + +void gnrc_ipv6_netif_set_rtr_adv(gnrc_ipv6_netif_t *netif, bool enable) +{ + gnrc_ndp_router_set_rtr_adv(netif, enable); +} +#endif + ipv6_addr_t *gnrc_ipv6_netif_add_addr(kernel_pid_t pid, const ipv6_addr_t *addr, uint8_t prefix_len, uint8_t flags) { @@ -245,6 +269,20 @@ static void _remove_addr_from_entry(gnrc_ipv6_netif_t *entry, ipv6_addr_t *addr) ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)), entry->pid); ipv6_addr_set_unspecified(&(entry->addrs[i].addr)); entry->addrs[i].flags = 0; +#ifdef MODULE_GNRC_NDP_ROUTER + /* Removal of prefixes MAY allow the router to retransmit up to + * GNRC_NDP_MAX_INIT_RTR_ADV_NUMOF unsolicited RA + * (see https://tools.ietf.org/html/rfc4861#section-6.2.4) */ + if ((entry->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) && + (entry->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV) && + (!ipv6_addr_is_multicast(addr) && + !ipv6_addr_is_link_local(addr))) { + entry->rtr_adv_count = GNRC_NDP_MAX_INIT_RTR_ADV_NUMOF; + mutex_unlock(&entry->mutex); /* function below relocks the mutex */ + gnrc_ndp_router_retrans_rtr_adv(entry); + return; + } +#endif mutex_unlock(&entry->mutex); return; @@ -763,6 +801,9 @@ void gnrc_ipv6_netif_init_by_dev(void) } mutex_unlock(&ipv6_if->mutex); +#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)) + gnrc_ipv6_netif_set_router(ipv6_if, true); +#endif #ifdef MODULE_GNRC_NDP_HOST /* start periodic router solicitations */ gnrc_ndp_host_init(ipv6_if);