diff --git a/Makefile.dep b/Makefile.dep index b1a028e5afaf..d7b244c58a92 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -136,29 +136,30 @@ endif ifneq (,$(filter gnrc_sixlowpan_default,$(USEMODULE))) USEMODULE += gnrc_ipv6_default + USEMODULE += gnrc_ipv6_nib_6ln USEMODULE += gnrc_sixlowpan - USEMODULE += gnrc_sixlowpan_nd USEMODULE += gnrc_sixlowpan_frag USEMODULE += gnrc_sixlowpan_iphc endif ifneq (,$(filter gnrc_sixlowpan_router_default,$(USEMODULE))) USEMODULE += gnrc_ipv6_router_default + USEMODULE += gnrc_ipv6_nib_6lr USEMODULE += gnrc_sixlowpan_router USEMODULE += gnrc_sixlowpan_frag USEMODULE += gnrc_sixlowpan_iphc endif ifneq (,$(filter gnrc_sixlowpan_border_router_default,$(USEMODULE))) + USEMODULE += gnrc_ipv6_nib_6lbr 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_nd_router + USEMODULE += gnrc_ipv6_router endif ifneq (,$(filter gnrc_sixlowpan_frag,$(USEMODULE))) @@ -182,50 +183,14 @@ ifneq (,$(filter gnrc_sixlowpan_ctx,$(USEMODULE))) USEMODULE += xtimer 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 - -ifneq (,$(filter gnrc_sixlowpan_nd,$(USEMODULE))) - USEMODULE += gnrc_ndp - USEMODULE += gnrc_ndp_internal - USEMODULE += gnrc_sixlowpan_ctx - USEMODULE += random - USEMODULE += xtimer -endif - ifneq (,$(filter gnrc_ipv6_default,$(USEMODULE))) USEMODULE += gnrc_ipv6 USEMODULE += gnrc_icmpv6 - ifeq (1,$(GNRC_NETIF_NUMOF)) - ifeq (,$(filter gnrc_sixlowpan_nd,$(USEMODULE))) - USEMODULE += gnrc_ndp_host - endif - else - USEMODULE += gnrc_ndp_host - endif endif ifneq (,$(filter gnrc_ipv6_router_default,$(USEMODULE))) USEMODULE += gnrc_ipv6_router USEMODULE += gnrc_icmpv6 - ifeq (1,$(GNRC_NETIF_NUMOF)) - ifeq (,$(filter gnrc_sixlowpan_nd_router,$(USEMODULE))) - USEMODULE += gnrc_ndp_router - endif - else - USEMODULE += gnrc_ndp_router - endif -endif - -ifneq (,$(filter gnrc_ndp_host,$(USEMODULE))) - USEMODULE += gnrc_ndp_node - USEMODULE += random - USEMODULE += xtimer endif ifneq (,$(filter gnrc_ndp_router,$(USEMODULE))) @@ -242,20 +207,9 @@ ifneq (,$(filter gnrc_ndp_%,$(USEMODULE))) USEMODULE += gnrc_ndp endif -ifneq (,$(filter gnrc_ndp,$(USEMODULE))) - ifneq (,$(filter gnrc_sixlowpan,$(USEMODULE))) - USEMODULE += gnrc_sixlowpan_nd - else - USEMODULE += gnrc_ndp_node - endif - USEMODULE += gnrc_ndp_internal - USEMODULE += gnrc_icmpv6 - USEMODULE += random - USEMODULE += xtimer -endif - ifneq (,$(filter gnrc_ndp2,$(USEMODULE))) USEMODULE += gnrc_icmpv6 + USEMODULE += gnrc_netif2 endif ifneq (,$(filter gnrc_icmpv6_echo,$(USEMODULE))) @@ -301,7 +255,7 @@ ifneq (,$(filter gnrc_ipv6,$(USEMODULE))) USEMODULE += inet_csum USEMODULE += ipv6_addr USEMODULE += gnrc_ipv6_hdr - USEMODULE += gnrc_ipv6_nc + USEMODULE += gnrc_ipv6_nib USEMODULE += gnrc_netif2 endif diff --git a/sys/include/net/gnrc/ipv6.h b/sys/include/net/gnrc/ipv6.h index 0b9704b247d5..661531b4da92 100644 --- a/sys/include/net/gnrc/ipv6.h +++ b/sys/include/net/gnrc/ipv6.h @@ -36,9 +36,7 @@ #include "net/ipv6.h" #include "net/gnrc/ipv6/ext.h" #include "net/gnrc/ipv6/hdr.h" -#ifndef MODULE_GNRC_IPV6_NIB -#include "net/gnrc/ipv6/nc.h" -#endif +#include "net/gnrc/ipv6/nib.h" #ifdef MODULE_FIB #include "net/fib.h" diff --git a/sys/include/net/gnrc/ipv6/nib.h b/sys/include/net/gnrc/ipv6/nib.h index 0883a2cc583b..43fe775635d6 100644 --- a/sys/include/net/gnrc/ipv6/nib.h +++ b/sys/include/net/gnrc/ipv6/nib.h @@ -33,6 +33,7 @@ #include "net/ipv6/addr.h" #include "net/ipv6/hdr.h" #include "net/gnrc/ipv6/nib/nc.h" +#include "net/gnrc/netif2.h" #include "net/gnrc/pkt.h" #ifdef __cplusplus @@ -194,13 +195,67 @@ extern "C" { * @brief Recalculate reachability timeout time. * * This message type is for the event of recalculating the reachability timeout - * time. The expected message context is a valid interface. + * time. The expected message context is a valid + * [interface](@ref net_gnrc_netif2). * * @note Only handled with @ref GNRC_IPV6_NIB_CONF_ARSM != 0 */ #define GNRC_IPV6_NIB_RECALC_REACH_TIME (0x4fceU) /** @} */ +/** + * @brief Types for gnrc_netif2_ipv6_t::route_info_cb + * @anchor net_gnrc_ipv6_nib_route_info_type + */ +enum { + GNRC_IPV6_NIB_ROUTE_INFO_TYPE_UNDEF = 0, /**< undefined */ + /** + * @brief reactive routing query + * + * A reactive routing query is issued when a route is unknown to the NIB. + * A reactive routing protocol can use this call to search for a route in a + * reactive manner. + * + * The `ctx_addr` will be the destination address of the unknown route, + * `ctx` a pointer to the packet as `gnrc_pktsnip_t` that caused the route + * look-up (to possibly queue it for later sending). + */ + GNRC_IPV6_NIB_ROUTE_INFO_TYPE_RRQ, + + /** + * @brief route notification + * + * A route notification is issued when an already established route is + * taken. A routing protocol can use this call to update its information on + * the route. + * + * The `ctx_addr` is the prefix of the route, `ctx` is set to a value equal + * to the length of the prefix in bits. + */ + GNRC_IPV6_NIB_ROUTE_INFO_TYPE_RN, + + /** + * @brief neighbor state change + * + * A neighbor state change is issued when ever the NUD state of a neighbor + * changes. A routing protocol can use this call to update its information + * on routes via this neighbor. + * + * The `ctx_addr` is the address of the neighbor, `ctx` is a value equal + * to the new NUD state as defined in [the NC info flags](@ref + * net_gnrc_ipv6_nib_nc_info). If the entry is deleted, `ctx` will be set + * to @ref GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE (except if it was + * already in the `UNREACHABLE` state). This does not include cache-outs, + * since they give no information about the neighbor's reachability (you + * might however get an INCOMPLETE or STALE notification due to that, as + * soon as the neighbor enters the neighbor cache again). + * + * Be adviced to only use `ctx_addr` in the context of the callback, since + * it might be overwritten, after the callback was left. + */ + GNRC_IPV6_NIB_ROUTE_INFO_TYPE_NSC, +}; + /** * @brief Initialize NIB */ @@ -209,11 +264,11 @@ void gnrc_ipv6_nib_init(void); /** * @brief Adds an interface to be managed by the NIB. * - * @pre `(KERNEL_PID_UNDEF < iface)` + * @pre `netif != NULL` * - * @param[in] iface The interface to be managed by the NIB + * @param[in,out] netif The interface to be managed by the NIB */ -void gnrc_ipv6_nib_init_iface(kernel_pid_t iface); +void gnrc_ipv6_nib_init_iface(gnrc_netif2_t *netif); /** * @brief Gets link-layer address of next hop to a destination address @@ -221,8 +276,8 @@ void gnrc_ipv6_nib_init_iface(kernel_pid_t iface); * @pre `(dst != NULL) && (nce != NULL)` * * @param[in] dst Destination address of a packet. - * @param[in] iface Restrict search to this interface. May be - * `KERNEL_PID_UNDEF` for any interface. + * @param[in] netif Restrict search to this interface. May be `NULL` for any + * interface. * @param[in] pkt The IPv6 packet in sending order for which the next hop * is searched. Needed for queuing for with reactive * routing or address resolution. May be `NULL`. @@ -237,13 +292,13 @@ void gnrc_ipv6_nib_init_iface(kernel_pid_t iface); * solicitation sent). */ int gnrc_ipv6_nib_get_next_hop_l2addr(const ipv6_addr_t *dst, - kernel_pid_t iface, gnrc_pktsnip_t *pkt, + gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt, gnrc_ipv6_nib_nc_t *nce); /** * @brief Handles a received ICMPv6 packet * - * @pre `iface != KERNEL_PID_UNDEF` + * @pre `netif != NULL` * @pre `ipv6 != NULL` * @pre `icmpv6 != NULL` * @pre `icmpv6_len > sizeof(icmpv6_hdr_t)` @@ -274,13 +329,13 @@ int gnrc_ipv6_nib_get_next_hop_l2addr(const ipv6_addr_t *dst, * @see [RFC 6775, section 8.2.4](https://tools.ietf.org/html/rfc6775#section-8.2.4) * @see [RFC 6775, section 8.2.5](https://tools.ietf.org/html/rfc6775#section-8.2.5) * - * @param[in] iface The interface the packet came over. + * @param[in] netif The interface the packet came over. * @param[in] ipv6 The IPv6 header of the received packet. * @param[in] icmpv6 The ICMPv6 header and payload of the received * packet. * @param[in] icmpv6_len The number of bytes at @p icmpv6. */ -void gnrc_ipv6_nib_handle_pkt(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +void gnrc_ipv6_nib_handle_pkt(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6, const icmpv6_hdr_t *icmpv6, size_t icmpv6_len); /** @@ -292,6 +347,25 @@ void gnrc_ipv6_nib_handle_pkt(kernel_pid_t iface, const ipv6_hdr_t *ipv6, */ void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type); +#if GNRC_IPV6_NIB_CONF_ROUTER || defined(DOXYGEN) +/** + * @brief Changes the state if an interface advertises itself as a router + * or not + * + * @param[in] netif The interface for which the state should be changed. + * @param[in] enable `true`, to enable advertising the interface as a router. + * `false`, to disable advertising the interface as a + * router. + */ +void gnrc_ipv6_nib_change_rtr_adv_iface(gnrc_netif2_t *netif, bool enable); +#else +/** + * @brief Optimization to NOP for non-routers + */ +#define gnrc_ipv6_nib_change_rtr_adv_iface(netif, enable) \ + (void)netif; (void)enable +#endif + #ifdef __cplusplus } #endif diff --git a/sys/include/net/gnrc/ipv6/nib/conf.h b/sys/include/net/gnrc/ipv6/nib/conf.h index e3c28286e0aa..90992df16583 100644 --- a/sys/include/net/gnrc/ipv6/nib/conf.h +++ b/sys/include/net/gnrc/ipv6/nib/conf.h @@ -199,10 +199,8 @@ extern "C" { /** * @brief Maximum link-layer address length (aligned) */ -#if (GNRC_NETIF_HDR_L2ADDR_MAX_LEN % 8) -#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (((GNRC_NETIF_HDR_L2ADDR_MAX_LEN >> 3) + 1) << 3) -#else -#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (GNRC_NETIF_HDR_L2ADDR_MAX_LEN) +#ifndef GNRC_IPV6_NIB_L2ADDR_MAX_LEN +#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (8U) #endif /** diff --git a/sys/include/net/gnrc/ndp2.h b/sys/include/net/gnrc/ndp2.h index def42558d9e3..ab7d4bd84ac8 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/include/net/gnrc/netif2/conf.h b/sys/include/net/gnrc/netif2/conf.h index 80544f71690a..085f622a2552 100644 --- a/sys/include/net/gnrc/netif2/conf.h +++ b/sys/include/net/gnrc/netif2/conf.h @@ -20,6 +20,7 @@ #include "net/ieee802154.h" #include "net/ethernet/hdr.h" +#include "net/gnrc/ipv6/nib/conf.h" #include "thread.h" #ifdef __cplusplus @@ -60,7 +61,7 @@ extern "C" { * * @note Used for calculation of @ref GNRC_NETIF2_IPV6_GROUPS_NUMOF */ -#ifdef MODULE_GNRC_IPV6_ROUTER +#if GNRC_IPV6_NIB_CONF_ROUTER #define GNRC_NETIF2_IPV6_RTR_ADDR (1) #else #define GNRC_NETIF2_IPV6_RTR_ADDR (0) @@ -109,7 +110,7 @@ extern "C" { #elif MODULE_CC110X #define GNRC_NETIF2_L2ADDR_MAXLEN (1U) #else -#define GNRC_NETIF2_L2ADDR_MAXLEN (8U) +#define GNRC_NETIF2_L2ADDR_MAXLEN (GNRC_IPV6_NIB_L2ADDR_MAX_LEN) #endif #endif diff --git a/sys/include/net/gnrc/netif2/ipv6.h b/sys/include/net/gnrc/netif2/ipv6.h index ba9b9811dc41..4357ddcf5bd8 100644 --- a/sys/include/net/gnrc/netif2/ipv6.h +++ b/sys/include/net/gnrc/netif2/ipv6.h @@ -115,9 +115,8 @@ typedef struct { * The callback may be `NULL` if no such behavior is required by the routing * protocol (or no routing protocol is present). * - * @todo Define types (RRQ, RRN, NSC) in NIB - * - * @param[in] type Type of the route info. + * @param[in] type [Type](@ref net_gnrc_ipv6_nib_route_info_type) of + * the route info. * @param[in] ctx_addr Context address of the route info. * @param[in] ctx Further context of the route info. */ diff --git a/sys/net/gnrc/netif2/gnrc_netif2.c b/sys/net/gnrc/netif2/gnrc_netif2.c index a72c2f993982..18ea7ec008b5 100644 --- a/sys/net/gnrc/netif2/gnrc_netif2.c +++ b/sys/net/gnrc/netif2/gnrc_netif2.c @@ -19,6 +19,9 @@ #include "net/ethernet.h" #include "net/ipv6.h" #include "net/gnrc.h" +#ifdef MODULE_GNRC_IPV6_NIB +#include "net/gnrc/ipv6/nib.h" +#endif /* MODULE_GNRC_IPV6_NIB */ #ifdef MODULE_NETSTATS_IPV6 #include "net/netstats.h" #endif @@ -278,7 +281,7 @@ int gnrc_netif2_set_from_netdev(gnrc_netif2_t *netif, } else { if (gnrc_netif2_is_rtr_adv(netif)) { - gnrc_ipv6_nib_iface_cease_rtr_adv(netif); + gnrc_ipv6_nib_change_rtr_adv_iface(netif, false); } netif->flags &= ~GNRC_NETIF2_FLAGS_IPV6_FORWARDING; } @@ -286,12 +289,8 @@ int gnrc_netif2_set_from_netdev(gnrc_netif2_t *netif, break; case NETOPT_IPV6_SND_RTR_ADV: assert(opt->data_len == sizeof(netopt_enable_t)); - if (*(((netopt_enable_t *)opt->data)) == NETOPT_ENABLE) { - gnrc_ipv6_nib_iface_start_rtr_adv(netif); - } - else { - gnrc_ipv6_nib_iface_cease_rtr_adv(netif); - } + gnrc_ipv6_nib_change_rtr_adv_iface(netif, + (*(((netopt_enable_t *)opt->data)) == NETOPT_ENABLE)); res = sizeof(netopt_enable_t); break; #endif /* GNRC_IPV6_NIB_CONF_ROUTER */ diff --git a/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c b/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c index 1ce69e48ac14..9184a29b8814 100644 --- a/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c +++ b/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c @@ -23,11 +23,7 @@ #include "kernel_types.h" #include "net/ipv6/hdr.h" #include "net/gnrc.h" -#ifndef MODULE_GNRC_IPV6_NIB -#include "net/gnrc/ndp.h" -#else #include "net/gnrc/ipv6/nib.h" -#endif #include "net/protnum.h" #include "od.h" #include "utlist.h" @@ -98,40 +94,6 @@ void gnrc_icmpv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt) break; #endif -#ifndef MODULE_GNRC_IPV6_NIB -#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)) - case ICMPV6_RTR_SOL: - DEBUG("icmpv6: router solicitation received\n"); - 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: - DEBUG("icmpv6: router advertisement received\n"); - gnrc_ndp_rtr_adv_handle(iface, pkt, ipv6->data, (ndp_rtr_adv_t *)hdr, - icmpv6->size); - break; - - case ICMPV6_NBR_SOL: - DEBUG("icmpv6: neighbor solicitation received\n"); - gnrc_ndp_nbr_sol_handle(iface, pkt, ipv6->data, (ndp_nbr_sol_t *)hdr, - icmpv6->size); - break; - - case ICMPV6_NBR_ADV: - DEBUG("icmpv6: neighbor advertisement received\n"); - gnrc_ndp_nbr_adv_handle(iface, pkt, ipv6->data, (ndp_nbr_adv_t *)hdr, - icmpv6->size); - break; -#endif - - case ICMPV6_REDIRECT: - DEBUG("icmpv6: redirect message received\n"); - /* TODO */ - break; -#else /* MODULE_GNRC_IPV6_NIB */ case ICMPV6_RTR_SOL: case ICMPV6_RTR_ADV: case ICMPV6_NBR_SOL: @@ -140,9 +102,9 @@ void gnrc_icmpv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt) case ICMPV6_DAR: case ICMPV6_DAC: DEBUG("icmpv6: NDP message received. Handle with gnrc_ipv6_nib\n"); - gnrc_ipv6_nib_handle_pkt(iface, ipv6->data, hdr, icmpv6->size); + gnrc_ipv6_nib_handle_pkt(gnrc_netif2_get_by_pid(iface), + ipv6->data, hdr, icmpv6->size); break; -#endif /* MODULE_GNRC_IPV6_NIB */ default: DEBUG("icmpv6: unknown type field %u\n", hdr->type); diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index ffa95c1ccbfb..e70da32d3587 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -29,11 +29,7 @@ #include "thread.h" #include "utlist.h" -#ifndef MODULE_GNRC_IPV6_NIB -#include "net/gnrc/ipv6/nc.h" -#else #include "net/gnrc/ipv6/nib.h" -#endif #include "net/gnrc/netif2/internal.h" #include "net/gnrc/ipv6/whitelist.h" #include "net/gnrc/ipv6/blacklist.h" @@ -290,83 +286,6 @@ static void *_event_loop(void *args) msg_reply(&msg, &reply); break; -#ifndef MODULE_GNRC_IPV6_NIB -#ifdef MODULE_GNRC_NDP - case GNRC_NDP_MSG_RTR_TIMEOUT: - DEBUG("ipv6: Router timeout received\n"); - ((gnrc_ipv6_nc_t *)msg.content.ptr)->flags &= ~GNRC_IPV6_NC_IS_ROUTER; - break; - - /* XXX reactivate when https://github.com/RIOT-OS/RIOT/issues/5122 is - * solved properly */ - /* case GNRC_NDP_MSG_ADDR_TIMEOUT: */ - /* DEBUG("ipv6: Router advertisement timer event received\n"); */ - /* gnrc_ipv6_netif_remove_addr(KERNEL_PID_UNDEF, */ - /* msg.content.ptr); */ - /* break; */ - - case GNRC_NDP_MSG_NBR_SOL_RETRANS: - DEBUG("ipv6: Neigbor solicitation retransmission timer event received\n"); - gnrc_ndp_retrans_nbr_sol(msg.content.ptr); - break; - - case GNRC_NDP_MSG_NC_STATE_TIMEOUT: - DEBUG("ipv6: Neigbor cache state timeout received\n"); - gnrc_ndp_state_timeout(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(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(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"); - gnrc_ndp_host_retrans_rtr_sol(msg.content.ptr); - break; -#endif -#ifdef MODULE_GNRC_SIXLOWPAN_ND - case GNRC_SIXLOWPAN_ND_MSG_MC_RTR_SOL: - DEBUG("ipv6: Multicast router solicitation event received\n"); - gnrc_sixlowpan_nd_mc_rtr_sol(msg.content.ptr); - break; - case GNRC_SIXLOWPAN_ND_MSG_UC_RTR_SOL: - DEBUG("ipv6: Unicast router solicitation event received\n"); - gnrc_sixlowpan_nd_uc_rtr_sol(msg.content.ptr); - break; -# ifdef MODULE_GNRC_SIXLOWPAN_CTX - case GNRC_SIXLOWPAN_ND_MSG_DELETE_CTX: - DEBUG("ipv6: Delete 6LoWPAN context event received\n"); - gnrc_sixlowpan_ctx_remove(((((gnrc_sixlowpan_ctx_t *)msg.content.ptr)->flags_id) & - GNRC_SIXLOWPAN_CTX_FLAGS_CID_MASK)); - break; -# endif -#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(msg.content.ptr); - break; - /* XXX reactivate when https://github.com/RIOT-OS/RIOT/issues/5122 is - * solved properly */ - /* case GNRC_SIXLOWPAN_ND_MSG_AR_TIMEOUT: */ - /* DEBUG("ipv6: address registration timeout received\n"); */ - /* gnrc_sixlowpan_nd_router_gc_nc(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 = msg.content.ptr; - gnrc_ndp_internal_send_rtr_adv(nc_entry->iface, NULL, - &(nc_entry->ipv6_addr), false); - break; -#endif -#else /* MODULE_GNRC_IPV6_NIB */ case GNRC_IPV6_NIB_SND_UC_NS: case GNRC_IPV6_NIB_SND_MC_NS: case GNRC_IPV6_NIB_SND_NA: @@ -385,7 +304,6 @@ static void *_event_loop(void *args) DEBUG("ipv6: NIB timer event received\n"); gnrc_ipv6_nib_handle_timer_event(msg.content.ptr, msg.type); break; -#endif /* MODULE_GNRC_IPV6_NIB */ default: break; } @@ -646,38 +564,6 @@ static void _send_multicast(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt, #endif /* GNRC_NETIF_NUMOF */ } -#ifndef MODULE_GNRC_IPV6_NIB -static inline kernel_pid_t _next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len, - kernel_pid_t iface, ipv6_addr_t *dst, - gnrc_pktsnip_t *pkt) -{ - kernel_pid_t found_iface; -#if defined(MODULE_GNRC_SIXLOWPAN_ND) - (void)pkt; - found_iface = gnrc_sixlowpan_nd_next_hop_l2addr(l2addr, l2addr_len, iface, dst); - if (found_iface > KERNEL_PID_UNDEF) { - return found_iface; - } -#endif -#if defined(MODULE_GNRC_NDP_NODE) - found_iface = gnrc_ndp_node_next_hop_l2addr(l2addr, l2addr_len, iface, dst, pkt); -#elif !defined(MODULE_GNRC_SIXLOWPAN_ND) && defined(MODULE_GNRC_IPV6_NC) - (void)pkt; - gnrc_ipv6_nc_t *nc = gnrc_ipv6_nc_get(iface, dst); - found_iface = gnrc_ipv6_nc_get_l2_addr(l2addr, l2addr_len, nc); -#elif !defined(MODULE_GNRC_SIXLOWPAN_ND) - found_iface = KERNEL_PID_UNDEF; - (void)l2addr; - (void)l2addr_len; - (void)iface; - (void)dst; - (void)pkt; - *l2addr_len = 0; -#endif - return found_iface; -} -#endif /* MODULE_GNRC_IPV6_NIB */ - static void _send(gnrc_pktsnip_t *pkt, bool prep_hdr) { kernel_pid_t iface = KERNEL_PID_UNDEF; @@ -771,32 +657,10 @@ static void _send(gnrc_pktsnip_t *pkt, bool prep_hdr) } } else { -#ifndef MODULE_GNRC_IPV6_NIB - uint8_t l2addr_len = GNRC_IPV6_NC_L2_ADDR_MAX; - uint8_t l2addr[l2addr_len]; - - iface = _next_hop_l2addr(l2addr, &l2addr_len, iface, &hdr->dst, pkt); - - if (iface == KERNEL_PID_UNDEF) { - DEBUG("ipv6: error determining next hop's link layer address\n"); - gnrc_pktbuf_release(pkt); - return; - } - netif = gnrc_netif2_get_by_pid(iface); - assert(netif != NULL); - if (prep_hdr) { - if (_fill_ipv6_hdr(netif, ipv6, payload) < 0) { - /* error on filling up header */ - gnrc_pktbuf_release(pkt); - return; - } - } - - _send_unicast(netif, l2addr, l2addr_len, pkt); -#else /* MODULE_GNRC_IPV6_NIB */ gnrc_ipv6_nib_nc_t nce; + gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(iface); - if (gnrc_ipv6_nib_get_next_hop_l2addr(&hdr->dst, iface, pkt, + if (gnrc_ipv6_nib_get_next_hop_l2addr(&hdr->dst, netif, pkt, &nce) < 0) { /* packet is released by NIB */ return; @@ -814,7 +678,6 @@ static void _send(gnrc_pktsnip_t *pkt, bool prep_hdr) _send_unicast(netif, nce.l2addr, nce.l2addr_len, pkt); -#endif /* MODULE_GNRC_IPV6_NIB */ } } 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 8d71d9092e02..b9bf3934d451 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 @@ -25,9 +25,6 @@ #include "net/eui64.h" #include "net/ipv6/addr.h" -#ifdef MODULE_GNRC_IPV6_NIB -#include "net/gnrc/ipv6/nib.h" -#endif #include "net/gnrc/ndp.h" #include "net/gnrc/netapi.h" #include "net/gnrc/netif.h" @@ -176,11 +173,9 @@ static void _ipv6_netif_remove(gnrc_ipv6_netif_t *entry) return; } -#ifndef MODULE_GNRC_IPV6_NIB #ifdef MODULE_GNRC_NDP gnrc_ndp_netif_remove(entry); #endif -#endif /* MODULE_GNRC_IPV6_NIB */ mutex_lock(&entry->mutex); xtimer_remove(&entry->rtr_sol_timer); @@ -240,13 +235,9 @@ void gnrc_ipv6_netif_add(kernel_pid_t pid) mutex_unlock(&free_entry->mutex); -#ifndef MODULE_GNRC_IPV6_NIB #ifdef MODULE_GNRC_NDP gnrc_ndp_netif_add(free_entry); #endif -#else /* MODULE_GNRC_IPV6_NIB */ - gnrc_ipv6_nib_init_iface(pid); -#endif /* MODULE_GNRC_IPV6_NIB */ DEBUG(" * pid = %" PRIkernel_pid " ", free_entry->pid); DEBUG("cur_hl = %d ", free_entry->cur_hl); diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-6ln.c b/sys/net/gnrc/network_layer/ipv6/nib/_nib-6ln.c index 8f0908bdde84..e4beb0e09f02 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-6ln.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-6ln.c @@ -13,6 +13,7 @@ * @author Martine Lenders */ +#include "net/gnrc/netif2/internal.h" #include "net/gnrc/ipv6/nib.h" #include "_nib-6ln.h" @@ -26,49 +27,88 @@ static char addr_str[IPV6_ADDR_MAX_STR_LEN]; #endif -static bool _is_iface_eui64(kernel_pid_t iface, const eui64_t *eui64) +static inline bool _is_iface_eui64(gnrc_netif2_t *netif, const eui64_t *eui64) { - eui64_t iface_eui64; + /* TODO: adapt for short addresses */ + return (netif->l2addr_len == sizeof(eui64_t)) && + (memcmp(&netif->l2addr, eui64, netif->l2addr_len) == 0); +} - /* XXX: this *should* return successful so don't test it ;-) */ - gnrc_netapi_get(iface, NETOPT_ADDRESS_LONG, 0, - &iface_eui64, sizeof(iface_eui64)); - return (memcmp(&iface_eui64, eui64, sizeof(iface_eui64)) != 0); +static inline uint8_t _reverse_iid(const ipv6_addr_t *dst, + const gnrc_netif2_t *netif, uint8_t *l2addr) +{ + switch (netif->device_type) { +#ifdef MODULE_NETDEV_ETH + case NETDEV_TYPE_ETHERNET: + l2addr[0] = dst->u8[8] ^ 0x02; + l2addr[1] = dst->u8[9]; + l2addr[2] = dst->u8[10]; + l2addr[3] = dst->u8[13]; + l2addr[4] = dst->u8[14]; + l2addr[5] = dst->u8[15]; + return ETHERNET_ADDR_LEN; +#endif +#ifdef MODULE_NETDEV_IEEE802154 + case NETDEV_TYPE_IEEE802154: + /* assume address was based on EUI-64 + * (see https://tools.ietf.org/html/rfc6775#section-5.2) */ + memcpy(l2addr, &dst->u64[1], sizeof(dst->u64[1])); + l2addr[0] ^= 0x02; + return sizeof(dst->u64[1]); +#endif +#ifdef MODULE_CC110X + case NETDEV_TYPE_CC110X: + l2addr[0] = dst->u8[15]; + return sizeof(uint8_t); +#endif + default: + (void)dst; + (void)l2addr; + return 0; + } } -bool _resolve_addr_from_ipv6(const ipv6_addr_t *dst, kernel_pid_t iface, +bool _resolve_addr_from_ipv6(const ipv6_addr_t *dst, gnrc_netif2_t *netif, gnrc_ipv6_nib_nc_t *nce) { - gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(iface); - bool res = (netif != NULL) && _is_6ln(netif) && + bool res = (netif != NULL) && gnrc_netif2_is_6ln(netif) && ipv6_addr_is_link_local(dst); if (res) { - memcpy(&nce->ipv6, dst, sizeof(nce->ipv6)); - memcpy(&nce->l2addr, &dst->u64[1], sizeof(dst->u64[1])); - nce->l2addr[0] ^= 0x02; - nce->info = 0; - nce->info |= (iface << GNRC_IPV6_NIB_NC_INFO_IFACE_POS) & - GNRC_IPV6_NIB_NC_INFO_IFACE_MASK; - nce->info |= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE; - nce->info |= GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED; - nce->l2addr_len = sizeof(dst->u64[1]); + uint8_t l2addr_len; + + if ((l2addr_len = _reverse_iid(dst, netif, nce->l2addr)) > 0) { + DEBUG("nib: resolve address %s%%%u by reverse translating to ", + ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), + (unsigned)netif->pid); + nce->l2addr_len = l2addr_len; + DEBUG("%s\n", + gnrc_netif2_addr_to_str(nce->l2addr, nce->l2addr_len, + addr_str)); + memcpy(&nce->ipv6, dst, sizeof(nce->ipv6)); + nce->info = 0; + nce->info |= (netif->pid << GNRC_IPV6_NIB_NC_INFO_IFACE_POS) & + GNRC_IPV6_NIB_NC_INFO_IFACE_MASK; + nce->info |= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE; + nce->info |= GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED; + } + else { + res = false; + } } return res; } -uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +uint8_t _handle_aro(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6, const icmpv6_hdr_t *icmpv6, const sixlowpan_nd_opt_ar_t *aro, const ndp_opt_t *sl2ao, _nib_onl_entry_t *nce) { - gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(iface); - #if !GNRC_IPV6_NIB_CONF_6LR (void)sl2ao; #endif assert(netif != NULL); - if (_is_6ln(netif) && (aro->len == SIXLOWPAN_ND_OPT_AR_LEN)) { + if (gnrc_netif2_is_6ln(netif) && (aro->len == SIXLOWPAN_ND_OPT_AR_LEN)) { DEBUG("nib: valid ARO received\n"); DEBUG(" - length: %u\n", aro->len); DEBUG(" - status: %u\n", aro->status); @@ -78,7 +118,7 @@ uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6, aro->eui64.uint8[3], aro->eui64.uint8[4], aro->eui64.uint8[5], aro->eui64.uint8[6], aro->eui64.uint8[7]); if (icmpv6->type == ICMPV6_NBR_ADV) { - if (!_is_iface_eui64(iface, &aro->eui64)) { + if (!_is_iface_eui64(netif, &aro->eui64)) { DEBUG("nib: ARO EUI-64 is not mine, ignoring ARO\n"); return _ADDR_REG_STATUS_IGNORE; } @@ -92,7 +132,7 @@ uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6, (byteorder_ntohs(aro->ltime) - 1U) * SEC_PER_MIN * MS_PER_SEC; DEBUG("nib: Address registration successful. " - "Scheduling re-registration in %ums\n", + "Scheduling re-registration in %" PRIu32 "ms\n", next_ns); assert(nce != NULL); _evtimer_add(nce, GNRC_IPV6_NIB_SND_UC_NS, &nce->nud_timeout, @@ -103,22 +143,19 @@ uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6, DEBUG("nib: Address registration reports duplicate. " "Removing address %s%%%u\n", ipv6_addr_to_str(addr_str, - &((ndp_nbr_adv_t *)icmpv6)->tgt, - sizeof(addr_str)), - iface); - gnrc_ipv6_netif_remove_addr(iface, - &((ndp_nbr_adv_t *)icmpv6)->tgt); + &ipv6->dst, + sizeof(addr_str)), netif->pid); + gnrc_netif2_ipv6_addr_remove(netif, &ipv6->dst); /* TODO: generate new address */ break; case SIXLOWPAN_ND_STATUS_NC_FULL: { DEBUG("nib: Router's neighbor cache is full. " "Searching new router for DAD\n"); - _nib_dr_entry_t *dr = _nib_drl_get(&ipv6->src, iface); + _nib_dr_entry_t *dr = _nib_drl_get(&ipv6->src, netif->pid); assert(dr != NULL); /* otherwise we wouldn't be here */ _nib_drl_remove(dr); if (_nib_drl_iter(NULL) == NULL) { /* no DRL left */ - _nib_iface_t *nib_iface = _nib_iface_get(iface); - nib_iface->rs_sent = 0; + netif->ipv6.rs_sent = 0; /* TODO: search new router */ } else { @@ -131,8 +168,9 @@ uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6, return aro->status; } #if GNRC_IPV6_NIB_CONF_6LR - else if (_is_6lr(netif) && (icmpv6->type == ICMPV6_NBR_SOL)) { - return _reg_addr_upstream(iface, ipv6, icmpv6, aro, sl2ao); + else if (gnrc_netif2_is_6lr(netif) && + (icmpv6->type == ICMPV6_NBR_SOL)) { + return _reg_addr_upstream(netif, ipv6, icmpv6, aro, sl2ao); } #endif } diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-6ln.h b/sys/net/gnrc/network_layer/ipv6/nib/_nib-6ln.h index 6967c3a8d91d..1ba822bf58ca 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-6ln.h +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-6ln.h @@ -44,38 +44,23 @@ extern "C" { */ #define _ADDR_REG_STATUS_IGNORE (4) -/** - * @brief Checks if interface represents a 6LN - * - * @todo Use corresponding function in `gnrc_netif2` instead. - * - * @param[in] netif A network interface. - * - * @return true, when the @p netif represents a 6LN. - * @return false, when the @p netif does not represent a 6LN. - */ -static inline bool _is_6ln(const gnrc_ipv6_netif_t *netif) -{ - return (netif->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN); -} - /** * @brief Resolves address statically from destination address using reverse * translation of the IID * * @param[in] dst A destination address. - * @param[in] iface The interface to @p dst. + * @param[in] netif The interface to @p dst. * @param[out] nce Neighbor cache entry to resolve into * * @return true when @p nce was set, false when not. */ -bool _resolve_addr_from_ipv6(const ipv6_addr_t *dst, kernel_pid_t iface, +bool _resolve_addr_from_ipv6(const ipv6_addr_t *dst, gnrc_netif2_t *netif, gnrc_ipv6_nib_nc_t *nce); /** * @brief Handles ARO * - * @param[in] iface The interface the ARO-carrying message came over. + * @param[in] netif The interface the ARO-carrying message came over. * @param[in] ipv6 The IPv6 header of the message carrying the ARO. * @param[in] icmpv6 The message carrying the ARO. * @param[in] aro ARO that carries the address registration information. @@ -85,13 +70,12 @@ bool _resolve_addr_from_ipv6(const ipv6_addr_t *dst, kernel_pid_t iface, * @return registration status of the address (including * @ref _ADDR_REG_STATUS_TENTATIVE and @ref _ADDR_REG_STATUS_IGNORE). */ -uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +uint8_t _handle_aro(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6, const icmpv6_hdr_t *icmpv6, const sixlowpan_nd_opt_ar_t *aro, const ndp_opt_t *sl2ao, _nib_onl_entry_t *nce); #else /* GNRC_IPV6_NIB_CONF_6LN || defined(DOXYGEN) */ -#define _is_6ln(netif) (false) -#define _resolve_addr_from_ipv6(dst, iface, nce) (false) +#define _resolve_addr_from_ipv6(dst, netif, nce) (false) /* _handle_aro() doesn't make sense without 6LR so don't even use it * => throw error in case it is compiled in => don't define it here as NOP macro */ diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-6lr.c b/sys/net/gnrc/network_layer/ipv6/nib/_nib-6lr.c index b85ed575589e..9cfaf55f0aa3 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-6lr.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-6lr.c @@ -14,6 +14,7 @@ */ #include "net/gnrc/ipv6/nib.h" +#include "net/gnrc/netif2/internal.h" #include "net/gnrc/sixlowpan/nd.h" #include "_nib-6lr.h" @@ -47,13 +48,13 @@ static uint8_t _update_nce_ar_state(const sixlowpan_nd_opt_ar_t *aro, } } -uint8_t _reg_addr_upstream(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +uint8_t _reg_addr_upstream(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6, const icmpv6_hdr_t *icmpv6, const sixlowpan_nd_opt_ar_t *aro, const ndp_opt_t *sl2ao) { if (!ipv6_addr_is_unspecified(&ipv6->src) && (sl2ao != NULL)) { - _nib_onl_entry_t *nce = _nib_onl_get(&ipv6->src, iface); + _nib_onl_entry_t *nce = _nib_onl_get(&ipv6->src, netif->pid); DEBUG("nib: Trying to register %s with EUI-64 " "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", @@ -66,8 +67,8 @@ uint8_t _reg_addr_upstream(kernel_pid_t iface, const ipv6_hdr_t *ipv6, #if GNRC_IPV6_NIB_CONF_MULTIHOP_DAD /* TODO */ #endif - if (byteorder_ntohs(aro->ltime) != 0) { - _handle_sl2ao(iface, ipv6, icmpv6, sl2ao); + if (aro->ltime.u16 != 0) { + _handle_sl2ao(netif, ipv6, icmpv6, sl2ao); return _update_nce_ar_state(aro, nce); } else if (nce != NULL) { @@ -88,7 +89,8 @@ uint8_t _reg_addr_upstream(kernel_pid_t iface, const ipv6_hdr_t *ipv6, return _ADDR_REG_STATUS_IGNORE; } -gnrc_pktsnip_t *_copy_and_handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +gnrc_pktsnip_t *_copy_and_handle_aro(gnrc_netif2_t *netif, + const ipv6_hdr_t *ipv6, const ndp_nbr_sol_t *nbr_sol, const sixlowpan_nd_opt_ar_t *aro, const ndp_opt_t *sl2ao) @@ -96,7 +98,7 @@ gnrc_pktsnip_t *_copy_and_handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6, gnrc_pktsnip_t *reply_aro = NULL; if (aro != NULL) { - uint8_t status = _handle_aro(iface, ipv6, (icmpv6_hdr_t *)nbr_sol, aro, + uint8_t status = _handle_aro(netif, ipv6, (icmpv6_hdr_t *)nbr_sol, aro, sl2ao, NULL); if ((status != _ADDR_REG_STATUS_TENTATIVE) && diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-6lr.h b/sys/net/gnrc/network_layer/ipv6/nib/_nib-6lr.h index 0fc0049e58f1..6248600e69ce 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-6lr.h +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-6lr.h @@ -33,21 +33,6 @@ extern "C" { #endif #if GNRC_IPV6_NIB_CONF_6LR || defined(DOXYGEN) -/** - * @brief Checks if interface represents a 6LR - * - * @todo Use corresponding function in `gnrc_netif2` instead. - * - * @param[in] netif A network interface. - * - * @return true, when the @p netif represents a 6LR. - * @return false, when the @p netif does not represent a 6LR. - */ -static inline bool _is_6lr(const gnrc_ipv6_netif_t *netif) -{ - return _is_6ln(netif) && (netif->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER); -} - /** * @brief Gets address registration state of a neighbor * @@ -81,17 +66,17 @@ static inline void _set_ar_state(_nib_onl_entry_t *entry, uint16_t state) * @param[in] netif A network interface. * @param[in] icmpv6 An ICMPv6 message. */ -static inline bool _rtr_sol_on_6lr(const gnrc_ipv6_netif_t *netif, +static inline bool _rtr_sol_on_6lr(const gnrc_netif2_t *netif, const icmpv6_hdr_t *icmpv6) { - return _is_6lr(netif) && (icmpv6->type == ICMPV6_RTR_SOL); + return gnrc_netif2_is_6lr(netif) && (icmpv6->type == ICMPV6_RTR_SOL); } /** * @brief Registers an address to the (upstream; in case of multihop DAD) * router * - * @param[in] iface The interface the ARO-carrying NS came over. + * @param[in] netif The interface the ARO-carrying NS came over. * @param[in] ipv6 The IPv6 header of the message carrying the ARO. * @param[in] icmpv6 The neighbor solicitation carrying the ARO * (handed over as @ref icmpv6_hdr_t, since it is just @@ -102,7 +87,7 @@ static inline bool _rtr_sol_on_6lr(const gnrc_ipv6_netif_t *netif, * @return registration status of the address (including * @ref _ADDR_REG_STATUS_TENTATIVE and @ref _ADDR_REG_STATUS_IGNORE). */ -uint8_t _reg_addr_upstream(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +uint8_t _reg_addr_upstream(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6, const icmpv6_hdr_t *icmpv6, const sixlowpan_nd_opt_ar_t *aro, const ndp_opt_t *sl2ao); @@ -111,7 +96,7 @@ uint8_t _reg_addr_upstream(kernel_pid_t iface, const ipv6_hdr_t *ipv6, /** * @brief Handles and copies ARO from NS to NA * - * @param[in] iface The interface the ARO-carrying NS came over. + * @param[in] netif The interface the ARO-carrying NS came over. * @param[in] ipv6 The IPv6 header of the message carrying the original * ARO. * @param[in] nbr_sol The neighbor solicitation carrying the original ARO @@ -123,16 +108,15 @@ uint8_t _reg_addr_upstream(kernel_pid_t iface, const ipv6_hdr_t *ipv6, * @return registration status of the address (including * @ref _ADDR_REG_STATUS_TENTATIVE and @ref _ADDR_REG_STATUS_IGNORE). */ -gnrc_pktsnip_t *_copy_and_handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +gnrc_pktsnip_t *_copy_and_handle_aro(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6, const ndp_nbr_sol_t *nbr_sol, const sixlowpan_nd_opt_ar_t *aro, const ndp_opt_t *sl2ao); #else /* GNRC_IPV6_NIB_CONF_6LR || defined(DOXYGEN) */ -#define _is_6lr(netif) (false) #define _rtr_sol_on_6lr(netif, icmpv6) (false) #define _get_ar_state(nbr) (_ADDR_REG_STATUS_IGNORE) #define _set_ar_state(nbr, state) (void)nbr; (void)state -#define _copy_and_handle_aro(iface, ipv6, icmpv6, aro, sl2ao) \ +#define _copy_and_handle_aro(netif, ipv6, icmpv6, aro, sl2ao) \ (NULL) /* _reg_addr_upstream() doesn't make sense without 6LR so don't even use it * => throw error in case it is compiled in => don't define it here as NOP macro diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.c b/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.c index c678f3cecb4f..22ac8c2ce19e 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.c @@ -16,6 +16,10 @@ #include "xtimer.h" #include "net/gnrc/ndp2.h" #include "net/gnrc/ipv6/nib.h" +#include "net/gnrc/netif2/internal.h" +#ifdef MODULE_GNRC_SIXLOWPAN_ND +#include "net/gnrc/sixlowpan/nd.h" +#endif #include "_nib-arsm.h" #include "_nib-6lr.h" @@ -36,26 +40,50 @@ static char addr_str[IPV6_ADDR_MAX_STR_LEN]; * * @return The length of the L2 address carried in @p opt. */ -static inline unsigned _get_l2addr_len(gnrc_ipv6_netif_t *netif, +static inline unsigned _get_l2addr_len(gnrc_netif2_t *netif, const ndp_opt_t *opt); -void _snd_ns(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif, +void _snd_ns(const ipv6_addr_t *tgt, gnrc_netif2_t *netif, const ipv6_addr_t *src, const ipv6_addr_t *dst) { gnrc_pktsnip_t *ext_opt = NULL; +#ifdef MODULE_GNRC_SIXLOWPAN_ND + _nib_dr_entry_t *dr = _nib_drl_get_dr(); + + assert(netif != NULL); + /* add ARO based on interface */ + if ((src != NULL) && gnrc_netif2_is_6ln(netif) && + (_nib_onl_get_if(dr->next_hop) == (unsigned)netif->pid) && + ipv6_addr_equal(&dr->next_hop->ipv6, dst)) { + netdev_t *dev = netif->dev; + uint8_t l2src[GNRC_NETIF2_L2ADDR_MAXLEN]; + size_t l2src_len = (uint16_t)dev->driver->get(dev, NETOPT_ADDRESS_LONG, + l2src, sizeof(l2src)); + if (l2src_len != sizeof(eui64_t)) { + DEBUG("nib: can't get EUI-64 of the interface for ARO\n"); + return; + } + ext_opt = gnrc_sixlowpan_nd_opt_ar_build(0, GNRC_SIXLOWPAN_ND_AR_LTIME, + (eui64_t *)l2src, NULL); + if (ext_opt == NULL) { + DEBUG("nib: error allocating ARO.\n"); + return; + } + } +#endif /* MODULE_GNRC_SIXLOWPAN_ND */ gnrc_ndp2_nbr_sol_send(tgt, netif, src, dst, ext_opt); } void _snd_uc_ns(_nib_onl_entry_t *nbr, bool reset) { - gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(_nib_onl_get_if(nbr)); - _nib_iface_t *iface = _nib_iface_get(_nib_onl_get_if(nbr)); + gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(nbr)); - DEBUG("unicast to %s (retrans. timer = %ums)\n", + assert(netif != NULL); + gnrc_netif2_acquire(netif); + DEBUG("nib: unicast to %s (retrans. timer = %ums)\n", ipv6_addr_to_str(addr_str, &nbr->ipv6, sizeof(addr_str)), - (unsigned)iface->retrans_time); - assert((netif != NULL) && (iface != NULL)); + (unsigned)netif->ipv6.retrans_time); #if GNRC_IPV6_NIB_CONF_ARSM if (reset) { nbr->ns_sent = 0; @@ -65,20 +93,20 @@ void _snd_uc_ns(_nib_onl_entry_t *nbr, bool reset) #endif _snd_ns(&nbr->ipv6, netif, NULL, &nbr->ipv6); _evtimer_add(nbr, GNRC_IPV6_NIB_SND_UC_NS, &nbr->nud_timeout, - iface->retrans_time); + netif->ipv6.retrans_time); + gnrc_netif2_release(netif); #if GNRC_IPV6_NIB_CONF_ARSM nbr->ns_sent++; #endif } -void _handle_sl2ao(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +void _handle_sl2ao(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6, const icmpv6_hdr_t *icmpv6, const ndp_opt_t *sl2ao) { - _nib_onl_entry_t *nce = _nib_onl_get(&ipv6->src, iface); - gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(iface); + assert(netif != NULL); + _nib_onl_entry_t *nce = _nib_onl_get(&ipv6->src, netif->pid); unsigned l2addr_len; - assert(netif != NULL); l2addr_len = _get_l2addr_len(netif, sl2ao); if (l2addr_len == 0U) { DEBUG("nib: Unexpected SL2AO length. Ignoring SL2AO\n"); @@ -93,13 +121,14 @@ void _handle_sl2ao(kernel_pid_t iface, const ipv6_hdr_t *ipv6, !_rtr_sol_on_6lr(netif, icmpv6)) { DEBUG("nib: L2 address differs. Setting STALE\n"); evtimer_del(&_nib_evtimer, &nce->nud_timeout.event); - _set_nud_state(nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE); + _set_nud_state(netif, nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE); } #endif /* GNRC_IPV6_NIB_CONF_ARSM */ if ((nce == NULL) || !(nce->mode & _NC)) { DEBUG("nib: Creating NCE for (ipv6 = %s, iface = %u, nud_state = STALE)\n", - ipv6_addr_to_str(addr_str, &ipv6->src, sizeof(addr_str)), iface); - nce = _nib_nc_add(&ipv6->src, iface, + ipv6_addr_to_str(addr_str, &ipv6->src, sizeof(addr_str)), + netif->pid); + nce = _nib_nc_add(&ipv6->src, netif->pid, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE); if (nce != NULL) { if (icmpv6->type == ICMPV6_NBR_SOL) { @@ -126,13 +155,13 @@ void _handle_sl2ao(kernel_pid_t iface, const ipv6_hdr_t *ipv6, if (icmpv6->type == ICMPV6_RTR_ADV) { DEBUG("nib: %s%%%u is a router\n", ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)), - iface); + netif->pid); nce->info |= GNRC_IPV6_NIB_NC_INFO_IS_ROUTER; } else if (icmpv6->type != ICMPV6_NBR_SOL) { DEBUG("nib: %s%%%u is probably not a router\n", ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)), - iface); + netif->pid); nce->info &= ~GNRC_IPV6_NIB_NC_INFO_IS_ROUTER; } #if GNRC_IPV6_NIB_CONF_ARSM @@ -146,27 +175,40 @@ void _handle_sl2ao(kernel_pid_t iface, const ipv6_hdr_t *ipv6, } } -static inline unsigned _get_l2addr_len(gnrc_ipv6_netif_t *netif, +static inline unsigned _get_l2addr_len(gnrc_netif2_t *netif, const ndp_opt_t *opt) { -#if GNRC_IPV6_NIB_CONF_6LN - if (_is_6ln(netif)) { - switch (opt->len) { - case 1U: - return 2U; - case 2U: - return 8U; - default: - return 0U; - } - } -#else - (void)netif; -#endif /* GNRC_IPV6_NIB_CONF_6LN */ - if (opt->len == 1U) { - return 6U; + switch (netif->device_type) { +#ifdef MODULE_CC110X + case NETDEV_TYPE_CC110X: + (void)opt; + return sizeof(uint8_t); +#endif +#ifdef MODULE_NETDEV_ETH + case NETDEV_TYPE_ETHERNET: + (void)opt; + return ETHERNET_ADDR_LEN; +#endif +#ifdef MODULE_NETDEV_NRFMIN + case NETDEV_TYPE_NRFMIN: + (void)opt; + return sizeof(uint16_t); +#endif +#ifdef MODULE_NETDEV_IEEE802154 + case NETDEV_TYPE_IEEE802154: + switch (opt->len) { + case 1U: + return IEEE802154_SHORT_ADDRESS_LEN; + case 2U: + return IEEE802154_LONG_ADDRESS_LEN; + default: + return 0U; + } +#endif + default: + (void)opt; + return 0U; } - return 0U; } #if GNRC_IPV6_NIB_CONF_ARSM @@ -207,7 +249,7 @@ static inline bool _rflag_set(const ndp_nbr_adv_t *nbr_adv); * * @param[in] nce A neighbor cache entry. * @param[in] tl2ao The TL2AO. - * @param[in] iface The interface the TL2AO came over. + * @param[in] netif The interface the TL2AO came over. * @param[in] tl2ao_addr_len Length of the L2 address in the TL2AO. * * @return `true`, if the TL2AO changes the NCE. @@ -215,7 +257,7 @@ static inline bool _rflag_set(const ndp_nbr_adv_t *nbr_adv); */ static inline bool _tl2ao_changes_nce(_nib_onl_entry_t *nce, const ndp_opt_t *tl2ao, - kernel_pid_t iface, + gnrc_netif2_t *netif, unsigned tl2ao_addr_len); void _handle_snd_ns(_nib_onl_entry_t *nbr) @@ -233,7 +275,10 @@ void _handle_snd_ns(_nib_onl_entry_t *nbr) break; case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE: if (nbr->ns_sent >= NDP_MAX_UC_SOL_NUMOF) { - _set_nud_state(nbr, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE); + gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(nbr)); + + _set_nud_state(netif, nbr, + GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE); } /* falls through intentionally */ case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE: @@ -253,13 +298,16 @@ void _handle_state_timeout(_nib_onl_entry_t *nbr) DEBUG("nib: Timeout reachability\n"); new_state = GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE; /* falls through intentionally */ - case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY: - _set_nud_state(nbr, new_state); + case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY: { + gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(nbr)); + + _set_nud_state(netif, nbr, new_state); if (new_state == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE) { DEBUG("nib: Timeout DELAY state\n"); _probe_nbr(nbr, true); } break; + } } } @@ -274,24 +322,25 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset) break; case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE: case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE: { - _nib_iface_t *iface = _nib_iface_get(_nib_onl_get_if(nbr)); + gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(nbr)); uint32_t next_ns = _evtimer_lookup(nbr, GNRC_IPV6_NIB_SND_MC_NS); - if (next_ns > iface->retrans_time) { - gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(_nib_onl_get_if(nbr)); + + assert(netif != NULL); + gnrc_netif2_acquire(netif); + if (next_ns > netif->ipv6.retrans_time) { ipv6_addr_t sol_nodes; - uint32_t retrans_time = iface->retrans_time; + uint32_t retrans_time = netif->ipv6.retrans_time; DEBUG("multicast to %s's solicited nodes ", ipv6_addr_to_str(addr_str, &nbr->ipv6, sizeof(addr_str))); - assert(netif != NULL); if (reset) { nbr->ns_sent = 0; } if (state == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE) { /* first 3 retransmissions in PROBE, assume 1 higher to - * not send after iface->retrans_timer sec again, + * not send after netif->ipv6.retrans_timer sec again, * but the next backoff after that => subtract 2 */ retrans_time = _exp_backoff_retrans_timer(nbr->ns_sent - 2, retrans_time); @@ -312,9 +361,10 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset) "a multicast NS within %ums)\n", ipv6_addr_to_str(addr_str, &nbr->ipv6, sizeof(addr_str)), - (unsigned)iface->retrans_time); + (unsigned)netif->ipv6.retrans_time); } #endif + gnrc_netif2_release(netif); } break; case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE: @@ -324,10 +374,9 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset) } } -void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce, +void _handle_adv_l2(gnrc_netif2_t *netif, _nib_onl_entry_t *nce, const icmpv6_hdr_t *icmpv6, const ndp_opt_t *tl2ao) { - gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(iface); unsigned l2addr_len = 0; assert(nce != NULL); @@ -342,7 +391,7 @@ void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce, if ((_get_nud_state(nce) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE) || _oflag_set((ndp_nbr_adv_t *)icmpv6) || _redirect_with_tl2ao(icmpv6, tl2ao) || - _tl2ao_changes_nce(nce, tl2ao, iface, l2addr_len)) { + _tl2ao_changes_nce(nce, tl2ao, netif, l2addr_len)) { bool nce_was_incomplete = (_get_nud_state(nce) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE); if (tl2ao != NULL) { @@ -353,17 +402,17 @@ void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce, nce->l2addr_len = 0; } if (_sflag_set((ndp_nbr_adv_t *)icmpv6)) { - _set_reachable(iface, nce); + _set_reachable(netif, nce); } else if ((icmpv6->type != ICMPV6_NBR_ADV) || !_sflag_set((ndp_nbr_adv_t *)icmpv6) || (!nce_was_incomplete && - _tl2ao_changes_nce(nce, tl2ao, iface, l2addr_len))) { + _tl2ao_changes_nce(nce, tl2ao, netif, l2addr_len))) { DEBUG("nib: Set %s%%%u to STALE\n", ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)), - iface); + (unsigned)netif->pid); evtimer_del(&_nib_evtimer, &nce->nud_timeout.event); - _set_nud_state(nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE); + _set_nud_state(netif, nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE); } if (_oflag_set((ndp_nbr_adv_t *)icmpv6) || ((icmpv6->type == ICMPV6_NBR_ADV) && nce_was_incomplete)) { @@ -391,30 +440,57 @@ void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce, if ((icmpv6->type == ICMPV6_NBR_ADV) && !_sflag_set((ndp_nbr_adv_t *)icmpv6) && (_get_nud_state(nce) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE) && - _tl2ao_changes_nce(nce, tl2ao, iface, l2addr_len)) { + _tl2ao_changes_nce(nce, tl2ao, netif, l2addr_len)) { evtimer_del(&_nib_evtimer, &nce->nud_timeout.event); - _set_nud_state(nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE); + _set_nud_state(netif, nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE); } } else if ((icmpv6->type == ICMPV6_NBR_ADV) && (_get_nud_state(nce) != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE) && (_get_nud_state(nce) != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED) && _sflag_set((ndp_nbr_adv_t *)icmpv6) && - !_tl2ao_changes_nce(nce, tl2ao, iface, l2addr_len)) { - _set_reachable(iface, nce); + !_tl2ao_changes_nce(nce, tl2ao, netif, l2addr_len)) { + _set_reachable(netif, nce); } } -void _set_reachable(unsigned iface, _nib_onl_entry_t *nce) +void _recalc_reach_time(gnrc_netif2_ipv6_t *netif) { - _nib_iface_t *nib_netif = _nib_iface_get(iface); + const uint32_t half = (netif->reach_time_base >> 1); + + netif->reach_time = random_uint32_range(half, + netif->reach_time_base + half); + _evtimer_add(netif, GNRC_IPV6_NIB_RECALC_REACH_TIME, + &netif->recalc_reach_time, + GNRC_IPV6_NIB_CONF_REACH_TIME_RESET); +} +void _set_reachable(gnrc_netif2_t *netif, _nib_onl_entry_t *nce) +{ DEBUG("nib: Set %s%%%u to REACHABLE for %ums\n", ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)), - iface, (unsigned)nib_netif->reach_time); - _set_nud_state(nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE); + netif->pid, (unsigned)netif->ipv6.reach_time); + _set_nud_state(netif, nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE); _evtimer_add(nce, GNRC_IPV6_NIB_REACH_TIMEOUT, &nce->nud_timeout, - nib_netif->reach_time); + netif->ipv6.reach_time); +} + +void _set_nud_state(gnrc_netif2_t *netif, _nib_onl_entry_t *nce, + uint16_t state) +{ + nce->info &= ~GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK; + nce->info |= state; + +#if GNRC_IPV6_NIB_CONF_ROUTER + gnrc_netif2_acquire(netif); + if ((netif != NULL) && (netif->ipv6.route_info_cb)) { + netif->ipv6.route_info_cb(GNRC_IPV6_NIB_ROUTE_INFO_TYPE_NSC, + &nce->ipv6, (void *)((intptr_t)state)); + } + gnrc_netif2_release(netif); +#else + (void)netif; +#endif } /* internal functions */ @@ -443,13 +519,13 @@ static inline bool _redirect_with_tl2ao(icmpv6_hdr_t *icmpv6, ndp_opt_t *tl2ao) static inline bool _tl2ao_changes_nce(_nib_onl_entry_t *nce, const ndp_opt_t *tl2ao, - kernel_pid_t iface, + gnrc_netif2_t *netif, unsigned tl2ao_addr_len) { return ((tl2ao != NULL) && (((nce->l2addr_len != tl2ao_addr_len) && (memcmp(nce->l2addr, tl2ao + 1, tl2ao_addr_len) != 0)) || - (_nib_onl_get_if(nce) != (unsigned)iface))); + (_nib_onl_get_if(nce) != (unsigned)netif->pid))); } static inline bool _oflag_set(const ndp_nbr_adv_t *nbr_adv) diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.h b/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.h index 44b681273d0c..b0c356f3c46a 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.h +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-arsm.h @@ -24,6 +24,7 @@ #include #include "net/gnrc/ipv6/nib/conf.h" +#include "net/gnrc/netif2.h" #include "net/ndp.h" #include "net/icmpv6.h" @@ -47,7 +48,7 @@ extern "C" { * @param[in] dst Destination address for neighbor solicitation. May not * be NULL. */ -void _snd_ns(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif, +void _snd_ns(const ipv6_addr_t *tgt, gnrc_netif2_t *netif, const ipv6_addr_t *src, const ipv6_addr_t *dst); /** @@ -72,12 +73,12 @@ void _snd_uc_ns(_nib_onl_entry_t *nbr, bool reset); * to the ARSM, but ARSM isn't the only mechanism using it (e.g. the * 6Lo address registration uses it). * - * @param[in] iface Interface the SL2AO was sent over. + * @param[in] netif Interface the SL2AO was sent over. * @param[in] ipv6 IPv6 header of the message carrying the SL2AO. * @param[in] icmpv6 ICMPv6 header of the message carrying the SL2AO. * @param[in] sl2ao The SL2AO */ -void _handle_sl2ao(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +void _handle_sl2ao(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6, const icmpv6_hdr_t *icmpv6, const ndp_opt_t *sl2ao); #if GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN) @@ -111,7 +112,7 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset); * This can either be an TL2AO or for a link-layer without addresses just a * neighbor advertisement. * - * @param[in] iface Interface the link-layer information was advertised + * @param[in] netif Interface the link-layer information was advertised * over. * @param[in] nce Neighbor cache entry that is updated by the advertised * link-layer information. @@ -120,53 +121,62 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset); * @param[in] tl2ao The TL2AO carrying the link-layer information. May be * NULL for link-layers without addresses. */ -void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce, +void _handle_adv_l2(gnrc_netif2_t *netif, _nib_onl_entry_t *nce, const icmpv6_hdr_t *icmpv6, const ndp_opt_t *tl2ao); + +/** + * @brief Recalculates the (randomized) reachable time of on a network + * interface. + * + * @see [RFC 4861, section 6.3.4](https://tools.ietf.org/html/rfc4861#section-6.3.4) + * + * @param[in] netif Interface to set reachable time for. + */ +void _recalc_reach_time(gnrc_netif2_ipv6_t *netif); + /** * @brief Sets a neighbor cache entry reachable and starts the required * event timers * - * @param[in] iface Interface to the NCE + * @param[in] netif Interface to the NCE * @param[in] nce The neighbor cache entry to set reachable */ -void _set_reachable(unsigned iface, _nib_onl_entry_t *nce); +void _set_reachable(gnrc_netif2_t *netif, _nib_onl_entry_t *nce); /** * @brief Initializes interface for address registration state machine * - * @param[in] nib_iface An interface + * @param[in] netif An interface */ -static inline void _init_iface_arsm(_nib_iface_t *nib_iface) +static inline void _init_iface_arsm(gnrc_netif2_t *netif) { - nib_iface->reach_time_base = NDP_REACH_MS; - nib_iface->retrans_time = NDP_RETRANS_TIMER_MS; - _nib_iface_recalc_reach_time(nib_iface); + netif->ipv6.reach_time_base = NDP_REACH_MS; + _recalc_reach_time(&netif->ipv6); } /** * @brief Gets neighbor unreachability state of a neighbor * - * @param[in] entry Neighbor cache entry representing the neighbor. + * @param[in] nbr Neighbor cache entry representing the neighbor. * - * @return Neighbor unreachability state of the @p entry. + * @return Neighbor unreachability state of the @p nbr. */ -static inline uint16_t _get_nud_state(_nib_onl_entry_t *entry) +static inline uint16_t _get_nud_state(_nib_onl_entry_t *nbr) { - return (entry->info & GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK); + return (nbr->info & GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK); } /** * @brief Sets neighbor unreachablility state of a neighbor * - * @param[in] entry Neighbor cache entry representing the neighbor. + * @param[in] netif The network interface (to signal routing protocol using + * gnrc_netif_t::ipv6::route_info_cb()) + * @param[in] nbr Neighbor cache entry representing the neighbor. * @param[in] state Neighbor unreachability state for the neighbor. */ -static inline void _set_nud_state(_nib_onl_entry_t *entry, uint16_t state) -{ - entry->info &= ~GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK; - entry->info |= state; -} +void _set_nud_state(gnrc_netif2_t *netif, _nib_onl_entry_t *nbr, + uint16_t state); #else /* GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN) */ #define _handle_snd_ns(ctx) (void)ctx @@ -175,11 +185,12 @@ static inline void _set_nud_state(_nib_onl_entry_t *entry, uint16_t state) #define _init_iface_arsm(netif) (void)netif #define _handle_adv_l2(netif, nce, icmpv6, tl2ao) (void)netif; (void)nce; \ (void)icmpv6; (void)tl2ao +#define _recalc_reach_time(netif) (void)netif; #define _set_reachable(netif, nce) (void)netif; (void)nce #define _init_iface_arsm(netif) (void)netif -#define _get_nud_state(entry) (GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED) -#define _set_nud_state(entry, state) (void)entry; (void)state +#define _get_nud_state(nbr) (GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED) +#define _set_nud_state(netif, nce, state) (void)netif; (void)nbr; (void)state #endif /* GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN) */ #ifdef __cplusplus diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c b/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c index 854d5e8e5b6c..4b1be07f50cf 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.c @@ -21,7 +21,7 @@ #include "net/gnrc/ipv6/nib/conf.h" #include "net/gnrc/ipv6/nib/nc.h" #include "net/gnrc/ipv6/nib.h" -#include "net/gnrc/netif.h" +#include "net/gnrc/netif2/internal.h" #include "random.h" #include "_nib-internal.h" @@ -36,7 +36,6 @@ static clist_node_t _next_removable = { NULL }; static _nib_onl_entry_t _nodes[GNRC_IPV6_NIB_NUMOF]; static _nib_offl_entry_t _dsts[GNRC_IPV6_NIB_OFFL_NUMOF]; static _nib_dr_entry_t _def_routers[GNRC_IPV6_NIB_DEFAULT_ROUTER_NUMOF]; -static _nib_iface_t _nis[GNRC_NETIF_NUMOF]; #if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C static _nib_abr_entry_t _abrs[GNRC_IPV6_NIB_ABR_NUMOF]; @@ -61,7 +60,6 @@ void _nib_init(void) memset(_nodes, 0, sizeof(_nodes)); memset(_def_routers, 0, sizeof(_def_routers)); memset(_dsts, 0, sizeof(_dsts)); - memset(_nis, 0, sizeof(_nis)); #if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C memset(_abrs, 0, sizeof(_abrs)); #endif @@ -226,15 +224,21 @@ _nib_onl_entry_t *_nib_onl_get(const ipv6_addr_t *addr, unsigned iface) void _nib_nc_set_reachable(_nib_onl_entry_t *node) { #if GNRC_IPV6_NIB_CONF_ARSM - _nib_iface_t *iface = _nib_iface_get(_nib_onl_get_if(node)); + gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(node)); - DEBUG("nib: set %s%%%u reachable (reachable time = %u)\n", - ipv6_addr_to_str(addr_str, &node->ipv6, sizeof(addr_str)), - _nib_onl_get_if(node), iface->reach_time); node->info &= ~GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK; node->info |= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE; +#ifdef TEST_SUITES + /* exit early for unittests */ + if (netif == NULL) { + return; + } +#endif + DEBUG("nib: set %s%%%u reachable (reachable time = %u)\n", + ipv6_addr_to_str(addr_str, &node->ipv6, sizeof(addr_str)), + _nib_onl_get_if(node), (unsigned)netif->ipv6.reach_time); _evtimer_add(node, GNRC_IPV6_NIB_REACH_TIMEOUT, &node->nud_timeout, - iface->reach_time); + netif->ipv6.reach_time); #else (void)node; #endif @@ -281,10 +285,9 @@ void _nib_nc_get(const _nib_onl_entry_t *node, gnrc_ipv6_nib_nc_t *nce) #if GNRC_IPV6_NIB_CONF_ARSM #if GNRC_IPV6_NIB_CONF_6LN if (ipv6_addr_is_link_local(&nce->ipv6)) { - gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(_nib_onl_get_if(node)); + gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(node)); assert(netif != NULL); - if ((netif->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) && - !(netif->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER)) { + if (gnrc_netif2_is_6ln(netif) && !gnrc_netif2_is_rtr(netif)) { _get_l2addr_from_ipv6(nce->l2addr, &node->ipv6); nce->l2addr_len = sizeof(uint64_t); return; @@ -768,42 +771,6 @@ _nib_offl_entry_t *_nib_pl_add(unsigned iface, return dst; } -_nib_iface_t *_nib_iface_get(unsigned iface) -{ - _nib_iface_t *ni = NULL; - - assert(iface <= _NIB_IF_MAX); - for (unsigned i = 0; i < GNRC_NETIF_NUMOF; i++) { - _nib_iface_t *tmp = &_nis[i]; - if (((unsigned)tmp->pid) == iface) { - return tmp; - } - if ((ni == NULL) && (tmp->pid == KERNEL_PID_UNDEF)) { - ni = tmp; - } - } - if (ni != NULL) { - memset(ni, 0, sizeof(_nib_iface_t)); - /* TODO: set random reachable time using constants from #6220 */ - ni->pid = (kernel_pid_t)iface; - } - return ni; -} - -#if GNRC_IPV6_NIB_CONF_ARSM -void _nib_iface_recalc_reach_time(_nib_iface_t *iface) -{ - uint32_t factor = random_uint32_range(NDP_MIN_RANDOM_FACTOR, - NDP_MAX_RANDOM_FACTOR); - - /* random factor was times 1000 so we need to divide it again */ - iface->reach_time = (iface->reach_time_base * factor) / 1000; - _evtimer_add(iface, GNRC_IPV6_NIB_RECALC_REACH_TIME, - &iface->recalc_reach_time, - GNRC_IPV6_NIB_CONF_REACH_TIME_RESET); -} -#endif - static void _override_node(const ipv6_addr_t *addr, unsigned iface, _nib_onl_entry_t *node) { diff --git a/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.h b/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.h index 24e39f423447..97af9ec93e4b 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.h +++ b/sys/net/gnrc/network_layer/ipv6/nib/_nib-internal.h @@ -193,56 +193,6 @@ typedef struct { preferred (UINT32_MAX means forever) */ } _nib_offl_entry_t; -/** - * @brief Interface specific information for Neighbor Discovery - */ -typedef struct { -#if GNRC_IPV6_NIB_CONF_ARSM - /** - * @brief base for random reachable time calculation - */ - uint32_t reach_time_base; - uint32_t reach_time; /**< reachable time (in ms) */ -#endif - uint32_t retrans_time; /**< retransmission time (in ms) */ -#if GNRC_IPV6_NIB_CONF_ROUTER || defined(DOXYGEN) - /** - * @brief timestamp in milliseconds of last unsolicited router - * advertisement - * - * @note Only available if @ref GNRC_IPV6_NIB_CONF_ROUTER. - */ - uint32_t last_ra; -#endif -#if GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN) - /** - * @brief Event for @ref GNRC_IPV6_NIB_RECALC_REACH_TIME - */ - evtimer_msg_event_t recalc_reach_time; -#endif - kernel_pid_t pid; /**< identifier of the interface */ -#if GNRC_IPV6_NIB_CONF_ROUTER || defined(DOXYGEN) - /** - * @brief number of unsolicited router advertisements sent - * - * This only counts up to the first @ref NDP_MAX_INIT_RA_NUMOF on interface - * initialization. The last @ref NDP_MAX_FIN_RA_NUMOF of an advertising - * interface are counted from UINT8_MAX - @ref NDP_MAX_FIN_RA_NUMOF + 1. - * - * @note Only available if @ref GNRC_IPV6_NIB_CONF_ROUTER. - */ - uint8_t ra_sent; -#endif - /** - * @brief number of unsolicited router solicitations scheduled - */ - uint8_t rs_sent; - /** - * @brief number of unsolicited neighbor advertisements scheduled - */ - uint8_t na_sent; -} _nib_iface_t; - /** * @brief Internal NIB-representation of the authoritative border router * for multihop prefix and 6LoWPAN context dissemination @@ -795,30 +745,6 @@ void _nib_ft_get(const _nib_offl_entry_t *dst, gnrc_ipv6_nib_ft_t *fte); int _nib_get_route(const ipv6_addr_t *dst, gnrc_pktsnip_t *ctx, gnrc_ipv6_nib_ft_t *entry); -/** - * @brief Gets (or creates if it not exists) interface information for - * neighbor discovery - * - * @pre `(iface <= _NIB_IF_MAX)` - * - * @param[in] iface Interface identifier to get information for. - * - * @return Interface information on @p iface. - * @return NULL, if no space left for interface. - */ -_nib_iface_t *_nib_iface_get(unsigned iface); - -/** - * @brief Recalculates randomized reachable time of an interface. - * - * @param[in] iface An interface. - */ -#if GNRC_IPV6_NIB_CONF_ARSM -void _nib_iface_recalc_reach_time(_nib_iface_t *iface); -#else -#define _nib_iface_recalc_reach_time(iface) (void)iface -#endif - /** * @brief Looks up if an event is queued in the event timer * diff --git a/sys/net/gnrc/network_layer/ipv6/nib/nib.c b/sys/net/gnrc/network_layer/ipv6/nib/nib.c index e36a1f5536a0..e1a6533524ea 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/nib.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/nib.c @@ -16,9 +16,10 @@ #include #include +#include "log.h" #include "net/ipv6/addr.h" #include "net/gnrc/nettype.h" -#include "net/gnrc/ipv6/netif.h" +#include "net/gnrc/netif2/internal.h" #include "net/gnrc/ipv6/nib.h" #include "net/gnrc/ndp2.h" #include "net/gnrc/pktqueue.h" @@ -49,24 +50,16 @@ static gnrc_pktqueue_t _queue_pool[GNRC_IPV6_NIB_NUMOF]; * @internal * @{ */ -static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +static void _handle_nbr_sol(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6, const ndp_nbr_sol_t *nbr_sol, size_t icmpv6_len); -static void _handle_nbr_adv(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +static void _handle_nbr_adv(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6, const ndp_nbr_adv_t *nbr_adv, size_t icmpv6_len); -static bool _resolve_addr(const ipv6_addr_t *dst, kernel_pid_t iface, +static bool _resolve_addr(const ipv6_addr_t *dst, gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt, gnrc_ipv6_nib_nc_t *nce, _nib_onl_entry_t *entry); static void _handle_snd_na(gnrc_pktsnip_t *pkt); - -/* interface flag checks */ -#if GNRC_IPV6_NIB_CONF_ROUTER -static inline bool _is_rtr(const gnrc_ipv6_netif_t *netif) -{ - return (netif->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER); -} -#endif /** @} */ void gnrc_ipv6_nib_init(void) @@ -83,27 +76,13 @@ void gnrc_ipv6_nib_init(void) mutex_unlock(&_nib_mutex); } -void gnrc_ipv6_nib_init_iface(kernel_pid_t iface) +void gnrc_ipv6_nib_init_iface(gnrc_netif2_t *netif) { - _nib_iface_t *nib_iface; + ipv6_addr_t addr = IPV6_ADDR_UNSPECIFIED; - assert(iface > KERNEL_PID_UNDEF); - DEBUG("nib: Initialize interface %u\n", (unsigned)iface); - mutex_lock(&_nib_mutex); - nib_iface = _nib_iface_get(iface); -#ifdef TEST_SUITES - if (nib_iface == NULL) { - /* in the unittests old NC and NIB are mixed, so this function leads to - * crashes. To prevent this we early exit here, if the interface was - * not found - * TODO: remove when gnrc_ipv6_nc is removed. - */ - mutex_unlock(&_nib_mutex); - return; - } -#else - assert(nib_iface != NULL); -#endif + assert(netif != NULL); + DEBUG("nib: Initialize interface %u\n", netif->pid); + gnrc_netif2_acquire(netif); /* TODO: * - set link-local address here for stateless address auto-configuration * and 6LN @@ -112,46 +91,116 @@ void gnrc_ipv6_nib_init_iface(kernel_pid_t iface) * - join all router group of link-local address here on router node here * - become an router advertising interface here on non-6LR here */ - _init_iface_arsm(nib_iface); - nib_iface->rs_sent = 0; - nib_iface->na_sent = 0; + _init_iface_arsm(netif); + netif->ipv6.retrans_time = NDP_RETRANS_TIMER_MS; + netif->ipv6.na_sent = 0; #if GNRC_IPV6_NIB_CONF_ROUTER - nib_iface->last_ra = UINT32_MAX; - nib_iface->ra_sent = 0; + netif->ipv6.rtr_ltime = 1800U; + netif->ipv6.last_ra = UINT32_MAX; + netif->ipv6.ra_sent = 0; + netif->flags |= GNRC_NETIF2_FLAGS_IPV6_FORWARDING; +#if !GNRC_IPV6_NIB_CONF_6LR || GNRC_IPV6_NIB_CONF_6LBR + netif->flags |= GNRC_NETIF2_FLAGS_IPV6_RTR_ADV; #endif - mutex_unlock(&_nib_mutex); +#if GNRC_IPV6_NIB_CONF_6LBR + netif->flags |= GNRC_NETIF2_FLAGS_6LO_ABR; +#endif + memcpy(&addr, &ipv6_addr_all_routers_link_local, sizeof(addr)); + if (gnrc_netif2_ipv6_group_join(netif, &addr) < 0) { + LOG_ERROR("nib: Can't join link-local all-routers on interface %u\n", + netif->pid); + return; + } +#endif +#if GNRC_IPV6_NIB_CONF_6LN + netif->ipv6.rs_sent = 0; +#endif + memcpy(&addr, &ipv6_addr_all_nodes_link_local, sizeof(addr)); + if (gnrc_netif2_ipv6_group_join(netif, &addr) < 0) { + LOG_ERROR("nib: Can't join link-local all-nodes on interface %u\n", + netif->pid); + return; + } +#if GNRC_IPV6_NIB_CONF_6LN || GNRC_IPV6_NIB_CONF_SLAAC +#if GNRC_IPV6_NIB_CONF_6LN + if (netif->device_type == NETDEV_TYPE_IEEE802154) { + /* see https://tools.ietf.org/html/rfc6775#section-5.2 */ + uint16_t src_len = IEEE802154_LONG_ADDRESS_LEN; + gnrc_netapi_opt_t opt = { .opt = NETOPT_SRC_LEN, + .data = &src_len, + .data_len = sizeof(src_len) }; + + /* XXX we are supposed to be in interface context here, so use driver + * directly everything else would deadlock anyway */ + netif->ops->set(netif, &opt); + } +#endif + uint8_t flags = GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID; + /* TODO: set TENTATIVE as soon as there is a SLAAC implementation if not + * 6LN ;-) */ + + gnrc_netif2_ipv6_get_iid(netif, (eui64_t *)&addr.u64[1]); + ipv6_addr_set_link_local_prefix(&addr); + if (gnrc_netif2_ipv6_addr_add(netif, &addr, 64U, flags) < 0) { + LOG_ERROR("nib: Can't add link-local address on interface %u\n", + netif->pid); + return; + } +#if GNRC_IPV6_NIB_CONF_ARSM + /* TODO: SHOULD delay join between 0 and MAX_RTR_SOLICITATION_DELAY */ + ipv6_addr_set_solicited_nodes(&addr, &addr); + if (gnrc_netif2_ipv6_group_join(netif, &addr) < 0) { + LOG_ERROR("nib: Can't join solicited-nodes of link-local address on " + "interface %u\n", netif->pid); + return; + } +#endif +#if GNRC_IPV6_NIB_CONF_SLAAC + /* TODO send NS to solicited nodes and wait netif->ipv6.retrans_time to + * confirm uniqueness of the link-local address */ +#endif +#endif + gnrc_netif2_release(netif); } int gnrc_ipv6_nib_get_next_hop_l2addr(const ipv6_addr_t *dst, - kernel_pid_t iface, gnrc_pktsnip_t *pkt, + gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt, gnrc_ipv6_nib_nc_t *nce) { int res = 0; + DEBUG("nib: get next hop link-layer address of %s%%%u\n", + ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), + (netif != NULL) ? (unsigned)netif->pid : 0U); + gnrc_netif2_acquire(netif); mutex_lock(&_nib_mutex); do { /* XXX: hidden goto ;-) */ if (ipv6_addr_is_link_local(dst)) { /* TODO: Prefix-based on-link determination */ - if ((iface == KERNEL_PID_UNDEF) || - !_resolve_addr(dst, iface, pkt, nce, - _nib_onl_get(dst, iface))) { + if ((netif == NULL) || + !_resolve_addr(dst, netif, pkt, nce, + _nib_onl_get(dst, netif->pid))) { res = -EHOSTUNREACH; break; } } else { - /* TODO: Off-link next hop determination */ + /* TODO: Off-link next hop determination; + * might need netif locking */ res = -EHOSTUNREACH; } } while (0); mutex_unlock(&_nib_mutex); + gnrc_netif2_release(netif); return res; } -void gnrc_ipv6_nib_handle_pkt(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +void gnrc_ipv6_nib_handle_pkt(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6, const icmpv6_hdr_t *icmpv6, size_t icmpv6_len) { DEBUG("nib: Handle packet (icmpv6->type = %u)\n", icmpv6->type); + assert(netif != NULL); + gnrc_netif2_acquire(netif); mutex_lock(&_nib_mutex); switch (icmpv6->type) { #if GNRC_IPV6_NIB_CONF_ROUTER @@ -163,10 +212,10 @@ void gnrc_ipv6_nib_handle_pkt(kernel_pid_t iface, const ipv6_hdr_t *ipv6, /* TODO */ break; case ICMPV6_NBR_SOL: - _handle_nbr_sol(iface, ipv6, (ndp_nbr_sol_t *)icmpv6, icmpv6_len); + _handle_nbr_sol(netif, ipv6, (ndp_nbr_sol_t *)icmpv6, icmpv6_len); break; case ICMPV6_NBR_ADV: - _handle_nbr_adv(iface, ipv6, (ndp_nbr_adv_t *)icmpv6, icmpv6_len); + _handle_nbr_adv(netif, ipv6, (ndp_nbr_adv_t *)icmpv6, icmpv6_len); break; #if GNRC_IPV6_NIB_CONF_REDIRECT case ICMPV6_REDIRECT: @@ -183,6 +232,7 @@ void gnrc_ipv6_nib_handle_pkt(kernel_pid_t iface, const ipv6_hdr_t *ipv6, #endif /* GNRC_IPV6_NIB_CONF_MULTIHOP_DAD */ } mutex_unlock(&_nib_mutex); + gnrc_netif2_release(netif); } void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type) @@ -191,6 +241,7 @@ void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type) ctx, type, (unsigned)xtimer_now_usec() / 1000); mutex_lock(&_nib_mutex); switch (type) { + /* TODO: remember netif locking if ctx is a gnrc_netif2_t */ #if GNRC_IPV6_NIB_CONF_ARSM case GNRC_IPV6_NIB_SND_UC_NS: case GNRC_IPV6_NIB_SND_MC_NS: @@ -201,7 +252,7 @@ void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type) _handle_state_timeout(ctx); break; case GNRC_IPV6_NIB_RECALC_REACH_TIME: - _nib_iface_recalc_reach_time(ctx); + _recalc_reach_time(ctx); break; #endif /* GNRC_IPV6_NIB_CONF_ARSM */ case GNRC_IPV6_NIB_SND_NA: @@ -246,6 +297,22 @@ void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type) mutex_unlock(&_nib_mutex); } +#if GNRC_IPV6_NIB_CONF_ROUTER +void gnrc_ipv6_nib_change_rtr_adv_iface(gnrc_netif2_t *netif, bool enable) +{ + if (enable) { + netif->flags |= GNRC_NETIF2_FLAGS_IPV6_RTR_ADV; + /* TODO: start router advertisements */ + } + else { + netif->flags &= ~GNRC_NETIF2_FLAGS_IPV6_RTR_ADV; + /* TODO: + * - start final router advertisements, + * - start router solicitations? */ + } +} +#endif + /* Iterator for NDP options in a packet */ #define FOREACH_OPT(ndp_pkt, opt, icmpv6_len) \ for (opt = (ndp_opt_t *)(ndp_pkt + 1); \ @@ -253,40 +320,19 @@ void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type) icmpv6_len -= (opt->len << 3), \ opt = (ndp_opt_t *)(((uint8_t *)opt) + (opt->len << 3))) -static size_t _get_l2src(kernel_pid_t iface, 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(iface, 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(iface, NETOPT_ADDRESS_LONG, 0, - l2src, l2src_maxlen)) > max_short_len)) { - l2src_len = (uint16_t)res; - } - else if ((res = gnrc_netapi_get(iface, NETOPT_ADDRESS, 0, l2src, - l2src_maxlen)) >= 0) { - l2src_len = (uint16_t)res; - } - else { - DEBUG("nib: 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 } -static void _send_delayed_nbr_adv(const gnrc_ipv6_netif_t *netif, +static void _send_delayed_nbr_adv(const gnrc_netif2_t *netif, const ipv6_addr_t *tgt, const ipv6_addr_t *dst, gnrc_pktsnip_t *reply_aro) @@ -296,13 +342,15 @@ static void _send_delayed_nbr_adv(const gnrc_ipv6_netif_t *netif, uint8_t reply_flags = NDP_NBR_ADV_FLAGS_S; #if GNRC_IPV6_NIB_CONF_ROUTER - if (_is_rtr(netif)) { + if (gnrc_netif2_is_rtr(netif)) { reply_flags |= NDP_NBR_ADV_FLAGS_R; } #endif +#if GNRC_NETIF2_L2ADDR_MAXLEN > 0 if (ipv6_addr_is_multicast(dst)) { - uint8_t l2addr[GNRC_IPV6_NIB_L2ADDR_MAX_LEN]; - size_t l2addr_len = _get_l2src(netif->pid, l2addr, sizeof(l2addr)); + uint8_t l2addr[GNRC_NETIF2_L2ADDR_MAXLEN]; + size_t l2addr_len = _get_l2src(netif, l2addr); + if (l2addr_len > 0) { extra_opts = gnrc_ndp2_opt_tl2a_build(l2addr, l2addr_len, extra_opts); @@ -319,6 +367,10 @@ static void _send_delayed_nbr_adv(const gnrc_ipv6_netif_t *netif, else { reply_flags |= NDP_NBR_ADV_FLAGS_O; } +#else /* GNRC_NETIF2_L2ADDR_MAXLEN > 0 */ + reply_flags |= NDP_NBR_ADV_FLAGS_O; +#endif + /* discard const qualifier */ nbr_adv = gnrc_ndp2_nbr_adv_build(tgt, reply_flags, extra_opts); if (nbr_adv == NULL) { DEBUG("nib: No space left in packet buffer. Not replying NS"); @@ -336,12 +388,12 @@ static void _send_delayed_nbr_adv(const gnrc_ipv6_netif_t *netif, } } -static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +static void _handle_nbr_sol(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6, const ndp_nbr_sol_t *nbr_sol, size_t icmpv6_len) { size_t tmp_len = icmpv6_len - sizeof(ndp_nbr_sol_t); + int tgt_idx; ndp_opt_t *opt; - ipv6_addr_t *local; /* check validity, see: https://tools.ietf.org/html/rfc4861#section-7.1.1 */ /* checksum is checked by GNRC's ICMPv6 module */ @@ -365,9 +417,9 @@ static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6, return; } /* check if target is assigned only now in case the length was wrong */ - local = gnrc_ipv6_netif_find_addr(iface, &nbr_sol->tgt); - if (local == NULL) { - DEBUG("nib: Target address %s is not assigned to a local interface\n", + tgt_idx = gnrc_netif2_ipv6_addr_idx(netif, &nbr_sol->tgt); + if (tgt_idx < 0) { + DEBUG("nib: Target address %s is not assigned to the local interface\n", ipv6_addr_to_str(addr_str, &nbr_sol->tgt, sizeof(addr_str))); return; } @@ -395,6 +447,7 @@ static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6, /* TODO SLAAC behavior */ #endif /* GNRC_IPV6_NIB_CONF_SLAAC */ if (!ipv6_addr_is_unspecified(&ipv6->src)) { + gnrc_pktsnip_t *reply_aro = NULL; #if GNRC_IPV6_NIB_CONF_6LR ndp_opt_t *sl2ao = NULL; sixlowpan_nd_opt_ar_t *aro = NULL; @@ -402,23 +455,24 @@ static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6, #define sl2ao (NULL) #define aro (NULL) #endif /* GNRC_IPV6_NIB_CONF_6LR */ - gnrc_ipv6_netif_t *netif; - gnrc_pktsnip_t *reply_aro = NULL; tmp_len = icmpv6_len - sizeof(ndp_nbr_sol_t); - netif = gnrc_ipv6_netif_get(iface); - /* TODO: Set STALE NCE if link-layer has no addresses */ + if (!(netif->flags & GNRC_NETIF2_FLAGS_HAS_L2ADDR)) { + /* Set STALE NCE if link-layer has no addresses */ + _nib_nc_add(&ipv6->src, netif->pid, + GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE); + } FOREACH_OPT(nbr_sol, opt, tmp_len) { switch (opt->type) { case NDP_OPT_SL2A: #if GNRC_IPV6_NIB_CONF_6LR - if (_is_6lr(netif)) { + if (gnrc_netif2_is_6lr(netif)) { DEBUG("nib: Storing SL2AO for later handling\n"); sl2ao = opt; break; } #endif /* GNRC_IPV6_NIB_CONF_6LR */ - _handle_sl2ao(iface, ipv6, (const icmpv6_hdr_t *)nbr_sol, + _handle_sl2ao(netif, ipv6, (const icmpv6_hdr_t *)nbr_sol, opt); break; #if GNRC_IPV6_NIB_CONF_6LR @@ -432,9 +486,9 @@ static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6, opt->type); } } - reply_aro = _copy_and_handle_aro(iface, ipv6, nbr_sol, aro, sl2ao); + reply_aro = _copy_and_handle_aro(netif, ipv6, nbr_sol, aro, sl2ao); /* check if target address is anycast */ - if (gnrc_ipv6_netif_addr_is_non_unicast(local)) { + if (netif->ipv6.addrs_flags[tgt_idx] & GNRC_NETIF2_IPV6_ADDRS_FLAGS_ANYCAST) { _send_delayed_nbr_adv(netif, &nbr_sol->tgt, &ipv6->dst, reply_aro); } else { @@ -445,7 +499,7 @@ static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6, } } -static void _handle_nbr_adv(kernel_pid_t iface, const ipv6_hdr_t *ipv6, +static void _handle_nbr_adv(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6, const ndp_nbr_adv_t *nbr_adv, size_t icmpv6_len) { size_t tmp_len = icmpv6_len - sizeof(ndp_nbr_adv_t); @@ -501,7 +555,7 @@ static void _handle_nbr_adv(kernel_pid_t iface, const ipv6_hdr_t *ipv6, #if GNRC_IPV6_NIB_CONF_SLAAC /* TODO SLAAC behavior */ #endif - if (((nce = _nib_onl_get(&nbr_adv->tgt, iface)) != NULL) && + if (((nce = _nib_onl_get(&nbr_adv->tgt, netif->pid)) != NULL) && (nce->mode & _NC)) { #if GNRC_IPV6_NIB_CONF_ARSM bool tl2ao_avail = false; @@ -512,13 +566,13 @@ static void _handle_nbr_adv(kernel_pid_t iface, const ipv6_hdr_t *ipv6, switch (opt->type) { #if GNRC_IPV6_NIB_CONF_ARSM case NDP_OPT_TL2A: - _handle_adv_l2(iface, nce, (icmpv6_hdr_t *)nbr_adv, opt); + _handle_adv_l2(netif, nce, (icmpv6_hdr_t *)nbr_adv, opt); tl2ao_avail = true; break; #endif #if GNRC_IPV6_NIB_CONF_6LN case NDP_OPT_AR: - _handle_aro(iface, ipv6, (const icmpv6_hdr_t *)nbr_adv, + _handle_aro(netif, ipv6, (const icmpv6_hdr_t *)nbr_adv, (const sixlowpan_nd_opt_ar_t *)opt, opt, nce); break; #endif @@ -531,11 +585,11 @@ static void _handle_nbr_adv(kernel_pid_t iface, const ipv6_hdr_t *ipv6, if (!tl2ao_avail && (nbr_adv->flags & NDP_NBR_ADV_FLAGS_S) && (_get_nud_state(nce) != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE)) { /* reachability confirmed without TL2AO */ - _set_reachable(iface, nce); + _set_reachable(netif, nce); + } + if (!(netif->flags & GNRC_NETIF2_FLAGS_HAS_L2ADDR)) { + _handle_adv_l2(netif, nce, (icmpv6_hdr_t *)nbr_adv, NULL); } - /* TODO: handling for of advertised link-layer with link-layers without - * addresses */ - /* _handle_adv_l2(iface, nce, (icmpv6_hdr_t *)nbr_adv, NULL); */ #endif } } @@ -567,7 +621,7 @@ static gnrc_pktqueue_t *_alloc_queue_entry(gnrc_pktsnip_t *pkt) } #endif -static bool _resolve_addr(const ipv6_addr_t *dst, kernel_pid_t iface, +static bool _resolve_addr(const ipv6_addr_t *dst, gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt, gnrc_ipv6_nib_nc_t *nce, _nib_onl_entry_t *entry) { @@ -575,29 +629,44 @@ static bool _resolve_addr(const ipv6_addr_t *dst, kernel_pid_t iface, #if GNRC_IPV6_NIB_CONF_ARSM if ((entry != NULL) && (entry->mode & _NC) && _is_reachable(entry)) { if (_get_nud_state(entry) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE) { - _set_nud_state(entry, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY); + _set_nud_state(netif, entry, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY); _evtimer_add(entry, GNRC_IPV6_NIB_DELAY_TIMEOUT, &entry->nud_timeout, NDP_DELAY_FIRST_PROBE_MS); } + DEBUG("nib: resolve address %s%%%u from neighbor cache\n", + ipv6_addr_to_str(addr_str, &entry->ipv6, sizeof(addr_str)), + _nib_onl_get_if(entry)); _nib_nc_get(entry, nce); res = true; } #else if (entry != NULL) { + DEBUG("nib: resolve address %s%%%u from neighbor cache\n", + ipv6_addr_to_str(addr_str, &entry->ipv6, sizeof(addr_str)), + _nib_onl_get_if(entry)); _nib_nc_get(entry, nce); res = true; } #endif - else if (!(res = _resolve_addr_from_ipv6(dst, iface, nce))) { + else if (!(res = _resolve_addr_from_ipv6(dst, netif, nce))) { #if GNRC_IPV6_NIB_CONF_ARSM bool reset = false; #endif + + DEBUG("nib: resolve address %s by probing neighbors\n", + ipv6_addr_to_str(addr_str, dst, sizeof(addr_str))); if ((entry == NULL) || !(entry->mode & _NC)) { - entry = _nib_nc_add(dst, iface, + entry = _nib_nc_add(dst, (netif != NULL) ? netif->pid : 0, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE); if (entry == NULL) { return false; } +#if GNRC_IPV6_NIB_CONF_ROUTER + if ((netif != NULL) && (netif->ipv6.route_info_cb != NULL)) { + netif->ipv6.route_info_cb(GNRC_IPV6_NIB_ROUTE_INFO_TYPE_NSC, + dst, (void *)GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE); + } +#endif #if GNRC_IPV6_NIB_CONF_ARSM reset = true; #endif diff --git a/sys/net/gnrc/network_layer/ipv6/nib/nib_nc.c b/sys/net/gnrc/network_layer/ipv6/nib/nib_nc.c index 4cd920a53539..09b7245f910b 100644 --- a/sys/net/gnrc/network_layer/ipv6/nib/nib_nc.c +++ b/sys/net/gnrc/network_layer/ipv6/nib/nib_nc.c @@ -18,7 +18,7 @@ #include #include "net/gnrc/ipv6.h" -#include "net/gnrc/netif.h" +#include "net/gnrc/netif2.h" #include "net/gnrc/ipv6/nib/nc.h" @@ -127,15 +127,16 @@ static const char *_ar_str[] = { void gnrc_ipv6_nib_nc_print(gnrc_ipv6_nib_nc_t *entry) { - char addr_str[IPV6_ADDR_MAX_STR_LEN]; + char addr_str[(IPV6_ADDR_MAX_STR_LEN > GNRC_IPV6_NIB_L2ADDR_MAX_LEN) ? + IPV6_ADDR_MAX_STR_LEN : GNRC_IPV6_NIB_L2ADDR_MAX_LEN]; printf("%s ", ipv6_addr_to_str(addr_str, &entry->ipv6, sizeof(addr_str))); if (gnrc_ipv6_nib_nc_get_iface(entry) != KERNEL_PID_UNDEF) { printf("dev #%u ", gnrc_ipv6_nib_nc_get_iface(entry)); } - printf("lladdr %s ", gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), - entry->l2addr, - entry->l2addr_len)); + printf("lladdr %s ", gnrc_netif2_addr_to_str(entry->l2addr, + entry->l2addr_len, + addr_str)); if (gnrc_ipv6_nib_nc_is_router(entry)) { printf("router"); } diff --git a/sys/net/gnrc/network_layer/ndp2/gnrc_ndp2.c b/sys/net/gnrc/network_layer/ndp2/gnrc_ndp2.c index eea675570101..4a2a1321ba7b 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 } /** @} */ diff --git a/sys/shell/commands/sc_gnrc_ipv6_nib.c b/sys/shell/commands/sc_gnrc_ipv6_nib.c index 4c7c2f34b7f3..83f6c5c698bb 100644 --- a/sys/shell/commands/sc_gnrc_ipv6_nib.c +++ b/sys/shell/commands/sc_gnrc_ipv6_nib.c @@ -106,8 +106,7 @@ static int _nib_neigh(int argc, char **argv) return 1; } if ((argc > 5) && /* TODO also check if interface supports link-layers or not */ - (l2addr_len = gnrc_netif_addr_from_str(l2addr, sizeof(l2addr), - argv[5])) == 0) { + (l2addr_len = gnrc_netif2_addr_from_str(argv[5], l2addr)) == 0) { _usage_nib_neigh(argv); return 1; } @@ -150,7 +149,7 @@ static int _nib_prefix(int argc, char **argv) ipv6_addr_t pfx; unsigned iface = atoi(argv[3]); unsigned pfx_len = ipv6_addr_split_prefix(argv[4]); - unsigned valid_ltime = UINT32_MAX, pref_ltime = UINT32_MAX; + uint32_t valid_ltime = UINT32_MAX, pref_ltime = UINT32_MAX; if (ipv6_addr_from_str(&pfx, argv[4]) == NULL) { _usage_nib_prefix(argv); diff --git a/tests/driver_kw2xrf/main.c b/tests/driver_kw2xrf/main.c index b2bb64701e90..8da60025a1c8 100644 --- a/tests/driver_kw2xrf/main.c +++ b/tests/driver_kw2xrf/main.c @@ -44,27 +44,13 @@ static bool _is_number(char *str) return true; } -static bool _is_iface(kernel_pid_t dev) -{ - kernel_pid_t ifs[GNRC_NETIF_NUMOF]; - size_t numof = gnrc_netif_get(ifs); - - for (size_t i = 0; i < numof && i < GNRC_NETIF_NUMOF; i++) { - if (ifs[i] == dev) { - return true; - } - } - - return false; -} - static void _set_test_mode(int argc, char **argv, uint8_t mode) { (void) argc; if (_is_number(argv[1])) { kernel_pid_t dev = atoi(argv[1]); - if (_is_iface(dev)) { + if (gnrc_netif2_get_by_pid(dev)) { gnrc_netapi_set(dev, NETOPT_RF_TESTMODE, 0, (void *)&mode, sizeof(mode)); return; } diff --git a/tests/gnrc_ipv6_nib/Makefile b/tests/gnrc_ipv6_nib/Makefile index e2fee99a0716..4d3586ef87dd 100644 --- a/tests/gnrc_ipv6_nib/Makefile +++ b/tests/gnrc_ipv6_nib/Makefile @@ -6,7 +6,10 @@ BOARD_INSUFFICIENT_MEMORY := chronos nucleo32-f031 nucleo32-f042 USEMODULE += gnrc_ipv6 USEMODULE += gnrc_ipv6_nib +USEMODULE += gnrc_netif2 USEMODULE += embunit +USEMODULE += netdev_eth +USEMODULE += netdev_test CFLAGS += -DDEVELHELP CFLAGS += -DGNRC_NETTYPE_NDP2=GNRC_NETTYPE_TEST diff --git a/tests/gnrc_ipv6_nib/common.h b/tests/gnrc_ipv6_nib/common.h index 97720c85b90a..f7c9de5388e2 100644 --- a/tests/gnrc_ipv6_nib/common.h +++ b/tests/gnrc_ipv6_nib/common.h @@ -22,14 +22,20 @@ #include #include "net/gnrc.h" +#include "net/gnrc/netif2.h" #ifdef __cplusplus extern "C" { #endif -#define _CALL(fn) _common_set_up(); _set_up(); puts("Calling " # fn); fn() +#define _LL0 (0xce) +#define _LL1 (0xab) +#define _LL2 (0xfe) +#define _LL3 (0xad) +#define _LL4 (0xf7) +#define _LL5 (0x26) -extern kernel_pid_t _mock_netif_pid; +extern gnrc_netif2_t *_mock_netif; void _tests_init(void); int _mock_netif_get(gnrc_netapi_opt_t *opt); diff --git a/tests/gnrc_ipv6_nib/main.c b/tests/gnrc_ipv6_nib/main.c index a409571ecc32..68e90aeb64ef 100644 --- a/tests/gnrc_ipv6_nib/main.c +++ b/tests/gnrc_ipv6_nib/main.c @@ -33,12 +33,6 @@ #include "sched.h" #define _BUFFER_SIZE (128) -#define _LL0 (0xce) -#define _LL1 (0xab) -#define _LL2 (0xfe) -#define _LL3 (0xad) -#define _LL4 (0xf7) -#define _LL5 (0x26) static const uint8_t _loc_l2[] = { _LL0, _LL1, _LL2, _LL3, _LL4, _LL5 }; static const ipv6_addr_t _loc_ll = { { @@ -74,7 +68,7 @@ static void _set_up(void) } } -static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH(kernel_pid_t iface) +static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH(gnrc_netif2_t *netif) { msg_t msg; gnrc_ipv6_nib_nc_t nce; @@ -82,9 +76,9 @@ static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH(kernel_pid_t iface gnrc_pktsnip_t *pkt; TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH, - gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll, iface, + gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll, netif, NULL, &nce)); - if (iface != KERNEL_PID_UNDEF) { + if (netif != NULL) { ndp_nbr_sol_t *nbr_sol; bool contains_sl2ao = false; @@ -96,7 +90,7 @@ static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH(kernel_pid_t iface TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE, gnrc_ipv6_nib_nc_get_nud_state(&nce)); TEST_ASSERT(!gnrc_ipv6_nib_nc_is_router(&nce)); - TEST_ASSERT_EQUAL_INT(iface, gnrc_ipv6_nib_nc_get_iface(&nce)); + TEST_ASSERT_EQUAL_INT(netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce)); TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_GC, gnrc_ipv6_nib_nc_get_ar_state(&nce)); TEST_ASSERT_EQUAL_INT(1, msg_avail()); @@ -128,22 +122,22 @@ static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH(kernel_pid_t iface static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH_no_iface(void) { - test_get_next_hop_l2addr__link_local_EHOSTUNREACH(KERNEL_PID_UNDEF); + test_get_next_hop_l2addr__link_local_EHOSTUNREACH(NULL); } static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH_iface(void) { - test_get_next_hop_l2addr__link_local_EHOSTUNREACH(_mock_netif_pid); + test_get_next_hop_l2addr__link_local_EHOSTUNREACH(_mock_netif); } static void test_get_next_hop_l2addr__link_local_static_conf(void) { gnrc_ipv6_nib_nc_t nce; - TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_nc_set(&_rem_ll, _mock_netif_pid, + TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_nc_set(&_rem_ll, _mock_netif->pid, _rem_l2, sizeof(_rem_l2))); TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll, - _mock_netif_pid, + _mock_netif, NULL, &nce)); TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0), "_rem_ll != nce.ipv6"); @@ -152,7 +146,7 @@ static void test_get_next_hop_l2addr__link_local_static_conf(void) "_rem_l2 != nce.l2addr"); TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED, gnrc_ipv6_nib_nc_get_nud_state(&nce)); - TEST_ASSERT_EQUAL_INT(_mock_netif_pid, gnrc_ipv6_nib_nc_get_iface(&nce)); + TEST_ASSERT_EQUAL_INT(_mock_netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce)); TEST_ASSERT(!gnrc_ipv6_nib_nc_is_router(&nce)); TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_MANUAL, gnrc_ipv6_nib_nc_get_ar_state(&nce)); @@ -172,7 +166,7 @@ void _simulate_ndp_handshake(const ipv6_addr_t *src, const ipv6_addr_t *dst, /* trigger sending of neighbor discovery */ TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH, gnrc_ipv6_nib_get_next_hop_l2addr(dst, - _mock_netif_pid, + _mock_netif, NULL, &nce)); TEST_ASSERT_EQUAL_INT(1, msg_avail()); /* clear message queue */ @@ -192,7 +186,7 @@ void _simulate_ndp_handshake(const ipv6_addr_t *src, const ipv6_addr_t *dst, tl2ao->type = NDP_OPT_TL2A; tl2ao->len = 1; memcpy(tl2ao + 1, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, (icmpv6_hdr_t *)nbr_adv, + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, (icmpv6_hdr_t *)nbr_adv, sizeof(ndp_nbr_adv_t) + 8U); } @@ -202,7 +196,7 @@ static void test_get_next_hop_l2addr__link_local_after_handshake(uint8_t adv_fla _simulate_ndp_handshake(&_loc_ll, &_rem_ll, adv_flags); TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll, - _mock_netif_pid, + _mock_netif, NULL, &nce)); TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0), "_rem_ll != nce.ipv6"); @@ -211,7 +205,7 @@ static void test_get_next_hop_l2addr__link_local_after_handshake(uint8_t adv_fla "_rem_l2 != nce.l2addr"); TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE, gnrc_ipv6_nib_nc_get_nud_state(&nce)); - TEST_ASSERT_EQUAL_INT(_mock_netif_pid, gnrc_ipv6_nib_nc_get_iface(&nce)); + TEST_ASSERT_EQUAL_INT(_mock_netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce)); if (adv_flags & NDP_NBR_ADV_FLAGS_R) { TEST_ASSERT(gnrc_ipv6_nib_nc_is_router(&nce)); } @@ -242,7 +236,7 @@ static void test_get_next_hop_l2addr__link_local_after_handshake_no_iface(void) _simulate_ndp_handshake(&_loc_ll, &_rem_ll, NDP_NBR_ADV_FLAGS_S); TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll, - KERNEL_PID_UNDEF, + NULL, NULL, &nce)); } @@ -257,7 +251,7 @@ static void test_handle_pkt__unknown_type(void) memcpy(&ipv6->dst, &_rem_ll, sizeof(ipv6->dst)); icmpv6->type = ICMPV6_ECHO_REQ; icmpv6->code = 0; - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, sizeof(icmpv6_hdr_t)); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); @@ -301,7 +295,7 @@ static void test_handle_pkt__nbr_sol__invalid_hl(void) size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_sol_nodes, 194U, 0U, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -315,7 +309,7 @@ static void test_handle_pkt__nbr_sol__invalid_code(void) size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_sol_nodes, 255U, 201U, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -330,7 +324,7 @@ static void test_handle_pkt__nbr_sol__invalid_icmpv6_len(void) _set_nbr_sol(&_rem_ll, &_loc_sol_nodes, 255U, 0U, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, sizeof(ndp_nbr_sol_t) - 1); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); @@ -346,7 +340,7 @@ static void test_handle_pkt__nbr_sol__invalid_tgt(void) &ipv6_addr_all_routers_site_local, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -364,7 +358,7 @@ static void test_handle_pkt__nbr_sol__invalid_opt_len(void) opt->type = NDP_OPT_SL2A; opt->len = 0U; icmpv6_len += sizeof(ndp_opt_t); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -378,7 +372,7 @@ static void test_handle_pkt__nbr_sol__invalid_dst(void) size_t icmpv6_len = _set_nbr_sol(&ipv6_addr_unspecified, &_loc_ll, 255U, 0U, &_loc_ll, NULL, 0); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -393,7 +387,7 @@ static void test_handle_pkt__nbr_sol__invalid_sl2ao(void) 255U, 0U, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -408,7 +402,7 @@ static void test_handle_pkt__nbr_sol__tgt_not_assigned(void) 255U, 0U, &_rem_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -425,12 +419,12 @@ static void test_pkt_is_nbr_adv(gnrc_pktsnip_t *pkt, const ipv6_addr_t *dst, ndp_nbr_adv_t *nbr_adv; ndp_opt_t *tl2ao; - /* first snip is a netif header to _mock_netif_pid */ + /* first snip is a netif header to _mock_netif */ TEST_ASSERT_NOT_NULL(pkt); TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_NETIF, pkt->type); TEST_ASSERT(sizeof(gnrc_netif_hdr_t) <= pkt->size); netif_hdr = pkt->data; - TEST_ASSERT_EQUAL_INT(_mock_netif_pid, netif_hdr->if_pid); + TEST_ASSERT_EQUAL_INT(_mock_netif->pid, netif_hdr->if_pid); /* second snip is an IPv6 header to dst */ TEST_ASSERT_NOT_NULL(pkt->next); TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_IPV6, pkt->next->type); @@ -475,7 +469,7 @@ static void test_handle_pkt__nbr_sol__ll_src(unsigned exp_nud_state, 255U, 0U, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(gnrc_ipv6_nib_nc_iter(0, &state, &nce), "Expected neighbor cache entry"); TEST_ASSERT_MESSAGE(ipv6_addr_equal(&_rem_ll, &nce.ipv6), @@ -485,7 +479,7 @@ static void test_handle_pkt__nbr_sol__ll_src(unsigned exp_nud_state, "_rem_l2 != nce.l2addr"); TEST_ASSERT_EQUAL_INT(exp_nud_state, gnrc_ipv6_nib_nc_get_nud_state(&nce)); TEST_ASSERT(!gnrc_ipv6_nib_nc_is_router(&nce)); - TEST_ASSERT_EQUAL_INT(_mock_netif_pid, gnrc_ipv6_nib_nc_get_iface(&nce)); + TEST_ASSERT_EQUAL_INT(_mock_netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce)); TEST_ASSERT_EQUAL_INT(exp_ar_state, gnrc_ipv6_nib_nc_get_ar_state(&nce)); TEST_ASSERT_EQUAL_INT(1, msg_avail()); msg_receive(&msg); @@ -518,7 +512,7 @@ static void test_handle_pkt__nbr_sol__ll_src_no_sl2ao(void) size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_sol_nodes, 255U, 0U, &_loc_ll, NULL, 0); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); TEST_ASSERT_EQUAL_INT(1, msg_avail()); @@ -570,7 +564,7 @@ static void test_handle_pkt__nbr_adv__invalid_hl(void) NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -585,7 +579,7 @@ static void test_handle_pkt__nbr_adv__invalid_code(void) NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -601,7 +595,7 @@ static void test_handle_pkt__nbr_adv__invalid_icmpv6_len(void) &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, sizeof(ndp_nbr_adv_t) - 1); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); @@ -618,7 +612,7 @@ static void test_handle_pkt__nbr_adv__invalid_tgt(void) &ipv6_addr_all_routers_site_local, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -633,7 +627,7 @@ static void test_handle_pkt__nbr_adv__invalid_flags(void) 255U, 0U, NDP_NBR_ADV_FLAGS_S, &_loc_ll, NULL, 0); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -652,7 +646,7 @@ static void test_handle_pkt__nbr_adv__invalid_opt_len(void) opt->type = NDP_OPT_SL2A; opt->len = 0U; icmpv6_len += sizeof(ndp_opt_t); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -667,7 +661,7 @@ static void test_handle_pkt__nbr_adv__unspecified_src(void) NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -682,7 +676,7 @@ static void test_handle_pkt__nbr_adv__unsolicited(void) NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); TEST_ASSERT_EQUAL_INT(0, msg_avail()); @@ -752,20 +746,6 @@ int _mock_netif_get(gnrc_netapi_opt_t *opt) } memcpy(opt->data, _loc_l2, sizeof(_loc_l2)); return sizeof(_loc_l2); - case NETOPT_SRC_LEN: { - uint16_t *val = opt->data; - if (opt->data_len != sizeof(uint16_t)) { - return -EOVERFLOW; - } - *val = sizeof(_loc_l2); - return sizeof(uint16_t); - } - case NETOPT_IPV6_IID: - if (opt->data_len < sizeof(_loc_iid)) { - return -EOVERFLOW; - } - memcpy(opt->data, _loc_iid, sizeof(_loc_iid)); - return sizeof(_loc_iid); case NETOPT_IS_WIRED: return 1; case NETOPT_MAX_PACKET_SIZE: { diff --git a/tests/gnrc_ipv6_nib/mockup_netif.c b/tests/gnrc_ipv6_nib/mockup_netif.c index 45f4074ddd4f..fce45710f470 100644 --- a/tests/gnrc_ipv6_nib/mockup_netif.c +++ b/tests/gnrc_ipv6_nib/mockup_netif.c @@ -16,63 +16,73 @@ #include "common.h" #include "msg.h" #include "net/gnrc.h" +#include "net/ethernet.h" #include "net/gnrc/ipv6/nib.h" -#include "net/gnrc/ipv6/netif.h" -#include "net/gnrc/netdev.h" +#include "net/gnrc/netif2/ethernet.h" +#include "net/gnrc/netif2/internal.h" +#include "net/netdev_test.h" #include "sched.h" #include "thread.h" #define _MSG_QUEUE_SIZE (2) -kernel_pid_t _mock_netif_pid = KERNEL_PID_UNDEF; +gnrc_netif2_t *_mock_netif = NULL; +static netdev_test_t _mock_netdev; static char _mock_netif_stack[THREAD_STACKSIZE_DEFAULT]; static gnrc_netreg_entry_t dumper; static msg_t _main_msg_queue[_MSG_QUEUE_SIZE]; -static msg_t _mock_netif_msg_queue[_MSG_QUEUE_SIZE]; -static void *_mock_netif_thread(void *args) +void _common_set_up(void) { - msg_t msg, reply = { .type = GNRC_NETAPI_MSG_TYPE_ACK }; + assert(_mock_netif != NULL); + gnrc_ipv6_nib_init(); + gnrc_netif2_acquire(_mock_netif); + gnrc_ipv6_nib_init_iface(_mock_netif); + gnrc_netif2_release(_mock_netif); +} - (void)args; - msg_init_queue(_mock_netif_msg_queue, _MSG_QUEUE_SIZE); - while (1) { - msg_receive(&msg); - switch (msg.type) { - case GNRC_NETAPI_MSG_TYPE_GET: - reply.content.value = (uint32_t)_mock_netif_get(msg.content.ptr); - break; - case GNRC_NETAPI_MSG_TYPE_SET: - reply.content.value = (uint32_t)(-ENOTSUP); - break; - case GNRC_NETAPI_MSG_TYPE_SND: - case GNRC_NETAPI_MSG_TYPE_RCV: - gnrc_pktbuf_release(msg.content.ptr); - } - msg_reply(&msg, &reply); - } - return NULL; +int _get_device_type(netdev_t *dev, void *value, size_t max_len) +{ + (void)dev; + assert(max_len == sizeof(uint16_t)); + *((uint16_t *)value) = NETDEV_TYPE_ETHERNET; + return sizeof(uint16_t); } -void _common_set_up(void) +int _get_max_packet_size(netdev_t *dev, void *value, size_t max_len) { - gnrc_ipv6_nib_init(); - gnrc_ipv6_nib_init_iface(_mock_netif_pid); + (void)dev; + assert(max_len == sizeof(uint16_t)); + *((uint16_t *)value) = ETHERNET_DATA_LEN; + return sizeof(uint16_t); +} + +int _get_address(netdev_t *dev, void *value, size_t max_len) +{ + static const uint8_t addr[] = { _LL0, _LL1, _LL2, _LL3, _LL4, _LL5 }; + + (void)dev; + assert(max_len >= sizeof(addr)); + memcpy(value, addr, sizeof(addr)); + return sizeof(addr); } void _tests_init(void) { msg_init_queue(_main_msg_queue, _MSG_QUEUE_SIZE); - _mock_netif_pid = thread_create(_mock_netif_stack, - sizeof(_mock_netif_stack), - GNRC_NETDEV_MAC_PRIO, - THREAD_CREATE_STACKTEST, - _mock_netif_thread, NULL, "mock_netif"); - assert(_mock_netif_pid > KERNEL_PID_UNDEF); - gnrc_netif_add(_mock_netif_pid); - gnrc_ipv6_netif_init_by_dev(); - thread_yield(); + netdev_test_setup(&_mock_netdev, 0); + netdev_test_set_get_cb(&_mock_netdev, NETOPT_DEVICE_TYPE, + _get_device_type); + netdev_test_set_get_cb(&_mock_netdev, NETOPT_MAX_PACKET_SIZE, + _get_max_packet_size); + netdev_test_set_get_cb(&_mock_netdev, NETOPT_ADDRESS, + _get_address); + _mock_netif = gnrc_netif2_ethernet_create( + _mock_netif_stack, THREAD_STACKSIZE_DEFAULT, GNRC_NETIF2_PRIO, + "mockup_eth", &_mock_netdev.netdev + ); + assert(_mock_netif != NULL); gnrc_netreg_entry_init_pid(&dumper, GNRC_NETREG_DEMUX_CTX_ALL, sched_active_pid); gnrc_netreg_register(GNRC_NETTYPE_NDP2, &dumper); diff --git a/tests/gnrc_ipv6_nib_6ln/Makefile b/tests/gnrc_ipv6_nib_6ln/Makefile index 779e22bc1be3..2d9b05ee300e 100644 --- a/tests/gnrc_ipv6_nib_6ln/Makefile +++ b/tests/gnrc_ipv6_nib_6ln/Makefile @@ -8,8 +8,10 @@ BOARD_INSUFFICIENT_MEMORY := chronos nucleo-f030 nucleo-l053 nucleo32-f031 \ USEMODULE += gnrc_ipv6 USEMODULE += gnrc_sixlowpan USEMODULE += gnrc_ipv6_nib_6ln +USEMODULE += gnrc_netif2 USEMODULE += embunit -USEMODULE += netopt +USEMODULE += netdev_ieee802154 +USEMODULE += netdev_test CFLAGS += -DDEVELHELP CFLAGS += -DGNRC_NETTYPE_NDP2=GNRC_NETTYPE_TEST diff --git a/tests/gnrc_ipv6_nib_6ln/common.h b/tests/gnrc_ipv6_nib_6ln/common.h index 97720c85b90a..5862bad96397 100644 --- a/tests/gnrc_ipv6_nib_6ln/common.h +++ b/tests/gnrc_ipv6_nib_6ln/common.h @@ -22,14 +22,22 @@ #include #include "net/gnrc.h" +#include "net/gnrc/netif2.h" #ifdef __cplusplus extern "C" { #endif -#define _CALL(fn) _common_set_up(); _set_up(); puts("Calling " # fn); fn() +#define _LL0 (0xce) +#define _LL1 (0xab) +#define _LL2 (0xfe) +#define _LL3 (0xad) +#define _LL4 (0xf7) +#define _LL5 (0x26) +#define _LL6 (0xef) +#define _LL7 (0xa4) -extern kernel_pid_t _mock_netif_pid; +extern gnrc_netif2_t *_mock_netif; void _tests_init(void); int _mock_netif_get(gnrc_netapi_opt_t *opt); diff --git a/tests/gnrc_ipv6_nib_6ln/main.c b/tests/gnrc_ipv6_nib_6ln/main.c index dbf14f86aed1..b9da5942ac95 100644 --- a/tests/gnrc_ipv6_nib_6ln/main.c +++ b/tests/gnrc_ipv6_nib_6ln/main.c @@ -33,14 +33,6 @@ #include "sched.h" #define _BUFFER_SIZE (128) -#define _LL0 (0xce) -#define _LL1 (0xab) -#define _LL2 (0xfe) -#define _LL3 (0xad) -#define _LL4 (0xf7) -#define _LL5 (0x26) -#define _LL6 (0xef) -#define _LL7 (0xa4) static const uint8_t _loc_l2[] = { _LL0, _LL1, _LL2, _LL3, _LL4, _LL5, _LL6, _LL7 }; @@ -79,8 +71,7 @@ static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH(void) gnrc_ipv6_nib_nc_t nce; TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH, - gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll, - KERNEL_PID_UNDEF, + gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll, NULL, NULL, &nce)); TEST_ASSERT_EQUAL_INT(0, msg_avail()); TEST_ASSERT(gnrc_pktbuf_is_empty()); @@ -90,10 +81,10 @@ static void test_get_next_hop_l2addr__link_local_static_conf(void) { gnrc_ipv6_nib_nc_t nce; - TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_nc_set(&_rem_ll, _mock_netif_pid, + TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_nc_set(&_rem_ll, _mock_netif->pid, _rem_l2, sizeof(_rem_l2))); TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll, - _mock_netif_pid, + _mock_netif, NULL, &nce)); TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0), "_rem_ll != nce.ipv6"); @@ -102,7 +93,7 @@ static void test_get_next_hop_l2addr__link_local_static_conf(void) "_rem_l2 != nce.l2addr"); TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED, gnrc_ipv6_nib_nc_get_nud_state(&nce)); - TEST_ASSERT_EQUAL_INT(_mock_netif_pid, gnrc_ipv6_nib_nc_get_iface(&nce)); + TEST_ASSERT_EQUAL_INT(_mock_netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce)); TEST_ASSERT(!gnrc_ipv6_nib_nc_is_router(&nce)); TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_MANUAL, gnrc_ipv6_nib_nc_get_ar_state(&nce)); @@ -115,7 +106,7 @@ static void test_get_next_hop_l2addr__link_local(void) gnrc_ipv6_nib_nc_t nce; TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll, - _mock_netif_pid, + _mock_netif, NULL, &nce)); TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0), "_rem_ll != nce.ipv6"); @@ -124,7 +115,7 @@ static void test_get_next_hop_l2addr__link_local(void) "_rem_l2 != nce.l2addr"); TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE, gnrc_ipv6_nib_nc_get_nud_state(&nce)); - TEST_ASSERT_EQUAL_INT(_mock_netif_pid, gnrc_ipv6_nib_nc_get_iface(&nce)); + TEST_ASSERT_EQUAL_INT(_mock_netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce)); TEST_ASSERT(!gnrc_ipv6_nib_nc_is_router(&nce)); TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED, gnrc_ipv6_nib_nc_get_ar_state(&nce)); @@ -143,7 +134,7 @@ static void test_handle_pkt__unknown_type(void) memcpy(&ipv6->dst, &_rem_ll, sizeof(ipv6->dst)); icmpv6->type = ICMPV6_ECHO_REQ; icmpv6->code = 0; - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, sizeof(icmpv6_hdr_t)); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); @@ -187,7 +178,7 @@ static void test_handle_pkt__nbr_sol__invalid_hl(void) size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_ll, 194U, 0U, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -201,7 +192,7 @@ static void test_handle_pkt__nbr_sol__invalid_code(void) size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_ll, 255U, 201U, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -216,7 +207,7 @@ static void test_handle_pkt__nbr_sol__invalid_icmpv6_len(void) _set_nbr_sol(&_rem_ll, &_loc_ll, 255U, 0U, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, sizeof(ndp_nbr_sol_t) - 1); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); @@ -232,7 +223,7 @@ static void test_handle_pkt__nbr_sol__invalid_tgt(void) &ipv6_addr_all_routers_site_local, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -250,7 +241,7 @@ static void test_handle_pkt__nbr_sol__invalid_opt_len(void) opt->type = NDP_OPT_SL2A; opt->len = 0U; icmpv6_len += sizeof(ndp_opt_t); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -264,7 +255,7 @@ static void test_handle_pkt__nbr_sol__invalid_dst(void) size_t icmpv6_len = _set_nbr_sol(&ipv6_addr_unspecified, &_loc_ll, 255U, 0U, &_loc_ll, NULL, 0); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -279,7 +270,7 @@ static void test_handle_pkt__nbr_sol__invalid_sl2ao(void) 255U, 0U, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -294,7 +285,7 @@ static void test_handle_pkt__nbr_sol__tgt_not_assigned(void) 255U, 0U, &_rem_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -308,12 +299,12 @@ static void test_pkt_is_nbr_adv(gnrc_pktsnip_t *pkt, const ipv6_addr_t *dst, ipv6_hdr_t *ipv6_hdr; ndp_nbr_adv_t *nbr_adv; - /* first snip is a netif header to _mock_netif_pid */ + /* first snip is a netif header to _mock_netif */ TEST_ASSERT_NOT_NULL(pkt); TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_NETIF, pkt->type); TEST_ASSERT(sizeof(gnrc_netif_hdr_t) <= pkt->size); netif_hdr = pkt->data; - TEST_ASSERT_EQUAL_INT(_mock_netif_pid, netif_hdr->if_pid); + TEST_ASSERT_EQUAL_INT(_mock_netif->pid, netif_hdr->if_pid); /* second snip is an IPv6 header to dst */ TEST_ASSERT_NOT_NULL(pkt->next); TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_IPV6, pkt->next->type); @@ -348,7 +339,7 @@ static void test_handle_pkt__nbr_sol__ll_src(unsigned exp_nud_state, 255U, 0U, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(gnrc_ipv6_nib_nc_iter(0, &state, &nce), "Expected neighbor cache entry"); TEST_ASSERT_MESSAGE(ipv6_addr_equal(&_rem_ll, &nce.ipv6), @@ -358,7 +349,7 @@ static void test_handle_pkt__nbr_sol__ll_src(unsigned exp_nud_state, "_rem_l2 != nce.l2addr"); TEST_ASSERT_EQUAL_INT(exp_nud_state, gnrc_ipv6_nib_nc_get_nud_state(&nce)); TEST_ASSERT(!gnrc_ipv6_nib_nc_is_router(&nce)); - TEST_ASSERT_EQUAL_INT(_mock_netif_pid, gnrc_ipv6_nib_nc_get_iface(&nce)); + TEST_ASSERT_EQUAL_INT(_mock_netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce)); TEST_ASSERT_EQUAL_INT(exp_ar_state, gnrc_ipv6_nib_nc_get_ar_state(&nce)); TEST_ASSERT_EQUAL_INT(1, msg_avail()); msg_receive(&msg); @@ -390,7 +381,7 @@ static void test_handle_pkt__nbr_sol__ll_src_no_sl2ao(void) size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_ll, 255U, 0U, &_loc_ll, NULL, 0); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); TEST_ASSERT_EQUAL_INT(1, msg_avail()); @@ -441,7 +432,7 @@ static void test_handle_pkt__nbr_adv__invalid_hl(void) NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -456,7 +447,7 @@ static void test_handle_pkt__nbr_adv__invalid_code(void) NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -472,7 +463,7 @@ static void test_handle_pkt__nbr_adv__invalid_icmpv6_len(void) &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, sizeof(ndp_nbr_adv_t) - 1); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); @@ -489,7 +480,7 @@ static void test_handle_pkt__nbr_adv__invalid_tgt(void) &ipv6_addr_all_routers_site_local, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -504,7 +495,7 @@ static void test_handle_pkt__nbr_adv__invalid_flags(void) 255U, 0U, NDP_NBR_ADV_FLAGS_S, &_loc_ll, NULL, 0); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -523,7 +514,7 @@ static void test_handle_pkt__nbr_adv__invalid_opt_len(void) opt->type = NDP_OPT_SL2A; opt->len = 0U; icmpv6_len += sizeof(ndp_opt_t); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -538,7 +529,7 @@ static void test_handle_pkt__nbr_adv__unspecified_src(void) NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); /* TODO: check other views as well */ @@ -553,7 +544,7 @@ static void test_handle_pkt__nbr_adv__unsolicited(void) NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2, sizeof(_rem_l2)); - gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len); + gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len); TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce), "There is an unexpected neighbor cache entry"); TEST_ASSERT_EQUAL_INT(0, msg_avail()); diff --git a/tests/gnrc_ipv6_nib_6ln/mockup_netif.c b/tests/gnrc_ipv6_nib_6ln/mockup_netif.c index 45f4074ddd4f..faa8435b3a67 100644 --- a/tests/gnrc_ipv6_nib_6ln/mockup_netif.c +++ b/tests/gnrc_ipv6_nib_6ln/mockup_netif.c @@ -16,63 +16,84 @@ #include "common.h" #include "msg.h" #include "net/gnrc.h" +#include "net/ethernet.h" #include "net/gnrc/ipv6/nib.h" -#include "net/gnrc/ipv6/netif.h" -#include "net/gnrc/netdev.h" +#include "net/gnrc/netif2/ieee802154.h" +#include "net/gnrc/netif2/internal.h" +#include "net/netdev_test.h" #include "sched.h" #include "thread.h" #define _MSG_QUEUE_SIZE (2) -kernel_pid_t _mock_netif_pid = KERNEL_PID_UNDEF; +gnrc_netif2_t *_mock_netif = NULL; +static netdev_test_t _mock_netdev; static char _mock_netif_stack[THREAD_STACKSIZE_DEFAULT]; static gnrc_netreg_entry_t dumper; static msg_t _main_msg_queue[_MSG_QUEUE_SIZE]; -static msg_t _mock_netif_msg_queue[_MSG_QUEUE_SIZE]; -static void *_mock_netif_thread(void *args) +void _common_set_up(void) { - msg_t msg, reply = { .type = GNRC_NETAPI_MSG_TYPE_ACK }; + assert(_mock_netif != NULL); + gnrc_ipv6_nib_init(); + gnrc_netif2_acquire(_mock_netif); + gnrc_ipv6_nib_init_iface(_mock_netif); + gnrc_netif2_release(_mock_netif); +} - (void)args; - msg_init_queue(_mock_netif_msg_queue, _MSG_QUEUE_SIZE); - while (1) { - msg_receive(&msg); - switch (msg.type) { - case GNRC_NETAPI_MSG_TYPE_GET: - reply.content.value = (uint32_t)_mock_netif_get(msg.content.ptr); - break; - case GNRC_NETAPI_MSG_TYPE_SET: - reply.content.value = (uint32_t)(-ENOTSUP); - break; - case GNRC_NETAPI_MSG_TYPE_SND: - case GNRC_NETAPI_MSG_TYPE_RCV: - gnrc_pktbuf_release(msg.content.ptr); - } - msg_reply(&msg, &reply); - } - return NULL; +int _get_device_type(netdev_t *dev, void *value, size_t max_len) +{ + (void)dev; + assert(max_len == sizeof(uint16_t)); + *((uint16_t *)value) = NETDEV_TYPE_IEEE802154; + return sizeof(uint16_t); } -void _common_set_up(void) +int _get_max_packet_size(netdev_t *dev, void *value, size_t max_len) { - gnrc_ipv6_nib_init(); - gnrc_ipv6_nib_init_iface(_mock_netif_pid); + (void)dev; + assert(max_len == sizeof(uint16_t)); + *((uint16_t *)value) = 102U; + return sizeof(uint16_t); +} + +int _get_src_len(netdev_t *dev, void *value, size_t max_len) +{ + (void)dev; + assert(max_len == sizeof(uint16_t)); + *((uint16_t *)value) = IEEE802154_LONG_ADDRESS_LEN; + return sizeof(uint16_t); +} + +int _get_address_long(netdev_t *dev, void *value, size_t max_len) +{ + static const uint8_t addr[] = { _LL0, _LL1, _LL2, _LL3, + _LL4, _LL5, _LL6, _LL7 }; + + (void)dev; + assert(max_len >= sizeof(addr)); + memcpy(value, addr, sizeof(addr)); + return sizeof(addr); } void _tests_init(void) { msg_init_queue(_main_msg_queue, _MSG_QUEUE_SIZE); - _mock_netif_pid = thread_create(_mock_netif_stack, - sizeof(_mock_netif_stack), - GNRC_NETDEV_MAC_PRIO, - THREAD_CREATE_STACKTEST, - _mock_netif_thread, NULL, "mock_netif"); - assert(_mock_netif_pid > KERNEL_PID_UNDEF); - gnrc_netif_add(_mock_netif_pid); - gnrc_ipv6_netif_init_by_dev(); - thread_yield(); + netdev_test_setup(&_mock_netdev, 0); + netdev_test_set_get_cb(&_mock_netdev, NETOPT_DEVICE_TYPE, + _get_device_type); + netdev_test_set_get_cb(&_mock_netdev, NETOPT_MAX_PACKET_SIZE, + _get_max_packet_size); + netdev_test_set_get_cb(&_mock_netdev, NETOPT_SRC_LEN, + _get_src_len); + netdev_test_set_get_cb(&_mock_netdev, NETOPT_ADDRESS_LONG, + _get_address_long); + _mock_netif = gnrc_netif2_ieee802154_create( + _mock_netif_stack, THREAD_STACKSIZE_DEFAULT, GNRC_NETIF2_PRIO, + "mockup_wpan", &_mock_netdev.netdev.netdev + ); + assert(_mock_netif != NULL); gnrc_netreg_entry_init_pid(&dumper, GNRC_NETREG_DEMUX_CTX_ALL, sched_active_pid); gnrc_netreg_register(GNRC_NETTYPE_NDP2, &dumper); diff --git a/tests/gnrc_ndp2/Makefile b/tests/gnrc_ndp2/Makefile index 3122a5b958a7..40203bb6a289 100644 --- a/tests/gnrc_ndp2/Makefile +++ b/tests/gnrc_ndp2/Makefile @@ -4,8 +4,11 @@ include ../Makefile.tests_common BOARD_INSUFFICIENT_MEMORY := nucleo32-f031 nucleo32-f042 +USEMODULE += gnrc_ipv6_nib USEMODULE += gnrc_ndp2 +USEMODULE += gnrc_netif2 USEMODULE += embunit +USEMODULE += netdev_test CFLAGS += -DGNRC_NETTYPE_NDP2=GNRC_NETTYPE_TEST CFLAGS += -DGNRC_PKTBUF_SIZE=512 diff --git a/tests/gnrc_ndp2/main.c b/tests/gnrc_ndp2/main.c index 2a4f7bccb96c..fe46bab5bcf4 100644 --- a/tests/gnrc_ndp2/main.c +++ b/tests/gnrc_ndp2/main.c @@ -25,12 +25,15 @@ #include "embUnit.h" #include "embUnit/embUnit.h" #include "msg.h" +#include "net/gnrc/ipv6/nib/conf.h" #include "net/gnrc/netapi.h" -#include "net/gnrc/netdev.h" +#include "net/gnrc/netif/hdr.h" +#include "net/gnrc/netif2/internal.h" #include "net/gnrc/netreg.h" #include "net/gnrc/pktbuf.h" #include "net/icmpv6.h" #include "net/ndp.h" +#include "net/netdev_test.h" #include "net/netopt.h" #include "sched.h" @@ -63,7 +66,7 @@ static const ipv6_addr_t test_pfx = { { 0x47, 0x25, 0xd9, 0x3b, 0x7f, 0xcc, 0x15 0x64, 0x3e, 0x76, 0x0d, 0x30, 0x10, 0x0d, 0xc8 } }; static const uint8_t test_src_l2[] = { 0xe7, 0x43, 0xb7, 0x74, 0xd7, 0xa9, 0x30, 0x74 }; -static kernel_pid_t test_iface = KERNEL_PID_UNDEF; +static gnrc_netif2_t *test_netif = NULL; static void init_pkt_handler(void); static inline size_t ceil8(size_t size); @@ -405,11 +408,11 @@ static inline ipv6_addr_t *_get_ipv6_dst(ipv6_hdr_t *hdr) return &hdr->dst; } -#define ASSERT_NETIF_HDR(iface, pkt) \ +#define ASSERT_NETIF_HDR(netif, pkt) \ TEST_ASSERT_NOT_NULL(pkt); \ TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_NETIF, pkt->type); \ TEST_ASSERT_NOT_NULL(pkt->data); \ - TEST_ASSERT_EQUAL_INT(iface, _get_iface(pkt->data)) + TEST_ASSERT_EQUAL_INT(netif->pid, _get_iface(pkt->data)) #define ASSERT_IPV6_HDR(src, dst, pkt) \ TEST_ASSERT_NOT_NULL(pkt); \ @@ -428,7 +431,6 @@ static inline ipv6_addr_t *_get_ipv6_dst(ipv6_hdr_t *hdr) static void test_nbr_sol_send(const ipv6_addr_t *src) { msg_t msg; - gnrc_ipv6_netif_t *test_netif = gnrc_ipv6_netif_get(test_iface); gnrc_pktsnip_t *pkt; ndp_nbr_sol_t *nbr_sol; @@ -438,7 +440,7 @@ static void test_nbr_sol_send(const ipv6_addr_t *src) TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type); pkt = msg.content.ptr; /* check packet */ - ASSERT_NETIF_HDR(test_iface, pkt); + ASSERT_NETIF_HDR(test_netif, pkt); if ((src != NULL) && ipv6_addr_is_unspecified(src)) { ASSERT_IPV6_HDR(&ipv6_addr_unspecified, &test_dst, pkt->next); } @@ -488,7 +490,6 @@ static void test_nbr_adv_send(const ipv6_addr_t *tgt, const ipv6_addr_t *dst, bool supply_tl2a, gnrc_pktsnip_t *exp_ext_opts) { msg_t msg; - gnrc_ipv6_netif_t *test_netif = gnrc_ipv6_netif_get(test_iface); gnrc_pktsnip_t *pkt; ndp_nbr_adv_t *nbr_adv; @@ -498,7 +499,7 @@ static void test_nbr_adv_send(const ipv6_addr_t *tgt, const ipv6_addr_t *dst, TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type); pkt = msg.content.ptr; /* check packet */ - ASSERT_NETIF_HDR(test_iface, pkt); + ASSERT_NETIF_HDR(test_netif, pkt); if (ipv6_addr_is_unspecified(dst)) { ASSERT_IPV6_HDR(&ipv6_addr_unspecified, &ipv6_addr_all_nodes_link_local, pkt->next); @@ -548,46 +549,46 @@ static void test_nbr_adv_send(const ipv6_addr_t *tgt, const ipv6_addr_t *dst, static void test_nbr_adv_send__foreign_tgt_unspecified_dst_no_supply_tl2a_no_ext_opts(void) { - test_nbr_adv_send(&test_tgt, &ipv6_addr_unspecified, false, NULL); + test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, false, NULL); } static void test_nbr_adv_send__foreign_tgt_unspecified_dst_no_supply_tl2a_ext_opts(void) { gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF); - test_nbr_adv_send(&test_tgt, &ipv6_addr_unspecified, false, ext_opts); + test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, false, ext_opts); } static void test_nbr_adv_send__foreign_tgt_unspecified_dst_supply_tl2a_no_ext_opts(void) { - test_nbr_adv_send(&test_tgt, &ipv6_addr_unspecified, true, NULL); + test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, true, NULL); } static void test_nbr_adv_send__foreign_tgt_unspecified_dst_supply_tl2a_ext_opts(void) { gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF); - test_nbr_adv_send(&test_tgt, &ipv6_addr_unspecified, true, ext_opts); + test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, true, ext_opts); } static void test_nbr_adv_send__foreign_tgt_specified_dst_no_supply_tl2a_no_ext_opts(void) { - test_nbr_adv_send(&test_tgt, &test_dst, false, NULL); + test_nbr_adv_send(&test_src, &test_dst, false, NULL); } static void test_nbr_adv_send__foreign_tgt_specified_dst_no_supply_tl2a_ext_opts(void) { gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF); - test_nbr_adv_send(&test_tgt, &test_dst, false, ext_opts); + test_nbr_adv_send(&test_src, &test_dst, false, ext_opts); } static void test_nbr_adv_send__foreign_tgt_specified_dst_supply_tl2a_no_ext_opts(void) { - test_nbr_adv_send(&test_tgt, &test_dst, true, NULL); + test_nbr_adv_send(&test_src, &test_dst, true, NULL); } static void test_nbr_adv_send__foreign_tgt_specified_dst_supply_tl2a_ext_opts(void) { gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF); - test_nbr_adv_send(&test_tgt, &test_dst, true, ext_opts); + test_nbr_adv_send(&test_src, &test_dst, true, ext_opts); } static void test_nbr_adv_send__src_tgt_unspecified_dst_no_supply_tl2a_no_ext_opts(void) @@ -637,7 +638,6 @@ static void test_nbr_adv_send__src_tgt_specified_dst_supply_tl2a_ext_opts(void) static void test_rtr_sol_send(const ipv6_addr_t *dst) { msg_t msg; - gnrc_ipv6_netif_t *test_netif = gnrc_ipv6_netif_get(test_iface); gnrc_pktsnip_t *pkt; ndp_rtr_sol_t *rtr_sol; @@ -647,7 +647,7 @@ static void test_rtr_sol_send(const ipv6_addr_t *dst) TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type); pkt = msg.content.ptr; /* check packet */ - ASSERT_NETIF_HDR(test_iface, pkt); + ASSERT_NETIF_HDR(test_netif, pkt); if (dst != NULL) { ASSERT_IPV6_HDR(&test_src, dst, pkt->next); } @@ -701,7 +701,6 @@ static void test_rtr_adv_send(const ipv6_addr_t *src, const ipv6_addr_t *dst, bool fin, gnrc_pktsnip_t *exp_ext_opts) { msg_t msg; - gnrc_ipv6_netif_t *test_netif = gnrc_ipv6_netif_get(test_iface); gnrc_pktsnip_t *pkt; ndp_rtr_adv_t *rtr_adv; @@ -711,7 +710,7 @@ static void test_rtr_adv_send(const ipv6_addr_t *src, const ipv6_addr_t *dst, TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type); pkt = msg.content.ptr; /* check packet */ - ASSERT_NETIF_HDR(test_iface, pkt); + ASSERT_NETIF_HDR(test_netif, pkt); /* testing for unspecified source is complicated so we skip it here and * do it in later integration tests */ if (dst != NULL) { @@ -930,11 +929,25 @@ int main(void) static char test_netif_stack[THREAD_STACKSIZE_DEFAULT]; static msg_t msg_queue_main[MSG_QUEUE_SIZE]; -static msg_t msg_queue_netif[MSG_QUEUE_SIZE]; static gnrc_netreg_entry_t netreg_entry; +static netdev_test_t dev; + +static int _test_netif_send(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt) +{ + (void)netif; + gnrc_pktbuf_release(pkt); + return 0; +} + +static gnrc_pktsnip_t *_test_netif_recv(gnrc_netif2_t *netif) +{ + (void)netif; + return NULL; +} -int test_iface_get(gnrc_netapi_opt_t *opt) +static int _test_netif_get(gnrc_netif2_t *netif, gnrc_netapi_opt_t *opt) { + (void)netif; switch (opt->opt) { case NETOPT_ADDRESS_LONG: if (opt->data_len < sizeof(test_src_l2)) { @@ -971,44 +984,37 @@ int test_iface_get(gnrc_netapi_opt_t *opt) } } -static void *test_iface_thread(void *args) -{ - msg_t msg, reply = { .type = GNRC_NETAPI_MSG_TYPE_ACK }; - - (void)args; - msg_init_queue(msg_queue_netif, MSG_QUEUE_SIZE); - while (1) { - msg_receive(&msg); - switch (msg.type) { - case GNRC_NETAPI_MSG_TYPE_SND: - case GNRC_NETAPI_MSG_TYPE_RCV: - gnrc_pktbuf_release(msg.content.ptr); - continue; - case GNRC_NETAPI_MSG_TYPE_GET: - reply.content.value = (uint32_t)test_iface_get(msg.content.ptr); - break; - case GNRC_NETAPI_MSG_TYPE_SET: - reply.content.value = (uint32_t)(-ENOTSUP); - break; - } - msg_reply(&msg, &reply); - } - return NULL; +static int _test_netif_set(gnrc_netif2_t *netif, const gnrc_netapi_opt_t *opt) +{ + (void)netif; + (void)opt; + return -ENOTSUP; } +static const gnrc_netif2_ops_t _test_netif_ops = { + .send = _test_netif_send, + .recv = _test_netif_recv, + .get = _test_netif_get, + .set = _test_netif_set, +}; + static void init_pkt_handler(void) { msg_init_queue(msg_queue_main, MSG_QUEUE_SIZE); gnrc_netreg_entry_init_pid(&netreg_entry, GNRC_NETREG_DEMUX_CTX_ALL, sched_active_pid); gnrc_netreg_register(GNRC_NETTYPE_NDP2, &netreg_entry); - test_iface = thread_create(test_netif_stack, sizeof(test_netif_stack), - GNRC_NETDEV_MAC_PRIO, THREAD_CREATE_STACKTEST, - test_iface_thread, NULL, "test-iface"); - TEST_ASSERT_MESSAGE(test_iface > KERNEL_PID_UNDEF, + netdev_test_setup(&dev, NULL); + test_netif = gnrc_netif2_create(test_netif_stack, sizeof(test_netif_stack), + GNRC_NETIF2_PRIO, "test-netif", + &dev.netdev, &_test_netif_ops); + TEST_ASSERT_MESSAGE(test_netif != NULL, "Unable to start test interface"); - gnrc_netif_add(test_iface); - gnrc_ipv6_netif_init_by_dev(); + memcpy(&test_netif->ipv6.addrs[0], &test_src, + sizeof(test_netif->ipv6.addrs[0])); + test_netif->ipv6.addrs_flags[0] = GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID; + memcpy(test_netif->l2addr, test_src_l2, sizeof(test_netif->l2addr)); + test_netif->l2addr_len = sizeof(test_src_l2); } static inline size_t ceil8(size_t size) diff --git a/tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-internal.c b/tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-internal.c index eaa328db553d..72ebd5334a6a 100644 --- a/tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-internal.c +++ b/tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-internal.c @@ -1910,33 +1910,6 @@ static void test_nib_abr_iter__three_elem_middle_removed(void) } #endif -/* - * Creates GNRC_NETIF_NUMOF interfaces and then tries to add another. - * Expected result: should return NULL - */ -static void test_nib_iface_get__no_space_left(void) -{ - unsigned iface = 1; - - for (int i = 0; i < GNRC_NETIF_NUMOF; i++) { - TEST_ASSERT_NOT_NULL(_nib_iface_get(iface++)); - } - TEST_ASSERT_NULL(_nib_iface_get(iface)); -} - -/* - * Creates an interface and then gets the same interface. - * Expected result: interface pointers should equal - */ -static void test_nib_iface_get__success(void) -{ - _nib_iface_t *ni1, *ni2; - - TEST_ASSERT_NOT_NULL((ni1 = _nib_iface_get(IFACE))); - TEST_ASSERT_NOT_NULL((ni2 = _nib_iface_get(IFACE))); - TEST_ASSERT(ni1 == ni2); -} - Test *tests_gnrc_ipv6_nib_internal_tests(void) { EMB_UNIT_TESTFIXTURES(fixtures) { @@ -2035,8 +2008,6 @@ Test *tests_gnrc_ipv6_nib_internal_tests(void) new_TestFixture(test_nib_abr_iter__three_elem), new_TestFixture(test_nib_abr_iter__three_elem_middle_removed), #endif - new_TestFixture(test_nib_iface_get__no_space_left), - new_TestFixture(test_nib_iface_get__success), }; EMB_UNIT_TESTCALLER(tests, set_up, NULL, diff --git a/tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-nc.c b/tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-nc.c index c014c9e0076a..37b68c2aa4f6 100644 --- a/tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-nc.c +++ b/tests/unittests/tests-gnrc_ipv6_nib/tests-gnrc_ipv6_nib-nc.c @@ -276,20 +276,12 @@ static void test_nib_nc_mark_reachable__unmanaged(void) static void test_nib_nc_mark_reachable__success(void) { void *iter_state = NULL; - _nib_onl_entry_t *node; -#if GNRC_IPV6_NIB_CONF_ARSM - evtimer_msg_event_t *event; -#endif - _nib_iface_t *iface; static const ipv6_addr_t addr = { .u64 = { { .u8 = GLOBAL_PREFIX }, { .u64 = TEST_UINT64 } } }; gnrc_ipv6_nib_nc_t nce; - TEST_ASSERT_NOT_NULL((node = _nib_nc_add(&addr, IFACE, - GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE))); - /* set an "infinite" reachability time */ - iface = _nib_iface_get(_nib_onl_get_if(node)); - iface->reach_time = UINT32_MAX; + TEST_ASSERT_NOT_NULL(_nib_nc_add(&addr, IFACE, + GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE)); /* check pre-state */ TEST_ASSERT(gnrc_ipv6_nib_nc_iter(0, &iter_state, &nce)); @@ -306,11 +298,6 @@ static void test_nib_nc_mark_reachable__success(void) /* check if entry is reachable */ TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE, gnrc_ipv6_nib_nc_get_nud_state(&nce)); - /* check if there now is an event for reachability timeout of node */ - TEST_ASSERT_NOT_NULL((event = (evtimer_msg_event_t *)_nib_evtimer.events)); - TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_REACH_TIMEOUT, event->msg.type); - TEST_ASSERT_MESSAGE(node == event->msg.content.ptr, - "event's context is not node"); #endif /* check if still the only entry */ TEST_ASSERT(!gnrc_ipv6_nib_nc_iter(0, &iter_state, &nce));