diff --git a/Makefile.dep b/Makefile.dep index b1a028e5afaf765197fec513c23324abba3b7253..b350a9a1f7c86188183217553d70e25df0d7746b 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -256,6 +256,7 @@ endif ifneq (,$(filter gnrc_ndp2,$(USEMODULE))) USEMODULE += gnrc_icmpv6 + USEMODULE += gnrc_netif2 endif ifneq (,$(filter gnrc_icmpv6_echo,$(USEMODULE))) diff --git a/sys/include/net/gnrc/ndp2.h b/sys/include/net/gnrc/ndp2.h index def42558d9e38be19058a729509156a2555f7777..ab7d4bd84ac8746b3836244a1ebcc63fc014e32e 100644 --- a/sys/include/net/gnrc/ndp2.h +++ b/sys/include/net/gnrc/ndp2.h @@ -24,8 +24,9 @@ #include "kernel_types.h" #include "net/gnrc/pkt.h" -#include "net/gnrc/ipv6/netif.h" +#include "net/gnrc/netif2.h" #include "net/ipv6/addr.h" +#include "net/ipv6/hdr.h" #ifdef __cplusplus extern "C" { @@ -269,7 +270,7 @@ gnrc_pktsnip_t *gnrc_ndp2_opt_mtu_build(uint32_t mtu, gnrc_pktsnip_t *next); * for a neighbor solicitation so be sure to check that. * **Will be released** in an error case. */ -void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif, +void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_netif2_t *netif, const ipv6_addr_t *src, const ipv6_addr_t *dst, gnrc_pktsnip_t *ext_opts); @@ -315,7 +316,7 @@ void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif, * check that. * **Will be released** in an error case. */ -void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif, +void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_netif2_t *netif, const ipv6_addr_t *dst, bool supply_tl2a, gnrc_pktsnip_t *ext_opts); @@ -328,7 +329,7 @@ void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif, * @param[in] netif Interface to send over. May not be NULL. * @param[in] dst Destination for the router solicitation. ff02::2 if NULL. */ -void gnrc_ndp2_rtr_sol_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *dst); +void gnrc_ndp2_rtr_sol_send(gnrc_netif2_t *netif, const ipv6_addr_t *dst); /** * @brief Send pre-compiled router advertisement depending on a given network @@ -355,7 +356,7 @@ void gnrc_ndp2_rtr_sol_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *dst); * for a neighbor advertisement so be sure to check that. * **Will be released** in an error case. */ -void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src, +void gnrc_ndp2_rtr_adv_send(gnrc_netif2_t *netif, const ipv6_addr_t *src, const ipv6_addr_t *dst, bool fin, gnrc_pktsnip_t *ext_opts); diff --git a/sys/net/gnrc/network_layer/ndp2/gnrc_ndp2.c b/sys/net/gnrc/network_layer/ndp2/gnrc_ndp2.c index eea675570101b4170034fed58b49df8eca596dbe..4a2a1321ba7b2717040d838dab50fa7d3bda7ff4 100644 --- a/sys/net/gnrc/network_layer/ndp2/gnrc_ndp2.c +++ b/sys/net/gnrc/network_layer/ndp2/gnrc_ndp2.c @@ -15,7 +15,7 @@ #include "net/gnrc/icmpv6.h" #include "net/gnrc/ipv6.h" -#include "net/gnrc/netif.h" +#include "net/gnrc/netif2/internal.h" #ifdef MODULE_GNRC_SIXLOWPAN_ND #include "net/gnrc/sixlowpan/nd.h" #endif @@ -167,8 +167,7 @@ gnrc_pktsnip_t *gnrc_ndp2_opt_sl2a_build(const uint8_t *l2addr, { assert((l2addr != NULL) && (l2addr_len != 0)); DEBUG("ndp2: building source link-layer address option (l2addr: %s)\n", - gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), l2addr, - l2addr_len)); + gnrc_netif2_addr_to_str(l2addr, l2addr_len, addr_str)); return _opt_l2a_build(l2addr, l2addr_len, next, NDP_OPT_SL2A); } @@ -178,8 +177,7 @@ gnrc_pktsnip_t *gnrc_ndp2_opt_tl2a_build(const uint8_t *l2addr, { assert((l2addr != NULL) && (l2addr_len != 0)); DEBUG("ndp2: building target link-layer address option (l2addr: %s)\n", - gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), l2addr, - l2addr_len)); + gnrc_netif2_addr_to_str(l2addr, l2addr_len, addr_str)); return _opt_l2a_build(l2addr, l2addr_len, next, NDP_OPT_TL2A); } @@ -223,14 +221,13 @@ gnrc_pktsnip_t *gnrc_ndp2_opt_mtu_build(uint32_t mtu, gnrc_pktsnip_t *next) return pkt; } -static gnrc_pktsnip_t *_build_headers(gnrc_ipv6_netif_t *netif, +static gnrc_pktsnip_t *_build_headers(gnrc_netif2_t *netif, const ipv6_addr_t *src, const ipv6_addr_t *dst, gnrc_pktsnip_t *payload); -static size_t _get_l2src(gnrc_ipv6_netif_t *netif, uint8_t *l2src, - size_t l2src_maxlen); +static inline size_t _get_l2src(const gnrc_netif2_t *netif, uint8_t *l2src); -void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif, +void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_netif2_t *netif, const ipv6_addr_t *src, const ipv6_addr_t *dst, gnrc_pktsnip_t *ext_opts) { @@ -250,49 +247,58 @@ void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif, sizeof(addr_str))); DEBUG("tgt: %s, ", ipv6_addr_to_str(addr_str, tgt, sizeof(addr_str))); DEBUG("dst: %s)\n", ipv6_addr_to_str(addr_str, dst, sizeof(addr_str))); - /* check if there is a fitting source address to target */ - if (src == NULL) { - src = gnrc_ipv6_netif_find_best_src_addr(netif->pid, tgt, false); - } + gnrc_netif2_acquire(netif); + do { /* XXX hidden goto */ + /* check if there is a fitting source address to target */ + if (src == NULL) { + src = gnrc_netif2_ipv6_addr_best_src(netif, tgt, false); + } - /* add SL2AO based on interface and source address */ - if ((src != NULL) && !ipv6_addr_is_unspecified(src)) { - l2src_len = _get_l2src(netif, l2src, sizeof(l2src)); + /* add SL2AO based on interface and source address */ + if ((src != NULL) && !ipv6_addr_is_unspecified(src)) { + l2src_len = _get_l2src(netif, l2src); - if (l2src_len > 0) { - /* add source address link-layer address option */ - hdr = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, pkt); + if (l2src_len > 0) { + /* add source address link-layer address option */ + hdr = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, pkt); - if (hdr == NULL) { - DEBUG("ndp2: error allocating SL2AO.\n"); - gnrc_pktbuf_release(pkt); - return; + if (hdr == NULL) { + DEBUG("ndp2: error allocating SL2AO.\n"); + break; + } + pkt = hdr; } + } + /* add neighbor solicitation header */ + hdr = gnrc_ndp2_nbr_sol_build(tgt, pkt); + if (hdr == NULL) { + DEBUG("ndp2: error allocating neighbor solicitation.\n"); + break; + } + pkt = hdr; + /* add remaining headers */ + hdr = _build_headers(netif, src, dst, pkt); + if (hdr == NULL) { + DEBUG("ndp2: error adding lower-layer headers.\n"); + break; + } + else { pkt = hdr; + if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2, + GNRC_NETREG_DEMUX_CTX_ALL, + pkt) == 0) { + DEBUG("ndp2: unable to send neighbor solicitation\n"); + break; + } } - } - /* add neighbor solicitation header */ - hdr = gnrc_ndp2_nbr_sol_build(tgt, pkt); - if (hdr == NULL) { - DEBUG("ndp2: error allocating neighbor solicitation.\n"); - gnrc_pktbuf_release(pkt); + gnrc_netif2_release(netif); return; - } - pkt = hdr; - /* add remaining headers */ - hdr = _build_headers(netif, src, dst, pkt); - if (hdr == NULL) { - DEBUG("ndp2: error adding lower-layer headers.\n"); - gnrc_pktbuf_release(pkt); - } - else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2, - GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) { - DEBUG("ndp2: unable to send neighbor solicitation\n"); - gnrc_pktbuf_release(hdr); - } + } while (0); + gnrc_pktbuf_release(pkt); + gnrc_netif2_release(netif); } -void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif, +void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_netif2_t *netif, const ipv6_addr_t *dst, bool supply_tl2a, gnrc_pktsnip_t *ext_opts) { @@ -307,68 +313,83 @@ void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif, ipv6_addr_to_str(addr_str, tgt, sizeof(addr_str))); DEBUG("dst: %s, supply_tl2a: %d)\n", ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), supply_tl2a); - if ((netif->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) && - (netif->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV)) { - adv_flags |= NDP_NBR_ADV_FLAGS_R; - } - if (ipv6_addr_is_unspecified(dst)) { - memcpy(&real_dst, &ipv6_addr_all_nodes_link_local, sizeof(ipv6_addr_t)); - supply_tl2a = true; - } - else { - memcpy(&real_dst, dst, sizeof(real_dst)); - adv_flags |= NDP_NBR_ADV_FLAGS_S; - } - /* add SL2AO based on target address */ - if (supply_tl2a) { - uint8_t l2tgt[8]; - size_t l2tgt_len; - /* we previously checked if we are the target, so we can take our L2tgt */ - l2tgt_len = _get_l2src(netif, l2tgt, sizeof(l2tgt)); - - if (l2tgt_len > 0) { - /* add target address link-layer address option */ - hdr = gnrc_ndp2_opt_tl2a_build(l2tgt, l2tgt_len, pkt); - - if (hdr == NULL) { - DEBUG("ndp2: error allocating TL2AO.\n"); - gnrc_pktbuf_release(ext_opts); - return; + gnrc_netif2_acquire(netif); + do { /* XXX: hidden goto */ + int tgt_idx; + + if ((tgt_idx = gnrc_netif2_ipv6_addr_idx(netif, tgt)) < 0) { + DEBUG("ndp2: tgt not assigned to interface. Abort sending\n"); + break; + } + if (gnrc_netif2_is_rtr(netif) && gnrc_netif2_is_rtr_adv(netif)) { + adv_flags |= NDP_NBR_ADV_FLAGS_R; + } + if (ipv6_addr_is_unspecified(dst)) { + memcpy(&real_dst, &ipv6_addr_all_nodes_link_local, + sizeof(ipv6_addr_t)); + supply_tl2a = true; + } + else { + memcpy(&real_dst, dst, sizeof(real_dst)); + adv_flags |= NDP_NBR_ADV_FLAGS_S; + } + /* add SL2AO based on target address */ + if (supply_tl2a) { + uint8_t l2tgt[8]; + size_t l2tgt_len; + /* we previously checked if we are the target, so we can take our L2tgt */ + l2tgt_len = _get_l2src(netif, l2tgt); + + if (l2tgt_len > 0) { + /* add target address link-layer address option */ + hdr = gnrc_ndp2_opt_tl2a_build(l2tgt, l2tgt_len, pkt); + + if (hdr == NULL) { + DEBUG("ndp2: error allocating TL2AO.\n"); + break; + } + pkt = hdr; } + } + /* TODO: also check if the node provides proxy servies for tgt */ + if ((pkt != NULL) && + (netif->ipv6.addrs_flags[tgt_idx] & + GNRC_NETIF2_IPV6_ADDRS_FLAGS_ANYCAST)) { + /* TL2A is not supplied and tgt is not anycast */ + adv_flags |= NDP_NBR_ADV_FLAGS_O; + } + /* add neighbor advertisement header */ + hdr = gnrc_ndp2_nbr_adv_build(tgt, adv_flags, pkt); + if (hdr == NULL) { + DEBUG("ndp2: error allocating neighbor advertisement.\n"); + break; + } + pkt = hdr; + /* add remaining headers */ + hdr = _build_headers(netif, NULL, &real_dst, pkt); + if (hdr == NULL) { + DEBUG("ndp2: error adding lower-layer headers.\n"); + break; + } + else { pkt = hdr; + if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2, + GNRC_NETREG_DEMUX_CTX_ALL, + pkt) == 0) { + DEBUG("ndp2: unable to send neighbor advertisement\n"); + break; + } } - } - /* TODO: also check if the node provides proxy services for tgt */ - if ((pkt != NULL) && - (!gnrc_ipv6_netif_addr_is_non_unicast(tgt) || supply_tl2a)) { - /* TL2A is not supplied and tgt is not anycast */ - adv_flags |= NDP_NBR_ADV_FLAGS_O; - } - /* add neighbor advertisement header */ - hdr = gnrc_ndp2_nbr_adv_build(tgt, adv_flags, pkt); - if (hdr == NULL) { - DEBUG("ndp2: error allocating neighbor advertisement.\n"); - gnrc_pktbuf_release(pkt); + gnrc_netif2_release(netif); return; - } - pkt = hdr; - /* add remaining headers */ - hdr = _build_headers(netif, NULL, &real_dst, pkt); - if (hdr == NULL) { - DEBUG("ndp2: error adding lower-layer headers.\n"); - gnrc_pktbuf_release(pkt); - } - else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2, - GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) { - DEBUG("ndp2: unable to send neighbor advertisement\n"); - gnrc_pktbuf_release(hdr); - } + } while (0); + gnrc_pktbuf_release(pkt); + gnrc_netif2_release(netif); } -void gnrc_ndp2_rtr_sol_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *dst) +void gnrc_ndp2_rtr_sol_send(gnrc_netif2_t *netif, const ipv6_addr_t *dst) { gnrc_pktsnip_t *hdr, *pkt = NULL; - ipv6_addr_t *src = NULL; assert(netif != NULL); if (dst == NULL) { @@ -377,43 +398,53 @@ void gnrc_ndp2_rtr_sol_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *dst) DEBUG("ndp2: send router solicitation (iface: %" PRIkernel_pid ", dst: %s)\n", netif->pid, ipv6_addr_to_str(addr_str, dst, sizeof(addr_str))); - /* add SL2AO => check if there is a fitting source address to target */ - if ((src = gnrc_ipv6_netif_find_best_src_addr(netif->pid, dst, - false)) != NULL) { - uint8_t l2src[8]; - size_t l2src_len = _get_l2src(netif, l2src, sizeof(l2src)); - if (l2src_len > 0) { - /* add source address link-layer address option */ - pkt = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, NULL); - if (pkt == NULL) { - DEBUG("ndp2: error allocating SL2AO.\n"); - gnrc_pktbuf_release(pkt); - return; + gnrc_netif2_acquire(netif); + do { /* XXX: hidden goto */ + ipv6_addr_t *src = NULL; + + /* add SL2AO => check if there is a fitting source address to target */ + if ((src = gnrc_netif2_ipv6_addr_best_src(netif, dst, false)) != NULL) { + uint8_t l2src[8]; + size_t l2src_len = _get_l2src(netif, l2src); + if (l2src_len > 0) { + /* add source address link-layer address option */ + pkt = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, NULL); + if (pkt == NULL) { + DEBUG("ndp2: error allocating SL2AO.\n"); + break; + } } } - } - /* add router solicitation header */ - hdr = gnrc_ndp2_rtr_sol_build(pkt); - if (hdr == NULL) { - DEBUG("ndp2: error allocating router solicitation.\n"); - gnrc_pktbuf_release(pkt); + /* add router solicitation header */ + hdr = gnrc_ndp2_rtr_sol_build(pkt); + if (hdr == NULL) { + DEBUG("ndp2: error allocating router solicitation.\n"); + break; + } + pkt = hdr; + /* add remaining headers */ + hdr = _build_headers(netif, src, dst, pkt); + if (hdr == NULL) { + DEBUG("ndp2: error adding lower-layer headers.\n"); + break; + } + else { + pkt = hdr; + if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2, + GNRC_NETREG_DEMUX_CTX_ALL, + pkt) == 0) { + DEBUG("ndp2: unable to send router advertisement\n"); + break; + } + } + gnrc_netif2_release(netif); return; - } - pkt = hdr; - /* add remaining headers */ - hdr = _build_headers(netif, src, dst, pkt); - if (hdr == NULL) { - DEBUG("ndp2: error adding lower-layer headers.\n"); - gnrc_pktbuf_release(pkt); - } - else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2, - GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) { - DEBUG("ndp2: unable to send router advertisement\n"); - gnrc_pktbuf_release(hdr); - } + } while (0); + gnrc_pktbuf_release(pkt); + gnrc_netif2_release(netif); } -void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src, +void gnrc_ndp2_rtr_adv_send(gnrc_netif2_t *netif, const ipv6_addr_t *src, const ipv6_addr_t *dst, bool fin, gnrc_pktsnip_t *ext_opts) { @@ -422,6 +453,7 @@ void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src, uint32_t reach_time = 0, retrans_timer = 0; uint16_t adv_ltime = 0; uint8_t cur_hl = 0; + uint8_t flags = 0; if (dst == NULL) { dst = &ipv6_addr_all_nodes_link_local; @@ -429,78 +461,91 @@ void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src, DEBUG("ndp2: send router advertisement (iface: %" PRIkernel_pid ", dst: %s%s\n", netif->pid, ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), fin ? ", final" : ""); - if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_MTU) { - if ((hdr = gnrc_ndp2_opt_mtu_build(netif->mtu, pkt)) == NULL) { - DEBUG("ndp rtr: no space left in packet buffer\n"); - return; - } - pkt = hdr; - } - if (src == NULL) { - /* get address from source selection algorithm. - * Only link local addresses may be used (RFC 4861 section 4.1) */ - src = gnrc_ipv6_netif_find_best_src_addr(netif->pid, dst, true); - } - /* add SL2A for source address */ - if (src != NULL) { - DEBUG(" - SL2A\n"); - uint8_t l2src[8]; - size_t l2src_len; - /* optimization note: MAY also be omitted to facilitate in-bound load balancing over - * replicated interfaces. - * source: https://tools.ietf.org/html/rfc4861#section-6.2.3 */ - l2src_len = _get_l2src(netif, l2src, sizeof(l2src)); - if (l2src_len > 0) { - /* add source address link-layer address option */ - hdr = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, pkt); - - if (hdr == NULL) { - DEBUG("ndp2: error allocating Source Link-layer address option.\n"); - gnrc_pktbuf_release(pkt); - return; + gnrc_netif2_acquire(netif); + do { /* XXX: hidden goto */ + if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_MTU) { + if ((hdr = gnrc_ndp2_opt_mtu_build(netif->ipv6.mtu, pkt)) == NULL) { + DEBUG("ndp rtr: no space left in packet buffer\n"); + break; } pkt = hdr; } - } - if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_CUR_HL) { - cur_hl = netif->cur_hl; - } - if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_REACH_TIME) { - - if (netif->reach_time > (3600 * US_PER_SEC)) { /* reach_time > 1 hour */ - reach_time = (3600 * MS_PER_SEC); + if (src == NULL) { + /* get address from source selection algorithm. + * Only link local addresses may be used (RFC 4861 section 4.1) */ + src = gnrc_netif2_ipv6_addr_best_src(netif, dst, true); + } + /* add SL2A for source address */ + if (src != NULL) { + DEBUG(" - SL2A\n"); + uint8_t l2src[8]; + size_t l2src_len; + /* optimization note: MAY also be omitted to facilitate in-bound load balancing over + * replicated interfaces. + * source: https://tools.ietf.org/html/rfc4861#section-6.2.3 */ + l2src_len = _get_l2src(netif, l2src); + if (l2src_len > 0) { + /* add source address link-layer address option */ + hdr = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, pkt); + + if (hdr == NULL) { + DEBUG("ndp2: error allocating Source Link-layer address " + "option.\n"); + break; + } + pkt = hdr; + } + } + if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_CUR_HL) { + cur_hl = netif->cur_hl; + } + if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_REACH_TIME) { + if (netif->ipv6.reach_time_base > (3600 * MS_PER_SEC)) { + /* reach_time > 1 hour */ + reach_time = (3600 * MS_PER_SEC); + } + else { + reach_time = netif->ipv6.reach_time_base; + } + } + if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_RETRANS_TIMER) { + retrans_timer = netif->ipv6.retrans_time; + } + if (!fin) { + adv_ltime = netif->ipv6.rtr_ltime; + } + if (netif->ipv6.aac_mode == GNRC_NETIF2_AAC_DHCP) { + flags |= NDP_RTR_ADV_FLAGS_M; + if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_O_FLAG) { + flags |= NDP_RTR_ADV_FLAGS_O; + } + } + hdr = gnrc_ndp2_rtr_adv_build(cur_hl, flags, adv_ltime, reach_time, + retrans_timer, pkt); + if (hdr == NULL) { + DEBUG("ndp2: error allocating router advertisement.\n"); + break; + } + pkt = hdr; + hdr = _build_headers(netif, src, dst, pkt); + if (hdr == NULL) { + DEBUG("ndp2: error adding lower-layer headers.\n"); + break; } else { - reach_time = netif->reach_time / US_PER_MS; + pkt = hdr; + if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2, + GNRC_NETREG_DEMUX_CTX_ALL, + pkt) == 0) { + DEBUG("ndp2: unable to send router solicitation\n"); + break; + } } - } - if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_RETRANS_TIMER) { - retrans_timer = netif->retrans_timer / US_PER_MS; - } - if (!fin) { - /* TODO set netif dependent adv_ltime */ - adv_ltime = 1800U; - } - hdr = gnrc_ndp2_rtr_adv_build(cur_hl, - (netif->flags & (GNRC_IPV6_NETIF_FLAGS_OTHER_CONF | - GNRC_IPV6_NETIF_FLAGS_MANAGED)) >> 8, - adv_ltime, reach_time, retrans_timer, pkt); - if (hdr == NULL) { - DEBUG("ndp2: error allocating router advertisement.\n"); - gnrc_pktbuf_release(pkt); + gnrc_netif2_release(netif); return; - } - pkt = hdr; - hdr = _build_headers(netif, src, dst, pkt); - if (hdr == NULL) { - DEBUG("ndp2: error adding lower-layer headers.\n"); - gnrc_pktbuf_release(pkt); - } - else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2, - GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) { - DEBUG("ndp2: unable to send router solicitation\n"); - gnrc_pktbuf_release(hdr); - } + } while (0); + gnrc_pktbuf_release(pkt); + gnrc_netif2_release(netif); #else (void)netif; (void)src; @@ -511,7 +556,7 @@ void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src, #endif /* GNRC_IPV6_NIB_CONF_ROUTER */ } -static gnrc_pktsnip_t *_build_headers(gnrc_ipv6_netif_t *netif, +static gnrc_pktsnip_t *_build_headers(gnrc_netif2_t *netif, const ipv6_addr_t *src, const ipv6_addr_t *dst, gnrc_pktsnip_t *payload) @@ -536,37 +581,16 @@ static gnrc_pktsnip_t *_build_headers(gnrc_ipv6_netif_t *netif, return l2hdr; } -static size_t _get_l2src(gnrc_ipv6_netif_t *netif, uint8_t *l2src, - size_t l2src_maxlen) +static inline size_t _get_l2src(const gnrc_netif2_t *netif, uint8_t *l2src) { - bool try_long = false; - int res; - uint16_t l2src_len; - /* maximum address length that fits into a minimum length (8) S/TL2A option */ - const uint16_t max_short_len = 6; - - /* try getting source address */ - if ((gnrc_netapi_get(netif->pid, NETOPT_SRC_LEN, 0, &l2src_len, - sizeof(l2src_len)) >= 0) && - (l2src_len > max_short_len)) { - try_long = true; - } - - if (try_long && ((res = gnrc_netapi_get(netif->pid, NETOPT_ADDRESS_LONG, 0, - l2src, - l2src_maxlen)) > max_short_len)) { - l2src_len = (uint16_t)res; - } - else if ((res = gnrc_netapi_get(netif->pid, NETOPT_ADDRESS, 0, l2src, - l2src_maxlen)) >= 0) { - l2src_len = (uint16_t)res; - } - else { - DEBUG("ndp2: no link-layer address found.\n"); - l2src_len = 0; - } - - return l2src_len; +#if GNRC_NETIF2_L2ADDR_MAXLEN > 0 + memcpy(l2src, netif->l2addr, netif->l2addr_len); + return netif->l2addr_len; +#else + (void)netif; + (void)l2src; + return 0; +#endif } /** @} */