Merge pull request #7456 from miri64/gnrc_ipv6_nib/feat/port-to-gnrc_netif2
gnrc_ipv6_nib: port to gnrc_netif2
This commit is contained in:
commit
b83bc1b763
58
Makefile.dep
58
Makefile.dep
@ -136,29 +136,30 @@ endif
|
|||||||
|
|
||||||
ifneq (,$(filter gnrc_sixlowpan_default,$(USEMODULE)))
|
ifneq (,$(filter gnrc_sixlowpan_default,$(USEMODULE)))
|
||||||
USEMODULE += gnrc_ipv6_default
|
USEMODULE += gnrc_ipv6_default
|
||||||
|
USEMODULE += gnrc_ipv6_nib_6ln
|
||||||
USEMODULE += gnrc_sixlowpan
|
USEMODULE += gnrc_sixlowpan
|
||||||
USEMODULE += gnrc_sixlowpan_nd
|
|
||||||
USEMODULE += gnrc_sixlowpan_frag
|
USEMODULE += gnrc_sixlowpan_frag
|
||||||
USEMODULE += gnrc_sixlowpan_iphc
|
USEMODULE += gnrc_sixlowpan_iphc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter gnrc_sixlowpan_router_default,$(USEMODULE)))
|
ifneq (,$(filter gnrc_sixlowpan_router_default,$(USEMODULE)))
|
||||||
USEMODULE += gnrc_ipv6_router_default
|
USEMODULE += gnrc_ipv6_router_default
|
||||||
|
USEMODULE += gnrc_ipv6_nib_6lr
|
||||||
USEMODULE += gnrc_sixlowpan_router
|
USEMODULE += gnrc_sixlowpan_router
|
||||||
USEMODULE += gnrc_sixlowpan_frag
|
USEMODULE += gnrc_sixlowpan_frag
|
||||||
USEMODULE += gnrc_sixlowpan_iphc
|
USEMODULE += gnrc_sixlowpan_iphc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter gnrc_sixlowpan_border_router_default,$(USEMODULE)))
|
ifneq (,$(filter gnrc_sixlowpan_border_router_default,$(USEMODULE)))
|
||||||
|
USEMODULE += gnrc_ipv6_nib_6lbr
|
||||||
USEMODULE += gnrc_ipv6_router_default
|
USEMODULE += gnrc_ipv6_router_default
|
||||||
USEMODULE += gnrc_sixlowpan_nd_border_router
|
|
||||||
USEMODULE += gnrc_sixlowpan_router
|
USEMODULE += gnrc_sixlowpan_router
|
||||||
USEMODULE += gnrc_sixlowpan_frag
|
USEMODULE += gnrc_sixlowpan_frag
|
||||||
USEMODULE += gnrc_sixlowpan_iphc
|
USEMODULE += gnrc_sixlowpan_iphc
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter gnrc_sixlowpan_router,$(USEMODULE)))
|
ifneq (,$(filter gnrc_sixlowpan_router,$(USEMODULE)))
|
||||||
USEMODULE += gnrc_sixlowpan_nd_router
|
USEMODULE += gnrc_ipv6_router
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter gnrc_sixlowpan_frag,$(USEMODULE)))
|
ifneq (,$(filter gnrc_sixlowpan_frag,$(USEMODULE)))
|
||||||
@ -182,50 +183,14 @@ ifneq (,$(filter gnrc_sixlowpan_ctx,$(USEMODULE)))
|
|||||||
USEMODULE += xtimer
|
USEMODULE += xtimer
|
||||||
endif
|
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)))
|
ifneq (,$(filter gnrc_ipv6_default,$(USEMODULE)))
|
||||||
USEMODULE += gnrc_ipv6
|
USEMODULE += gnrc_ipv6
|
||||||
USEMODULE += gnrc_icmpv6
|
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
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter gnrc_ipv6_router_default,$(USEMODULE)))
|
ifneq (,$(filter gnrc_ipv6_router_default,$(USEMODULE)))
|
||||||
USEMODULE += gnrc_ipv6_router
|
USEMODULE += gnrc_ipv6_router
|
||||||
USEMODULE += gnrc_icmpv6
|
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
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter gnrc_ndp_router,$(USEMODULE)))
|
ifneq (,$(filter gnrc_ndp_router,$(USEMODULE)))
|
||||||
@ -242,20 +207,9 @@ ifneq (,$(filter gnrc_ndp_%,$(USEMODULE)))
|
|||||||
USEMODULE += gnrc_ndp
|
USEMODULE += gnrc_ndp
|
||||||
endif
|
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)))
|
ifneq (,$(filter gnrc_ndp2,$(USEMODULE)))
|
||||||
USEMODULE += gnrc_icmpv6
|
USEMODULE += gnrc_icmpv6
|
||||||
|
USEMODULE += gnrc_netif2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter gnrc_icmpv6_echo,$(USEMODULE)))
|
ifneq (,$(filter gnrc_icmpv6_echo,$(USEMODULE)))
|
||||||
@ -301,7 +255,7 @@ ifneq (,$(filter gnrc_ipv6,$(USEMODULE)))
|
|||||||
USEMODULE += inet_csum
|
USEMODULE += inet_csum
|
||||||
USEMODULE += ipv6_addr
|
USEMODULE += ipv6_addr
|
||||||
USEMODULE += gnrc_ipv6_hdr
|
USEMODULE += gnrc_ipv6_hdr
|
||||||
USEMODULE += gnrc_ipv6_nc
|
USEMODULE += gnrc_ipv6_nib
|
||||||
USEMODULE += gnrc_netif2
|
USEMODULE += gnrc_netif2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|||||||
@ -36,9 +36,7 @@
|
|||||||
#include "net/ipv6.h"
|
#include "net/ipv6.h"
|
||||||
#include "net/gnrc/ipv6/ext.h"
|
#include "net/gnrc/ipv6/ext.h"
|
||||||
#include "net/gnrc/ipv6/hdr.h"
|
#include "net/gnrc/ipv6/hdr.h"
|
||||||
#ifndef MODULE_GNRC_IPV6_NIB
|
#include "net/gnrc/ipv6/nib.h"
|
||||||
#include "net/gnrc/ipv6/nc.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MODULE_FIB
|
#ifdef MODULE_FIB
|
||||||
#include "net/fib.h"
|
#include "net/fib.h"
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
#include "net/ipv6/addr.h"
|
#include "net/ipv6/addr.h"
|
||||||
#include "net/ipv6/hdr.h"
|
#include "net/ipv6/hdr.h"
|
||||||
#include "net/gnrc/ipv6/nib/nc.h"
|
#include "net/gnrc/ipv6/nib/nc.h"
|
||||||
|
#include "net/gnrc/netif2.h"
|
||||||
#include "net/gnrc/pkt.h"
|
#include "net/gnrc/pkt.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -194,13 +195,67 @@ extern "C" {
|
|||||||
* @brief Recalculate reachability timeout time.
|
* @brief Recalculate reachability timeout time.
|
||||||
*
|
*
|
||||||
* This message type is for the event of recalculating the reachability timeout
|
* 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
|
* @note Only handled with @ref GNRC_IPV6_NIB_CONF_ARSM != 0
|
||||||
*/
|
*/
|
||||||
#define GNRC_IPV6_NIB_RECALC_REACH_TIME (0x4fceU)
|
#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
|
* @brief Initialize NIB
|
||||||
*/
|
*/
|
||||||
@ -209,11 +264,11 @@ void gnrc_ipv6_nib_init(void);
|
|||||||
/**
|
/**
|
||||||
* @brief Adds an interface to be managed by the NIB.
|
* @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
|
* @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)`
|
* @pre `(dst != NULL) && (nce != NULL)`
|
||||||
*
|
*
|
||||||
* @param[in] dst Destination address of a packet.
|
* @param[in] dst Destination address of a packet.
|
||||||
* @param[in] iface Restrict search to this interface. May be
|
* @param[in] netif Restrict search to this interface. May be `NULL` for any
|
||||||
* `KERNEL_PID_UNDEF` for any interface.
|
* interface.
|
||||||
* @param[in] pkt The IPv6 packet in sending order for which the next hop
|
* @param[in] pkt The IPv6 packet in sending order for which the next hop
|
||||||
* is searched. Needed for queuing for with reactive
|
* is searched. Needed for queuing for with reactive
|
||||||
* routing or address resolution. May be `NULL`.
|
* routing or address resolution. May be `NULL`.
|
||||||
@ -237,13 +292,13 @@ void gnrc_ipv6_nib_init_iface(kernel_pid_t iface);
|
|||||||
* solicitation sent).
|
* solicitation sent).
|
||||||
*/
|
*/
|
||||||
int gnrc_ipv6_nib_get_next_hop_l2addr(const ipv6_addr_t *dst,
|
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);
|
gnrc_ipv6_nib_nc_t *nce);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handles a received ICMPv6 packet
|
* @brief Handles a received ICMPv6 packet
|
||||||
*
|
*
|
||||||
* @pre `iface != KERNEL_PID_UNDEF`
|
* @pre `netif != NULL`
|
||||||
* @pre `ipv6 != NULL`
|
* @pre `ipv6 != NULL`
|
||||||
* @pre `icmpv6 != NULL`
|
* @pre `icmpv6 != NULL`
|
||||||
* @pre `icmpv6_len > sizeof(icmpv6_hdr_t)`
|
* @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.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)
|
* @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] ipv6 The IPv6 header of the received packet.
|
||||||
* @param[in] icmpv6 The ICMPv6 header and payload of the received
|
* @param[in] icmpv6 The ICMPv6 header and payload of the received
|
||||||
* packet.
|
* packet.
|
||||||
* @param[in] icmpv6_len The number of bytes at @p icmpv6.
|
* @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);
|
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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -199,10 +199,8 @@ extern "C" {
|
|||||||
/**
|
/**
|
||||||
* @brief Maximum link-layer address length (aligned)
|
* @brief Maximum link-layer address length (aligned)
|
||||||
*/
|
*/
|
||||||
#if (GNRC_NETIF_HDR_L2ADDR_MAX_LEN % 8)
|
#ifndef GNRC_IPV6_NIB_L2ADDR_MAX_LEN
|
||||||
#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (((GNRC_NETIF_HDR_L2ADDR_MAX_LEN >> 3) + 1) << 3)
|
#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (8U)
|
||||||
#else
|
|
||||||
#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (GNRC_NETIF_HDR_L2ADDR_MAX_LEN)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -24,8 +24,9 @@
|
|||||||
|
|
||||||
#include "kernel_types.h"
|
#include "kernel_types.h"
|
||||||
#include "net/gnrc/pkt.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/addr.h"
|
||||||
|
#include "net/ipv6/hdr.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
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.
|
* for a neighbor solicitation so be sure to check that.
|
||||||
* **Will be released** in an error case.
|
* **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,
|
const ipv6_addr_t *src, const ipv6_addr_t *dst,
|
||||||
gnrc_pktsnip_t *ext_opts);
|
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.
|
* check that.
|
||||||
* **Will be released** in an error case.
|
* **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,
|
const ipv6_addr_t *dst, bool supply_tl2a,
|
||||||
gnrc_pktsnip_t *ext_opts);
|
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] netif Interface to send over. May not be NULL.
|
||||||
* @param[in] dst Destination for the router solicitation. ff02::2 if 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
|
* @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.
|
* for a neighbor advertisement so be sure to check that.
|
||||||
* **Will be released** in an error case.
|
* **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,
|
const ipv6_addr_t *dst, bool fin,
|
||||||
gnrc_pktsnip_t *ext_opts);
|
gnrc_pktsnip_t *ext_opts);
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "net/ieee802154.h"
|
#include "net/ieee802154.h"
|
||||||
#include "net/ethernet/hdr.h"
|
#include "net/ethernet/hdr.h"
|
||||||
|
#include "net/gnrc/ipv6/nib/conf.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -60,7 +61,7 @@ extern "C" {
|
|||||||
*
|
*
|
||||||
* @note Used for calculation of @ref GNRC_NETIF2_IPV6_GROUPS_NUMOF
|
* @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)
|
#define GNRC_NETIF2_IPV6_RTR_ADDR (1)
|
||||||
#else
|
#else
|
||||||
#define GNRC_NETIF2_IPV6_RTR_ADDR (0)
|
#define GNRC_NETIF2_IPV6_RTR_ADDR (0)
|
||||||
@ -109,7 +110,7 @@ extern "C" {
|
|||||||
#elif MODULE_CC110X
|
#elif MODULE_CC110X
|
||||||
#define GNRC_NETIF2_L2ADDR_MAXLEN (1U)
|
#define GNRC_NETIF2_L2ADDR_MAXLEN (1U)
|
||||||
#else
|
#else
|
||||||
#define GNRC_NETIF2_L2ADDR_MAXLEN (8U)
|
#define GNRC_NETIF2_L2ADDR_MAXLEN (GNRC_IPV6_NIB_L2ADDR_MAX_LEN)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -115,9 +115,8 @@ typedef struct {
|
|||||||
* The callback may be `NULL` if no such behavior is required by the routing
|
* The callback may be `NULL` if no such behavior is required by the routing
|
||||||
* protocol (or no routing protocol is present).
|
* protocol (or no routing protocol is present).
|
||||||
*
|
*
|
||||||
* @todo Define types (RRQ, RRN, NSC) in NIB
|
* @param[in] type [Type](@ref net_gnrc_ipv6_nib_route_info_type) of
|
||||||
*
|
* the route info.
|
||||||
* @param[in] type Type of the route info.
|
|
||||||
* @param[in] ctx_addr Context address of the route info.
|
* @param[in] ctx_addr Context address of the route info.
|
||||||
* @param[in] ctx Further context of the route info.
|
* @param[in] ctx Further context of the route info.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -19,6 +19,9 @@
|
|||||||
#include "net/ethernet.h"
|
#include "net/ethernet.h"
|
||||||
#include "net/ipv6.h"
|
#include "net/ipv6.h"
|
||||||
#include "net/gnrc.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
|
#ifdef MODULE_NETSTATS_IPV6
|
||||||
#include "net/netstats.h"
|
#include "net/netstats.h"
|
||||||
#endif
|
#endif
|
||||||
@ -278,7 +281,7 @@ int gnrc_netif2_set_from_netdev(gnrc_netif2_t *netif,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (gnrc_netif2_is_rtr_adv(netif)) {
|
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;
|
netif->flags &= ~GNRC_NETIF2_FLAGS_IPV6_FORWARDING;
|
||||||
}
|
}
|
||||||
@ -286,12 +289,8 @@ int gnrc_netif2_set_from_netdev(gnrc_netif2_t *netif,
|
|||||||
break;
|
break;
|
||||||
case NETOPT_IPV6_SND_RTR_ADV:
|
case NETOPT_IPV6_SND_RTR_ADV:
|
||||||
assert(opt->data_len == sizeof(netopt_enable_t));
|
assert(opt->data_len == sizeof(netopt_enable_t));
|
||||||
if (*(((netopt_enable_t *)opt->data)) == NETOPT_ENABLE) {
|
gnrc_ipv6_nib_change_rtr_adv_iface(netif,
|
||||||
gnrc_ipv6_nib_iface_start_rtr_adv(netif);
|
(*(((netopt_enable_t *)opt->data)) == NETOPT_ENABLE));
|
||||||
}
|
|
||||||
else {
|
|
||||||
gnrc_ipv6_nib_iface_cease_rtr_adv(netif);
|
|
||||||
}
|
|
||||||
res = sizeof(netopt_enable_t);
|
res = sizeof(netopt_enable_t);
|
||||||
break;
|
break;
|
||||||
#endif /* GNRC_IPV6_NIB_CONF_ROUTER */
|
#endif /* GNRC_IPV6_NIB_CONF_ROUTER */
|
||||||
|
|||||||
@ -23,11 +23,7 @@
|
|||||||
#include "kernel_types.h"
|
#include "kernel_types.h"
|
||||||
#include "net/ipv6/hdr.h"
|
#include "net/ipv6/hdr.h"
|
||||||
#include "net/gnrc.h"
|
#include "net/gnrc.h"
|
||||||
#ifndef MODULE_GNRC_IPV6_NIB
|
|
||||||
#include "net/gnrc/ndp.h"
|
|
||||||
#else
|
|
||||||
#include "net/gnrc/ipv6/nib.h"
|
#include "net/gnrc/ipv6/nib.h"
|
||||||
#endif
|
|
||||||
#include "net/protnum.h"
|
#include "net/protnum.h"
|
||||||
#include "od.h"
|
#include "od.h"
|
||||||
#include "utlist.h"
|
#include "utlist.h"
|
||||||
@ -98,40 +94,6 @@ void gnrc_icmpv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#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_SOL:
|
||||||
case ICMPV6_RTR_ADV:
|
case ICMPV6_RTR_ADV:
|
||||||
case ICMPV6_NBR_SOL:
|
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_DAR:
|
||||||
case ICMPV6_DAC:
|
case ICMPV6_DAC:
|
||||||
DEBUG("icmpv6: NDP message received. Handle with gnrc_ipv6_nib\n");
|
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;
|
break;
|
||||||
#endif /* MODULE_GNRC_IPV6_NIB */
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DEBUG("icmpv6: unknown type field %u\n", hdr->type);
|
DEBUG("icmpv6: unknown type field %u\n", hdr->type);
|
||||||
|
|||||||
@ -29,11 +29,7 @@
|
|||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "utlist.h"
|
#include "utlist.h"
|
||||||
|
|
||||||
#ifndef MODULE_GNRC_IPV6_NIB
|
|
||||||
#include "net/gnrc/ipv6/nc.h"
|
|
||||||
#else
|
|
||||||
#include "net/gnrc/ipv6/nib.h"
|
#include "net/gnrc/ipv6/nib.h"
|
||||||
#endif
|
|
||||||
#include "net/gnrc/netif2/internal.h"
|
#include "net/gnrc/netif2/internal.h"
|
||||||
#include "net/gnrc/ipv6/whitelist.h"
|
#include "net/gnrc/ipv6/whitelist.h"
|
||||||
#include "net/gnrc/ipv6/blacklist.h"
|
#include "net/gnrc/ipv6/blacklist.h"
|
||||||
@ -290,83 +286,6 @@ static void *_event_loop(void *args)
|
|||||||
msg_reply(&msg, &reply);
|
msg_reply(&msg, &reply);
|
||||||
break;
|
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_UC_NS:
|
||||||
case GNRC_IPV6_NIB_SND_MC_NS:
|
case GNRC_IPV6_NIB_SND_MC_NS:
|
||||||
case GNRC_IPV6_NIB_SND_NA:
|
case GNRC_IPV6_NIB_SND_NA:
|
||||||
@ -385,7 +304,6 @@ static void *_event_loop(void *args)
|
|||||||
DEBUG("ipv6: NIB timer event received\n");
|
DEBUG("ipv6: NIB timer event received\n");
|
||||||
gnrc_ipv6_nib_handle_timer_event(msg.content.ptr, msg.type);
|
gnrc_ipv6_nib_handle_timer_event(msg.content.ptr, msg.type);
|
||||||
break;
|
break;
|
||||||
#endif /* MODULE_GNRC_IPV6_NIB */
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -646,38 +564,6 @@ static void _send_multicast(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt,
|
|||||||
#endif /* GNRC_NETIF_NUMOF */
|
#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)
|
static void _send(gnrc_pktsnip_t *pkt, bool prep_hdr)
|
||||||
{
|
{
|
||||||
kernel_pid_t iface = KERNEL_PID_UNDEF;
|
kernel_pid_t iface = KERNEL_PID_UNDEF;
|
||||||
@ -771,32 +657,10 @@ static void _send(gnrc_pktsnip_t *pkt, bool prep_hdr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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_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) {
|
&nce) < 0) {
|
||||||
/* packet is released by NIB */
|
/* packet is released by NIB */
|
||||||
return;
|
return;
|
||||||
@ -814,7 +678,6 @@ static void _send(gnrc_pktsnip_t *pkt, bool prep_hdr)
|
|||||||
|
|
||||||
_send_unicast(netif, nce.l2addr,
|
_send_unicast(netif, nce.l2addr,
|
||||||
nce.l2addr_len, pkt);
|
nce.l2addr_len, pkt);
|
||||||
#endif /* MODULE_GNRC_IPV6_NIB */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
#include "net/eui64.h"
|
#include "net/eui64.h"
|
||||||
#include "net/ipv6/addr.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/ndp.h"
|
||||||
#include "net/gnrc/netapi.h"
|
#include "net/gnrc/netapi.h"
|
||||||
#include "net/gnrc/netif.h"
|
#include "net/gnrc/netif.h"
|
||||||
@ -176,11 +173,9 @@ static void _ipv6_netif_remove(gnrc_ipv6_netif_t *entry)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MODULE_GNRC_IPV6_NIB
|
|
||||||
#ifdef MODULE_GNRC_NDP
|
#ifdef MODULE_GNRC_NDP
|
||||||
gnrc_ndp_netif_remove(entry);
|
gnrc_ndp_netif_remove(entry);
|
||||||
#endif
|
#endif
|
||||||
#endif /* MODULE_GNRC_IPV6_NIB */
|
|
||||||
|
|
||||||
mutex_lock(&entry->mutex);
|
mutex_lock(&entry->mutex);
|
||||||
xtimer_remove(&entry->rtr_sol_timer);
|
xtimer_remove(&entry->rtr_sol_timer);
|
||||||
@ -240,13 +235,9 @@ void gnrc_ipv6_netif_add(kernel_pid_t pid)
|
|||||||
|
|
||||||
mutex_unlock(&free_entry->mutex);
|
mutex_unlock(&free_entry->mutex);
|
||||||
|
|
||||||
#ifndef MODULE_GNRC_IPV6_NIB
|
|
||||||
#ifdef MODULE_GNRC_NDP
|
#ifdef MODULE_GNRC_NDP
|
||||||
gnrc_ndp_netif_add(free_entry);
|
gnrc_ndp_netif_add(free_entry);
|
||||||
#endif
|
#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(" * pid = %" PRIkernel_pid " ", free_entry->pid);
|
||||||
DEBUG("cur_hl = %d ", free_entry->cur_hl);
|
DEBUG("cur_hl = %d ", free_entry->cur_hl);
|
||||||
|
|||||||
@ -13,6 +13,7 @@
|
|||||||
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "net/gnrc/netif2/internal.h"
|
||||||
#include "net/gnrc/ipv6/nib.h"
|
#include "net/gnrc/ipv6/nib.h"
|
||||||
|
|
||||||
#include "_nib-6ln.h"
|
#include "_nib-6ln.h"
|
||||||
@ -26,49 +27,88 @@
|
|||||||
static char addr_str[IPV6_ADDR_MAX_STR_LEN];
|
static char addr_str[IPV6_ADDR_MAX_STR_LEN];
|
||||||
#endif
|
#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)) &&
|
||||||
/* XXX: this *should* return successful so don't test it ;-) */
|
(memcmp(&netif->l2addr, eui64, netif->l2addr_len) == 0);
|
||||||
gnrc_netapi_get(iface, NETOPT_ADDRESS_LONG, 0,
|
|
||||||
&iface_eui64, sizeof(iface_eui64));
|
|
||||||
return (memcmp(&iface_eui64, eui64, sizeof(iface_eui64)) != 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _resolve_addr_from_ipv6(const ipv6_addr_t *dst, kernel_pid_t iface,
|
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, gnrc_netif2_t *netif,
|
||||||
gnrc_ipv6_nib_nc_t *nce)
|
gnrc_ipv6_nib_nc_t *nce)
|
||||||
{
|
{
|
||||||
gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(iface);
|
bool res = (netif != NULL) && gnrc_netif2_is_6ln(netif) &&
|
||||||
bool res = (netif != NULL) && _is_6ln(netif) &&
|
|
||||||
ipv6_addr_is_link_local(dst);
|
ipv6_addr_is_link_local(dst);
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
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));
|
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 = 0;
|
||||||
nce->info |= (iface << GNRC_IPV6_NIB_NC_INFO_IFACE_POS) &
|
nce->info |= (netif->pid << GNRC_IPV6_NIB_NC_INFO_IFACE_POS) &
|
||||||
GNRC_IPV6_NIB_NC_INFO_IFACE_MASK;
|
GNRC_IPV6_NIB_NC_INFO_IFACE_MASK;
|
||||||
nce->info |= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE;
|
nce->info |= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE;
|
||||||
nce->info |= GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED;
|
nce->info |= GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED;
|
||||||
nce->l2addr_len = sizeof(dst->u64[1]);
|
}
|
||||||
|
else {
|
||||||
|
res = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return res;
|
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 icmpv6_hdr_t *icmpv6,
|
||||||
const sixlowpan_nd_opt_ar_t *aro, const ndp_opt_t *sl2ao,
|
const sixlowpan_nd_opt_ar_t *aro, const ndp_opt_t *sl2ao,
|
||||||
_nib_onl_entry_t *nce)
|
_nib_onl_entry_t *nce)
|
||||||
{
|
{
|
||||||
gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(iface);
|
|
||||||
|
|
||||||
#if !GNRC_IPV6_NIB_CONF_6LR
|
#if !GNRC_IPV6_NIB_CONF_6LR
|
||||||
(void)sl2ao;
|
(void)sl2ao;
|
||||||
#endif
|
#endif
|
||||||
assert(netif != NULL);
|
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("nib: valid ARO received\n");
|
||||||
DEBUG(" - length: %u\n", aro->len);
|
DEBUG(" - length: %u\n", aro->len);
|
||||||
DEBUG(" - status: %u\n", aro->status);
|
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[3], aro->eui64.uint8[4], aro->eui64.uint8[5],
|
||||||
aro->eui64.uint8[6], aro->eui64.uint8[7]);
|
aro->eui64.uint8[6], aro->eui64.uint8[7]);
|
||||||
if (icmpv6->type == ICMPV6_NBR_ADV) {
|
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");
|
DEBUG("nib: ARO EUI-64 is not mine, ignoring ARO\n");
|
||||||
return _ADDR_REG_STATUS_IGNORE;
|
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) *
|
(byteorder_ntohs(aro->ltime) - 1U) *
|
||||||
SEC_PER_MIN * MS_PER_SEC;
|
SEC_PER_MIN * MS_PER_SEC;
|
||||||
DEBUG("nib: Address registration successful. "
|
DEBUG("nib: Address registration successful. "
|
||||||
"Scheduling re-registration in %ums\n",
|
"Scheduling re-registration in %" PRIu32 "ms\n",
|
||||||
next_ns);
|
next_ns);
|
||||||
assert(nce != NULL);
|
assert(nce != NULL);
|
||||||
_evtimer_add(nce, GNRC_IPV6_NIB_SND_UC_NS, &nce->nud_timeout,
|
_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. "
|
DEBUG("nib: Address registration reports duplicate. "
|
||||||
"Removing address %s%%%u\n",
|
"Removing address %s%%%u\n",
|
||||||
ipv6_addr_to_str(addr_str,
|
ipv6_addr_to_str(addr_str,
|
||||||
&((ndp_nbr_adv_t *)icmpv6)->tgt,
|
&ipv6->dst,
|
||||||
sizeof(addr_str)),
|
sizeof(addr_str)), netif->pid);
|
||||||
iface);
|
gnrc_netif2_ipv6_addr_remove(netif, &ipv6->dst);
|
||||||
gnrc_ipv6_netif_remove_addr(iface,
|
|
||||||
&((ndp_nbr_adv_t *)icmpv6)->tgt);
|
|
||||||
/* TODO: generate new address */
|
/* TODO: generate new address */
|
||||||
break;
|
break;
|
||||||
case SIXLOWPAN_ND_STATUS_NC_FULL: {
|
case SIXLOWPAN_ND_STATUS_NC_FULL: {
|
||||||
DEBUG("nib: Router's neighbor cache is full. "
|
DEBUG("nib: Router's neighbor cache is full. "
|
||||||
"Searching new router for DAD\n");
|
"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 */
|
assert(dr != NULL); /* otherwise we wouldn't be here */
|
||||||
_nib_drl_remove(dr);
|
_nib_drl_remove(dr);
|
||||||
if (_nib_drl_iter(NULL) == NULL) { /* no DRL left */
|
if (_nib_drl_iter(NULL) == NULL) { /* no DRL left */
|
||||||
_nib_iface_t *nib_iface = _nib_iface_get(iface);
|
netif->ipv6.rs_sent = 0;
|
||||||
nib_iface->rs_sent = 0;
|
|
||||||
/* TODO: search new router */
|
/* TODO: search new router */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -131,8 +168,9 @@ uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
|
|||||||
return aro->status;
|
return aro->status;
|
||||||
}
|
}
|
||||||
#if GNRC_IPV6_NIB_CONF_6LR
|
#if GNRC_IPV6_NIB_CONF_6LR
|
||||||
else if (_is_6lr(netif) && (icmpv6->type == ICMPV6_NBR_SOL)) {
|
else if (gnrc_netif2_is_6lr(netif) &&
|
||||||
return _reg_addr_upstream(iface, ipv6, icmpv6, aro, sl2ao);
|
(icmpv6->type == ICMPV6_NBR_SOL)) {
|
||||||
|
return _reg_addr_upstream(netif, ipv6, icmpv6, aro, sl2ao);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,38 +44,23 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define _ADDR_REG_STATUS_IGNORE (4)
|
#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
|
* @brief Resolves address statically from destination address using reverse
|
||||||
* translation of the IID
|
* translation of the IID
|
||||||
*
|
*
|
||||||
* @param[in] dst A destination address.
|
* @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
|
* @param[out] nce Neighbor cache entry to resolve into
|
||||||
*
|
*
|
||||||
* @return true when @p nce was set, false when not.
|
* @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);
|
gnrc_ipv6_nib_nc_t *nce);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handles ARO
|
* @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] ipv6 The IPv6 header of the message carrying the ARO.
|
||||||
* @param[in] icmpv6 The message carrying the ARO.
|
* @param[in] icmpv6 The message carrying the ARO.
|
||||||
* @param[in] aro ARO that carries the address registration information.
|
* @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
|
* @return registration status of the address (including
|
||||||
* @ref _ADDR_REG_STATUS_TENTATIVE and @ref _ADDR_REG_STATUS_IGNORE).
|
* @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 icmpv6_hdr_t *icmpv6,
|
||||||
const sixlowpan_nd_opt_ar_t *aro, const ndp_opt_t *sl2ao,
|
const sixlowpan_nd_opt_ar_t *aro, const ndp_opt_t *sl2ao,
|
||||||
_nib_onl_entry_t *nce);
|
_nib_onl_entry_t *nce);
|
||||||
#else /* GNRC_IPV6_NIB_CONF_6LN || defined(DOXYGEN) */
|
#else /* GNRC_IPV6_NIB_CONF_6LN || defined(DOXYGEN) */
|
||||||
#define _is_6ln(netif) (false)
|
#define _resolve_addr_from_ipv6(dst, netif, nce) (false)
|
||||||
#define _resolve_addr_from_ipv6(dst, iface, nce) (false)
|
|
||||||
/* _handle_aro() doesn't make sense without 6LR so don't even use it
|
/* _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
|
* => throw error in case it is compiled in => don't define it here as NOP macro
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "net/gnrc/ipv6/nib.h"
|
#include "net/gnrc/ipv6/nib.h"
|
||||||
|
#include "net/gnrc/netif2/internal.h"
|
||||||
#include "net/gnrc/sixlowpan/nd.h"
|
#include "net/gnrc/sixlowpan/nd.h"
|
||||||
|
|
||||||
#include "_nib-6lr.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 icmpv6_hdr_t *icmpv6,
|
||||||
const sixlowpan_nd_opt_ar_t *aro,
|
const sixlowpan_nd_opt_ar_t *aro,
|
||||||
const ndp_opt_t *sl2ao)
|
const ndp_opt_t *sl2ao)
|
||||||
{
|
{
|
||||||
if (!ipv6_addr_is_unspecified(&ipv6->src) && (sl2ao != NULL)) {
|
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 "
|
DEBUG("nib: Trying to register %s with EUI-64 "
|
||||||
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
|
"%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
|
#if GNRC_IPV6_NIB_CONF_MULTIHOP_DAD
|
||||||
/* TODO */
|
/* TODO */
|
||||||
#endif
|
#endif
|
||||||
if (byteorder_ntohs(aro->ltime) != 0) {
|
if (aro->ltime.u16 != 0) {
|
||||||
_handle_sl2ao(iface, ipv6, icmpv6, sl2ao);
|
_handle_sl2ao(netif, ipv6, icmpv6, sl2ao);
|
||||||
return _update_nce_ar_state(aro, nce);
|
return _update_nce_ar_state(aro, nce);
|
||||||
}
|
}
|
||||||
else if (nce != NULL) {
|
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;
|
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 ndp_nbr_sol_t *nbr_sol,
|
||||||
const sixlowpan_nd_opt_ar_t *aro,
|
const sixlowpan_nd_opt_ar_t *aro,
|
||||||
const ndp_opt_t *sl2ao)
|
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;
|
gnrc_pktsnip_t *reply_aro = NULL;
|
||||||
|
|
||||||
if (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);
|
sl2ao, NULL);
|
||||||
|
|
||||||
if ((status != _ADDR_REG_STATUS_TENTATIVE) &&
|
if ((status != _ADDR_REG_STATUS_TENTATIVE) &&
|
||||||
|
|||||||
@ -33,21 +33,6 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GNRC_IPV6_NIB_CONF_6LR || defined(DOXYGEN)
|
#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
|
* @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] netif A network interface.
|
||||||
* @param[in] icmpv6 An ICMPv6 message.
|
* @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)
|
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)
|
* @brief Registers an address to the (upstream; in case of multihop DAD)
|
||||||
* router
|
* 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] ipv6 The IPv6 header of the message carrying the ARO.
|
||||||
* @param[in] icmpv6 The neighbor solicitation carrying the ARO
|
* @param[in] icmpv6 The neighbor solicitation carrying the ARO
|
||||||
* (handed over as @ref icmpv6_hdr_t, since it is just
|
* (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
|
* @return registration status of the address (including
|
||||||
* @ref _ADDR_REG_STATUS_TENTATIVE and @ref _ADDR_REG_STATUS_IGNORE).
|
* @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 icmpv6_hdr_t *icmpv6,
|
||||||
const sixlowpan_nd_opt_ar_t *aro,
|
const sixlowpan_nd_opt_ar_t *aro,
|
||||||
const ndp_opt_t *sl2ao);
|
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
|
* @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
|
* @param[in] ipv6 The IPv6 header of the message carrying the original
|
||||||
* ARO.
|
* ARO.
|
||||||
* @param[in] nbr_sol The neighbor solicitation 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
|
* @return registration status of the address (including
|
||||||
* @ref _ADDR_REG_STATUS_TENTATIVE and @ref _ADDR_REG_STATUS_IGNORE).
|
* @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 ndp_nbr_sol_t *nbr_sol,
|
||||||
const sixlowpan_nd_opt_ar_t *aro,
|
const sixlowpan_nd_opt_ar_t *aro,
|
||||||
const ndp_opt_t *sl2ao);
|
const ndp_opt_t *sl2ao);
|
||||||
#else /* GNRC_IPV6_NIB_CONF_6LR || defined(DOXYGEN) */
|
#else /* GNRC_IPV6_NIB_CONF_6LR || defined(DOXYGEN) */
|
||||||
#define _is_6lr(netif) (false)
|
|
||||||
#define _rtr_sol_on_6lr(netif, icmpv6) (false)
|
#define _rtr_sol_on_6lr(netif, icmpv6) (false)
|
||||||
#define _get_ar_state(nbr) (_ADDR_REG_STATUS_IGNORE)
|
#define _get_ar_state(nbr) (_ADDR_REG_STATUS_IGNORE)
|
||||||
#define _set_ar_state(nbr, state) (void)nbr; (void)state
|
#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)
|
(NULL)
|
||||||
/* _reg_addr_upstream() doesn't make sense without 6LR so don't even use it
|
/* _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
|
* => throw error in case it is compiled in => don't define it here as NOP macro
|
||||||
|
|||||||
@ -16,6 +16,10 @@
|
|||||||
#include "xtimer.h"
|
#include "xtimer.h"
|
||||||
#include "net/gnrc/ndp2.h"
|
#include "net/gnrc/ndp2.h"
|
||||||
#include "net/gnrc/ipv6/nib.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-arsm.h"
|
||||||
#include "_nib-6lr.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.
|
* @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);
|
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)
|
const ipv6_addr_t *src, const ipv6_addr_t *dst)
|
||||||
{
|
{
|
||||||
gnrc_pktsnip_t *ext_opt = NULL;
|
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);
|
gnrc_ndp2_nbr_sol_send(tgt, netif, src, dst, ext_opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _snd_uc_ns(_nib_onl_entry_t *nbr, bool reset)
|
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));
|
gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(nbr));
|
||||||
_nib_iface_t *iface = _nib_iface_get(_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)),
|
ipv6_addr_to_str(addr_str, &nbr->ipv6, sizeof(addr_str)),
|
||||||
(unsigned)iface->retrans_time);
|
(unsigned)netif->ipv6.retrans_time);
|
||||||
assert((netif != NULL) && (iface != NULL));
|
|
||||||
#if GNRC_IPV6_NIB_CONF_ARSM
|
#if GNRC_IPV6_NIB_CONF_ARSM
|
||||||
if (reset) {
|
if (reset) {
|
||||||
nbr->ns_sent = 0;
|
nbr->ns_sent = 0;
|
||||||
@ -65,20 +93,20 @@ void _snd_uc_ns(_nib_onl_entry_t *nbr, bool reset)
|
|||||||
#endif
|
#endif
|
||||||
_snd_ns(&nbr->ipv6, netif, NULL, &nbr->ipv6);
|
_snd_ns(&nbr->ipv6, netif, NULL, &nbr->ipv6);
|
||||||
_evtimer_add(nbr, GNRC_IPV6_NIB_SND_UC_NS, &nbr->nud_timeout,
|
_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
|
#if GNRC_IPV6_NIB_CONF_ARSM
|
||||||
nbr->ns_sent++;
|
nbr->ns_sent++;
|
||||||
#endif
|
#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)
|
const icmpv6_hdr_t *icmpv6, const ndp_opt_t *sl2ao)
|
||||||
{
|
{
|
||||||
_nib_onl_entry_t *nce = _nib_onl_get(&ipv6->src, iface);
|
assert(netif != NULL);
|
||||||
gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(iface);
|
_nib_onl_entry_t *nce = _nib_onl_get(&ipv6->src, netif->pid);
|
||||||
unsigned l2addr_len;
|
unsigned l2addr_len;
|
||||||
|
|
||||||
assert(netif != NULL);
|
|
||||||
l2addr_len = _get_l2addr_len(netif, sl2ao);
|
l2addr_len = _get_l2addr_len(netif, sl2ao);
|
||||||
if (l2addr_len == 0U) {
|
if (l2addr_len == 0U) {
|
||||||
DEBUG("nib: Unexpected SL2AO length. Ignoring SL2AO\n");
|
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)) {
|
!_rtr_sol_on_6lr(netif, icmpv6)) {
|
||||||
DEBUG("nib: L2 address differs. Setting STALE\n");
|
DEBUG("nib: L2 address differs. Setting STALE\n");
|
||||||
evtimer_del(&_nib_evtimer, &nce->nud_timeout.event);
|
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 */
|
#endif /* GNRC_IPV6_NIB_CONF_ARSM */
|
||||||
if ((nce == NULL) || !(nce->mode & _NC)) {
|
if ((nce == NULL) || !(nce->mode & _NC)) {
|
||||||
DEBUG("nib: Creating NCE for (ipv6 = %s, iface = %u, nud_state = STALE)\n",
|
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);
|
ipv6_addr_to_str(addr_str, &ipv6->src, sizeof(addr_str)),
|
||||||
nce = _nib_nc_add(&ipv6->src, iface,
|
netif->pid);
|
||||||
|
nce = _nib_nc_add(&ipv6->src, netif->pid,
|
||||||
GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
|
GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
|
||||||
if (nce != NULL) {
|
if (nce != NULL) {
|
||||||
if (icmpv6->type == ICMPV6_NBR_SOL) {
|
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) {
|
if (icmpv6->type == ICMPV6_RTR_ADV) {
|
||||||
DEBUG("nib: %s%%%u is a router\n",
|
DEBUG("nib: %s%%%u is a router\n",
|
||||||
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
|
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
|
||||||
iface);
|
netif->pid);
|
||||||
nce->info |= GNRC_IPV6_NIB_NC_INFO_IS_ROUTER;
|
nce->info |= GNRC_IPV6_NIB_NC_INFO_IS_ROUTER;
|
||||||
}
|
}
|
||||||
else if (icmpv6->type != ICMPV6_NBR_SOL) {
|
else if (icmpv6->type != ICMPV6_NBR_SOL) {
|
||||||
DEBUG("nib: %s%%%u is probably not a router\n",
|
DEBUG("nib: %s%%%u is probably not a router\n",
|
||||||
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
|
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
|
||||||
iface);
|
netif->pid);
|
||||||
nce->info &= ~GNRC_IPV6_NIB_NC_INFO_IS_ROUTER;
|
nce->info &= ~GNRC_IPV6_NIB_NC_INFO_IS_ROUTER;
|
||||||
}
|
}
|
||||||
#if GNRC_IPV6_NIB_CONF_ARSM
|
#if GNRC_IPV6_NIB_CONF_ARSM
|
||||||
@ -146,28 +175,41 @@ 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)
|
const ndp_opt_t *opt)
|
||||||
{
|
{
|
||||||
#if GNRC_IPV6_NIB_CONF_6LN
|
switch (netif->device_type) {
|
||||||
if (_is_6ln(netif)) {
|
#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) {
|
switch (opt->len) {
|
||||||
case 1U:
|
case 1U:
|
||||||
return 2U;
|
return IEEE802154_SHORT_ADDRESS_LEN;
|
||||||
case 2U:
|
case 2U:
|
||||||
return 8U;
|
return IEEE802154_LONG_ADDRESS_LEN;
|
||||||
default:
|
default:
|
||||||
return 0U;
|
return 0U;
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
#else
|
default:
|
||||||
(void)netif;
|
(void)opt;
|
||||||
#endif /* GNRC_IPV6_NIB_CONF_6LN */
|
|
||||||
if (opt->len == 1U) {
|
|
||||||
return 6U;
|
|
||||||
}
|
|
||||||
return 0U;
|
return 0U;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if GNRC_IPV6_NIB_CONF_ARSM
|
#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] nce A neighbor cache entry.
|
||||||
* @param[in] tl2ao The TL2AO.
|
* @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.
|
* @param[in] tl2ao_addr_len Length of the L2 address in the TL2AO.
|
||||||
*
|
*
|
||||||
* @return `true`, if the TL2AO changes the NCE.
|
* @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,
|
static inline bool _tl2ao_changes_nce(_nib_onl_entry_t *nce,
|
||||||
const ndp_opt_t *tl2ao,
|
const ndp_opt_t *tl2ao,
|
||||||
kernel_pid_t iface,
|
gnrc_netif2_t *netif,
|
||||||
unsigned tl2ao_addr_len);
|
unsigned tl2ao_addr_len);
|
||||||
|
|
||||||
void _handle_snd_ns(_nib_onl_entry_t *nbr)
|
void _handle_snd_ns(_nib_onl_entry_t *nbr)
|
||||||
@ -233,7 +275,10 @@ void _handle_snd_ns(_nib_onl_entry_t *nbr)
|
|||||||
break;
|
break;
|
||||||
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE:
|
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE:
|
||||||
if (nbr->ns_sent >= NDP_MAX_UC_SOL_NUMOF) {
|
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 */
|
/* falls through intentionally */
|
||||||
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE:
|
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE:
|
||||||
@ -253,8 +298,10 @@ void _handle_state_timeout(_nib_onl_entry_t *nbr)
|
|||||||
DEBUG("nib: Timeout reachability\n");
|
DEBUG("nib: Timeout reachability\n");
|
||||||
new_state = GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE;
|
new_state = GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE;
|
||||||
/* falls through intentionally */
|
/* falls through intentionally */
|
||||||
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY:
|
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY: {
|
||||||
_set_nud_state(nbr, new_state);
|
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) {
|
if (new_state == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE) {
|
||||||
DEBUG("nib: Timeout DELAY state\n");
|
DEBUG("nib: Timeout DELAY state\n");
|
||||||
_probe_nbr(nbr, true);
|
_probe_nbr(nbr, true);
|
||||||
@ -262,6 +309,7 @@ void _handle_state_timeout(_nib_onl_entry_t *nbr)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _probe_nbr(_nib_onl_entry_t *nbr, bool reset)
|
void _probe_nbr(_nib_onl_entry_t *nbr, bool reset)
|
||||||
{
|
{
|
||||||
@ -274,24 +322,25 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset)
|
|||||||
break;
|
break;
|
||||||
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE:
|
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE:
|
||||||
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE: {
|
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,
|
uint32_t next_ns = _evtimer_lookup(nbr,
|
||||||
GNRC_IPV6_NIB_SND_MC_NS);
|
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;
|
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 ",
|
DEBUG("multicast to %s's solicited nodes ",
|
||||||
ipv6_addr_to_str(addr_str, &nbr->ipv6,
|
ipv6_addr_to_str(addr_str, &nbr->ipv6,
|
||||||
sizeof(addr_str)));
|
sizeof(addr_str)));
|
||||||
assert(netif != NULL);
|
|
||||||
if (reset) {
|
if (reset) {
|
||||||
nbr->ns_sent = 0;
|
nbr->ns_sent = 0;
|
||||||
}
|
}
|
||||||
if (state == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE) {
|
if (state == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE) {
|
||||||
/* first 3 retransmissions in PROBE, assume 1 higher to
|
/* 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 */
|
* but the next backoff after that => subtract 2 */
|
||||||
retrans_time = _exp_backoff_retrans_timer(nbr->ns_sent - 2,
|
retrans_time = _exp_backoff_retrans_timer(nbr->ns_sent - 2,
|
||||||
retrans_time);
|
retrans_time);
|
||||||
@ -312,9 +361,10 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset)
|
|||||||
"a multicast NS within %ums)\n",
|
"a multicast NS within %ums)\n",
|
||||||
ipv6_addr_to_str(addr_str, &nbr->ipv6,
|
ipv6_addr_to_str(addr_str, &nbr->ipv6,
|
||||||
sizeof(addr_str)),
|
sizeof(addr_str)),
|
||||||
(unsigned)iface->retrans_time);
|
(unsigned)netif->ipv6.retrans_time);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
gnrc_netif2_release(netif);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE:
|
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)
|
const icmpv6_hdr_t *icmpv6, const ndp_opt_t *tl2ao)
|
||||||
{
|
{
|
||||||
gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(iface);
|
|
||||||
unsigned l2addr_len = 0;
|
unsigned l2addr_len = 0;
|
||||||
|
|
||||||
assert(nce != NULL);
|
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) ||
|
if ((_get_nud_state(nce) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE) ||
|
||||||
_oflag_set((ndp_nbr_adv_t *)icmpv6) ||
|
_oflag_set((ndp_nbr_adv_t *)icmpv6) ||
|
||||||
_redirect_with_tl2ao(icmpv6, tl2ao) ||
|
_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 =
|
bool nce_was_incomplete =
|
||||||
(_get_nud_state(nce) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE);
|
(_get_nud_state(nce) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE);
|
||||||
if (tl2ao != NULL) {
|
if (tl2ao != NULL) {
|
||||||
@ -353,17 +402,17 @@ void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce,
|
|||||||
nce->l2addr_len = 0;
|
nce->l2addr_len = 0;
|
||||||
}
|
}
|
||||||
if (_sflag_set((ndp_nbr_adv_t *)icmpv6)) {
|
if (_sflag_set((ndp_nbr_adv_t *)icmpv6)) {
|
||||||
_set_reachable(iface, nce);
|
_set_reachable(netif, nce);
|
||||||
}
|
}
|
||||||
else if ((icmpv6->type != ICMPV6_NBR_ADV) ||
|
else if ((icmpv6->type != ICMPV6_NBR_ADV) ||
|
||||||
!_sflag_set((ndp_nbr_adv_t *)icmpv6) ||
|
!_sflag_set((ndp_nbr_adv_t *)icmpv6) ||
|
||||||
(!nce_was_incomplete &&
|
(!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",
|
DEBUG("nib: Set %s%%%u to STALE\n",
|
||||||
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
|
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
|
||||||
iface);
|
(unsigned)netif->pid);
|
||||||
evtimer_del(&_nib_evtimer, &nce->nud_timeout.event);
|
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) ||
|
if (_oflag_set((ndp_nbr_adv_t *)icmpv6) ||
|
||||||
((icmpv6->type == ICMPV6_NBR_ADV) && nce_was_incomplete)) {
|
((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) &&
|
if ((icmpv6->type == ICMPV6_NBR_ADV) &&
|
||||||
!_sflag_set((ndp_nbr_adv_t *)icmpv6) &&
|
!_sflag_set((ndp_nbr_adv_t *)icmpv6) &&
|
||||||
(_get_nud_state(nce) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE) &&
|
(_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);
|
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) &&
|
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_INCOMPLETE) &&
|
||||||
(_get_nud_state(nce) != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED) &&
|
(_get_nud_state(nce) != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED) &&
|
||||||
_sflag_set((ndp_nbr_adv_t *)icmpv6) &&
|
_sflag_set((ndp_nbr_adv_t *)icmpv6) &&
|
||||||
!_tl2ao_changes_nce(nce, tl2ao, iface, l2addr_len)) {
|
!_tl2ao_changes_nce(nce, tl2ao, netif, l2addr_len)) {
|
||||||
_set_reachable(iface, nce);
|
_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",
|
DEBUG("nib: Set %s%%%u to REACHABLE for %ums\n",
|
||||||
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
|
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
|
||||||
iface, (unsigned)nib_netif->reach_time);
|
netif->pid, (unsigned)netif->ipv6.reach_time);
|
||||||
_set_nud_state(nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE);
|
_set_nud_state(netif, nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE);
|
||||||
_evtimer_add(nce, GNRC_IPV6_NIB_REACH_TIMEOUT, &nce->nud_timeout,
|
_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 */
|
/* 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,
|
static inline bool _tl2ao_changes_nce(_nib_onl_entry_t *nce,
|
||||||
const ndp_opt_t *tl2ao,
|
const ndp_opt_t *tl2ao,
|
||||||
kernel_pid_t iface,
|
gnrc_netif2_t *netif,
|
||||||
unsigned tl2ao_addr_len)
|
unsigned tl2ao_addr_len)
|
||||||
{
|
{
|
||||||
return ((tl2ao != NULL) &&
|
return ((tl2ao != NULL) &&
|
||||||
(((nce->l2addr_len != tl2ao_addr_len) &&
|
(((nce->l2addr_len != tl2ao_addr_len) &&
|
||||||
(memcmp(nce->l2addr, tl2ao + 1, tl2ao_addr_len) != 0)) ||
|
(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)
|
static inline bool _oflag_set(const ndp_nbr_adv_t *nbr_adv)
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "net/gnrc/ipv6/nib/conf.h"
|
#include "net/gnrc/ipv6/nib/conf.h"
|
||||||
|
#include "net/gnrc/netif2.h"
|
||||||
#include "net/ndp.h"
|
#include "net/ndp.h"
|
||||||
#include "net/icmpv6.h"
|
#include "net/icmpv6.h"
|
||||||
|
|
||||||
@ -47,7 +48,7 @@ extern "C" {
|
|||||||
* @param[in] dst Destination address for neighbor solicitation. May not
|
* @param[in] dst Destination address for neighbor solicitation. May not
|
||||||
* be NULL.
|
* 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);
|
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
|
* to the ARSM, but ARSM isn't the only mechanism using it (e.g. the
|
||||||
* 6Lo address registration uses it).
|
* 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] ipv6 IPv6 header of the message carrying the SL2AO.
|
||||||
* @param[in] icmpv6 ICMPv6 header of the message carrying the SL2AO.
|
* @param[in] icmpv6 ICMPv6 header of the message carrying the SL2AO.
|
||||||
* @param[in] sl2ao 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);
|
const icmpv6_hdr_t *icmpv6, const ndp_opt_t *sl2ao);
|
||||||
|
|
||||||
#if GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN)
|
#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
|
* This can either be an TL2AO or for a link-layer without addresses just a
|
||||||
* neighbor advertisement.
|
* neighbor advertisement.
|
||||||
*
|
*
|
||||||
* @param[in] iface Interface the link-layer information was advertised
|
* @param[in] netif Interface the link-layer information was advertised
|
||||||
* over.
|
* over.
|
||||||
* @param[in] nce Neighbor cache entry that is updated by the advertised
|
* @param[in] nce Neighbor cache entry that is updated by the advertised
|
||||||
* link-layer information.
|
* 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
|
* @param[in] tl2ao The TL2AO carrying the link-layer information. May be
|
||||||
* NULL for link-layers without addresses.
|
* 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);
|
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
|
* @brief Sets a neighbor cache entry reachable and starts the required
|
||||||
* event timers
|
* 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
|
* @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
|
* @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;
|
netif->ipv6.reach_time_base = NDP_REACH_MS;
|
||||||
nib_iface->retrans_time = NDP_RETRANS_TIMER_MS;
|
_recalc_reach_time(&netif->ipv6);
|
||||||
_nib_iface_recalc_reach_time(nib_iface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets neighbor unreachability state of a neighbor
|
* @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
|
* @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.
|
* @param[in] state Neighbor unreachability state for the neighbor.
|
||||||
*/
|
*/
|
||||||
static inline void _set_nud_state(_nib_onl_entry_t *entry, uint16_t state)
|
void _set_nud_state(gnrc_netif2_t *netif, _nib_onl_entry_t *nbr,
|
||||||
{
|
uint16_t state);
|
||||||
entry->info &= ~GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK;
|
|
||||||
entry->info |= state;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN) */
|
#else /* GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN) */
|
||||||
#define _handle_snd_ns(ctx) (void)ctx
|
#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 _init_iface_arsm(netif) (void)netif
|
||||||
#define _handle_adv_l2(netif, nce, icmpv6, tl2ao) (void)netif; (void)nce; \
|
#define _handle_adv_l2(netif, nce, icmpv6, tl2ao) (void)netif; (void)nce; \
|
||||||
(void)icmpv6; (void)tl2ao
|
(void)icmpv6; (void)tl2ao
|
||||||
|
#define _recalc_reach_time(netif) (void)netif;
|
||||||
#define _set_reachable(netif, nce) (void)netif; (void)nce
|
#define _set_reachable(netif, nce) (void)netif; (void)nce
|
||||||
#define _init_iface_arsm(netif) (void)netif
|
#define _init_iface_arsm(netif) (void)netif
|
||||||
|
|
||||||
#define _get_nud_state(entry) (GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED)
|
#define _get_nud_state(nbr) (GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED)
|
||||||
#define _set_nud_state(entry, state) (void)entry; (void)state
|
#define _set_nud_state(netif, nce, state) (void)netif; (void)nbr; (void)state
|
||||||
#endif /* GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN) */
|
#endif /* GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN) */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
#include "net/gnrc/ipv6/nib/conf.h"
|
#include "net/gnrc/ipv6/nib/conf.h"
|
||||||
#include "net/gnrc/ipv6/nib/nc.h"
|
#include "net/gnrc/ipv6/nib/nc.h"
|
||||||
#include "net/gnrc/ipv6/nib.h"
|
#include "net/gnrc/ipv6/nib.h"
|
||||||
#include "net/gnrc/netif.h"
|
#include "net/gnrc/netif2/internal.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
|
||||||
#include "_nib-internal.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_onl_entry_t _nodes[GNRC_IPV6_NIB_NUMOF];
|
||||||
static _nib_offl_entry_t _dsts[GNRC_IPV6_NIB_OFFL_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_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
|
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
|
||||||
static _nib_abr_entry_t _abrs[GNRC_IPV6_NIB_ABR_NUMOF];
|
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(_nodes, 0, sizeof(_nodes));
|
||||||
memset(_def_routers, 0, sizeof(_def_routers));
|
memset(_def_routers, 0, sizeof(_def_routers));
|
||||||
memset(_dsts, 0, sizeof(_dsts));
|
memset(_dsts, 0, sizeof(_dsts));
|
||||||
memset(_nis, 0, sizeof(_nis));
|
|
||||||
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
|
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
|
||||||
memset(_abrs, 0, sizeof(_abrs));
|
memset(_abrs, 0, sizeof(_abrs));
|
||||||
#endif
|
#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)
|
void _nib_nc_set_reachable(_nib_onl_entry_t *node)
|
||||||
{
|
{
|
||||||
#if GNRC_IPV6_NIB_CONF_ARSM
|
#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_MASK;
|
||||||
node->info |= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE;
|
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,
|
_evtimer_add(node, GNRC_IPV6_NIB_REACH_TIMEOUT, &node->nud_timeout,
|
||||||
iface->reach_time);
|
netif->ipv6.reach_time);
|
||||||
#else
|
#else
|
||||||
(void)node;
|
(void)node;
|
||||||
#endif
|
#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_ARSM
|
||||||
#if GNRC_IPV6_NIB_CONF_6LN
|
#if GNRC_IPV6_NIB_CONF_6LN
|
||||||
if (ipv6_addr_is_link_local(&nce->ipv6)) {
|
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);
|
assert(netif != NULL);
|
||||||
if ((netif->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) &&
|
if (gnrc_netif2_is_6ln(netif) && !gnrc_netif2_is_rtr(netif)) {
|
||||||
!(netif->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER)) {
|
|
||||||
_get_l2addr_from_ipv6(nce->l2addr, &node->ipv6);
|
_get_l2addr_from_ipv6(nce->l2addr, &node->ipv6);
|
||||||
nce->l2addr_len = sizeof(uint64_t);
|
nce->l2addr_len = sizeof(uint64_t);
|
||||||
return;
|
return;
|
||||||
@ -768,42 +771,6 @@ _nib_offl_entry_t *_nib_pl_add(unsigned iface,
|
|||||||
return dst;
|
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,
|
static void _override_node(const ipv6_addr_t *addr, unsigned iface,
|
||||||
_nib_onl_entry_t *node)
|
_nib_onl_entry_t *node)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -193,56 +193,6 @@ typedef struct {
|
|||||||
preferred (UINT32_MAX means forever) */
|
preferred (UINT32_MAX means forever) */
|
||||||
} _nib_offl_entry_t;
|
} _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
|
* @brief Internal NIB-representation of the authoritative border router
|
||||||
* for multihop prefix and 6LoWPAN context dissemination
|
* 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,
|
int _nib_get_route(const ipv6_addr_t *dst, gnrc_pktsnip_t *ctx,
|
||||||
gnrc_ipv6_nib_ft_t *entry);
|
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
|
* @brief Looks up if an event is queued in the event timer
|
||||||
*
|
*
|
||||||
|
|||||||
@ -16,9 +16,10 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
#include "net/ipv6/addr.h"
|
#include "net/ipv6/addr.h"
|
||||||
#include "net/gnrc/nettype.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/ipv6/nib.h"
|
||||||
#include "net/gnrc/ndp2.h"
|
#include "net/gnrc/ndp2.h"
|
||||||
#include "net/gnrc/pktqueue.h"
|
#include "net/gnrc/pktqueue.h"
|
||||||
@ -49,24 +50,16 @@ static gnrc_pktqueue_t _queue_pool[GNRC_IPV6_NIB_NUMOF];
|
|||||||
* @internal
|
* @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);
|
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);
|
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,
|
gnrc_pktsnip_t *pkt, gnrc_ipv6_nib_nc_t *nce,
|
||||||
_nib_onl_entry_t *entry);
|
_nib_onl_entry_t *entry);
|
||||||
|
|
||||||
static void _handle_snd_na(gnrc_pktsnip_t *pkt);
|
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)
|
void gnrc_ipv6_nib_init(void)
|
||||||
@ -83,27 +76,13 @@ void gnrc_ipv6_nib_init(void)
|
|||||||
mutex_unlock(&_nib_mutex);
|
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);
|
assert(netif != NULL);
|
||||||
DEBUG("nib: Initialize interface %u\n", (unsigned)iface);
|
DEBUG("nib: Initialize interface %u\n", netif->pid);
|
||||||
mutex_lock(&_nib_mutex);
|
gnrc_netif2_acquire(netif);
|
||||||
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
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
* - set link-local address here for stateless address auto-configuration
|
* - set link-local address here for stateless address auto-configuration
|
||||||
* and 6LN
|
* 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
|
* - join all router group of link-local address here on router node here
|
||||||
* - become an router advertising interface here on non-6LR here */
|
* - become an router advertising interface here on non-6LR here */
|
||||||
|
|
||||||
_init_iface_arsm(nib_iface);
|
_init_iface_arsm(netif);
|
||||||
nib_iface->rs_sent = 0;
|
netif->ipv6.retrans_time = NDP_RETRANS_TIMER_MS;
|
||||||
nib_iface->na_sent = 0;
|
netif->ipv6.na_sent = 0;
|
||||||
#if GNRC_IPV6_NIB_CONF_ROUTER
|
#if GNRC_IPV6_NIB_CONF_ROUTER
|
||||||
nib_iface->last_ra = UINT32_MAX;
|
netif->ipv6.rtr_ltime = 1800U;
|
||||||
nib_iface->ra_sent = 0;
|
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
|
#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,
|
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)
|
gnrc_ipv6_nib_nc_t *nce)
|
||||||
{
|
{
|
||||||
int res = 0;
|
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);
|
mutex_lock(&_nib_mutex);
|
||||||
do { /* XXX: hidden goto ;-) */
|
do { /* XXX: hidden goto ;-) */
|
||||||
if (ipv6_addr_is_link_local(dst)) {
|
if (ipv6_addr_is_link_local(dst)) {
|
||||||
/* TODO: Prefix-based on-link determination */
|
/* TODO: Prefix-based on-link determination */
|
||||||
if ((iface == KERNEL_PID_UNDEF) ||
|
if ((netif == NULL) ||
|
||||||
!_resolve_addr(dst, iface, pkt, nce,
|
!_resolve_addr(dst, netif, pkt, nce,
|
||||||
_nib_onl_get(dst, iface))) {
|
_nib_onl_get(dst, netif->pid))) {
|
||||||
res = -EHOSTUNREACH;
|
res = -EHOSTUNREACH;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* TODO: Off-link next hop determination */
|
/* TODO: Off-link next hop determination;
|
||||||
|
* might need netif locking */
|
||||||
res = -EHOSTUNREACH;
|
res = -EHOSTUNREACH;
|
||||||
}
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
mutex_unlock(&_nib_mutex);
|
mutex_unlock(&_nib_mutex);
|
||||||
|
gnrc_netif2_release(netif);
|
||||||
return res;
|
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)
|
const icmpv6_hdr_t *icmpv6, size_t icmpv6_len)
|
||||||
{
|
{
|
||||||
DEBUG("nib: Handle packet (icmpv6->type = %u)\n", icmpv6->type);
|
DEBUG("nib: Handle packet (icmpv6->type = %u)\n", icmpv6->type);
|
||||||
|
assert(netif != NULL);
|
||||||
|
gnrc_netif2_acquire(netif);
|
||||||
mutex_lock(&_nib_mutex);
|
mutex_lock(&_nib_mutex);
|
||||||
switch (icmpv6->type) {
|
switch (icmpv6->type) {
|
||||||
#if GNRC_IPV6_NIB_CONF_ROUTER
|
#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 */
|
/* TODO */
|
||||||
break;
|
break;
|
||||||
case ICMPV6_NBR_SOL:
|
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;
|
break;
|
||||||
case ICMPV6_NBR_ADV:
|
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;
|
break;
|
||||||
#if GNRC_IPV6_NIB_CONF_REDIRECT
|
#if GNRC_IPV6_NIB_CONF_REDIRECT
|
||||||
case ICMPV6_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 */
|
#endif /* GNRC_IPV6_NIB_CONF_MULTIHOP_DAD */
|
||||||
}
|
}
|
||||||
mutex_unlock(&_nib_mutex);
|
mutex_unlock(&_nib_mutex);
|
||||||
|
gnrc_netif2_release(netif);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type)
|
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);
|
ctx, type, (unsigned)xtimer_now_usec() / 1000);
|
||||||
mutex_lock(&_nib_mutex);
|
mutex_lock(&_nib_mutex);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
/* TODO: remember netif locking if ctx is a gnrc_netif2_t */
|
||||||
#if GNRC_IPV6_NIB_CONF_ARSM
|
#if GNRC_IPV6_NIB_CONF_ARSM
|
||||||
case GNRC_IPV6_NIB_SND_UC_NS:
|
case GNRC_IPV6_NIB_SND_UC_NS:
|
||||||
case GNRC_IPV6_NIB_SND_MC_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);
|
_handle_state_timeout(ctx);
|
||||||
break;
|
break;
|
||||||
case GNRC_IPV6_NIB_RECALC_REACH_TIME:
|
case GNRC_IPV6_NIB_RECALC_REACH_TIME:
|
||||||
_nib_iface_recalc_reach_time(ctx);
|
_recalc_reach_time(ctx);
|
||||||
break;
|
break;
|
||||||
#endif /* GNRC_IPV6_NIB_CONF_ARSM */
|
#endif /* GNRC_IPV6_NIB_CONF_ARSM */
|
||||||
case GNRC_IPV6_NIB_SND_NA:
|
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);
|
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 */
|
/* Iterator for NDP options in a packet */
|
||||||
#define FOREACH_OPT(ndp_pkt, opt, icmpv6_len) \
|
#define FOREACH_OPT(ndp_pkt, opt, icmpv6_len) \
|
||||||
for (opt = (ndp_opt_t *)(ndp_pkt + 1); \
|
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), \
|
icmpv6_len -= (opt->len << 3), \
|
||||||
opt = (ndp_opt_t *)(((uint8_t *)opt) + (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,
|
static inline size_t _get_l2src(const gnrc_netif2_t *netif, uint8_t *l2src)
|
||||||
size_t l2src_maxlen)
|
|
||||||
{
|
{
|
||||||
bool try_long = false;
|
#if GNRC_NETIF2_L2ADDR_MAXLEN > 0
|
||||||
int res;
|
memcpy(l2src, netif->l2addr, netif->l2addr_len);
|
||||||
uint16_t l2src_len;
|
return netif->l2addr_len;
|
||||||
/* maximum address length that fits into a minimum length (8) S/TL2A
|
#else
|
||||||
* option */
|
(void)netif;
|
||||||
const uint16_t max_short_len = 6;
|
(void)l2src;
|
||||||
|
return 0;
|
||||||
/* try getting source address */
|
#endif
|
||||||
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,
|
static void _send_delayed_nbr_adv(const gnrc_netif2_t *netif,
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _send_delayed_nbr_adv(const gnrc_ipv6_netif_t *netif,
|
|
||||||
const ipv6_addr_t *tgt,
|
const ipv6_addr_t *tgt,
|
||||||
const ipv6_addr_t *dst,
|
const ipv6_addr_t *dst,
|
||||||
gnrc_pktsnip_t *reply_aro)
|
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;
|
uint8_t reply_flags = NDP_NBR_ADV_FLAGS_S;
|
||||||
|
|
||||||
#if GNRC_IPV6_NIB_CONF_ROUTER
|
#if GNRC_IPV6_NIB_CONF_ROUTER
|
||||||
if (_is_rtr(netif)) {
|
if (gnrc_netif2_is_rtr(netif)) {
|
||||||
reply_flags |= NDP_NBR_ADV_FLAGS_R;
|
reply_flags |= NDP_NBR_ADV_FLAGS_R;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if GNRC_NETIF2_L2ADDR_MAXLEN > 0
|
||||||
if (ipv6_addr_is_multicast(dst)) {
|
if (ipv6_addr_is_multicast(dst)) {
|
||||||
uint8_t l2addr[GNRC_IPV6_NIB_L2ADDR_MAX_LEN];
|
uint8_t l2addr[GNRC_NETIF2_L2ADDR_MAXLEN];
|
||||||
size_t l2addr_len = _get_l2src(netif->pid, l2addr, sizeof(l2addr));
|
size_t l2addr_len = _get_l2src(netif, l2addr);
|
||||||
|
|
||||||
if (l2addr_len > 0) {
|
if (l2addr_len > 0) {
|
||||||
extra_opts = gnrc_ndp2_opt_tl2a_build(l2addr, l2addr_len,
|
extra_opts = gnrc_ndp2_opt_tl2a_build(l2addr, l2addr_len,
|
||||||
extra_opts);
|
extra_opts);
|
||||||
@ -319,6 +367,10 @@ static void _send_delayed_nbr_adv(const gnrc_ipv6_netif_t *netif,
|
|||||||
else {
|
else {
|
||||||
reply_flags |= NDP_NBR_ADV_FLAGS_O;
|
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);
|
nbr_adv = gnrc_ndp2_nbr_adv_build(tgt, reply_flags, extra_opts);
|
||||||
if (nbr_adv == NULL) {
|
if (nbr_adv == NULL) {
|
||||||
DEBUG("nib: No space left in packet buffer. Not replying NS");
|
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)
|
const ndp_nbr_sol_t *nbr_sol, size_t icmpv6_len)
|
||||||
{
|
{
|
||||||
size_t tmp_len = icmpv6_len - sizeof(ndp_nbr_sol_t);
|
size_t tmp_len = icmpv6_len - sizeof(ndp_nbr_sol_t);
|
||||||
|
int tgt_idx;
|
||||||
ndp_opt_t *opt;
|
ndp_opt_t *opt;
|
||||||
ipv6_addr_t *local;
|
|
||||||
|
|
||||||
/* check validity, see: https://tools.ietf.org/html/rfc4861#section-7.1.1 */
|
/* check validity, see: https://tools.ietf.org/html/rfc4861#section-7.1.1 */
|
||||||
/* checksum is checked by GNRC's ICMPv6 module */
|
/* 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;
|
return;
|
||||||
}
|
}
|
||||||
/* check if target is assigned only now in case the length was wrong */
|
/* check if target is assigned only now in case the length was wrong */
|
||||||
local = gnrc_ipv6_netif_find_addr(iface, &nbr_sol->tgt);
|
tgt_idx = gnrc_netif2_ipv6_addr_idx(netif, &nbr_sol->tgt);
|
||||||
if (local == NULL) {
|
if (tgt_idx < 0) {
|
||||||
DEBUG("nib: Target address %s is not assigned to a local interface\n",
|
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)));
|
ipv6_addr_to_str(addr_str, &nbr_sol->tgt, sizeof(addr_str)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -395,6 +447,7 @@ static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
|
|||||||
/* TODO SLAAC behavior */
|
/* TODO SLAAC behavior */
|
||||||
#endif /* GNRC_IPV6_NIB_CONF_SLAAC */
|
#endif /* GNRC_IPV6_NIB_CONF_SLAAC */
|
||||||
if (!ipv6_addr_is_unspecified(&ipv6->src)) {
|
if (!ipv6_addr_is_unspecified(&ipv6->src)) {
|
||||||
|
gnrc_pktsnip_t *reply_aro = NULL;
|
||||||
#if GNRC_IPV6_NIB_CONF_6LR
|
#if GNRC_IPV6_NIB_CONF_6LR
|
||||||
ndp_opt_t *sl2ao = NULL;
|
ndp_opt_t *sl2ao = NULL;
|
||||||
sixlowpan_nd_opt_ar_t *aro = 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 sl2ao (NULL)
|
||||||
#define aro (NULL)
|
#define aro (NULL)
|
||||||
#endif /* GNRC_IPV6_NIB_CONF_6LR */
|
#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);
|
tmp_len = icmpv6_len - sizeof(ndp_nbr_sol_t);
|
||||||
|
|
||||||
netif = gnrc_ipv6_netif_get(iface);
|
if (!(netif->flags & GNRC_NETIF2_FLAGS_HAS_L2ADDR)) {
|
||||||
/* TODO: Set STALE NCE if link-layer has no addresses */
|
/* 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) {
|
FOREACH_OPT(nbr_sol, opt, tmp_len) {
|
||||||
switch (opt->type) {
|
switch (opt->type) {
|
||||||
case NDP_OPT_SL2A:
|
case NDP_OPT_SL2A:
|
||||||
#if GNRC_IPV6_NIB_CONF_6LR
|
#if GNRC_IPV6_NIB_CONF_6LR
|
||||||
if (_is_6lr(netif)) {
|
if (gnrc_netif2_is_6lr(netif)) {
|
||||||
DEBUG("nib: Storing SL2AO for later handling\n");
|
DEBUG("nib: Storing SL2AO for later handling\n");
|
||||||
sl2ao = opt;
|
sl2ao = opt;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif /* GNRC_IPV6_NIB_CONF_6LR */
|
#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);
|
opt);
|
||||||
break;
|
break;
|
||||||
#if GNRC_IPV6_NIB_CONF_6LR
|
#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);
|
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 */
|
/* 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);
|
_send_delayed_nbr_adv(netif, &nbr_sol->tgt, &ipv6->dst, reply_aro);
|
||||||
}
|
}
|
||||||
else {
|
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)
|
const ndp_nbr_adv_t *nbr_adv, size_t icmpv6_len)
|
||||||
{
|
{
|
||||||
size_t tmp_len = icmpv6_len - sizeof(ndp_nbr_adv_t);
|
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
|
#if GNRC_IPV6_NIB_CONF_SLAAC
|
||||||
/* TODO SLAAC behavior */
|
/* TODO SLAAC behavior */
|
||||||
#endif
|
#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)) {
|
(nce->mode & _NC)) {
|
||||||
#if GNRC_IPV6_NIB_CONF_ARSM
|
#if GNRC_IPV6_NIB_CONF_ARSM
|
||||||
bool tl2ao_avail = false;
|
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) {
|
switch (opt->type) {
|
||||||
#if GNRC_IPV6_NIB_CONF_ARSM
|
#if GNRC_IPV6_NIB_CONF_ARSM
|
||||||
case NDP_OPT_TL2A:
|
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;
|
tl2ao_avail = true;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if GNRC_IPV6_NIB_CONF_6LN
|
#if GNRC_IPV6_NIB_CONF_6LN
|
||||||
case NDP_OPT_AR:
|
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);
|
(const sixlowpan_nd_opt_ar_t *)opt, opt, nce);
|
||||||
break;
|
break;
|
||||||
#endif
|
#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) &&
|
if (!tl2ao_avail && (nbr_adv->flags & NDP_NBR_ADV_FLAGS_S) &&
|
||||||
(_get_nud_state(nce) != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE)) {
|
(_get_nud_state(nce) != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE)) {
|
||||||
/* reachability confirmed without TL2AO */
|
/* 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
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -567,7 +621,7 @@ static gnrc_pktqueue_t *_alloc_queue_entry(gnrc_pktsnip_t *pkt)
|
|||||||
}
|
}
|
||||||
#endif
|
#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,
|
gnrc_pktsnip_t *pkt, gnrc_ipv6_nib_nc_t *nce,
|
||||||
_nib_onl_entry_t *entry)
|
_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 GNRC_IPV6_NIB_CONF_ARSM
|
||||||
if ((entry != NULL) && (entry->mode & _NC) && _is_reachable(entry)) {
|
if ((entry != NULL) && (entry->mode & _NC) && _is_reachable(entry)) {
|
||||||
if (_get_nud_state(entry) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE) {
|
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,
|
_evtimer_add(entry, GNRC_IPV6_NIB_DELAY_TIMEOUT,
|
||||||
&entry->nud_timeout, NDP_DELAY_FIRST_PROBE_MS);
|
&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);
|
_nib_nc_get(entry, nce);
|
||||||
res = true;
|
res = true;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (entry != NULL) {
|
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);
|
_nib_nc_get(entry, nce);
|
||||||
res = true;
|
res = true;
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
#if GNRC_IPV6_NIB_CONF_ARSM
|
||||||
bool reset = false;
|
bool reset = false;
|
||||||
#endif
|
#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)) {
|
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);
|
GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE);
|
||||||
if (entry == NULL) {
|
if (entry == NULL) {
|
||||||
return false;
|
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
|
#if GNRC_IPV6_NIB_CONF_ARSM
|
||||||
reset = true;
|
reset = true;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -18,7 +18,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "net/gnrc/ipv6.h"
|
#include "net/gnrc/ipv6.h"
|
||||||
#include "net/gnrc/netif.h"
|
#include "net/gnrc/netif2.h"
|
||||||
|
|
||||||
#include "net/gnrc/ipv6/nib/nc.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)
|
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)));
|
printf("%s ", ipv6_addr_to_str(addr_str, &entry->ipv6, sizeof(addr_str)));
|
||||||
if (gnrc_ipv6_nib_nc_get_iface(entry) != KERNEL_PID_UNDEF) {
|
if (gnrc_ipv6_nib_nc_get_iface(entry) != KERNEL_PID_UNDEF) {
|
||||||
printf("dev #%u ", gnrc_ipv6_nib_nc_get_iface(entry));
|
printf("dev #%u ", gnrc_ipv6_nib_nc_get_iface(entry));
|
||||||
}
|
}
|
||||||
printf("lladdr %s ", gnrc_netif_addr_to_str(addr_str, sizeof(addr_str),
|
printf("lladdr %s ", gnrc_netif2_addr_to_str(entry->l2addr,
|
||||||
entry->l2addr,
|
entry->l2addr_len,
|
||||||
entry->l2addr_len));
|
addr_str));
|
||||||
if (gnrc_ipv6_nib_nc_is_router(entry)) {
|
if (gnrc_ipv6_nib_nc_is_router(entry)) {
|
||||||
printf("router");
|
printf("router");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
#include "net/gnrc/icmpv6.h"
|
#include "net/gnrc/icmpv6.h"
|
||||||
#include "net/gnrc/ipv6.h"
|
#include "net/gnrc/ipv6.h"
|
||||||
#include "net/gnrc/netif.h"
|
#include "net/gnrc/netif2/internal.h"
|
||||||
#ifdef MODULE_GNRC_SIXLOWPAN_ND
|
#ifdef MODULE_GNRC_SIXLOWPAN_ND
|
||||||
#include "net/gnrc/sixlowpan/nd.h"
|
#include "net/gnrc/sixlowpan/nd.h"
|
||||||
#endif
|
#endif
|
||||||
@ -167,8 +167,7 @@ gnrc_pktsnip_t *gnrc_ndp2_opt_sl2a_build(const uint8_t *l2addr,
|
|||||||
{
|
{
|
||||||
assert((l2addr != NULL) && (l2addr_len != 0));
|
assert((l2addr != NULL) && (l2addr_len != 0));
|
||||||
DEBUG("ndp2: building source link-layer address option (l2addr: %s)\n",
|
DEBUG("ndp2: building source link-layer address option (l2addr: %s)\n",
|
||||||
gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), l2addr,
|
gnrc_netif2_addr_to_str(l2addr, l2addr_len, addr_str));
|
||||||
l2addr_len));
|
|
||||||
return _opt_l2a_build(l2addr, l2addr_len, next, NDP_OPT_SL2A);
|
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));
|
assert((l2addr != NULL) && (l2addr_len != 0));
|
||||||
DEBUG("ndp2: building target link-layer address option (l2addr: %s)\n",
|
DEBUG("ndp2: building target link-layer address option (l2addr: %s)\n",
|
||||||
gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), l2addr,
|
gnrc_netif2_addr_to_str(l2addr, l2addr_len, addr_str));
|
||||||
l2addr_len));
|
|
||||||
return _opt_l2a_build(l2addr, l2addr_len, next, NDP_OPT_TL2A);
|
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;
|
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 *src,
|
||||||
const ipv6_addr_t *dst,
|
const ipv6_addr_t *dst,
|
||||||
gnrc_pktsnip_t *payload);
|
gnrc_pktsnip_t *payload);
|
||||||
static size_t _get_l2src(gnrc_ipv6_netif_t *netif, uint8_t *l2src,
|
static inline size_t _get_l2src(const gnrc_netif2_t *netif, uint8_t *l2src);
|
||||||
size_t l2src_maxlen);
|
|
||||||
|
|
||||||
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,
|
const ipv6_addr_t *src, const ipv6_addr_t *dst,
|
||||||
gnrc_pktsnip_t *ext_opts)
|
gnrc_pktsnip_t *ext_opts)
|
||||||
{
|
{
|
||||||
@ -250,14 +247,16 @@ void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
|||||||
sizeof(addr_str)));
|
sizeof(addr_str)));
|
||||||
DEBUG("tgt: %s, ", ipv6_addr_to_str(addr_str, tgt, 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)));
|
DEBUG("dst: %s)\n", ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)));
|
||||||
|
gnrc_netif2_acquire(netif);
|
||||||
|
do { /* XXX hidden goto */
|
||||||
/* check if there is a fitting source address to target */
|
/* check if there is a fitting source address to target */
|
||||||
if (src == NULL) {
|
if (src == NULL) {
|
||||||
src = gnrc_ipv6_netif_find_best_src_addr(netif->pid, tgt, false);
|
src = gnrc_netif2_ipv6_addr_best_src(netif, tgt, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add SL2AO based on interface and source address */
|
/* add SL2AO based on interface and source address */
|
||||||
if ((src != NULL) && !ipv6_addr_is_unspecified(src)) {
|
if ((src != NULL) && !ipv6_addr_is_unspecified(src)) {
|
||||||
l2src_len = _get_l2src(netif, l2src, sizeof(l2src));
|
l2src_len = _get_l2src(netif, l2src);
|
||||||
|
|
||||||
if (l2src_len > 0) {
|
if (l2src_len > 0) {
|
||||||
/* add source address link-layer address option */
|
/* add source address link-layer address option */
|
||||||
@ -265,8 +264,7 @@ void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
|||||||
|
|
||||||
if (hdr == NULL) {
|
if (hdr == NULL) {
|
||||||
DEBUG("ndp2: error allocating SL2AO.\n");
|
DEBUG("ndp2: error allocating SL2AO.\n");
|
||||||
gnrc_pktbuf_release(pkt);
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
pkt = hdr;
|
pkt = hdr;
|
||||||
}
|
}
|
||||||
@ -275,24 +273,32 @@ void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
|||||||
hdr = gnrc_ndp2_nbr_sol_build(tgt, pkt);
|
hdr = gnrc_ndp2_nbr_sol_build(tgt, pkt);
|
||||||
if (hdr == NULL) {
|
if (hdr == NULL) {
|
||||||
DEBUG("ndp2: error allocating neighbor solicitation.\n");
|
DEBUG("ndp2: error allocating neighbor solicitation.\n");
|
||||||
gnrc_pktbuf_release(pkt);
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
pkt = hdr;
|
pkt = hdr;
|
||||||
/* add remaining headers */
|
/* add remaining headers */
|
||||||
hdr = _build_headers(netif, src, dst, pkt);
|
hdr = _build_headers(netif, src, dst, pkt);
|
||||||
if (hdr == NULL) {
|
if (hdr == NULL) {
|
||||||
DEBUG("ndp2: error adding lower-layer headers.\n");
|
DEBUG("ndp2: error adding lower-layer headers.\n");
|
||||||
gnrc_pktbuf_release(pkt);
|
break;
|
||||||
}
|
}
|
||||||
else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
|
else {
|
||||||
GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) {
|
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");
|
DEBUG("ndp2: unable to send neighbor solicitation\n");
|
||||||
gnrc_pktbuf_release(hdr);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
gnrc_netif2_release(netif);
|
||||||
|
return;
|
||||||
|
} 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,
|
const ipv6_addr_t *dst, bool supply_tl2a,
|
||||||
gnrc_pktsnip_t *ext_opts)
|
gnrc_pktsnip_t *ext_opts)
|
||||||
{
|
{
|
||||||
@ -307,12 +313,20 @@ 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)));
|
ipv6_addr_to_str(addr_str, tgt, sizeof(addr_str)));
|
||||||
DEBUG("dst: %s, supply_tl2a: %d)\n",
|
DEBUG("dst: %s, supply_tl2a: %d)\n",
|
||||||
ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), supply_tl2a);
|
ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), supply_tl2a);
|
||||||
if ((netif->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) &&
|
gnrc_netif2_acquire(netif);
|
||||||
(netif->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV)) {
|
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;
|
adv_flags |= NDP_NBR_ADV_FLAGS_R;
|
||||||
}
|
}
|
||||||
if (ipv6_addr_is_unspecified(dst)) {
|
if (ipv6_addr_is_unspecified(dst)) {
|
||||||
memcpy(&real_dst, &ipv6_addr_all_nodes_link_local, sizeof(ipv6_addr_t));
|
memcpy(&real_dst, &ipv6_addr_all_nodes_link_local,
|
||||||
|
sizeof(ipv6_addr_t));
|
||||||
supply_tl2a = true;
|
supply_tl2a = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -324,7 +338,7 @@ void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
|||||||
uint8_t l2tgt[8];
|
uint8_t l2tgt[8];
|
||||||
size_t l2tgt_len;
|
size_t l2tgt_len;
|
||||||
/* we previously checked if we are the target, so we can take our L2tgt */
|
/* we previously checked if we are the target, so we can take our L2tgt */
|
||||||
l2tgt_len = _get_l2src(netif, l2tgt, sizeof(l2tgt));
|
l2tgt_len = _get_l2src(netif, l2tgt);
|
||||||
|
|
||||||
if (l2tgt_len > 0) {
|
if (l2tgt_len > 0) {
|
||||||
/* add target address link-layer address option */
|
/* add target address link-layer address option */
|
||||||
@ -332,15 +346,15 @@ void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
|||||||
|
|
||||||
if (hdr == NULL) {
|
if (hdr == NULL) {
|
||||||
DEBUG("ndp2: error allocating TL2AO.\n");
|
DEBUG("ndp2: error allocating TL2AO.\n");
|
||||||
gnrc_pktbuf_release(ext_opts);
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
pkt = hdr;
|
pkt = hdr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* TODO: also check if the node provides proxy services for tgt */
|
/* TODO: also check if the node provides proxy servies for tgt */
|
||||||
if ((pkt != NULL) &&
|
if ((pkt != NULL) &&
|
||||||
(!gnrc_ipv6_netif_addr_is_non_unicast(tgt) || supply_tl2a)) {
|
(netif->ipv6.addrs_flags[tgt_idx] &
|
||||||
|
GNRC_NETIF2_IPV6_ADDRS_FLAGS_ANYCAST)) {
|
||||||
/* TL2A is not supplied and tgt is not anycast */
|
/* TL2A is not supplied and tgt is not anycast */
|
||||||
adv_flags |= NDP_NBR_ADV_FLAGS_O;
|
adv_flags |= NDP_NBR_ADV_FLAGS_O;
|
||||||
}
|
}
|
||||||
@ -348,27 +362,34 @@ void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
|||||||
hdr = gnrc_ndp2_nbr_adv_build(tgt, adv_flags, pkt);
|
hdr = gnrc_ndp2_nbr_adv_build(tgt, adv_flags, pkt);
|
||||||
if (hdr == NULL) {
|
if (hdr == NULL) {
|
||||||
DEBUG("ndp2: error allocating neighbor advertisement.\n");
|
DEBUG("ndp2: error allocating neighbor advertisement.\n");
|
||||||
gnrc_pktbuf_release(pkt);
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
pkt = hdr;
|
pkt = hdr;
|
||||||
/* add remaining headers */
|
/* add remaining headers */
|
||||||
hdr = _build_headers(netif, NULL, &real_dst, pkt);
|
hdr = _build_headers(netif, NULL, &real_dst, pkt);
|
||||||
if (hdr == NULL) {
|
if (hdr == NULL) {
|
||||||
DEBUG("ndp2: error adding lower-layer headers.\n");
|
DEBUG("ndp2: error adding lower-layer headers.\n");
|
||||||
gnrc_pktbuf_release(pkt);
|
break;
|
||||||
}
|
}
|
||||||
else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
|
else {
|
||||||
GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) {
|
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");
|
DEBUG("ndp2: unable to send neighbor advertisement\n");
|
||||||
gnrc_pktbuf_release(hdr);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
gnrc_netif2_release(netif);
|
||||||
|
return;
|
||||||
|
} 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;
|
gnrc_pktsnip_t *hdr, *pkt = NULL;
|
||||||
ipv6_addr_t *src = NULL;
|
|
||||||
|
|
||||||
assert(netif != NULL);
|
assert(netif != NULL);
|
||||||
if (dst == NULL) {
|
if (dst == NULL) {
|
||||||
@ -377,18 +398,20 @@ void gnrc_ndp2_rtr_sol_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *dst)
|
|||||||
DEBUG("ndp2: send router solicitation (iface: %" PRIkernel_pid
|
DEBUG("ndp2: send router solicitation (iface: %" PRIkernel_pid
|
||||||
", dst: %s)\n", netif->pid,
|
", dst: %s)\n", netif->pid,
|
||||||
ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)));
|
ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)));
|
||||||
|
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 */
|
/* add SL2AO => check if there is a fitting source address to target */
|
||||||
if ((src = gnrc_ipv6_netif_find_best_src_addr(netif->pid, dst,
|
if ((src = gnrc_netif2_ipv6_addr_best_src(netif, dst, false)) != NULL) {
|
||||||
false)) != NULL) {
|
|
||||||
uint8_t l2src[8];
|
uint8_t l2src[8];
|
||||||
size_t l2src_len = _get_l2src(netif, l2src, sizeof(l2src));
|
size_t l2src_len = _get_l2src(netif, l2src);
|
||||||
if (l2src_len > 0) {
|
if (l2src_len > 0) {
|
||||||
/* add source address link-layer address option */
|
/* add source address link-layer address option */
|
||||||
pkt = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, NULL);
|
pkt = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, NULL);
|
||||||
if (pkt == NULL) {
|
if (pkt == NULL) {
|
||||||
DEBUG("ndp2: error allocating SL2AO.\n");
|
DEBUG("ndp2: error allocating SL2AO.\n");
|
||||||
gnrc_pktbuf_release(pkt);
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,24 +419,32 @@ void gnrc_ndp2_rtr_sol_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *dst)
|
|||||||
hdr = gnrc_ndp2_rtr_sol_build(pkt);
|
hdr = gnrc_ndp2_rtr_sol_build(pkt);
|
||||||
if (hdr == NULL) {
|
if (hdr == NULL) {
|
||||||
DEBUG("ndp2: error allocating router solicitation.\n");
|
DEBUG("ndp2: error allocating router solicitation.\n");
|
||||||
gnrc_pktbuf_release(pkt);
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
pkt = hdr;
|
pkt = hdr;
|
||||||
/* add remaining headers */
|
/* add remaining headers */
|
||||||
hdr = _build_headers(netif, src, dst, pkt);
|
hdr = _build_headers(netif, src, dst, pkt);
|
||||||
if (hdr == NULL) {
|
if (hdr == NULL) {
|
||||||
DEBUG("ndp2: error adding lower-layer headers.\n");
|
DEBUG("ndp2: error adding lower-layer headers.\n");
|
||||||
gnrc_pktbuf_release(pkt);
|
break;
|
||||||
}
|
}
|
||||||
else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
|
else {
|
||||||
GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) {
|
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");
|
DEBUG("ndp2: unable to send router advertisement\n");
|
||||||
gnrc_pktbuf_release(hdr);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
gnrc_netif2_release(netif);
|
||||||
|
return;
|
||||||
|
} 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,
|
const ipv6_addr_t *dst, bool fin,
|
||||||
gnrc_pktsnip_t *ext_opts)
|
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;
|
uint32_t reach_time = 0, retrans_timer = 0;
|
||||||
uint16_t adv_ltime = 0;
|
uint16_t adv_ltime = 0;
|
||||||
uint8_t cur_hl = 0;
|
uint8_t cur_hl = 0;
|
||||||
|
uint8_t flags = 0;
|
||||||
|
|
||||||
if (dst == NULL) {
|
if (dst == NULL) {
|
||||||
dst = &ipv6_addr_all_nodes_link_local;
|
dst = &ipv6_addr_all_nodes_link_local;
|
||||||
@ -429,17 +461,19 @@ 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",
|
DEBUG("ndp2: send router advertisement (iface: %" PRIkernel_pid ", dst: %s%s\n",
|
||||||
netif->pid, ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)),
|
netif->pid, ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)),
|
||||||
fin ? ", final" : "");
|
fin ? ", final" : "");
|
||||||
if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_MTU) {
|
gnrc_netif2_acquire(netif);
|
||||||
if ((hdr = gnrc_ndp2_opt_mtu_build(netif->mtu, pkt)) == NULL) {
|
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");
|
DEBUG("ndp rtr: no space left in packet buffer\n");
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
pkt = hdr;
|
pkt = hdr;
|
||||||
}
|
}
|
||||||
if (src == NULL) {
|
if (src == NULL) {
|
||||||
/* get address from source selection algorithm.
|
/* get address from source selection algorithm.
|
||||||
* Only link local addresses may be used (RFC 4861 section 4.1) */
|
* Only link local addresses may be used (RFC 4861 section 4.1) */
|
||||||
src = gnrc_ipv6_netif_find_best_src_addr(netif->pid, dst, true);
|
src = gnrc_netif2_ipv6_addr_best_src(netif, dst, true);
|
||||||
}
|
}
|
||||||
/* add SL2A for source address */
|
/* add SL2A for source address */
|
||||||
if (src != NULL) {
|
if (src != NULL) {
|
||||||
@ -449,58 +483,69 @@ void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src,
|
|||||||
/* optimization note: MAY also be omitted to facilitate in-bound load balancing over
|
/* optimization note: MAY also be omitted to facilitate in-bound load balancing over
|
||||||
* replicated interfaces.
|
* replicated interfaces.
|
||||||
* source: https://tools.ietf.org/html/rfc4861#section-6.2.3 */
|
* source: https://tools.ietf.org/html/rfc4861#section-6.2.3 */
|
||||||
l2src_len = _get_l2src(netif, l2src, sizeof(l2src));
|
l2src_len = _get_l2src(netif, l2src);
|
||||||
if (l2src_len > 0) {
|
if (l2src_len > 0) {
|
||||||
/* add source address link-layer address option */
|
/* add source address link-layer address option */
|
||||||
hdr = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, pkt);
|
hdr = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, pkt);
|
||||||
|
|
||||||
if (hdr == NULL) {
|
if (hdr == NULL) {
|
||||||
DEBUG("ndp2: error allocating Source Link-layer address option.\n");
|
DEBUG("ndp2: error allocating Source Link-layer address "
|
||||||
gnrc_pktbuf_release(pkt);
|
"option.\n");
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
pkt = hdr;
|
pkt = hdr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_CUR_HL) {
|
if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_CUR_HL) {
|
||||||
cur_hl = netif->cur_hl;
|
cur_hl = netif->cur_hl;
|
||||||
}
|
}
|
||||||
if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_REACH_TIME) {
|
if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_REACH_TIME) {
|
||||||
|
if (netif->ipv6.reach_time_base > (3600 * MS_PER_SEC)) {
|
||||||
if (netif->reach_time > (3600 * US_PER_SEC)) { /* reach_time > 1 hour */
|
/* reach_time > 1 hour */
|
||||||
reach_time = (3600 * MS_PER_SEC);
|
reach_time = (3600 * MS_PER_SEC);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
reach_time = netif->reach_time / US_PER_MS;
|
reach_time = netif->ipv6.reach_time_base;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_RETRANS_TIMER) {
|
if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_RETRANS_TIMER) {
|
||||||
retrans_timer = netif->retrans_timer / US_PER_MS;
|
retrans_timer = netif->ipv6.retrans_time;
|
||||||
}
|
}
|
||||||
if (!fin) {
|
if (!fin) {
|
||||||
/* TODO set netif dependent adv_ltime */
|
adv_ltime = netif->ipv6.rtr_ltime;
|
||||||
adv_ltime = 1800U;
|
|
||||||
}
|
}
|
||||||
hdr = gnrc_ndp2_rtr_adv_build(cur_hl,
|
if (netif->ipv6.aac_mode == GNRC_NETIF2_AAC_DHCP) {
|
||||||
(netif->flags & (GNRC_IPV6_NETIF_FLAGS_OTHER_CONF |
|
flags |= NDP_RTR_ADV_FLAGS_M;
|
||||||
GNRC_IPV6_NETIF_FLAGS_MANAGED)) >> 8,
|
if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_O_FLAG) {
|
||||||
adv_ltime, reach_time, retrans_timer, pkt);
|
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) {
|
if (hdr == NULL) {
|
||||||
DEBUG("ndp2: error allocating router advertisement.\n");
|
DEBUG("ndp2: error allocating router advertisement.\n");
|
||||||
gnrc_pktbuf_release(pkt);
|
break;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
pkt = hdr;
|
pkt = hdr;
|
||||||
hdr = _build_headers(netif, src, dst, pkt);
|
hdr = _build_headers(netif, src, dst, pkt);
|
||||||
if (hdr == NULL) {
|
if (hdr == NULL) {
|
||||||
DEBUG("ndp2: error adding lower-layer headers.\n");
|
DEBUG("ndp2: error adding lower-layer headers.\n");
|
||||||
gnrc_pktbuf_release(pkt);
|
break;
|
||||||
}
|
}
|
||||||
else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
|
else {
|
||||||
GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) {
|
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");
|
DEBUG("ndp2: unable to send router solicitation\n");
|
||||||
gnrc_pktbuf_release(hdr);
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
gnrc_netif2_release(netif);
|
||||||
|
return;
|
||||||
|
} while (0);
|
||||||
|
gnrc_pktbuf_release(pkt);
|
||||||
|
gnrc_netif2_release(netif);
|
||||||
#else
|
#else
|
||||||
(void)netif;
|
(void)netif;
|
||||||
(void)src;
|
(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 */
|
#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 *src,
|
||||||
const ipv6_addr_t *dst,
|
const ipv6_addr_t *dst,
|
||||||
gnrc_pktsnip_t *payload)
|
gnrc_pktsnip_t *payload)
|
||||||
@ -536,37 +581,16 @@ static gnrc_pktsnip_t *_build_headers(gnrc_ipv6_netif_t *netif,
|
|||||||
return l2hdr;
|
return l2hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t _get_l2src(gnrc_ipv6_netif_t *netif, uint8_t *l2src,
|
static inline size_t _get_l2src(const gnrc_netif2_t *netif, uint8_t *l2src)
|
||||||
size_t l2src_maxlen)
|
|
||||||
{
|
{
|
||||||
bool try_long = false;
|
#if GNRC_NETIF2_L2ADDR_MAXLEN > 0
|
||||||
int res;
|
memcpy(l2src, netif->l2addr, netif->l2addr_len);
|
||||||
uint16_t l2src_len;
|
return netif->l2addr_len;
|
||||||
/* maximum address length that fits into a minimum length (8) S/TL2A option */
|
#else
|
||||||
const uint16_t max_short_len = 6;
|
(void)netif;
|
||||||
|
(void)l2src;
|
||||||
/* try getting source address */
|
return 0;
|
||||||
if ((gnrc_netapi_get(netif->pid, NETOPT_SRC_LEN, 0, &l2src_len,
|
#endif
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
@ -106,8 +106,7 @@ static int _nib_neigh(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if ((argc > 5) && /* TODO also check if interface supports link-layers or not */
|
if ((argc > 5) && /* TODO also check if interface supports link-layers or not */
|
||||||
(l2addr_len = gnrc_netif_addr_from_str(l2addr, sizeof(l2addr),
|
(l2addr_len = gnrc_netif2_addr_from_str(argv[5], l2addr)) == 0) {
|
||||||
argv[5])) == 0) {
|
|
||||||
_usage_nib_neigh(argv);
|
_usage_nib_neigh(argv);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -150,7 +149,7 @@ static int _nib_prefix(int argc, char **argv)
|
|||||||
ipv6_addr_t pfx;
|
ipv6_addr_t pfx;
|
||||||
unsigned iface = atoi(argv[3]);
|
unsigned iface = atoi(argv[3]);
|
||||||
unsigned pfx_len = ipv6_addr_split_prefix(argv[4]);
|
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) {
|
if (ipv6_addr_from_str(&pfx, argv[4]) == NULL) {
|
||||||
_usage_nib_prefix(argv);
|
_usage_nib_prefix(argv);
|
||||||
|
|||||||
@ -44,27 +44,13 @@ static bool _is_number(char *str)
|
|||||||
return true;
|
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)
|
static void _set_test_mode(int argc, char **argv, uint8_t mode)
|
||||||
{
|
{
|
||||||
(void) argc;
|
(void) argc;
|
||||||
if (_is_number(argv[1])) {
|
if (_is_number(argv[1])) {
|
||||||
kernel_pid_t dev = atoi(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));
|
gnrc_netapi_set(dev, NETOPT_RF_TESTMODE, 0, (void *)&mode, sizeof(mode));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,10 @@ BOARD_INSUFFICIENT_MEMORY := chronos nucleo32-f031 nucleo32-f042
|
|||||||
|
|
||||||
USEMODULE += gnrc_ipv6
|
USEMODULE += gnrc_ipv6
|
||||||
USEMODULE += gnrc_ipv6_nib
|
USEMODULE += gnrc_ipv6_nib
|
||||||
|
USEMODULE += gnrc_netif2
|
||||||
USEMODULE += embunit
|
USEMODULE += embunit
|
||||||
|
USEMODULE += netdev_eth
|
||||||
|
USEMODULE += netdev_test
|
||||||
|
|
||||||
CFLAGS += -DDEVELHELP
|
CFLAGS += -DDEVELHELP
|
||||||
CFLAGS += -DGNRC_NETTYPE_NDP2=GNRC_NETTYPE_TEST
|
CFLAGS += -DGNRC_NETTYPE_NDP2=GNRC_NETTYPE_TEST
|
||||||
|
|||||||
@ -22,14 +22,20 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "net/gnrc.h"
|
#include "net/gnrc.h"
|
||||||
|
#include "net/gnrc/netif2.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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);
|
void _tests_init(void);
|
||||||
int _mock_netif_get(gnrc_netapi_opt_t *opt);
|
int _mock_netif_get(gnrc_netapi_opt_t *opt);
|
||||||
|
|||||||
@ -33,12 +33,6 @@
|
|||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
|
|
||||||
#define _BUFFER_SIZE (128)
|
#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 uint8_t _loc_l2[] = { _LL0, _LL1, _LL2, _LL3, _LL4, _LL5 };
|
||||||
static const ipv6_addr_t _loc_ll = { {
|
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;
|
msg_t msg;
|
||||||
gnrc_ipv6_nib_nc_t nce;
|
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;
|
gnrc_pktsnip_t *pkt;
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH,
|
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));
|
NULL, &nce));
|
||||||
if (iface != KERNEL_PID_UNDEF) {
|
if (netif != NULL) {
|
||||||
ndp_nbr_sol_t *nbr_sol;
|
ndp_nbr_sol_t *nbr_sol;
|
||||||
bool contains_sl2ao = false;
|
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,
|
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE,
|
||||||
gnrc_ipv6_nib_nc_get_nud_state(&nce));
|
gnrc_ipv6_nib_nc_get_nud_state(&nce));
|
||||||
TEST_ASSERT(!gnrc_ipv6_nib_nc_is_router(&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,
|
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_GC,
|
||||||
gnrc_ipv6_nib_nc_get_ar_state(&nce));
|
gnrc_ipv6_nib_nc_get_ar_state(&nce));
|
||||||
TEST_ASSERT_EQUAL_INT(1, msg_avail());
|
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)
|
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)
|
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)
|
static void test_get_next_hop_l2addr__link_local_static_conf(void)
|
||||||
{
|
{
|
||||||
gnrc_ipv6_nib_nc_t nce;
|
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)));
|
_rem_l2, sizeof(_rem_l2)));
|
||||||
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
|
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
|
||||||
_mock_netif_pid,
|
_mock_netif,
|
||||||
NULL, &nce));
|
NULL, &nce));
|
||||||
TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0),
|
TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0),
|
||||||
"_rem_ll != nce.ipv6");
|
"_rem_ll != nce.ipv6");
|
||||||
@ -152,7 +146,7 @@ static void test_get_next_hop_l2addr__link_local_static_conf(void)
|
|||||||
"_rem_l2 != nce.l2addr");
|
"_rem_l2 != nce.l2addr");
|
||||||
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED,
|
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED,
|
||||||
gnrc_ipv6_nib_nc_get_nud_state(&nce));
|
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(!gnrc_ipv6_nib_nc_is_router(&nce));
|
||||||
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_MANUAL,
|
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_MANUAL,
|
||||||
gnrc_ipv6_nib_nc_get_ar_state(&nce));
|
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 */
|
/* trigger sending of neighbor discovery */
|
||||||
TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH,
|
TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH,
|
||||||
gnrc_ipv6_nib_get_next_hop_l2addr(dst,
|
gnrc_ipv6_nib_get_next_hop_l2addr(dst,
|
||||||
_mock_netif_pid,
|
_mock_netif,
|
||||||
NULL, &nce));
|
NULL, &nce));
|
||||||
TEST_ASSERT_EQUAL_INT(1, msg_avail());
|
TEST_ASSERT_EQUAL_INT(1, msg_avail());
|
||||||
/* clear message queue */
|
/* 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->type = NDP_OPT_TL2A;
|
||||||
tl2ao->len = 1;
|
tl2ao->len = 1;
|
||||||
memcpy(tl2ao + 1, _rem_l2, sizeof(_rem_l2));
|
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);
|
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);
|
_simulate_ndp_handshake(&_loc_ll, &_rem_ll, adv_flags);
|
||||||
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
|
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
|
||||||
_mock_netif_pid,
|
_mock_netif,
|
||||||
NULL, &nce));
|
NULL, &nce));
|
||||||
TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0),
|
TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0),
|
||||||
"_rem_ll != nce.ipv6");
|
"_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");
|
"_rem_l2 != nce.l2addr");
|
||||||
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE,
|
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE,
|
||||||
gnrc_ipv6_nib_nc_get_nud_state(&nce));
|
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) {
|
if (adv_flags & NDP_NBR_ADV_FLAGS_R) {
|
||||||
TEST_ASSERT(gnrc_ipv6_nib_nc_is_router(&nce));
|
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);
|
_simulate_ndp_handshake(&_loc_ll, &_rem_ll, NDP_NBR_ADV_FLAGS_S);
|
||||||
TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH,
|
TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH,
|
||||||
gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
|
gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
|
||||||
KERNEL_PID_UNDEF,
|
NULL,
|
||||||
NULL, &nce));
|
NULL, &nce));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,7 +251,7 @@ static void test_handle_pkt__unknown_type(void)
|
|||||||
memcpy(&ipv6->dst, &_rem_ll, sizeof(ipv6->dst));
|
memcpy(&ipv6->dst, &_rem_ll, sizeof(ipv6->dst));
|
||||||
icmpv6->type = ICMPV6_ECHO_REQ;
|
icmpv6->type = ICMPV6_ECHO_REQ;
|
||||||
icmpv6->code = 0;
|
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));
|
sizeof(icmpv6_hdr_t));
|
||||||
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"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,
|
size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_sol_nodes, 194U, 0U,
|
||||||
&_loc_ll, _rem_l2, sizeof(_rem_l2));
|
&_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_sol_nodes, 255U, 201U,
|
||||||
&_loc_ll, _rem_l2, sizeof(_rem_l2));
|
&_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
_set_nbr_sol(&_rem_ll, &_loc_sol_nodes, 255U, 0U, &_loc_ll, _rem_l2,
|
||||||
sizeof(_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);
|
sizeof(ndp_nbr_sol_t) - 1);
|
||||||
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"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,
|
&ipv6_addr_all_routers_site_local, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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->type = NDP_OPT_SL2A;
|
||||||
opt->len = 0U;
|
opt->len = 0U;
|
||||||
icmpv6_len += sizeof(ndp_opt_t);
|
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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
size_t icmpv6_len = _set_nbr_sol(&ipv6_addr_unspecified, &_loc_ll, 255U, 0U,
|
||||||
&_loc_ll, NULL, 0);
|
&_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
255U, 0U, &_loc_ll, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
255U, 0U, &_rem_ll, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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_nbr_adv_t *nbr_adv;
|
||||||
ndp_opt_t *tl2ao;
|
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_NOT_NULL(pkt);
|
||||||
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_NETIF, pkt->type);
|
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_NETIF, pkt->type);
|
||||||
TEST_ASSERT(sizeof(gnrc_netif_hdr_t) <= pkt->size);
|
TEST_ASSERT(sizeof(gnrc_netif_hdr_t) <= pkt->size);
|
||||||
netif_hdr = pkt->data;
|
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 */
|
/* second snip is an IPv6 header to dst */
|
||||||
TEST_ASSERT_NOT_NULL(pkt->next);
|
TEST_ASSERT_NOT_NULL(pkt->next);
|
||||||
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_IPV6, pkt->next->type);
|
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,
|
255U, 0U, &_loc_ll, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"Expected neighbor cache entry");
|
"Expected neighbor cache entry");
|
||||||
TEST_ASSERT_MESSAGE(ipv6_addr_equal(&_rem_ll, &nce.ipv6),
|
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");
|
"_rem_l2 != nce.l2addr");
|
||||||
TEST_ASSERT_EQUAL_INT(exp_nud_state, gnrc_ipv6_nib_nc_get_nud_state(&nce));
|
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(!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(exp_ar_state, gnrc_ipv6_nib_nc_get_ar_state(&nce));
|
||||||
TEST_ASSERT_EQUAL_INT(1, msg_avail());
|
TEST_ASSERT_EQUAL_INT(1, msg_avail());
|
||||||
msg_receive(&msg);
|
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,
|
size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_sol_nodes,
|
||||||
255U, 0U, &_loc_ll, NULL, 0);
|
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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
TEST_ASSERT_EQUAL_INT(1, msg_avail());
|
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,
|
NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
&_loc_ll, _rem_l2,
|
||||||
sizeof(_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);
|
sizeof(ndp_nbr_adv_t) - 1);
|
||||||
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"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,
|
&ipv6_addr_all_routers_site_local, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
255U, 0U, NDP_NBR_ADV_FLAGS_S, &_loc_ll,
|
||||||
NULL, 0);
|
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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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->type = NDP_OPT_SL2A;
|
||||||
opt->len = 0U;
|
opt->len = 0U;
|
||||||
icmpv6_len += sizeof(ndp_opt_t);
|
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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
NDP_NBR_ADV_FLAGS_S, &_loc_ll,
|
||||||
_rem_l2, sizeof(_rem_l2));
|
_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
TEST_ASSERT_EQUAL_INT(0, msg_avail());
|
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));
|
memcpy(opt->data, _loc_l2, sizeof(_loc_l2));
|
||||||
return 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:
|
case NETOPT_IS_WIRED:
|
||||||
return 1;
|
return 1;
|
||||||
case NETOPT_MAX_PACKET_SIZE: {
|
case NETOPT_MAX_PACKET_SIZE: {
|
||||||
|
|||||||
@ -16,63 +16,73 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "msg.h"
|
#include "msg.h"
|
||||||
#include "net/gnrc.h"
|
#include "net/gnrc.h"
|
||||||
|
#include "net/ethernet.h"
|
||||||
#include "net/gnrc/ipv6/nib.h"
|
#include "net/gnrc/ipv6/nib.h"
|
||||||
#include "net/gnrc/ipv6/netif.h"
|
#include "net/gnrc/netif2/ethernet.h"
|
||||||
#include "net/gnrc/netdev.h"
|
#include "net/gnrc/netif2/internal.h"
|
||||||
|
#include "net/netdev_test.h"
|
||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
#define _MSG_QUEUE_SIZE (2)
|
#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 char _mock_netif_stack[THREAD_STACKSIZE_DEFAULT];
|
||||||
static gnrc_netreg_entry_t dumper;
|
static gnrc_netreg_entry_t dumper;
|
||||||
static msg_t _main_msg_queue[_MSG_QUEUE_SIZE];
|
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)
|
|
||||||
{
|
|
||||||
msg_t msg, reply = { .type = GNRC_NETAPI_MSG_TYPE_ACK };
|
|
||||||
|
|
||||||
(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _common_set_up(void)
|
void _common_set_up(void)
|
||||||
{
|
{
|
||||||
|
assert(_mock_netif != NULL);
|
||||||
gnrc_ipv6_nib_init();
|
gnrc_ipv6_nib_init();
|
||||||
gnrc_ipv6_nib_init_iface(_mock_netif_pid);
|
gnrc_netif2_acquire(_mock_netif);
|
||||||
|
gnrc_ipv6_nib_init_iface(_mock_netif);
|
||||||
|
gnrc_netif2_release(_mock_netif);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _get_max_packet_size(netdev_t *dev, void *value, size_t max_len)
|
||||||
|
{
|
||||||
|
(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)
|
void _tests_init(void)
|
||||||
{
|
{
|
||||||
msg_init_queue(_main_msg_queue, _MSG_QUEUE_SIZE);
|
msg_init_queue(_main_msg_queue, _MSG_QUEUE_SIZE);
|
||||||
_mock_netif_pid = thread_create(_mock_netif_stack,
|
netdev_test_setup(&_mock_netdev, 0);
|
||||||
sizeof(_mock_netif_stack),
|
netdev_test_set_get_cb(&_mock_netdev, NETOPT_DEVICE_TYPE,
|
||||||
GNRC_NETDEV_MAC_PRIO,
|
_get_device_type);
|
||||||
THREAD_CREATE_STACKTEST,
|
netdev_test_set_get_cb(&_mock_netdev, NETOPT_MAX_PACKET_SIZE,
|
||||||
_mock_netif_thread, NULL, "mock_netif");
|
_get_max_packet_size);
|
||||||
assert(_mock_netif_pid > KERNEL_PID_UNDEF);
|
netdev_test_set_get_cb(&_mock_netdev, NETOPT_ADDRESS,
|
||||||
gnrc_netif_add(_mock_netif_pid);
|
_get_address);
|
||||||
gnrc_ipv6_netif_init_by_dev();
|
_mock_netif = gnrc_netif2_ethernet_create(
|
||||||
thread_yield();
|
_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,
|
gnrc_netreg_entry_init_pid(&dumper, GNRC_NETREG_DEMUX_CTX_ALL,
|
||||||
sched_active_pid);
|
sched_active_pid);
|
||||||
gnrc_netreg_register(GNRC_NETTYPE_NDP2, &dumper);
|
gnrc_netreg_register(GNRC_NETTYPE_NDP2, &dumper);
|
||||||
|
|||||||
@ -8,8 +8,10 @@ BOARD_INSUFFICIENT_MEMORY := chronos nucleo-f030 nucleo-l053 nucleo32-f031 \
|
|||||||
USEMODULE += gnrc_ipv6
|
USEMODULE += gnrc_ipv6
|
||||||
USEMODULE += gnrc_sixlowpan
|
USEMODULE += gnrc_sixlowpan
|
||||||
USEMODULE += gnrc_ipv6_nib_6ln
|
USEMODULE += gnrc_ipv6_nib_6ln
|
||||||
|
USEMODULE += gnrc_netif2
|
||||||
USEMODULE += embunit
|
USEMODULE += embunit
|
||||||
USEMODULE += netopt
|
USEMODULE += netdev_ieee802154
|
||||||
|
USEMODULE += netdev_test
|
||||||
|
|
||||||
CFLAGS += -DDEVELHELP
|
CFLAGS += -DDEVELHELP
|
||||||
CFLAGS += -DGNRC_NETTYPE_NDP2=GNRC_NETTYPE_TEST
|
CFLAGS += -DGNRC_NETTYPE_NDP2=GNRC_NETTYPE_TEST
|
||||||
|
|||||||
@ -22,14 +22,22 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "net/gnrc.h"
|
#include "net/gnrc.h"
|
||||||
|
#include "net/gnrc/netif2.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#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);
|
void _tests_init(void);
|
||||||
int _mock_netif_get(gnrc_netapi_opt_t *opt);
|
int _mock_netif_get(gnrc_netapi_opt_t *opt);
|
||||||
|
|||||||
@ -33,14 +33,6 @@
|
|||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
|
|
||||||
#define _BUFFER_SIZE (128)
|
#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,
|
static const uint8_t _loc_l2[] = { _LL0, _LL1, _LL2, _LL3,
|
||||||
_LL4, _LL5, _LL6, _LL7 };
|
_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;
|
gnrc_ipv6_nib_nc_t nce;
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH,
|
TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH,
|
||||||
gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
|
gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll, NULL,
|
||||||
KERNEL_PID_UNDEF,
|
|
||||||
NULL, &nce));
|
NULL, &nce));
|
||||||
TEST_ASSERT_EQUAL_INT(0, msg_avail());
|
TEST_ASSERT_EQUAL_INT(0, msg_avail());
|
||||||
TEST_ASSERT(gnrc_pktbuf_is_empty());
|
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;
|
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)));
|
_rem_l2, sizeof(_rem_l2)));
|
||||||
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
|
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
|
||||||
_mock_netif_pid,
|
_mock_netif,
|
||||||
NULL, &nce));
|
NULL, &nce));
|
||||||
TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0),
|
TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0),
|
||||||
"_rem_ll != nce.ipv6");
|
"_rem_ll != nce.ipv6");
|
||||||
@ -102,7 +93,7 @@ static void test_get_next_hop_l2addr__link_local_static_conf(void)
|
|||||||
"_rem_l2 != nce.l2addr");
|
"_rem_l2 != nce.l2addr");
|
||||||
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED,
|
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED,
|
||||||
gnrc_ipv6_nib_nc_get_nud_state(&nce));
|
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(!gnrc_ipv6_nib_nc_is_router(&nce));
|
||||||
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_MANUAL,
|
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_MANUAL,
|
||||||
gnrc_ipv6_nib_nc_get_ar_state(&nce));
|
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;
|
gnrc_ipv6_nib_nc_t nce;
|
||||||
|
|
||||||
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
|
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
|
||||||
_mock_netif_pid,
|
_mock_netif,
|
||||||
NULL, &nce));
|
NULL, &nce));
|
||||||
TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0),
|
TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0),
|
||||||
"_rem_ll != nce.ipv6");
|
"_rem_ll != nce.ipv6");
|
||||||
@ -124,7 +115,7 @@ static void test_get_next_hop_l2addr__link_local(void)
|
|||||||
"_rem_l2 != nce.l2addr");
|
"_rem_l2 != nce.l2addr");
|
||||||
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE,
|
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE,
|
||||||
gnrc_ipv6_nib_nc_get_nud_state(&nce));
|
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(!gnrc_ipv6_nib_nc_is_router(&nce));
|
||||||
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED,
|
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED,
|
||||||
gnrc_ipv6_nib_nc_get_ar_state(&nce));
|
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));
|
memcpy(&ipv6->dst, &_rem_ll, sizeof(ipv6->dst));
|
||||||
icmpv6->type = ICMPV6_ECHO_REQ;
|
icmpv6->type = ICMPV6_ECHO_REQ;
|
||||||
icmpv6->code = 0;
|
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));
|
sizeof(icmpv6_hdr_t));
|
||||||
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"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,
|
size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_ll, 194U, 0U,
|
||||||
&_loc_ll, _rem_l2, sizeof(_rem_l2));
|
&_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_ll, 255U, 201U,
|
||||||
&_loc_ll, _rem_l2, sizeof(_rem_l2));
|
&_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
_set_nbr_sol(&_rem_ll, &_loc_ll, 255U, 0U, &_loc_ll, _rem_l2,
|
||||||
sizeof(_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);
|
sizeof(ndp_nbr_sol_t) - 1);
|
||||||
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"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,
|
&ipv6_addr_all_routers_site_local, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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->type = NDP_OPT_SL2A;
|
||||||
opt->len = 0U;
|
opt->len = 0U;
|
||||||
icmpv6_len += sizeof(ndp_opt_t);
|
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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
size_t icmpv6_len = _set_nbr_sol(&ipv6_addr_unspecified, &_loc_ll, 255U, 0U,
|
||||||
&_loc_ll, NULL, 0);
|
&_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
255U, 0U, &_loc_ll, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
255U, 0U, &_rem_ll, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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;
|
ipv6_hdr_t *ipv6_hdr;
|
||||||
ndp_nbr_adv_t *nbr_adv;
|
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_NOT_NULL(pkt);
|
||||||
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_NETIF, pkt->type);
|
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_NETIF, pkt->type);
|
||||||
TEST_ASSERT(sizeof(gnrc_netif_hdr_t) <= pkt->size);
|
TEST_ASSERT(sizeof(gnrc_netif_hdr_t) <= pkt->size);
|
||||||
netif_hdr = pkt->data;
|
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 */
|
/* second snip is an IPv6 header to dst */
|
||||||
TEST_ASSERT_NOT_NULL(pkt->next);
|
TEST_ASSERT_NOT_NULL(pkt->next);
|
||||||
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_IPV6, pkt->next->type);
|
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,
|
255U, 0U, &_loc_ll, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"Expected neighbor cache entry");
|
"Expected neighbor cache entry");
|
||||||
TEST_ASSERT_MESSAGE(ipv6_addr_equal(&_rem_ll, &nce.ipv6),
|
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");
|
"_rem_l2 != nce.l2addr");
|
||||||
TEST_ASSERT_EQUAL_INT(exp_nud_state, gnrc_ipv6_nib_nc_get_nud_state(&nce));
|
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(!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(exp_ar_state, gnrc_ipv6_nib_nc_get_ar_state(&nce));
|
||||||
TEST_ASSERT_EQUAL_INT(1, msg_avail());
|
TEST_ASSERT_EQUAL_INT(1, msg_avail());
|
||||||
msg_receive(&msg);
|
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,
|
size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_ll,
|
||||||
255U, 0U, &_loc_ll, NULL, 0);
|
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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
TEST_ASSERT_EQUAL_INT(1, msg_avail());
|
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,
|
NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
&_loc_ll, _rem_l2,
|
||||||
sizeof(_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);
|
sizeof(ndp_nbr_adv_t) - 1);
|
||||||
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"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,
|
&ipv6_addr_all_routers_site_local, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
255U, 0U, NDP_NBR_ADV_FLAGS_S, &_loc_ll,
|
||||||
NULL, 0);
|
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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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->type = NDP_OPT_SL2A;
|
||||||
opt->len = 0U;
|
opt->len = 0U;
|
||||||
icmpv6_len += sizeof(ndp_opt_t);
|
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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2,
|
||||||
sizeof(_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
/* TODO: check other views as well */
|
/* 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,
|
NDP_NBR_ADV_FLAGS_S, &_loc_ll,
|
||||||
_rem_l2, sizeof(_rem_l2));
|
_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),
|
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
|
||||||
"There is an unexpected neighbor cache entry");
|
"There is an unexpected neighbor cache entry");
|
||||||
TEST_ASSERT_EQUAL_INT(0, msg_avail());
|
TEST_ASSERT_EQUAL_INT(0, msg_avail());
|
||||||
|
|||||||
@ -16,63 +16,84 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "msg.h"
|
#include "msg.h"
|
||||||
#include "net/gnrc.h"
|
#include "net/gnrc.h"
|
||||||
|
#include "net/ethernet.h"
|
||||||
#include "net/gnrc/ipv6/nib.h"
|
#include "net/gnrc/ipv6/nib.h"
|
||||||
#include "net/gnrc/ipv6/netif.h"
|
#include "net/gnrc/netif2/ieee802154.h"
|
||||||
#include "net/gnrc/netdev.h"
|
#include "net/gnrc/netif2/internal.h"
|
||||||
|
#include "net/netdev_test.h"
|
||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
#define _MSG_QUEUE_SIZE (2)
|
#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 char _mock_netif_stack[THREAD_STACKSIZE_DEFAULT];
|
||||||
static gnrc_netreg_entry_t dumper;
|
static gnrc_netreg_entry_t dumper;
|
||||||
static msg_t _main_msg_queue[_MSG_QUEUE_SIZE];
|
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)
|
|
||||||
{
|
|
||||||
msg_t msg, reply = { .type = GNRC_NETAPI_MSG_TYPE_ACK };
|
|
||||||
|
|
||||||
(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _common_set_up(void)
|
void _common_set_up(void)
|
||||||
{
|
{
|
||||||
|
assert(_mock_netif != NULL);
|
||||||
gnrc_ipv6_nib_init();
|
gnrc_ipv6_nib_init();
|
||||||
gnrc_ipv6_nib_init_iface(_mock_netif_pid);
|
gnrc_netif2_acquire(_mock_netif);
|
||||||
|
gnrc_ipv6_nib_init_iface(_mock_netif);
|
||||||
|
gnrc_netif2_release(_mock_netif);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _get_max_packet_size(netdev_t *dev, void *value, size_t max_len)
|
||||||
|
{
|
||||||
|
(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)
|
void _tests_init(void)
|
||||||
{
|
{
|
||||||
msg_init_queue(_main_msg_queue, _MSG_QUEUE_SIZE);
|
msg_init_queue(_main_msg_queue, _MSG_QUEUE_SIZE);
|
||||||
_mock_netif_pid = thread_create(_mock_netif_stack,
|
netdev_test_setup(&_mock_netdev, 0);
|
||||||
sizeof(_mock_netif_stack),
|
netdev_test_set_get_cb(&_mock_netdev, NETOPT_DEVICE_TYPE,
|
||||||
GNRC_NETDEV_MAC_PRIO,
|
_get_device_type);
|
||||||
THREAD_CREATE_STACKTEST,
|
netdev_test_set_get_cb(&_mock_netdev, NETOPT_MAX_PACKET_SIZE,
|
||||||
_mock_netif_thread, NULL, "mock_netif");
|
_get_max_packet_size);
|
||||||
assert(_mock_netif_pid > KERNEL_PID_UNDEF);
|
netdev_test_set_get_cb(&_mock_netdev, NETOPT_SRC_LEN,
|
||||||
gnrc_netif_add(_mock_netif_pid);
|
_get_src_len);
|
||||||
gnrc_ipv6_netif_init_by_dev();
|
netdev_test_set_get_cb(&_mock_netdev, NETOPT_ADDRESS_LONG,
|
||||||
thread_yield();
|
_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,
|
gnrc_netreg_entry_init_pid(&dumper, GNRC_NETREG_DEMUX_CTX_ALL,
|
||||||
sched_active_pid);
|
sched_active_pid);
|
||||||
gnrc_netreg_register(GNRC_NETTYPE_NDP2, &dumper);
|
gnrc_netreg_register(GNRC_NETTYPE_NDP2, &dumper);
|
||||||
|
|||||||
@ -4,8 +4,11 @@ include ../Makefile.tests_common
|
|||||||
|
|
||||||
BOARD_INSUFFICIENT_MEMORY := nucleo32-f031 nucleo32-f042
|
BOARD_INSUFFICIENT_MEMORY := nucleo32-f031 nucleo32-f042
|
||||||
|
|
||||||
|
USEMODULE += gnrc_ipv6_nib
|
||||||
USEMODULE += gnrc_ndp2
|
USEMODULE += gnrc_ndp2
|
||||||
|
USEMODULE += gnrc_netif2
|
||||||
USEMODULE += embunit
|
USEMODULE += embunit
|
||||||
|
USEMODULE += netdev_test
|
||||||
|
|
||||||
CFLAGS += -DGNRC_NETTYPE_NDP2=GNRC_NETTYPE_TEST
|
CFLAGS += -DGNRC_NETTYPE_NDP2=GNRC_NETTYPE_TEST
|
||||||
CFLAGS += -DGNRC_PKTBUF_SIZE=512
|
CFLAGS += -DGNRC_PKTBUF_SIZE=512
|
||||||
|
|||||||
@ -25,12 +25,15 @@
|
|||||||
#include "embUnit.h"
|
#include "embUnit.h"
|
||||||
#include "embUnit/embUnit.h"
|
#include "embUnit/embUnit.h"
|
||||||
#include "msg.h"
|
#include "msg.h"
|
||||||
|
#include "net/gnrc/ipv6/nib/conf.h"
|
||||||
#include "net/gnrc/netapi.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/netreg.h"
|
||||||
#include "net/gnrc/pktbuf.h"
|
#include "net/gnrc/pktbuf.h"
|
||||||
#include "net/icmpv6.h"
|
#include "net/icmpv6.h"
|
||||||
#include "net/ndp.h"
|
#include "net/ndp.h"
|
||||||
|
#include "net/netdev_test.h"
|
||||||
#include "net/netopt.h"
|
#include "net/netopt.h"
|
||||||
#include "sched.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 } };
|
0x64, 0x3e, 0x76, 0x0d, 0x30, 0x10, 0x0d, 0xc8 } };
|
||||||
static const uint8_t test_src_l2[] = { 0xe7, 0x43, 0xb7, 0x74, 0xd7, 0xa9, 0x30, 0x74 };
|
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 void init_pkt_handler(void);
|
||||||
static inline size_t ceil8(size_t size);
|
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;
|
return &hdr->dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ASSERT_NETIF_HDR(iface, pkt) \
|
#define ASSERT_NETIF_HDR(netif, pkt) \
|
||||||
TEST_ASSERT_NOT_NULL(pkt); \
|
TEST_ASSERT_NOT_NULL(pkt); \
|
||||||
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_NETIF, pkt->type); \
|
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_NETIF, pkt->type); \
|
||||||
TEST_ASSERT_NOT_NULL(pkt->data); \
|
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) \
|
#define ASSERT_IPV6_HDR(src, dst, pkt) \
|
||||||
TEST_ASSERT_NOT_NULL(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)
|
static void test_nbr_sol_send(const ipv6_addr_t *src)
|
||||||
{
|
{
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
gnrc_ipv6_netif_t *test_netif = gnrc_ipv6_netif_get(test_iface);
|
|
||||||
gnrc_pktsnip_t *pkt;
|
gnrc_pktsnip_t *pkt;
|
||||||
ndp_nbr_sol_t *nbr_sol;
|
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);
|
TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type);
|
||||||
pkt = msg.content.ptr;
|
pkt = msg.content.ptr;
|
||||||
/* check packet */
|
/* check packet */
|
||||||
ASSERT_NETIF_HDR(test_iface, pkt);
|
ASSERT_NETIF_HDR(test_netif, pkt);
|
||||||
if ((src != NULL) && ipv6_addr_is_unspecified(src)) {
|
if ((src != NULL) && ipv6_addr_is_unspecified(src)) {
|
||||||
ASSERT_IPV6_HDR(&ipv6_addr_unspecified, &test_dst, pkt->next);
|
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)
|
bool supply_tl2a, gnrc_pktsnip_t *exp_ext_opts)
|
||||||
{
|
{
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
gnrc_ipv6_netif_t *test_netif = gnrc_ipv6_netif_get(test_iface);
|
|
||||||
gnrc_pktsnip_t *pkt;
|
gnrc_pktsnip_t *pkt;
|
||||||
ndp_nbr_adv_t *nbr_adv;
|
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);
|
TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type);
|
||||||
pkt = msg.content.ptr;
|
pkt = msg.content.ptr;
|
||||||
/* check packet */
|
/* check packet */
|
||||||
ASSERT_NETIF_HDR(test_iface, pkt);
|
ASSERT_NETIF_HDR(test_netif, pkt);
|
||||||
if (ipv6_addr_is_unspecified(dst)) {
|
if (ipv6_addr_is_unspecified(dst)) {
|
||||||
ASSERT_IPV6_HDR(&ipv6_addr_unspecified, &ipv6_addr_all_nodes_link_local,
|
ASSERT_IPV6_HDR(&ipv6_addr_unspecified, &ipv6_addr_all_nodes_link_local,
|
||||||
pkt->next);
|
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)
|
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)
|
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);
|
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)
|
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)
|
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);
|
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)
|
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)
|
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);
|
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)
|
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)
|
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);
|
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)
|
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)
|
static void test_rtr_sol_send(const ipv6_addr_t *dst)
|
||||||
{
|
{
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
gnrc_ipv6_netif_t *test_netif = gnrc_ipv6_netif_get(test_iface);
|
|
||||||
gnrc_pktsnip_t *pkt;
|
gnrc_pktsnip_t *pkt;
|
||||||
ndp_rtr_sol_t *rtr_sol;
|
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);
|
TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type);
|
||||||
pkt = msg.content.ptr;
|
pkt = msg.content.ptr;
|
||||||
/* check packet */
|
/* check packet */
|
||||||
ASSERT_NETIF_HDR(test_iface, pkt);
|
ASSERT_NETIF_HDR(test_netif, pkt);
|
||||||
if (dst != NULL) {
|
if (dst != NULL) {
|
||||||
ASSERT_IPV6_HDR(&test_src, dst, pkt->next);
|
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)
|
bool fin, gnrc_pktsnip_t *exp_ext_opts)
|
||||||
{
|
{
|
||||||
msg_t msg;
|
msg_t msg;
|
||||||
gnrc_ipv6_netif_t *test_netif = gnrc_ipv6_netif_get(test_iface);
|
|
||||||
gnrc_pktsnip_t *pkt;
|
gnrc_pktsnip_t *pkt;
|
||||||
ndp_rtr_adv_t *rtr_adv;
|
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);
|
TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type);
|
||||||
pkt = msg.content.ptr;
|
pkt = msg.content.ptr;
|
||||||
/* check packet */
|
/* 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
|
/* testing for unspecified source is complicated so we skip it here and
|
||||||
* do it in later integration tests */
|
* do it in later integration tests */
|
||||||
if (dst != NULL) {
|
if (dst != NULL) {
|
||||||
@ -930,11 +929,25 @@ int main(void)
|
|||||||
|
|
||||||
static char test_netif_stack[THREAD_STACKSIZE_DEFAULT];
|
static char test_netif_stack[THREAD_STACKSIZE_DEFAULT];
|
||||||
static msg_t msg_queue_main[MSG_QUEUE_SIZE];
|
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 gnrc_netreg_entry_t netreg_entry;
|
||||||
|
static netdev_test_t dev;
|
||||||
|
|
||||||
int test_iface_get(gnrc_netapi_opt_t *opt)
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _test_netif_get(gnrc_netif2_t *netif, gnrc_netapi_opt_t *opt)
|
||||||
|
{
|
||||||
|
(void)netif;
|
||||||
switch (opt->opt) {
|
switch (opt->opt) {
|
||||||
case NETOPT_ADDRESS_LONG:
|
case NETOPT_ADDRESS_LONG:
|
||||||
if (opt->data_len < sizeof(test_src_l2)) {
|
if (opt->data_len < sizeof(test_src_l2)) {
|
||||||
@ -971,30 +984,19 @@ int test_iface_get(gnrc_netapi_opt_t *opt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *test_iface_thread(void *args)
|
static int _test_netif_set(gnrc_netif2_t *netif, const gnrc_netapi_opt_t *opt)
|
||||||
{
|
{
|
||||||
msg_t msg, reply = { .type = GNRC_NETAPI_MSG_TYPE_ACK };
|
(void)netif;
|
||||||
|
(void)opt;
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
|
||||||
(void)args;
|
static const gnrc_netif2_ops_t _test_netif_ops = {
|
||||||
msg_init_queue(msg_queue_netif, MSG_QUEUE_SIZE);
|
.send = _test_netif_send,
|
||||||
while (1) {
|
.recv = _test_netif_recv,
|
||||||
msg_receive(&msg);
|
.get = _test_netif_get,
|
||||||
switch (msg.type) {
|
.set = _test_netif_set,
|
||||||
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 void init_pkt_handler(void)
|
static void init_pkt_handler(void)
|
||||||
{
|
{
|
||||||
@ -1002,13 +1004,17 @@ static void init_pkt_handler(void)
|
|||||||
gnrc_netreg_entry_init_pid(&netreg_entry, GNRC_NETREG_DEMUX_CTX_ALL,
|
gnrc_netreg_entry_init_pid(&netreg_entry, GNRC_NETREG_DEMUX_CTX_ALL,
|
||||||
sched_active_pid);
|
sched_active_pid);
|
||||||
gnrc_netreg_register(GNRC_NETTYPE_NDP2, &netreg_entry);
|
gnrc_netreg_register(GNRC_NETTYPE_NDP2, &netreg_entry);
|
||||||
test_iface = thread_create(test_netif_stack, sizeof(test_netif_stack),
|
netdev_test_setup(&dev, NULL);
|
||||||
GNRC_NETDEV_MAC_PRIO, THREAD_CREATE_STACKTEST,
|
test_netif = gnrc_netif2_create(test_netif_stack, sizeof(test_netif_stack),
|
||||||
test_iface_thread, NULL, "test-iface");
|
GNRC_NETIF2_PRIO, "test-netif",
|
||||||
TEST_ASSERT_MESSAGE(test_iface > KERNEL_PID_UNDEF,
|
&dev.netdev, &_test_netif_ops);
|
||||||
|
TEST_ASSERT_MESSAGE(test_netif != NULL,
|
||||||
"Unable to start test interface");
|
"Unable to start test interface");
|
||||||
gnrc_netif_add(test_iface);
|
memcpy(&test_netif->ipv6.addrs[0], &test_src,
|
||||||
gnrc_ipv6_netif_init_by_dev();
|
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)
|
static inline size_t ceil8(size_t size)
|
||||||
|
|||||||
@ -1910,33 +1910,6 @@ static void test_nib_abr_iter__three_elem_middle_removed(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#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)
|
Test *tests_gnrc_ipv6_nib_internal_tests(void)
|
||||||
{
|
{
|
||||||
EMB_UNIT_TESTFIXTURES(fixtures) {
|
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),
|
||||||
new_TestFixture(test_nib_abr_iter__three_elem_middle_removed),
|
new_TestFixture(test_nib_abr_iter__three_elem_middle_removed),
|
||||||
#endif
|
#endif
|
||||||
new_TestFixture(test_nib_iface_get__no_space_left),
|
|
||||||
new_TestFixture(test_nib_iface_get__success),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EMB_UNIT_TESTCALLER(tests, set_up, NULL,
|
EMB_UNIT_TESTCALLER(tests, set_up, NULL,
|
||||||
|
|||||||
@ -276,20 +276,12 @@ static void test_nib_nc_mark_reachable__unmanaged(void)
|
|||||||
static void test_nib_nc_mark_reachable__success(void)
|
static void test_nib_nc_mark_reachable__success(void)
|
||||||
{
|
{
|
||||||
void *iter_state = NULL;
|
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 },
|
static const ipv6_addr_t addr = { .u64 = { { .u8 = GLOBAL_PREFIX },
|
||||||
{ .u64 = TEST_UINT64 } } };
|
{ .u64 = TEST_UINT64 } } };
|
||||||
gnrc_ipv6_nib_nc_t nce;
|
gnrc_ipv6_nib_nc_t nce;
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL((node = _nib_nc_add(&addr, IFACE,
|
TEST_ASSERT_NOT_NULL(_nib_nc_add(&addr, IFACE,
|
||||||
GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE)));
|
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;
|
|
||||||
|
|
||||||
/* check pre-state */
|
/* check pre-state */
|
||||||
TEST_ASSERT(gnrc_ipv6_nib_nc_iter(0, &iter_state, &nce));
|
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 */
|
/* check if entry is reachable */
|
||||||
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE,
|
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE,
|
||||||
gnrc_ipv6_nib_nc_get_nud_state(&nce));
|
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
|
#endif
|
||||||
/* check if still the only entry */
|
/* check if still the only entry */
|
||||||
TEST_ASSERT(!gnrc_ipv6_nib_nc_iter(0, &iter_state, &nce));
|
TEST_ASSERT(!gnrc_ipv6_nib_nc_iter(0, &iter_state, &nce));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user