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:
Martine Lenders 2017-11-11 19:10:14 +01:00 committed by GitHub
commit b83bc1b763
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 1090 additions and 1195 deletions

View File

@ -136,29 +136,30 @@ endif
ifneq (,$(filter gnrc_sixlowpan_default,$(USEMODULE)))
USEMODULE += gnrc_ipv6_default
USEMODULE += gnrc_ipv6_nib_6ln
USEMODULE += gnrc_sixlowpan
USEMODULE += gnrc_sixlowpan_nd
USEMODULE += gnrc_sixlowpan_frag
USEMODULE += gnrc_sixlowpan_iphc
endif
ifneq (,$(filter gnrc_sixlowpan_router_default,$(USEMODULE)))
USEMODULE += gnrc_ipv6_router_default
USEMODULE += gnrc_ipv6_nib_6lr
USEMODULE += gnrc_sixlowpan_router
USEMODULE += gnrc_sixlowpan_frag
USEMODULE += gnrc_sixlowpan_iphc
endif
ifneq (,$(filter gnrc_sixlowpan_border_router_default,$(USEMODULE)))
USEMODULE += gnrc_ipv6_nib_6lbr
USEMODULE += gnrc_ipv6_router_default
USEMODULE += gnrc_sixlowpan_nd_border_router
USEMODULE += gnrc_sixlowpan_router
USEMODULE += gnrc_sixlowpan_frag
USEMODULE += gnrc_sixlowpan_iphc
endif
ifneq (,$(filter gnrc_sixlowpan_router,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_nd_router
USEMODULE += gnrc_ipv6_router
endif
ifneq (,$(filter gnrc_sixlowpan_frag,$(USEMODULE)))
@ -182,50 +183,14 @@ ifneq (,$(filter gnrc_sixlowpan_ctx,$(USEMODULE)))
USEMODULE += xtimer
endif
ifneq (,$(filter gnrc_sixlowpan_nd_border_router,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_nd_router
endif
ifneq (,$(filter gnrc_sixlowpan_nd_router,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_nd
endif
ifneq (,$(filter gnrc_sixlowpan_nd,$(USEMODULE)))
USEMODULE += gnrc_ndp
USEMODULE += gnrc_ndp_internal
USEMODULE += gnrc_sixlowpan_ctx
USEMODULE += random
USEMODULE += xtimer
endif
ifneq (,$(filter gnrc_ipv6_default,$(USEMODULE)))
USEMODULE += gnrc_ipv6
USEMODULE += gnrc_icmpv6
ifeq (1,$(GNRC_NETIF_NUMOF))
ifeq (,$(filter gnrc_sixlowpan_nd,$(USEMODULE)))
USEMODULE += gnrc_ndp_host
endif
else
USEMODULE += gnrc_ndp_host
endif
endif
ifneq (,$(filter gnrc_ipv6_router_default,$(USEMODULE)))
USEMODULE += gnrc_ipv6_router
USEMODULE += gnrc_icmpv6
ifeq (1,$(GNRC_NETIF_NUMOF))
ifeq (,$(filter gnrc_sixlowpan_nd_router,$(USEMODULE)))
USEMODULE += gnrc_ndp_router
endif
else
USEMODULE += gnrc_ndp_router
endif
endif
ifneq (,$(filter gnrc_ndp_host,$(USEMODULE)))
USEMODULE += gnrc_ndp_node
USEMODULE += random
USEMODULE += xtimer
endif
ifneq (,$(filter gnrc_ndp_router,$(USEMODULE)))
@ -242,20 +207,9 @@ ifneq (,$(filter gnrc_ndp_%,$(USEMODULE)))
USEMODULE += gnrc_ndp
endif
ifneq (,$(filter gnrc_ndp,$(USEMODULE)))
ifneq (,$(filter gnrc_sixlowpan,$(USEMODULE)))
USEMODULE += gnrc_sixlowpan_nd
else
USEMODULE += gnrc_ndp_node
endif
USEMODULE += gnrc_ndp_internal
USEMODULE += gnrc_icmpv6
USEMODULE += random
USEMODULE += xtimer
endif
ifneq (,$(filter gnrc_ndp2,$(USEMODULE)))
USEMODULE += gnrc_icmpv6
USEMODULE += gnrc_netif2
endif
ifneq (,$(filter gnrc_icmpv6_echo,$(USEMODULE)))
@ -301,7 +255,7 @@ ifneq (,$(filter gnrc_ipv6,$(USEMODULE)))
USEMODULE += inet_csum
USEMODULE += ipv6_addr
USEMODULE += gnrc_ipv6_hdr
USEMODULE += gnrc_ipv6_nc
USEMODULE += gnrc_ipv6_nib
USEMODULE += gnrc_netif2
endif

View File

@ -36,9 +36,7 @@
#include "net/ipv6.h"
#include "net/gnrc/ipv6/ext.h"
#include "net/gnrc/ipv6/hdr.h"
#ifndef MODULE_GNRC_IPV6_NIB
#include "net/gnrc/ipv6/nc.h"
#endif
#include "net/gnrc/ipv6/nib.h"
#ifdef MODULE_FIB
#include "net/fib.h"

View File

@ -33,6 +33,7 @@
#include "net/ipv6/addr.h"
#include "net/ipv6/hdr.h"
#include "net/gnrc/ipv6/nib/nc.h"
#include "net/gnrc/netif2.h"
#include "net/gnrc/pkt.h"
#ifdef __cplusplus
@ -194,13 +195,67 @@ extern "C" {
* @brief Recalculate reachability timeout time.
*
* This message type is for the event of recalculating the reachability timeout
* time. The expected message context is a valid interface.
* time. The expected message context is a valid
* [interface](@ref net_gnrc_netif2).
*
* @note Only handled with @ref GNRC_IPV6_NIB_CONF_ARSM != 0
*/
#define GNRC_IPV6_NIB_RECALC_REACH_TIME (0x4fceU)
/** @} */
/**
* @brief Types for gnrc_netif2_ipv6_t::route_info_cb
* @anchor net_gnrc_ipv6_nib_route_info_type
*/
enum {
GNRC_IPV6_NIB_ROUTE_INFO_TYPE_UNDEF = 0, /**< undefined */
/**
* @brief reactive routing query
*
* A reactive routing query is issued when a route is unknown to the NIB.
* A reactive routing protocol can use this call to search for a route in a
* reactive manner.
*
* The `ctx_addr` will be the destination address of the unknown route,
* `ctx` a pointer to the packet as `gnrc_pktsnip_t` that caused the route
* look-up (to possibly queue it for later sending).
*/
GNRC_IPV6_NIB_ROUTE_INFO_TYPE_RRQ,
/**
* @brief route notification
*
* A route notification is issued when an already established route is
* taken. A routing protocol can use this call to update its information on
* the route.
*
* The `ctx_addr` is the prefix of the route, `ctx` is set to a value equal
* to the length of the prefix in bits.
*/
GNRC_IPV6_NIB_ROUTE_INFO_TYPE_RN,
/**
* @brief neighbor state change
*
* A neighbor state change is issued when ever the NUD state of a neighbor
* changes. A routing protocol can use this call to update its information
* on routes via this neighbor.
*
* The `ctx_addr` is the address of the neighbor, `ctx` is a value equal
* to the new NUD state as defined in [the NC info flags](@ref
* net_gnrc_ipv6_nib_nc_info). If the entry is deleted, `ctx` will be set
* to @ref GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE (except if it was
* already in the `UNREACHABLE` state). This does not include cache-outs,
* since they give no information about the neighbor's reachability (you
* might however get an INCOMPLETE or STALE notification due to that, as
* soon as the neighbor enters the neighbor cache again).
*
* Be adviced to only use `ctx_addr` in the context of the callback, since
* it might be overwritten, after the callback was left.
*/
GNRC_IPV6_NIB_ROUTE_INFO_TYPE_NSC,
};
/**
* @brief Initialize NIB
*/
@ -209,11 +264,11 @@ void gnrc_ipv6_nib_init(void);
/**
* @brief Adds an interface to be managed by the NIB.
*
* @pre `(KERNEL_PID_UNDEF < iface)`
* @pre `netif != NULL`
*
* @param[in] iface The interface to be managed by the NIB
* @param[in,out] netif The interface to be managed by the NIB
*/
void gnrc_ipv6_nib_init_iface(kernel_pid_t iface);
void gnrc_ipv6_nib_init_iface(gnrc_netif2_t *netif);
/**
* @brief Gets link-layer address of next hop to a destination address
@ -221,8 +276,8 @@ void gnrc_ipv6_nib_init_iface(kernel_pid_t iface);
* @pre `(dst != NULL) && (nce != NULL)`
*
* @param[in] dst Destination address of a packet.
* @param[in] iface Restrict search to this interface. May be
* `KERNEL_PID_UNDEF` for any interface.
* @param[in] netif Restrict search to this interface. May be `NULL` for any
* interface.
* @param[in] pkt The IPv6 packet in sending order for which the next hop
* is searched. Needed for queuing for with reactive
* routing or address resolution. May be `NULL`.
@ -237,13 +292,13 @@ void gnrc_ipv6_nib_init_iface(kernel_pid_t iface);
* solicitation sent).
*/
int gnrc_ipv6_nib_get_next_hop_l2addr(const ipv6_addr_t *dst,
kernel_pid_t iface, gnrc_pktsnip_t *pkt,
gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt,
gnrc_ipv6_nib_nc_t *nce);
/**
* @brief Handles a received ICMPv6 packet
*
* @pre `iface != KERNEL_PID_UNDEF`
* @pre `netif != NULL`
* @pre `ipv6 != NULL`
* @pre `icmpv6 != NULL`
* @pre `icmpv6_len > sizeof(icmpv6_hdr_t)`
@ -274,13 +329,13 @@ int gnrc_ipv6_nib_get_next_hop_l2addr(const ipv6_addr_t *dst,
* @see [RFC 6775, section 8.2.4](https://tools.ietf.org/html/rfc6775#section-8.2.4)
* @see [RFC 6775, section 8.2.5](https://tools.ietf.org/html/rfc6775#section-8.2.5)
*
* @param[in] iface The interface the packet came over.
* @param[in] netif The interface the packet came over.
* @param[in] ipv6 The IPv6 header of the received packet.
* @param[in] icmpv6 The ICMPv6 header and payload of the received
* packet.
* @param[in] icmpv6_len The number of bytes at @p icmpv6.
*/
void gnrc_ipv6_nib_handle_pkt(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
void gnrc_ipv6_nib_handle_pkt(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const icmpv6_hdr_t *icmpv6, size_t icmpv6_len);
/**
@ -292,6 +347,25 @@ void gnrc_ipv6_nib_handle_pkt(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
*/
void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type);
#if GNRC_IPV6_NIB_CONF_ROUTER || defined(DOXYGEN)
/**
* @brief Changes the state if an interface advertises itself as a router
* or not
*
* @param[in] netif The interface for which the state should be changed.
* @param[in] enable `true`, to enable advertising the interface as a router.
* `false`, to disable advertising the interface as a
* router.
*/
void gnrc_ipv6_nib_change_rtr_adv_iface(gnrc_netif2_t *netif, bool enable);
#else
/**
* @brief Optimization to NOP for non-routers
*/
#define gnrc_ipv6_nib_change_rtr_adv_iface(netif, enable) \
(void)netif; (void)enable
#endif
#ifdef __cplusplus
}
#endif

View File

@ -199,10 +199,8 @@ extern "C" {
/**
* @brief Maximum link-layer address length (aligned)
*/
#if (GNRC_NETIF_HDR_L2ADDR_MAX_LEN % 8)
#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (((GNRC_NETIF_HDR_L2ADDR_MAX_LEN >> 3) + 1) << 3)
#else
#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (GNRC_NETIF_HDR_L2ADDR_MAX_LEN)
#ifndef GNRC_IPV6_NIB_L2ADDR_MAX_LEN
#define GNRC_IPV6_NIB_L2ADDR_MAX_LEN (8U)
#endif
/**

View File

@ -24,8 +24,9 @@
#include "kernel_types.h"
#include "net/gnrc/pkt.h"
#include "net/gnrc/ipv6/netif.h"
#include "net/gnrc/netif2.h"
#include "net/ipv6/addr.h"
#include "net/ipv6/hdr.h"
#ifdef __cplusplus
extern "C" {
@ -269,7 +270,7 @@ gnrc_pktsnip_t *gnrc_ndp2_opt_mtu_build(uint32_t mtu, gnrc_pktsnip_t *next);
* for a neighbor solicitation so be sure to check that.
* **Will be released** in an error case.
*/
void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_netif2_t *netif,
const ipv6_addr_t *src, const ipv6_addr_t *dst,
gnrc_pktsnip_t *ext_opts);
@ -315,7 +316,7 @@ void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
* check that.
* **Will be released** in an error case.
*/
void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_netif2_t *netif,
const ipv6_addr_t *dst, bool supply_tl2a,
gnrc_pktsnip_t *ext_opts);
@ -328,7 +329,7 @@ void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
* @param[in] netif Interface to send over. May not be NULL.
* @param[in] dst Destination for the router solicitation. ff02::2 if NULL.
*/
void gnrc_ndp2_rtr_sol_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *dst);
void gnrc_ndp2_rtr_sol_send(gnrc_netif2_t *netif, const ipv6_addr_t *dst);
/**
* @brief Send pre-compiled router advertisement depending on a given network
@ -355,7 +356,7 @@ void gnrc_ndp2_rtr_sol_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *dst);
* for a neighbor advertisement so be sure to check that.
* **Will be released** in an error case.
*/
void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src,
void gnrc_ndp2_rtr_adv_send(gnrc_netif2_t *netif, const ipv6_addr_t *src,
const ipv6_addr_t *dst, bool fin,
gnrc_pktsnip_t *ext_opts);

View File

@ -20,6 +20,7 @@
#include "net/ieee802154.h"
#include "net/ethernet/hdr.h"
#include "net/gnrc/ipv6/nib/conf.h"
#include "thread.h"
#ifdef __cplusplus
@ -60,7 +61,7 @@ extern "C" {
*
* @note Used for calculation of @ref GNRC_NETIF2_IPV6_GROUPS_NUMOF
*/
#ifdef MODULE_GNRC_IPV6_ROUTER
#if GNRC_IPV6_NIB_CONF_ROUTER
#define GNRC_NETIF2_IPV6_RTR_ADDR (1)
#else
#define GNRC_NETIF2_IPV6_RTR_ADDR (0)
@ -109,7 +110,7 @@ extern "C" {
#elif MODULE_CC110X
#define GNRC_NETIF2_L2ADDR_MAXLEN (1U)
#else
#define GNRC_NETIF2_L2ADDR_MAXLEN (8U)
#define GNRC_NETIF2_L2ADDR_MAXLEN (GNRC_IPV6_NIB_L2ADDR_MAX_LEN)
#endif
#endif

View File

@ -115,9 +115,8 @@ typedef struct {
* The callback may be `NULL` if no such behavior is required by the routing
* protocol (or no routing protocol is present).
*
* @todo Define types (RRQ, RRN, NSC) in NIB
*
* @param[in] type Type of the route info.
* @param[in] type [Type](@ref net_gnrc_ipv6_nib_route_info_type) of
* the route info.
* @param[in] ctx_addr Context address of the route info.
* @param[in] ctx Further context of the route info.
*/

View File

@ -19,6 +19,9 @@
#include "net/ethernet.h"
#include "net/ipv6.h"
#include "net/gnrc.h"
#ifdef MODULE_GNRC_IPV6_NIB
#include "net/gnrc/ipv6/nib.h"
#endif /* MODULE_GNRC_IPV6_NIB */
#ifdef MODULE_NETSTATS_IPV6
#include "net/netstats.h"
#endif
@ -278,7 +281,7 @@ int gnrc_netif2_set_from_netdev(gnrc_netif2_t *netif,
}
else {
if (gnrc_netif2_is_rtr_adv(netif)) {
gnrc_ipv6_nib_iface_cease_rtr_adv(netif);
gnrc_ipv6_nib_change_rtr_adv_iface(netif, false);
}
netif->flags &= ~GNRC_NETIF2_FLAGS_IPV6_FORWARDING;
}
@ -286,12 +289,8 @@ int gnrc_netif2_set_from_netdev(gnrc_netif2_t *netif,
break;
case NETOPT_IPV6_SND_RTR_ADV:
assert(opt->data_len == sizeof(netopt_enable_t));
if (*(((netopt_enable_t *)opt->data)) == NETOPT_ENABLE) {
gnrc_ipv6_nib_iface_start_rtr_adv(netif);
}
else {
gnrc_ipv6_nib_iface_cease_rtr_adv(netif);
}
gnrc_ipv6_nib_change_rtr_adv_iface(netif,
(*(((netopt_enable_t *)opt->data)) == NETOPT_ENABLE));
res = sizeof(netopt_enable_t);
break;
#endif /* GNRC_IPV6_NIB_CONF_ROUTER */

View File

@ -23,11 +23,7 @@
#include "kernel_types.h"
#include "net/ipv6/hdr.h"
#include "net/gnrc.h"
#ifndef MODULE_GNRC_IPV6_NIB
#include "net/gnrc/ndp.h"
#else
#include "net/gnrc/ipv6/nib.h"
#endif
#include "net/protnum.h"
#include "od.h"
#include "utlist.h"
@ -98,40 +94,6 @@ void gnrc_icmpv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt)
break;
#endif
#ifndef MODULE_GNRC_IPV6_NIB
#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
case ICMPV6_RTR_SOL:
DEBUG("icmpv6: router solicitation received\n");
gnrc_ndp_rtr_sol_handle(iface, pkt, ipv6->data, (ndp_rtr_sol_t *)hdr,
icmpv6->size);
break;
#endif
#ifdef MODULE_GNRC_NDP
case ICMPV6_RTR_ADV:
DEBUG("icmpv6: router advertisement received\n");
gnrc_ndp_rtr_adv_handle(iface, pkt, ipv6->data, (ndp_rtr_adv_t *)hdr,
icmpv6->size);
break;
case ICMPV6_NBR_SOL:
DEBUG("icmpv6: neighbor solicitation received\n");
gnrc_ndp_nbr_sol_handle(iface, pkt, ipv6->data, (ndp_nbr_sol_t *)hdr,
icmpv6->size);
break;
case ICMPV6_NBR_ADV:
DEBUG("icmpv6: neighbor advertisement received\n");
gnrc_ndp_nbr_adv_handle(iface, pkt, ipv6->data, (ndp_nbr_adv_t *)hdr,
icmpv6->size);
break;
#endif
case ICMPV6_REDIRECT:
DEBUG("icmpv6: redirect message received\n");
/* TODO */
break;
#else /* MODULE_GNRC_IPV6_NIB */
case ICMPV6_RTR_SOL:
case ICMPV6_RTR_ADV:
case ICMPV6_NBR_SOL:
@ -140,9 +102,9 @@ void gnrc_icmpv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt)
case ICMPV6_DAR:
case ICMPV6_DAC:
DEBUG("icmpv6: NDP message received. Handle with gnrc_ipv6_nib\n");
gnrc_ipv6_nib_handle_pkt(iface, ipv6->data, hdr, icmpv6->size);
gnrc_ipv6_nib_handle_pkt(gnrc_netif2_get_by_pid(iface),
ipv6->data, hdr, icmpv6->size);
break;
#endif /* MODULE_GNRC_IPV6_NIB */
default:
DEBUG("icmpv6: unknown type field %u\n", hdr->type);

View File

@ -29,11 +29,7 @@
#include "thread.h"
#include "utlist.h"
#ifndef MODULE_GNRC_IPV6_NIB
#include "net/gnrc/ipv6/nc.h"
#else
#include "net/gnrc/ipv6/nib.h"
#endif
#include "net/gnrc/netif2/internal.h"
#include "net/gnrc/ipv6/whitelist.h"
#include "net/gnrc/ipv6/blacklist.h"
@ -290,83 +286,6 @@ static void *_event_loop(void *args)
msg_reply(&msg, &reply);
break;
#ifndef MODULE_GNRC_IPV6_NIB
#ifdef MODULE_GNRC_NDP
case GNRC_NDP_MSG_RTR_TIMEOUT:
DEBUG("ipv6: Router timeout received\n");
((gnrc_ipv6_nc_t *)msg.content.ptr)->flags &= ~GNRC_IPV6_NC_IS_ROUTER;
break;
/* XXX reactivate when https://github.com/RIOT-OS/RIOT/issues/5122 is
* solved properly */
/* case GNRC_NDP_MSG_ADDR_TIMEOUT: */
/* DEBUG("ipv6: Router advertisement timer event received\n"); */
/* gnrc_ipv6_netif_remove_addr(KERNEL_PID_UNDEF, */
/* msg.content.ptr); */
/* break; */
case GNRC_NDP_MSG_NBR_SOL_RETRANS:
DEBUG("ipv6: Neigbor solicitation retransmission timer event received\n");
gnrc_ndp_retrans_nbr_sol(msg.content.ptr);
break;
case GNRC_NDP_MSG_NC_STATE_TIMEOUT:
DEBUG("ipv6: Neigbor cache state timeout received\n");
gnrc_ndp_state_timeout(msg.content.ptr);
break;
#endif
#ifdef MODULE_GNRC_NDP_ROUTER
case GNRC_NDP_MSG_RTR_ADV_RETRANS:
DEBUG("ipv6: Router advertisement retransmission event received\n");
gnrc_ndp_router_retrans_rtr_adv(msg.content.ptr);
break;
case GNRC_NDP_MSG_RTR_ADV_DELAY:
DEBUG("ipv6: Delayed router advertisement event received\n");
gnrc_ndp_router_send_rtr_adv(msg.content.ptr);
break;
#endif
#ifdef MODULE_GNRC_NDP_HOST
case GNRC_NDP_MSG_RTR_SOL_RETRANS:
DEBUG("ipv6: Router solicitation retransmission event received\n");
gnrc_ndp_host_retrans_rtr_sol(msg.content.ptr);
break;
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_ND
case GNRC_SIXLOWPAN_ND_MSG_MC_RTR_SOL:
DEBUG("ipv6: Multicast router solicitation event received\n");
gnrc_sixlowpan_nd_mc_rtr_sol(msg.content.ptr);
break;
case GNRC_SIXLOWPAN_ND_MSG_UC_RTR_SOL:
DEBUG("ipv6: Unicast router solicitation event received\n");
gnrc_sixlowpan_nd_uc_rtr_sol(msg.content.ptr);
break;
# ifdef MODULE_GNRC_SIXLOWPAN_CTX
case GNRC_SIXLOWPAN_ND_MSG_DELETE_CTX:
DEBUG("ipv6: Delete 6LoWPAN context event received\n");
gnrc_sixlowpan_ctx_remove(((((gnrc_sixlowpan_ctx_t *)msg.content.ptr)->flags_id) &
GNRC_SIXLOWPAN_CTX_FLAGS_CID_MASK));
break;
# endif
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
case GNRC_SIXLOWPAN_ND_MSG_ABR_TIMEOUT:
DEBUG("ipv6: border router timeout event received\n");
gnrc_sixlowpan_nd_router_abr_remove(msg.content.ptr);
break;
/* XXX reactivate when https://github.com/RIOT-OS/RIOT/issues/5122 is
* solved properly */
/* case GNRC_SIXLOWPAN_ND_MSG_AR_TIMEOUT: */
/* DEBUG("ipv6: address registration timeout received\n"); */
/* gnrc_sixlowpan_nd_router_gc_nc(msg.content.ptr); */
/* break; */
case GNRC_NDP_MSG_RTR_ADV_SIXLOWPAN_DELAY:
DEBUG("ipv6: Delayed router advertisement event received\n");
gnrc_ipv6_nc_t *nc_entry = msg.content.ptr;
gnrc_ndp_internal_send_rtr_adv(nc_entry->iface, NULL,
&(nc_entry->ipv6_addr), false);
break;
#endif
#else /* MODULE_GNRC_IPV6_NIB */
case GNRC_IPV6_NIB_SND_UC_NS:
case GNRC_IPV6_NIB_SND_MC_NS:
case GNRC_IPV6_NIB_SND_NA:
@ -385,7 +304,6 @@ static void *_event_loop(void *args)
DEBUG("ipv6: NIB timer event received\n");
gnrc_ipv6_nib_handle_timer_event(msg.content.ptr, msg.type);
break;
#endif /* MODULE_GNRC_IPV6_NIB */
default:
break;
}
@ -646,38 +564,6 @@ static void _send_multicast(gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt,
#endif /* GNRC_NETIF_NUMOF */
}
#ifndef MODULE_GNRC_IPV6_NIB
static inline kernel_pid_t _next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len,
kernel_pid_t iface, ipv6_addr_t *dst,
gnrc_pktsnip_t *pkt)
{
kernel_pid_t found_iface;
#if defined(MODULE_GNRC_SIXLOWPAN_ND)
(void)pkt;
found_iface = gnrc_sixlowpan_nd_next_hop_l2addr(l2addr, l2addr_len, iface, dst);
if (found_iface > KERNEL_PID_UNDEF) {
return found_iface;
}
#endif
#if defined(MODULE_GNRC_NDP_NODE)
found_iface = gnrc_ndp_node_next_hop_l2addr(l2addr, l2addr_len, iface, dst, pkt);
#elif !defined(MODULE_GNRC_SIXLOWPAN_ND) && defined(MODULE_GNRC_IPV6_NC)
(void)pkt;
gnrc_ipv6_nc_t *nc = gnrc_ipv6_nc_get(iface, dst);
found_iface = gnrc_ipv6_nc_get_l2_addr(l2addr, l2addr_len, nc);
#elif !defined(MODULE_GNRC_SIXLOWPAN_ND)
found_iface = KERNEL_PID_UNDEF;
(void)l2addr;
(void)l2addr_len;
(void)iface;
(void)dst;
(void)pkt;
*l2addr_len = 0;
#endif
return found_iface;
}
#endif /* MODULE_GNRC_IPV6_NIB */
static void _send(gnrc_pktsnip_t *pkt, bool prep_hdr)
{
kernel_pid_t iface = KERNEL_PID_UNDEF;
@ -771,32 +657,10 @@ static void _send(gnrc_pktsnip_t *pkt, bool prep_hdr)
}
}
else {
#ifndef MODULE_GNRC_IPV6_NIB
uint8_t l2addr_len = GNRC_IPV6_NC_L2_ADDR_MAX;
uint8_t l2addr[l2addr_len];
iface = _next_hop_l2addr(l2addr, &l2addr_len, iface, &hdr->dst, pkt);
if (iface == KERNEL_PID_UNDEF) {
DEBUG("ipv6: error determining next hop's link layer address\n");
gnrc_pktbuf_release(pkt);
return;
}
netif = gnrc_netif2_get_by_pid(iface);
assert(netif != NULL);
if (prep_hdr) {
if (_fill_ipv6_hdr(netif, ipv6, payload) < 0) {
/* error on filling up header */
gnrc_pktbuf_release(pkt);
return;
}
}
_send_unicast(netif, l2addr, l2addr_len, pkt);
#else /* MODULE_GNRC_IPV6_NIB */
gnrc_ipv6_nib_nc_t nce;
gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(iface);
if (gnrc_ipv6_nib_get_next_hop_l2addr(&hdr->dst, iface, pkt,
if (gnrc_ipv6_nib_get_next_hop_l2addr(&hdr->dst, netif, pkt,
&nce) < 0) {
/* packet is released by NIB */
return;
@ -814,7 +678,6 @@ static void _send(gnrc_pktsnip_t *pkt, bool prep_hdr)
_send_unicast(netif, nce.l2addr,
nce.l2addr_len, pkt);
#endif /* MODULE_GNRC_IPV6_NIB */
}
}

View File

@ -25,9 +25,6 @@
#include "net/eui64.h"
#include "net/ipv6/addr.h"
#ifdef MODULE_GNRC_IPV6_NIB
#include "net/gnrc/ipv6/nib.h"
#endif
#include "net/gnrc/ndp.h"
#include "net/gnrc/netapi.h"
#include "net/gnrc/netif.h"
@ -176,11 +173,9 @@ static void _ipv6_netif_remove(gnrc_ipv6_netif_t *entry)
return;
}
#ifndef MODULE_GNRC_IPV6_NIB
#ifdef MODULE_GNRC_NDP
gnrc_ndp_netif_remove(entry);
#endif
#endif /* MODULE_GNRC_IPV6_NIB */
mutex_lock(&entry->mutex);
xtimer_remove(&entry->rtr_sol_timer);
@ -240,13 +235,9 @@ void gnrc_ipv6_netif_add(kernel_pid_t pid)
mutex_unlock(&free_entry->mutex);
#ifndef MODULE_GNRC_IPV6_NIB
#ifdef MODULE_GNRC_NDP
gnrc_ndp_netif_add(free_entry);
#endif
#else /* MODULE_GNRC_IPV6_NIB */
gnrc_ipv6_nib_init_iface(pid);
#endif /* MODULE_GNRC_IPV6_NIB */
DEBUG(" * pid = %" PRIkernel_pid " ", free_entry->pid);
DEBUG("cur_hl = %d ", free_entry->cur_hl);

View File

@ -13,6 +13,7 @@
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#include "net/gnrc/netif2/internal.h"
#include "net/gnrc/ipv6/nib.h"
#include "_nib-6ln.h"
@ -26,49 +27,88 @@
static char addr_str[IPV6_ADDR_MAX_STR_LEN];
#endif
static bool _is_iface_eui64(kernel_pid_t iface, const eui64_t *eui64)
static inline bool _is_iface_eui64(gnrc_netif2_t *netif, const eui64_t *eui64)
{
eui64_t iface_eui64;
/* XXX: this *should* return successful so don't test it ;-) */
gnrc_netapi_get(iface, NETOPT_ADDRESS_LONG, 0,
&iface_eui64, sizeof(iface_eui64));
return (memcmp(&iface_eui64, eui64, sizeof(iface_eui64)) != 0);
/* TODO: adapt for short addresses */
return (netif->l2addr_len == sizeof(eui64_t)) &&
(memcmp(&netif->l2addr, eui64, netif->l2addr_len) == 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_netif_t *netif = gnrc_ipv6_netif_get(iface);
bool res = (netif != NULL) && _is_6ln(netif) &&
bool res = (netif != NULL) && gnrc_netif2_is_6ln(netif) &&
ipv6_addr_is_link_local(dst);
if (res) {
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->l2addr, &dst->u64[1], sizeof(dst->u64[1]));
nce->l2addr[0] ^= 0x02;
nce->info = 0;
nce->info |= (iface << GNRC_IPV6_NIB_NC_INFO_IFACE_POS) &
nce->info |= (netif->pid << GNRC_IPV6_NIB_NC_INFO_IFACE_POS) &
GNRC_IPV6_NIB_NC_INFO_IFACE_MASK;
nce->info |= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE;
nce->info |= GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED;
nce->l2addr_len = sizeof(dst->u64[1]);
}
else {
res = false;
}
}
return res;
}
uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
uint8_t _handle_aro(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const icmpv6_hdr_t *icmpv6,
const sixlowpan_nd_opt_ar_t *aro, const ndp_opt_t *sl2ao,
_nib_onl_entry_t *nce)
{
gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(iface);
#if !GNRC_IPV6_NIB_CONF_6LR
(void)sl2ao;
#endif
assert(netif != NULL);
if (_is_6ln(netif) && (aro->len == SIXLOWPAN_ND_OPT_AR_LEN)) {
if (gnrc_netif2_is_6ln(netif) && (aro->len == SIXLOWPAN_ND_OPT_AR_LEN)) {
DEBUG("nib: valid ARO received\n");
DEBUG(" - length: %u\n", aro->len);
DEBUG(" - status: %u\n", aro->status);
@ -78,7 +118,7 @@ uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
aro->eui64.uint8[3], aro->eui64.uint8[4], aro->eui64.uint8[5],
aro->eui64.uint8[6], aro->eui64.uint8[7]);
if (icmpv6->type == ICMPV6_NBR_ADV) {
if (!_is_iface_eui64(iface, &aro->eui64)) {
if (!_is_iface_eui64(netif, &aro->eui64)) {
DEBUG("nib: ARO EUI-64 is not mine, ignoring ARO\n");
return _ADDR_REG_STATUS_IGNORE;
}
@ -92,7 +132,7 @@ uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
(byteorder_ntohs(aro->ltime) - 1U) *
SEC_PER_MIN * MS_PER_SEC;
DEBUG("nib: Address registration successful. "
"Scheduling re-registration in %ums\n",
"Scheduling re-registration in %" PRIu32 "ms\n",
next_ns);
assert(nce != NULL);
_evtimer_add(nce, GNRC_IPV6_NIB_SND_UC_NS, &nce->nud_timeout,
@ -103,22 +143,19 @@ uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
DEBUG("nib: Address registration reports duplicate. "
"Removing address %s%%%u\n",
ipv6_addr_to_str(addr_str,
&((ndp_nbr_adv_t *)icmpv6)->tgt,
sizeof(addr_str)),
iface);
gnrc_ipv6_netif_remove_addr(iface,
&((ndp_nbr_adv_t *)icmpv6)->tgt);
&ipv6->dst,
sizeof(addr_str)), netif->pid);
gnrc_netif2_ipv6_addr_remove(netif, &ipv6->dst);
/* TODO: generate new address */
break;
case SIXLOWPAN_ND_STATUS_NC_FULL: {
DEBUG("nib: Router's neighbor cache is full. "
"Searching new router for DAD\n");
_nib_dr_entry_t *dr = _nib_drl_get(&ipv6->src, iface);
_nib_dr_entry_t *dr = _nib_drl_get(&ipv6->src, netif->pid);
assert(dr != NULL); /* otherwise we wouldn't be here */
_nib_drl_remove(dr);
if (_nib_drl_iter(NULL) == NULL) { /* no DRL left */
_nib_iface_t *nib_iface = _nib_iface_get(iface);
nib_iface->rs_sent = 0;
netif->ipv6.rs_sent = 0;
/* TODO: search new router */
}
else {
@ -131,8 +168,9 @@ uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
return aro->status;
}
#if GNRC_IPV6_NIB_CONF_6LR
else if (_is_6lr(netif) && (icmpv6->type == ICMPV6_NBR_SOL)) {
return _reg_addr_upstream(iface, ipv6, icmpv6, aro, sl2ao);
else if (gnrc_netif2_is_6lr(netif) &&
(icmpv6->type == ICMPV6_NBR_SOL)) {
return _reg_addr_upstream(netif, ipv6, icmpv6, aro, sl2ao);
}
#endif
}

View File

@ -44,38 +44,23 @@ extern "C" {
*/
#define _ADDR_REG_STATUS_IGNORE (4)
/**
* @brief Checks if interface represents a 6LN
*
* @todo Use corresponding function in `gnrc_netif2` instead.
*
* @param[in] netif A network interface.
*
* @return true, when the @p netif represents a 6LN.
* @return false, when the @p netif does not represent a 6LN.
*/
static inline bool _is_6ln(const gnrc_ipv6_netif_t *netif)
{
return (netif->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN);
}
/**
* @brief Resolves address statically from destination address using reverse
* translation of the IID
*
* @param[in] dst A destination address.
* @param[in] iface The interface to @p dst.
* @param[in] netif The interface to @p dst.
* @param[out] nce Neighbor cache entry to resolve into
*
* @return true when @p nce was set, false when not.
*/
bool _resolve_addr_from_ipv6(const ipv6_addr_t *dst, kernel_pid_t iface,
bool _resolve_addr_from_ipv6(const ipv6_addr_t *dst, gnrc_netif2_t *netif,
gnrc_ipv6_nib_nc_t *nce);
/**
* @brief Handles ARO
*
* @param[in] iface The interface the ARO-carrying message came over.
* @param[in] netif The interface the ARO-carrying message came over.
* @param[in] ipv6 The IPv6 header of the message carrying the ARO.
* @param[in] icmpv6 The message carrying the ARO.
* @param[in] aro ARO that carries the address registration information.
@ -85,13 +70,12 @@ bool _resolve_addr_from_ipv6(const ipv6_addr_t *dst, kernel_pid_t iface,
* @return registration status of the address (including
* @ref _ADDR_REG_STATUS_TENTATIVE and @ref _ADDR_REG_STATUS_IGNORE).
*/
uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
uint8_t _handle_aro(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const icmpv6_hdr_t *icmpv6,
const sixlowpan_nd_opt_ar_t *aro, const ndp_opt_t *sl2ao,
_nib_onl_entry_t *nce);
#else /* GNRC_IPV6_NIB_CONF_6LN || defined(DOXYGEN) */
#define _is_6ln(netif) (false)
#define _resolve_addr_from_ipv6(dst, iface, nce) (false)
#define _resolve_addr_from_ipv6(dst, netif, nce) (false)
/* _handle_aro() doesn't make sense without 6LR so don't even use it
* => throw error in case it is compiled in => don't define it here as NOP macro
*/

View File

@ -14,6 +14,7 @@
*/
#include "net/gnrc/ipv6/nib.h"
#include "net/gnrc/netif2/internal.h"
#include "net/gnrc/sixlowpan/nd.h"
#include "_nib-6lr.h"
@ -47,13 +48,13 @@ static uint8_t _update_nce_ar_state(const sixlowpan_nd_opt_ar_t *aro,
}
}
uint8_t _reg_addr_upstream(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
uint8_t _reg_addr_upstream(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const icmpv6_hdr_t *icmpv6,
const sixlowpan_nd_opt_ar_t *aro,
const ndp_opt_t *sl2ao)
{
if (!ipv6_addr_is_unspecified(&ipv6->src) && (sl2ao != NULL)) {
_nib_onl_entry_t *nce = _nib_onl_get(&ipv6->src, iface);
_nib_onl_entry_t *nce = _nib_onl_get(&ipv6->src, netif->pid);
DEBUG("nib: Trying to register %s with EUI-64 "
"%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
@ -66,8 +67,8 @@ uint8_t _reg_addr_upstream(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
#if GNRC_IPV6_NIB_CONF_MULTIHOP_DAD
/* TODO */
#endif
if (byteorder_ntohs(aro->ltime) != 0) {
_handle_sl2ao(iface, ipv6, icmpv6, sl2ao);
if (aro->ltime.u16 != 0) {
_handle_sl2ao(netif, ipv6, icmpv6, sl2ao);
return _update_nce_ar_state(aro, nce);
}
else if (nce != NULL) {
@ -88,7 +89,8 @@ uint8_t _reg_addr_upstream(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
return _ADDR_REG_STATUS_IGNORE;
}
gnrc_pktsnip_t *_copy_and_handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
gnrc_pktsnip_t *_copy_and_handle_aro(gnrc_netif2_t *netif,
const ipv6_hdr_t *ipv6,
const ndp_nbr_sol_t *nbr_sol,
const sixlowpan_nd_opt_ar_t *aro,
const ndp_opt_t *sl2ao)
@ -96,7 +98,7 @@ gnrc_pktsnip_t *_copy_and_handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
gnrc_pktsnip_t *reply_aro = NULL;
if (aro != NULL) {
uint8_t status = _handle_aro(iface, ipv6, (icmpv6_hdr_t *)nbr_sol, aro,
uint8_t status = _handle_aro(netif, ipv6, (icmpv6_hdr_t *)nbr_sol, aro,
sl2ao, NULL);
if ((status != _ADDR_REG_STATUS_TENTATIVE) &&

View File

@ -33,21 +33,6 @@ extern "C" {
#endif
#if GNRC_IPV6_NIB_CONF_6LR || defined(DOXYGEN)
/**
* @brief Checks if interface represents a 6LR
*
* @todo Use corresponding function in `gnrc_netif2` instead.
*
* @param[in] netif A network interface.
*
* @return true, when the @p netif represents a 6LR.
* @return false, when the @p netif does not represent a 6LR.
*/
static inline bool _is_6lr(const gnrc_ipv6_netif_t *netif)
{
return _is_6ln(netif) && (netif->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER);
}
/**
* @brief Gets address registration state of a neighbor
*
@ -81,17 +66,17 @@ static inline void _set_ar_state(_nib_onl_entry_t *entry, uint16_t state)
* @param[in] netif A network interface.
* @param[in] icmpv6 An ICMPv6 message.
*/
static inline bool _rtr_sol_on_6lr(const gnrc_ipv6_netif_t *netif,
static inline bool _rtr_sol_on_6lr(const gnrc_netif2_t *netif,
const icmpv6_hdr_t *icmpv6)
{
return _is_6lr(netif) && (icmpv6->type == ICMPV6_RTR_SOL);
return gnrc_netif2_is_6lr(netif) && (icmpv6->type == ICMPV6_RTR_SOL);
}
/**
* @brief Registers an address to the (upstream; in case of multihop DAD)
* router
*
* @param[in] iface The interface the ARO-carrying NS came over.
* @param[in] netif The interface the ARO-carrying NS came over.
* @param[in] ipv6 The IPv6 header of the message carrying the ARO.
* @param[in] icmpv6 The neighbor solicitation carrying the ARO
* (handed over as @ref icmpv6_hdr_t, since it is just
@ -102,7 +87,7 @@ static inline bool _rtr_sol_on_6lr(const gnrc_ipv6_netif_t *netif,
* @return registration status of the address (including
* @ref _ADDR_REG_STATUS_TENTATIVE and @ref _ADDR_REG_STATUS_IGNORE).
*/
uint8_t _reg_addr_upstream(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
uint8_t _reg_addr_upstream(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const icmpv6_hdr_t *icmpv6,
const sixlowpan_nd_opt_ar_t *aro,
const ndp_opt_t *sl2ao);
@ -111,7 +96,7 @@ uint8_t _reg_addr_upstream(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
/**
* @brief Handles and copies ARO from NS to NA
*
* @param[in] iface The interface the ARO-carrying NS came over.
* @param[in] netif The interface the ARO-carrying NS came over.
* @param[in] ipv6 The IPv6 header of the message carrying the original
* ARO.
* @param[in] nbr_sol The neighbor solicitation carrying the original ARO
@ -123,16 +108,15 @@ uint8_t _reg_addr_upstream(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
* @return registration status of the address (including
* @ref _ADDR_REG_STATUS_TENTATIVE and @ref _ADDR_REG_STATUS_IGNORE).
*/
gnrc_pktsnip_t *_copy_and_handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
gnrc_pktsnip_t *_copy_and_handle_aro(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const ndp_nbr_sol_t *nbr_sol,
const sixlowpan_nd_opt_ar_t *aro,
const ndp_opt_t *sl2ao);
#else /* GNRC_IPV6_NIB_CONF_6LR || defined(DOXYGEN) */
#define _is_6lr(netif) (false)
#define _rtr_sol_on_6lr(netif, icmpv6) (false)
#define _get_ar_state(nbr) (_ADDR_REG_STATUS_IGNORE)
#define _set_ar_state(nbr, state) (void)nbr; (void)state
#define _copy_and_handle_aro(iface, ipv6, icmpv6, aro, sl2ao) \
#define _copy_and_handle_aro(netif, ipv6, icmpv6, aro, sl2ao) \
(NULL)
/* _reg_addr_upstream() doesn't make sense without 6LR so don't even use it
* => throw error in case it is compiled in => don't define it here as NOP macro

View File

@ -16,6 +16,10 @@
#include "xtimer.h"
#include "net/gnrc/ndp2.h"
#include "net/gnrc/ipv6/nib.h"
#include "net/gnrc/netif2/internal.h"
#ifdef MODULE_GNRC_SIXLOWPAN_ND
#include "net/gnrc/sixlowpan/nd.h"
#endif
#include "_nib-arsm.h"
#include "_nib-6lr.h"
@ -36,26 +40,50 @@ static char addr_str[IPV6_ADDR_MAX_STR_LEN];
*
* @return The length of the L2 address carried in @p opt.
*/
static inline unsigned _get_l2addr_len(gnrc_ipv6_netif_t *netif,
static inline unsigned _get_l2addr_len(gnrc_netif2_t *netif,
const ndp_opt_t *opt);
void _snd_ns(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
void _snd_ns(const ipv6_addr_t *tgt, gnrc_netif2_t *netif,
const ipv6_addr_t *src, const ipv6_addr_t *dst)
{
gnrc_pktsnip_t *ext_opt = NULL;
#ifdef MODULE_GNRC_SIXLOWPAN_ND
_nib_dr_entry_t *dr = _nib_drl_get_dr();
assert(netif != NULL);
/* add ARO based on interface */
if ((src != NULL) && gnrc_netif2_is_6ln(netif) &&
(_nib_onl_get_if(dr->next_hop) == (unsigned)netif->pid) &&
ipv6_addr_equal(&dr->next_hop->ipv6, dst)) {
netdev_t *dev = netif->dev;
uint8_t l2src[GNRC_NETIF2_L2ADDR_MAXLEN];
size_t l2src_len = (uint16_t)dev->driver->get(dev, NETOPT_ADDRESS_LONG,
l2src, sizeof(l2src));
if (l2src_len != sizeof(eui64_t)) {
DEBUG("nib: can't get EUI-64 of the interface for ARO\n");
return;
}
ext_opt = gnrc_sixlowpan_nd_opt_ar_build(0, GNRC_SIXLOWPAN_ND_AR_LTIME,
(eui64_t *)l2src, NULL);
if (ext_opt == NULL) {
DEBUG("nib: error allocating ARO.\n");
return;
}
}
#endif /* MODULE_GNRC_SIXLOWPAN_ND */
gnrc_ndp2_nbr_sol_send(tgt, netif, src, dst, ext_opt);
}
void _snd_uc_ns(_nib_onl_entry_t *nbr, bool reset)
{
gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(_nib_onl_get_if(nbr));
_nib_iface_t *iface = _nib_iface_get(_nib_onl_get_if(nbr));
gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(nbr));
DEBUG("unicast to %s (retrans. timer = %ums)\n",
assert(netif != NULL);
gnrc_netif2_acquire(netif);
DEBUG("nib: unicast to %s (retrans. timer = %ums)\n",
ipv6_addr_to_str(addr_str, &nbr->ipv6, sizeof(addr_str)),
(unsigned)iface->retrans_time);
assert((netif != NULL) && (iface != NULL));
(unsigned)netif->ipv6.retrans_time);
#if GNRC_IPV6_NIB_CONF_ARSM
if (reset) {
nbr->ns_sent = 0;
@ -65,20 +93,20 @@ void _snd_uc_ns(_nib_onl_entry_t *nbr, bool reset)
#endif
_snd_ns(&nbr->ipv6, netif, NULL, &nbr->ipv6);
_evtimer_add(nbr, GNRC_IPV6_NIB_SND_UC_NS, &nbr->nud_timeout,
iface->retrans_time);
netif->ipv6.retrans_time);
gnrc_netif2_release(netif);
#if GNRC_IPV6_NIB_CONF_ARSM
nbr->ns_sent++;
#endif
}
void _handle_sl2ao(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
void _handle_sl2ao(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const icmpv6_hdr_t *icmpv6, const ndp_opt_t *sl2ao)
{
_nib_onl_entry_t *nce = _nib_onl_get(&ipv6->src, iface);
gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(iface);
assert(netif != NULL);
_nib_onl_entry_t *nce = _nib_onl_get(&ipv6->src, netif->pid);
unsigned l2addr_len;
assert(netif != NULL);
l2addr_len = _get_l2addr_len(netif, sl2ao);
if (l2addr_len == 0U) {
DEBUG("nib: Unexpected SL2AO length. Ignoring SL2AO\n");
@ -93,13 +121,14 @@ void _handle_sl2ao(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
!_rtr_sol_on_6lr(netif, icmpv6)) {
DEBUG("nib: L2 address differs. Setting STALE\n");
evtimer_del(&_nib_evtimer, &nce->nud_timeout.event);
_set_nud_state(nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
_set_nud_state(netif, nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
}
#endif /* GNRC_IPV6_NIB_CONF_ARSM */
if ((nce == NULL) || !(nce->mode & _NC)) {
DEBUG("nib: Creating NCE for (ipv6 = %s, iface = %u, nud_state = STALE)\n",
ipv6_addr_to_str(addr_str, &ipv6->src, sizeof(addr_str)), iface);
nce = _nib_nc_add(&ipv6->src, iface,
ipv6_addr_to_str(addr_str, &ipv6->src, sizeof(addr_str)),
netif->pid);
nce = _nib_nc_add(&ipv6->src, netif->pid,
GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
if (nce != NULL) {
if (icmpv6->type == ICMPV6_NBR_SOL) {
@ -126,13 +155,13 @@ void _handle_sl2ao(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
if (icmpv6->type == ICMPV6_RTR_ADV) {
DEBUG("nib: %s%%%u is a router\n",
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
iface);
netif->pid);
nce->info |= GNRC_IPV6_NIB_NC_INFO_IS_ROUTER;
}
else if (icmpv6->type != ICMPV6_NBR_SOL) {
DEBUG("nib: %s%%%u is probably not a router\n",
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
iface);
netif->pid);
nce->info &= ~GNRC_IPV6_NIB_NC_INFO_IS_ROUTER;
}
#if GNRC_IPV6_NIB_CONF_ARSM
@ -146,27 +175,40 @@ void _handle_sl2ao(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
}
}
static inline unsigned _get_l2addr_len(gnrc_ipv6_netif_t *netif,
static inline unsigned _get_l2addr_len(gnrc_netif2_t *netif,
const ndp_opt_t *opt)
{
#if GNRC_IPV6_NIB_CONF_6LN
if (_is_6ln(netif)) {
switch (netif->device_type) {
#ifdef MODULE_CC110X
case NETDEV_TYPE_CC110X:
(void)opt;
return sizeof(uint8_t);
#endif
#ifdef MODULE_NETDEV_ETH
case NETDEV_TYPE_ETHERNET:
(void)opt;
return ETHERNET_ADDR_LEN;
#endif
#ifdef MODULE_NETDEV_NRFMIN
case NETDEV_TYPE_NRFMIN:
(void)opt;
return sizeof(uint16_t);
#endif
#ifdef MODULE_NETDEV_IEEE802154
case NETDEV_TYPE_IEEE802154:
switch (opt->len) {
case 1U:
return 2U;
return IEEE802154_SHORT_ADDRESS_LEN;
case 2U:
return 8U;
return IEEE802154_LONG_ADDRESS_LEN;
default:
return 0U;
}
}
#else
(void)netif;
#endif /* GNRC_IPV6_NIB_CONF_6LN */
if (opt->len == 1U) {
return 6U;
}
#endif
default:
(void)opt;
return 0U;
}
}
#if GNRC_IPV6_NIB_CONF_ARSM
@ -207,7 +249,7 @@ static inline bool _rflag_set(const ndp_nbr_adv_t *nbr_adv);
*
* @param[in] nce A neighbor cache entry.
* @param[in] tl2ao The TL2AO.
* @param[in] iface The interface the TL2AO came over.
* @param[in] netif The interface the TL2AO came over.
* @param[in] tl2ao_addr_len Length of the L2 address in the TL2AO.
*
* @return `true`, if the TL2AO changes the NCE.
@ -215,7 +257,7 @@ static inline bool _rflag_set(const ndp_nbr_adv_t *nbr_adv);
*/
static inline bool _tl2ao_changes_nce(_nib_onl_entry_t *nce,
const ndp_opt_t *tl2ao,
kernel_pid_t iface,
gnrc_netif2_t *netif,
unsigned tl2ao_addr_len);
void _handle_snd_ns(_nib_onl_entry_t *nbr)
@ -233,7 +275,10 @@ void _handle_snd_ns(_nib_onl_entry_t *nbr)
break;
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE:
if (nbr->ns_sent >= NDP_MAX_UC_SOL_NUMOF) {
_set_nud_state(nbr, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE);
gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(nbr));
_set_nud_state(netif, nbr,
GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE);
}
/* falls through intentionally */
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE:
@ -253,14 +298,17 @@ void _handle_state_timeout(_nib_onl_entry_t *nbr)
DEBUG("nib: Timeout reachability\n");
new_state = GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE;
/* falls through intentionally */
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY:
_set_nud_state(nbr, new_state);
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY: {
gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(nbr));
_set_nud_state(netif, nbr, new_state);
if (new_state == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE) {
DEBUG("nib: Timeout DELAY state\n");
_probe_nbr(nbr, true);
}
break;
}
}
}
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;
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE:
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE: {
_nib_iface_t *iface = _nib_iface_get(_nib_onl_get_if(nbr));
gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(nbr));
uint32_t next_ns = _evtimer_lookup(nbr,
GNRC_IPV6_NIB_SND_MC_NS);
if (next_ns > iface->retrans_time) {
gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(_nib_onl_get_if(nbr));
assert(netif != NULL);
gnrc_netif2_acquire(netif);
if (next_ns > netif->ipv6.retrans_time) {
ipv6_addr_t sol_nodes;
uint32_t retrans_time = iface->retrans_time;
uint32_t retrans_time = netif->ipv6.retrans_time;
DEBUG("multicast to %s's solicited nodes ",
ipv6_addr_to_str(addr_str, &nbr->ipv6,
sizeof(addr_str)));
assert(netif != NULL);
if (reset) {
nbr->ns_sent = 0;
}
if (state == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE) {
/* first 3 retransmissions in PROBE, assume 1 higher to
* not send after iface->retrans_timer sec again,
* not send after netif->ipv6.retrans_timer sec again,
* but the next backoff after that => subtract 2 */
retrans_time = _exp_backoff_retrans_timer(nbr->ns_sent - 2,
retrans_time);
@ -312,9 +361,10 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset)
"a multicast NS within %ums)\n",
ipv6_addr_to_str(addr_str, &nbr->ipv6,
sizeof(addr_str)),
(unsigned)iface->retrans_time);
(unsigned)netif->ipv6.retrans_time);
}
#endif
gnrc_netif2_release(netif);
}
break;
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE:
@ -324,10 +374,9 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset)
}
}
void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce,
void _handle_adv_l2(gnrc_netif2_t *netif, _nib_onl_entry_t *nce,
const icmpv6_hdr_t *icmpv6, const ndp_opt_t *tl2ao)
{
gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(iface);
unsigned l2addr_len = 0;
assert(nce != NULL);
@ -342,7 +391,7 @@ void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce,
if ((_get_nud_state(nce) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE) ||
_oflag_set((ndp_nbr_adv_t *)icmpv6) ||
_redirect_with_tl2ao(icmpv6, tl2ao) ||
_tl2ao_changes_nce(nce, tl2ao, iface, l2addr_len)) {
_tl2ao_changes_nce(nce, tl2ao, netif, l2addr_len)) {
bool nce_was_incomplete =
(_get_nud_state(nce) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE);
if (tl2ao != NULL) {
@ -353,17 +402,17 @@ void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce,
nce->l2addr_len = 0;
}
if (_sflag_set((ndp_nbr_adv_t *)icmpv6)) {
_set_reachable(iface, nce);
_set_reachable(netif, nce);
}
else if ((icmpv6->type != ICMPV6_NBR_ADV) ||
!_sflag_set((ndp_nbr_adv_t *)icmpv6) ||
(!nce_was_incomplete &&
_tl2ao_changes_nce(nce, tl2ao, iface, l2addr_len))) {
_tl2ao_changes_nce(nce, tl2ao, netif, l2addr_len))) {
DEBUG("nib: Set %s%%%u to STALE\n",
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
iface);
(unsigned)netif->pid);
evtimer_del(&_nib_evtimer, &nce->nud_timeout.event);
_set_nud_state(nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
_set_nud_state(netif, nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
}
if (_oflag_set((ndp_nbr_adv_t *)icmpv6) ||
((icmpv6->type == ICMPV6_NBR_ADV) && nce_was_incomplete)) {
@ -391,30 +440,57 @@ void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce,
if ((icmpv6->type == ICMPV6_NBR_ADV) &&
!_sflag_set((ndp_nbr_adv_t *)icmpv6) &&
(_get_nud_state(nce) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE) &&
_tl2ao_changes_nce(nce, tl2ao, iface, l2addr_len)) {
_tl2ao_changes_nce(nce, tl2ao, netif, l2addr_len)) {
evtimer_del(&_nib_evtimer, &nce->nud_timeout.event);
_set_nud_state(nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
_set_nud_state(netif, nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
}
}
else if ((icmpv6->type == ICMPV6_NBR_ADV) &&
(_get_nud_state(nce) != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE) &&
(_get_nud_state(nce) != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED) &&
_sflag_set((ndp_nbr_adv_t *)icmpv6) &&
!_tl2ao_changes_nce(nce, tl2ao, iface, l2addr_len)) {
_set_reachable(iface, nce);
!_tl2ao_changes_nce(nce, tl2ao, netif, l2addr_len)) {
_set_reachable(netif, nce);
}
}
void _set_reachable(unsigned iface, _nib_onl_entry_t *nce)
void _recalc_reach_time(gnrc_netif2_ipv6_t *netif)
{
_nib_iface_t *nib_netif = _nib_iface_get(iface);
const uint32_t half = (netif->reach_time_base >> 1);
netif->reach_time = random_uint32_range(half,
netif->reach_time_base + half);
_evtimer_add(netif, GNRC_IPV6_NIB_RECALC_REACH_TIME,
&netif->recalc_reach_time,
GNRC_IPV6_NIB_CONF_REACH_TIME_RESET);
}
void _set_reachable(gnrc_netif2_t *netif, _nib_onl_entry_t *nce)
{
DEBUG("nib: Set %s%%%u to REACHABLE for %ums\n",
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
iface, (unsigned)nib_netif->reach_time);
_set_nud_state(nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE);
netif->pid, (unsigned)netif->ipv6.reach_time);
_set_nud_state(netif, nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE);
_evtimer_add(nce, GNRC_IPV6_NIB_REACH_TIMEOUT, &nce->nud_timeout,
nib_netif->reach_time);
netif->ipv6.reach_time);
}
void _set_nud_state(gnrc_netif2_t *netif, _nib_onl_entry_t *nce,
uint16_t state)
{
nce->info &= ~GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK;
nce->info |= state;
#if GNRC_IPV6_NIB_CONF_ROUTER
gnrc_netif2_acquire(netif);
if ((netif != NULL) && (netif->ipv6.route_info_cb)) {
netif->ipv6.route_info_cb(GNRC_IPV6_NIB_ROUTE_INFO_TYPE_NSC,
&nce->ipv6, (void *)((intptr_t)state));
}
gnrc_netif2_release(netif);
#else
(void)netif;
#endif
}
/* internal functions */
@ -443,13 +519,13 @@ static inline bool _redirect_with_tl2ao(icmpv6_hdr_t *icmpv6, ndp_opt_t *tl2ao)
static inline bool _tl2ao_changes_nce(_nib_onl_entry_t *nce,
const ndp_opt_t *tl2ao,
kernel_pid_t iface,
gnrc_netif2_t *netif,
unsigned tl2ao_addr_len)
{
return ((tl2ao != NULL) &&
(((nce->l2addr_len != tl2ao_addr_len) &&
(memcmp(nce->l2addr, tl2ao + 1, tl2ao_addr_len) != 0)) ||
(_nib_onl_get_if(nce) != (unsigned)iface)));
(_nib_onl_get_if(nce) != (unsigned)netif->pid)));
}
static inline bool _oflag_set(const ndp_nbr_adv_t *nbr_adv)

View File

@ -24,6 +24,7 @@
#include <stdint.h>
#include "net/gnrc/ipv6/nib/conf.h"
#include "net/gnrc/netif2.h"
#include "net/ndp.h"
#include "net/icmpv6.h"
@ -47,7 +48,7 @@ extern "C" {
* @param[in] dst Destination address for neighbor solicitation. May not
* be NULL.
*/
void _snd_ns(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
void _snd_ns(const ipv6_addr_t *tgt, gnrc_netif2_t *netif,
const ipv6_addr_t *src, const ipv6_addr_t *dst);
/**
@ -72,12 +73,12 @@ void _snd_uc_ns(_nib_onl_entry_t *nbr, bool reset);
* to the ARSM, but ARSM isn't the only mechanism using it (e.g. the
* 6Lo address registration uses it).
*
* @param[in] iface Interface the SL2AO was sent over.
* @param[in] netif Interface the SL2AO was sent over.
* @param[in] ipv6 IPv6 header of the message carrying the SL2AO.
* @param[in] icmpv6 ICMPv6 header of the message carrying the SL2AO.
* @param[in] sl2ao The SL2AO
*/
void _handle_sl2ao(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
void _handle_sl2ao(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const icmpv6_hdr_t *icmpv6, const ndp_opt_t *sl2ao);
#if GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN)
@ -111,7 +112,7 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset);
* This can either be an TL2AO or for a link-layer without addresses just a
* neighbor advertisement.
*
* @param[in] iface Interface the link-layer information was advertised
* @param[in] netif Interface the link-layer information was advertised
* over.
* @param[in] nce Neighbor cache entry that is updated by the advertised
* link-layer information.
@ -120,53 +121,62 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset);
* @param[in] tl2ao The TL2AO carrying the link-layer information. May be
* NULL for link-layers without addresses.
*/
void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce,
void _handle_adv_l2(gnrc_netif2_t *netif, _nib_onl_entry_t *nce,
const icmpv6_hdr_t *icmpv6, const ndp_opt_t *tl2ao);
/**
* @brief Recalculates the (randomized) reachable time of on a network
* interface.
*
* @see [RFC 4861, section 6.3.4](https://tools.ietf.org/html/rfc4861#section-6.3.4)
*
* @param[in] netif Interface to set reachable time for.
*/
void _recalc_reach_time(gnrc_netif2_ipv6_t *netif);
/**
* @brief Sets a neighbor cache entry reachable and starts the required
* event timers
*
* @param[in] iface Interface to the NCE
* @param[in] netif Interface to the NCE
* @param[in] nce The neighbor cache entry to set reachable
*/
void _set_reachable(unsigned iface, _nib_onl_entry_t *nce);
void _set_reachable(gnrc_netif2_t *netif, _nib_onl_entry_t *nce);
/**
* @brief Initializes interface for address registration state machine
*
* @param[in] nib_iface An interface
* @param[in] netif An interface
*/
static inline void _init_iface_arsm(_nib_iface_t *nib_iface)
static inline void _init_iface_arsm(gnrc_netif2_t *netif)
{
nib_iface->reach_time_base = NDP_REACH_MS;
nib_iface->retrans_time = NDP_RETRANS_TIMER_MS;
_nib_iface_recalc_reach_time(nib_iface);
netif->ipv6.reach_time_base = NDP_REACH_MS;
_recalc_reach_time(&netif->ipv6);
}
/**
* @brief Gets neighbor unreachability state of a neighbor
*
* @param[in] entry Neighbor cache entry representing the neighbor.
* @param[in] nbr Neighbor cache entry representing the neighbor.
*
* @return Neighbor unreachability state of the @p entry.
* @return Neighbor unreachability state of the @p nbr.
*/
static inline uint16_t _get_nud_state(_nib_onl_entry_t *entry)
static inline uint16_t _get_nud_state(_nib_onl_entry_t *nbr)
{
return (entry->info & GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK);
return (nbr->info & GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK);
}
/**
* @brief Sets neighbor unreachablility state of a neighbor
*
* @param[in] entry Neighbor cache entry representing the neighbor.
* @param[in] netif The network interface (to signal routing protocol using
* gnrc_netif_t::ipv6::route_info_cb())
* @param[in] nbr Neighbor cache entry representing the neighbor.
* @param[in] state Neighbor unreachability state for the neighbor.
*/
static inline void _set_nud_state(_nib_onl_entry_t *entry, uint16_t state)
{
entry->info &= ~GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK;
entry->info |= state;
}
void _set_nud_state(gnrc_netif2_t *netif, _nib_onl_entry_t *nbr,
uint16_t state);
#else /* GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN) */
#define _handle_snd_ns(ctx) (void)ctx
@ -175,11 +185,12 @@ static inline void _set_nud_state(_nib_onl_entry_t *entry, uint16_t state)
#define _init_iface_arsm(netif) (void)netif
#define _handle_adv_l2(netif, nce, icmpv6, tl2ao) (void)netif; (void)nce; \
(void)icmpv6; (void)tl2ao
#define _recalc_reach_time(netif) (void)netif;
#define _set_reachable(netif, nce) (void)netif; (void)nce
#define _init_iface_arsm(netif) (void)netif
#define _get_nud_state(entry) (GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED)
#define _set_nud_state(entry, state) (void)entry; (void)state
#define _get_nud_state(nbr) (GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED)
#define _set_nud_state(netif, nce, state) (void)netif; (void)nbr; (void)state
#endif /* GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN) */
#ifdef __cplusplus

View File

@ -21,7 +21,7 @@
#include "net/gnrc/ipv6/nib/conf.h"
#include "net/gnrc/ipv6/nib/nc.h"
#include "net/gnrc/ipv6/nib.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/netif2/internal.h"
#include "random.h"
#include "_nib-internal.h"
@ -36,7 +36,6 @@ static clist_node_t _next_removable = { NULL };
static _nib_onl_entry_t _nodes[GNRC_IPV6_NIB_NUMOF];
static _nib_offl_entry_t _dsts[GNRC_IPV6_NIB_OFFL_NUMOF];
static _nib_dr_entry_t _def_routers[GNRC_IPV6_NIB_DEFAULT_ROUTER_NUMOF];
static _nib_iface_t _nis[GNRC_NETIF_NUMOF];
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
static _nib_abr_entry_t _abrs[GNRC_IPV6_NIB_ABR_NUMOF];
@ -61,7 +60,6 @@ void _nib_init(void)
memset(_nodes, 0, sizeof(_nodes));
memset(_def_routers, 0, sizeof(_def_routers));
memset(_dsts, 0, sizeof(_dsts));
memset(_nis, 0, sizeof(_nis));
#if GNRC_IPV6_NIB_CONF_MULTIHOP_P6C
memset(_abrs, 0, sizeof(_abrs));
#endif
@ -226,15 +224,21 @@ _nib_onl_entry_t *_nib_onl_get(const ipv6_addr_t *addr, unsigned iface)
void _nib_nc_set_reachable(_nib_onl_entry_t *node)
{
#if GNRC_IPV6_NIB_CONF_ARSM
_nib_iface_t *iface = _nib_iface_get(_nib_onl_get_if(node));
gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(node));
DEBUG("nib: set %s%%%u reachable (reachable time = %u)\n",
ipv6_addr_to_str(addr_str, &node->ipv6, sizeof(addr_str)),
_nib_onl_get_if(node), iface->reach_time);
node->info &= ~GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK;
node->info |= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE;
#ifdef TEST_SUITES
/* exit early for unittests */
if (netif == NULL) {
return;
}
#endif
DEBUG("nib: set %s%%%u reachable (reachable time = %u)\n",
ipv6_addr_to_str(addr_str, &node->ipv6, sizeof(addr_str)),
_nib_onl_get_if(node), (unsigned)netif->ipv6.reach_time);
_evtimer_add(node, GNRC_IPV6_NIB_REACH_TIMEOUT, &node->nud_timeout,
iface->reach_time);
netif->ipv6.reach_time);
#else
(void)node;
#endif
@ -281,10 +285,9 @@ void _nib_nc_get(const _nib_onl_entry_t *node, gnrc_ipv6_nib_nc_t *nce)
#if GNRC_IPV6_NIB_CONF_ARSM
#if GNRC_IPV6_NIB_CONF_6LN
if (ipv6_addr_is_link_local(&nce->ipv6)) {
gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(_nib_onl_get_if(node));
gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(node));
assert(netif != NULL);
if ((netif->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) &&
!(netif->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER)) {
if (gnrc_netif2_is_6ln(netif) && !gnrc_netif2_is_rtr(netif)) {
_get_l2addr_from_ipv6(nce->l2addr, &node->ipv6);
nce->l2addr_len = sizeof(uint64_t);
return;
@ -768,42 +771,6 @@ _nib_offl_entry_t *_nib_pl_add(unsigned iface,
return dst;
}
_nib_iface_t *_nib_iface_get(unsigned iface)
{
_nib_iface_t *ni = NULL;
assert(iface <= _NIB_IF_MAX);
for (unsigned i = 0; i < GNRC_NETIF_NUMOF; i++) {
_nib_iface_t *tmp = &_nis[i];
if (((unsigned)tmp->pid) == iface) {
return tmp;
}
if ((ni == NULL) && (tmp->pid == KERNEL_PID_UNDEF)) {
ni = tmp;
}
}
if (ni != NULL) {
memset(ni, 0, sizeof(_nib_iface_t));
/* TODO: set random reachable time using constants from #6220 */
ni->pid = (kernel_pid_t)iface;
}
return ni;
}
#if GNRC_IPV6_NIB_CONF_ARSM
void _nib_iface_recalc_reach_time(_nib_iface_t *iface)
{
uint32_t factor = random_uint32_range(NDP_MIN_RANDOM_FACTOR,
NDP_MAX_RANDOM_FACTOR);
/* random factor was times 1000 so we need to divide it again */
iface->reach_time = (iface->reach_time_base * factor) / 1000;
_evtimer_add(iface, GNRC_IPV6_NIB_RECALC_REACH_TIME,
&iface->recalc_reach_time,
GNRC_IPV6_NIB_CONF_REACH_TIME_RESET);
}
#endif
static void _override_node(const ipv6_addr_t *addr, unsigned iface,
_nib_onl_entry_t *node)
{

View File

@ -193,56 +193,6 @@ typedef struct {
preferred (UINT32_MAX means forever) */
} _nib_offl_entry_t;
/**
* @brief Interface specific information for Neighbor Discovery
*/
typedef struct {
#if GNRC_IPV6_NIB_CONF_ARSM
/**
* @brief base for random reachable time calculation
*/
uint32_t reach_time_base;
uint32_t reach_time; /**< reachable time (in ms) */
#endif
uint32_t retrans_time; /**< retransmission time (in ms) */
#if GNRC_IPV6_NIB_CONF_ROUTER || defined(DOXYGEN)
/**
* @brief timestamp in milliseconds of last unsolicited router
* advertisement
*
* @note Only available if @ref GNRC_IPV6_NIB_CONF_ROUTER.
*/
uint32_t last_ra;
#endif
#if GNRC_IPV6_NIB_CONF_ARSM || defined(DOXYGEN)
/**
* @brief Event for @ref GNRC_IPV6_NIB_RECALC_REACH_TIME
*/
evtimer_msg_event_t recalc_reach_time;
#endif
kernel_pid_t pid; /**< identifier of the interface */
#if GNRC_IPV6_NIB_CONF_ROUTER || defined(DOXYGEN)
/**
* @brief number of unsolicited router advertisements sent
*
* This only counts up to the first @ref NDP_MAX_INIT_RA_NUMOF on interface
* initialization. The last @ref NDP_MAX_FIN_RA_NUMOF of an advertising
* interface are counted from UINT8_MAX - @ref NDP_MAX_FIN_RA_NUMOF + 1.
*
* @note Only available if @ref GNRC_IPV6_NIB_CONF_ROUTER.
*/
uint8_t ra_sent;
#endif
/**
* @brief number of unsolicited router solicitations scheduled
*/
uint8_t rs_sent;
/**
* @brief number of unsolicited neighbor advertisements scheduled
*/
uint8_t na_sent;
} _nib_iface_t;
/**
* @brief Internal NIB-representation of the authoritative border router
* for multihop prefix and 6LoWPAN context dissemination
@ -795,30 +745,6 @@ void _nib_ft_get(const _nib_offl_entry_t *dst, gnrc_ipv6_nib_ft_t *fte);
int _nib_get_route(const ipv6_addr_t *dst, gnrc_pktsnip_t *ctx,
gnrc_ipv6_nib_ft_t *entry);
/**
* @brief Gets (or creates if it not exists) interface information for
* neighbor discovery
*
* @pre `(iface <= _NIB_IF_MAX)`
*
* @param[in] iface Interface identifier to get information for.
*
* @return Interface information on @p iface.
* @return NULL, if no space left for interface.
*/
_nib_iface_t *_nib_iface_get(unsigned iface);
/**
* @brief Recalculates randomized reachable time of an interface.
*
* @param[in] iface An interface.
*/
#if GNRC_IPV6_NIB_CONF_ARSM
void _nib_iface_recalc_reach_time(_nib_iface_t *iface);
#else
#define _nib_iface_recalc_reach_time(iface) (void)iface
#endif
/**
* @brief Looks up if an event is queued in the event timer
*

View File

@ -16,9 +16,10 @@
#include <errno.h>
#include <stdbool.h>
#include "log.h"
#include "net/ipv6/addr.h"
#include "net/gnrc/nettype.h"
#include "net/gnrc/ipv6/netif.h"
#include "net/gnrc/netif2/internal.h"
#include "net/gnrc/ipv6/nib.h"
#include "net/gnrc/ndp2.h"
#include "net/gnrc/pktqueue.h"
@ -49,24 +50,16 @@ static gnrc_pktqueue_t _queue_pool[GNRC_IPV6_NIB_NUMOF];
* @internal
* @{
*/
static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
static void _handle_nbr_sol(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const ndp_nbr_sol_t *nbr_sol, size_t icmpv6_len);
static void _handle_nbr_adv(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
static void _handle_nbr_adv(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const ndp_nbr_adv_t *nbr_adv, size_t icmpv6_len);
static bool _resolve_addr(const ipv6_addr_t *dst, kernel_pid_t iface,
static bool _resolve_addr(const ipv6_addr_t *dst, gnrc_netif2_t *netif,
gnrc_pktsnip_t *pkt, gnrc_ipv6_nib_nc_t *nce,
_nib_onl_entry_t *entry);
static void _handle_snd_na(gnrc_pktsnip_t *pkt);
/* interface flag checks */
#if GNRC_IPV6_NIB_CONF_ROUTER
static inline bool _is_rtr(const gnrc_ipv6_netif_t *netif)
{
return (netif->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER);
}
#endif
/** @} */
void gnrc_ipv6_nib_init(void)
@ -83,27 +76,13 @@ void gnrc_ipv6_nib_init(void)
mutex_unlock(&_nib_mutex);
}
void gnrc_ipv6_nib_init_iface(kernel_pid_t iface)
void gnrc_ipv6_nib_init_iface(gnrc_netif2_t *netif)
{
_nib_iface_t *nib_iface;
ipv6_addr_t addr = IPV6_ADDR_UNSPECIFIED;
assert(iface > KERNEL_PID_UNDEF);
DEBUG("nib: Initialize interface %u\n", (unsigned)iface);
mutex_lock(&_nib_mutex);
nib_iface = _nib_iface_get(iface);
#ifdef TEST_SUITES
if (nib_iface == NULL) {
/* in the unittests old NC and NIB are mixed, so this function leads to
* crashes. To prevent this we early exit here, if the interface was
* not found
* TODO: remove when gnrc_ipv6_nc is removed.
*/
mutex_unlock(&_nib_mutex);
return;
}
#else
assert(nib_iface != NULL);
#endif
assert(netif != NULL);
DEBUG("nib: Initialize interface %u\n", netif->pid);
gnrc_netif2_acquire(netif);
/* TODO:
* - set link-local address here for stateless address auto-configuration
* and 6LN
@ -112,46 +91,116 @@ void gnrc_ipv6_nib_init_iface(kernel_pid_t iface)
* - join all router group of link-local address here on router node here
* - become an router advertising interface here on non-6LR here */
_init_iface_arsm(nib_iface);
nib_iface->rs_sent = 0;
nib_iface->na_sent = 0;
_init_iface_arsm(netif);
netif->ipv6.retrans_time = NDP_RETRANS_TIMER_MS;
netif->ipv6.na_sent = 0;
#if GNRC_IPV6_NIB_CONF_ROUTER
nib_iface->last_ra = UINT32_MAX;
nib_iface->ra_sent = 0;
netif->ipv6.rtr_ltime = 1800U;
netif->ipv6.last_ra = UINT32_MAX;
netif->ipv6.ra_sent = 0;
netif->flags |= GNRC_NETIF2_FLAGS_IPV6_FORWARDING;
#if !GNRC_IPV6_NIB_CONF_6LR || GNRC_IPV6_NIB_CONF_6LBR
netif->flags |= GNRC_NETIF2_FLAGS_IPV6_RTR_ADV;
#endif
mutex_unlock(&_nib_mutex);
#if GNRC_IPV6_NIB_CONF_6LBR
netif->flags |= GNRC_NETIF2_FLAGS_6LO_ABR;
#endif
memcpy(&addr, &ipv6_addr_all_routers_link_local, sizeof(addr));
if (gnrc_netif2_ipv6_group_join(netif, &addr) < 0) {
LOG_ERROR("nib: Can't join link-local all-routers on interface %u\n",
netif->pid);
return;
}
#endif
#if GNRC_IPV6_NIB_CONF_6LN
netif->ipv6.rs_sent = 0;
#endif
memcpy(&addr, &ipv6_addr_all_nodes_link_local, sizeof(addr));
if (gnrc_netif2_ipv6_group_join(netif, &addr) < 0) {
LOG_ERROR("nib: Can't join link-local all-nodes on interface %u\n",
netif->pid);
return;
}
#if GNRC_IPV6_NIB_CONF_6LN || GNRC_IPV6_NIB_CONF_SLAAC
#if GNRC_IPV6_NIB_CONF_6LN
if (netif->device_type == NETDEV_TYPE_IEEE802154) {
/* see https://tools.ietf.org/html/rfc6775#section-5.2 */
uint16_t src_len = IEEE802154_LONG_ADDRESS_LEN;
gnrc_netapi_opt_t opt = { .opt = NETOPT_SRC_LEN,
.data = &src_len,
.data_len = sizeof(src_len) };
/* XXX we are supposed to be in interface context here, so use driver
* directly everything else would deadlock anyway */
netif->ops->set(netif, &opt);
}
#endif
uint8_t flags = GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID;
/* TODO: set TENTATIVE as soon as there is a SLAAC implementation if not
* 6LN ;-) */
gnrc_netif2_ipv6_get_iid(netif, (eui64_t *)&addr.u64[1]);
ipv6_addr_set_link_local_prefix(&addr);
if (gnrc_netif2_ipv6_addr_add(netif, &addr, 64U, flags) < 0) {
LOG_ERROR("nib: Can't add link-local address on interface %u\n",
netif->pid);
return;
}
#if GNRC_IPV6_NIB_CONF_ARSM
/* TODO: SHOULD delay join between 0 and MAX_RTR_SOLICITATION_DELAY */
ipv6_addr_set_solicited_nodes(&addr, &addr);
if (gnrc_netif2_ipv6_group_join(netif, &addr) < 0) {
LOG_ERROR("nib: Can't join solicited-nodes of link-local address on "
"interface %u\n", netif->pid);
return;
}
#endif
#if GNRC_IPV6_NIB_CONF_SLAAC
/* TODO send NS to solicited nodes and wait netif->ipv6.retrans_time to
* confirm uniqueness of the link-local address */
#endif
#endif
gnrc_netif2_release(netif);
}
int gnrc_ipv6_nib_get_next_hop_l2addr(const ipv6_addr_t *dst,
kernel_pid_t iface, gnrc_pktsnip_t *pkt,
gnrc_netif2_t *netif, gnrc_pktsnip_t *pkt,
gnrc_ipv6_nib_nc_t *nce)
{
int res = 0;
DEBUG("nib: get next hop link-layer address of %s%%%u\n",
ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)),
(netif != NULL) ? (unsigned)netif->pid : 0U);
gnrc_netif2_acquire(netif);
mutex_lock(&_nib_mutex);
do { /* XXX: hidden goto ;-) */
if (ipv6_addr_is_link_local(dst)) {
/* TODO: Prefix-based on-link determination */
if ((iface == KERNEL_PID_UNDEF) ||
!_resolve_addr(dst, iface, pkt, nce,
_nib_onl_get(dst, iface))) {
if ((netif == NULL) ||
!_resolve_addr(dst, netif, pkt, nce,
_nib_onl_get(dst, netif->pid))) {
res = -EHOSTUNREACH;
break;
}
}
else {
/* TODO: Off-link next hop determination */
/* TODO: Off-link next hop determination;
* might need netif locking */
res = -EHOSTUNREACH;
}
} while (0);
mutex_unlock(&_nib_mutex);
gnrc_netif2_release(netif);
return res;
}
void gnrc_ipv6_nib_handle_pkt(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
void gnrc_ipv6_nib_handle_pkt(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const icmpv6_hdr_t *icmpv6, size_t icmpv6_len)
{
DEBUG("nib: Handle packet (icmpv6->type = %u)\n", icmpv6->type);
assert(netif != NULL);
gnrc_netif2_acquire(netif);
mutex_lock(&_nib_mutex);
switch (icmpv6->type) {
#if GNRC_IPV6_NIB_CONF_ROUTER
@ -163,10 +212,10 @@ void gnrc_ipv6_nib_handle_pkt(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
/* TODO */
break;
case ICMPV6_NBR_SOL:
_handle_nbr_sol(iface, ipv6, (ndp_nbr_sol_t *)icmpv6, icmpv6_len);
_handle_nbr_sol(netif, ipv6, (ndp_nbr_sol_t *)icmpv6, icmpv6_len);
break;
case ICMPV6_NBR_ADV:
_handle_nbr_adv(iface, ipv6, (ndp_nbr_adv_t *)icmpv6, icmpv6_len);
_handle_nbr_adv(netif, ipv6, (ndp_nbr_adv_t *)icmpv6, icmpv6_len);
break;
#if GNRC_IPV6_NIB_CONF_REDIRECT
case ICMPV6_REDIRECT:
@ -183,6 +232,7 @@ void gnrc_ipv6_nib_handle_pkt(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
#endif /* GNRC_IPV6_NIB_CONF_MULTIHOP_DAD */
}
mutex_unlock(&_nib_mutex);
gnrc_netif2_release(netif);
}
void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type)
@ -191,6 +241,7 @@ void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type)
ctx, type, (unsigned)xtimer_now_usec() / 1000);
mutex_lock(&_nib_mutex);
switch (type) {
/* TODO: remember netif locking if ctx is a gnrc_netif2_t */
#if GNRC_IPV6_NIB_CONF_ARSM
case GNRC_IPV6_NIB_SND_UC_NS:
case GNRC_IPV6_NIB_SND_MC_NS:
@ -201,7 +252,7 @@ void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type)
_handle_state_timeout(ctx);
break;
case GNRC_IPV6_NIB_RECALC_REACH_TIME:
_nib_iface_recalc_reach_time(ctx);
_recalc_reach_time(ctx);
break;
#endif /* GNRC_IPV6_NIB_CONF_ARSM */
case GNRC_IPV6_NIB_SND_NA:
@ -246,6 +297,22 @@ void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type)
mutex_unlock(&_nib_mutex);
}
#if GNRC_IPV6_NIB_CONF_ROUTER
void gnrc_ipv6_nib_change_rtr_adv_iface(gnrc_netif2_t *netif, bool enable)
{
if (enable) {
netif->flags |= GNRC_NETIF2_FLAGS_IPV6_RTR_ADV;
/* TODO: start router advertisements */
}
else {
netif->flags &= ~GNRC_NETIF2_FLAGS_IPV6_RTR_ADV;
/* TODO:
* - start final router advertisements,
* - start router solicitations? */
}
}
#endif
/* Iterator for NDP options in a packet */
#define FOREACH_OPT(ndp_pkt, opt, icmpv6_len) \
for (opt = (ndp_opt_t *)(ndp_pkt + 1); \
@ -253,40 +320,19 @@ void gnrc_ipv6_nib_handle_timer_event(void *ctx, uint16_t type)
icmpv6_len -= (opt->len << 3), \
opt = (ndp_opt_t *)(((uint8_t *)opt) + (opt->len << 3)))
static size_t _get_l2src(kernel_pid_t iface, uint8_t *l2src,
size_t l2src_maxlen)
static inline size_t _get_l2src(const gnrc_netif2_t *netif, uint8_t *l2src)
{
bool try_long = false;
int res;
uint16_t l2src_len;
/* maximum address length that fits into a minimum length (8) S/TL2A
* option */
const uint16_t max_short_len = 6;
/* try getting source address */
if ((gnrc_netapi_get(iface, NETOPT_SRC_LEN, 0, &l2src_len,
sizeof(l2src_len)) >= 0) &&
(l2src_len > max_short_len)) {
try_long = true;
}
if (try_long && ((res = gnrc_netapi_get(iface, NETOPT_ADDRESS_LONG, 0,
l2src, l2src_maxlen)) > max_short_len)) {
l2src_len = (uint16_t)res;
}
else if ((res = gnrc_netapi_get(iface, NETOPT_ADDRESS, 0, l2src,
l2src_maxlen)) >= 0) {
l2src_len = (uint16_t)res;
}
else {
DEBUG("nib: No link-layer address found.\n");
l2src_len = 0;
}
return l2src_len;
#if GNRC_NETIF2_L2ADDR_MAXLEN > 0
memcpy(l2src, netif->l2addr, netif->l2addr_len);
return netif->l2addr_len;
#else
(void)netif;
(void)l2src;
return 0;
#endif
}
static void _send_delayed_nbr_adv(const gnrc_ipv6_netif_t *netif,
static void _send_delayed_nbr_adv(const gnrc_netif2_t *netif,
const ipv6_addr_t *tgt,
const ipv6_addr_t *dst,
gnrc_pktsnip_t *reply_aro)
@ -296,13 +342,15 @@ static void _send_delayed_nbr_adv(const gnrc_ipv6_netif_t *netif,
uint8_t reply_flags = NDP_NBR_ADV_FLAGS_S;
#if GNRC_IPV6_NIB_CONF_ROUTER
if (_is_rtr(netif)) {
if (gnrc_netif2_is_rtr(netif)) {
reply_flags |= NDP_NBR_ADV_FLAGS_R;
}
#endif
#if GNRC_NETIF2_L2ADDR_MAXLEN > 0
if (ipv6_addr_is_multicast(dst)) {
uint8_t l2addr[GNRC_IPV6_NIB_L2ADDR_MAX_LEN];
size_t l2addr_len = _get_l2src(netif->pid, l2addr, sizeof(l2addr));
uint8_t l2addr[GNRC_NETIF2_L2ADDR_MAXLEN];
size_t l2addr_len = _get_l2src(netif, l2addr);
if (l2addr_len > 0) {
extra_opts = gnrc_ndp2_opt_tl2a_build(l2addr, l2addr_len,
extra_opts);
@ -319,6 +367,10 @@ static void _send_delayed_nbr_adv(const gnrc_ipv6_netif_t *netif,
else {
reply_flags |= NDP_NBR_ADV_FLAGS_O;
}
#else /* GNRC_NETIF2_L2ADDR_MAXLEN > 0 */
reply_flags |= NDP_NBR_ADV_FLAGS_O;
#endif
/* discard const qualifier */
nbr_adv = gnrc_ndp2_nbr_adv_build(tgt, reply_flags, extra_opts);
if (nbr_adv == NULL) {
DEBUG("nib: No space left in packet buffer. Not replying NS");
@ -336,12 +388,12 @@ static void _send_delayed_nbr_adv(const gnrc_ipv6_netif_t *netif,
}
}
static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
static void _handle_nbr_sol(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const ndp_nbr_sol_t *nbr_sol, size_t icmpv6_len)
{
size_t tmp_len = icmpv6_len - sizeof(ndp_nbr_sol_t);
int tgt_idx;
ndp_opt_t *opt;
ipv6_addr_t *local;
/* check validity, see: https://tools.ietf.org/html/rfc4861#section-7.1.1 */
/* checksum is checked by GNRC's ICMPv6 module */
@ -365,9 +417,9 @@ static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
return;
}
/* check if target is assigned only now in case the length was wrong */
local = gnrc_ipv6_netif_find_addr(iface, &nbr_sol->tgt);
if (local == NULL) {
DEBUG("nib: Target address %s is not assigned to a local interface\n",
tgt_idx = gnrc_netif2_ipv6_addr_idx(netif, &nbr_sol->tgt);
if (tgt_idx < 0) {
DEBUG("nib: Target address %s is not assigned to the local interface\n",
ipv6_addr_to_str(addr_str, &nbr_sol->tgt, sizeof(addr_str)));
return;
}
@ -395,6 +447,7 @@ static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
/* TODO SLAAC behavior */
#endif /* GNRC_IPV6_NIB_CONF_SLAAC */
if (!ipv6_addr_is_unspecified(&ipv6->src)) {
gnrc_pktsnip_t *reply_aro = NULL;
#if GNRC_IPV6_NIB_CONF_6LR
ndp_opt_t *sl2ao = NULL;
sixlowpan_nd_opt_ar_t *aro = NULL;
@ -402,23 +455,24 @@ static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
#define sl2ao (NULL)
#define aro (NULL)
#endif /* GNRC_IPV6_NIB_CONF_6LR */
gnrc_ipv6_netif_t *netif;
gnrc_pktsnip_t *reply_aro = NULL;
tmp_len = icmpv6_len - sizeof(ndp_nbr_sol_t);
netif = gnrc_ipv6_netif_get(iface);
/* TODO: Set STALE NCE if link-layer has no addresses */
if (!(netif->flags & GNRC_NETIF2_FLAGS_HAS_L2ADDR)) {
/* Set STALE NCE if link-layer has no addresses */
_nib_nc_add(&ipv6->src, netif->pid,
GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
}
FOREACH_OPT(nbr_sol, opt, tmp_len) {
switch (opt->type) {
case NDP_OPT_SL2A:
#if GNRC_IPV6_NIB_CONF_6LR
if (_is_6lr(netif)) {
if (gnrc_netif2_is_6lr(netif)) {
DEBUG("nib: Storing SL2AO for later handling\n");
sl2ao = opt;
break;
}
#endif /* GNRC_IPV6_NIB_CONF_6LR */
_handle_sl2ao(iface, ipv6, (const icmpv6_hdr_t *)nbr_sol,
_handle_sl2ao(netif, ipv6, (const icmpv6_hdr_t *)nbr_sol,
opt);
break;
#if GNRC_IPV6_NIB_CONF_6LR
@ -432,9 +486,9 @@ static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
opt->type);
}
}
reply_aro = _copy_and_handle_aro(iface, ipv6, nbr_sol, aro, sl2ao);
reply_aro = _copy_and_handle_aro(netif, ipv6, nbr_sol, aro, sl2ao);
/* check if target address is anycast */
if (gnrc_ipv6_netif_addr_is_non_unicast(local)) {
if (netif->ipv6.addrs_flags[tgt_idx] & GNRC_NETIF2_IPV6_ADDRS_FLAGS_ANYCAST) {
_send_delayed_nbr_adv(netif, &nbr_sol->tgt, &ipv6->dst, reply_aro);
}
else {
@ -445,7 +499,7 @@ static void _handle_nbr_sol(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
}
}
static void _handle_nbr_adv(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
static void _handle_nbr_adv(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const ndp_nbr_adv_t *nbr_adv, size_t icmpv6_len)
{
size_t tmp_len = icmpv6_len - sizeof(ndp_nbr_adv_t);
@ -501,7 +555,7 @@ static void _handle_nbr_adv(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
#if GNRC_IPV6_NIB_CONF_SLAAC
/* TODO SLAAC behavior */
#endif
if (((nce = _nib_onl_get(&nbr_adv->tgt, iface)) != NULL) &&
if (((nce = _nib_onl_get(&nbr_adv->tgt, netif->pid)) != NULL) &&
(nce->mode & _NC)) {
#if GNRC_IPV6_NIB_CONF_ARSM
bool tl2ao_avail = false;
@ -512,13 +566,13 @@ static void _handle_nbr_adv(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
switch (opt->type) {
#if GNRC_IPV6_NIB_CONF_ARSM
case NDP_OPT_TL2A:
_handle_adv_l2(iface, nce, (icmpv6_hdr_t *)nbr_adv, opt);
_handle_adv_l2(netif, nce, (icmpv6_hdr_t *)nbr_adv, opt);
tl2ao_avail = true;
break;
#endif
#if GNRC_IPV6_NIB_CONF_6LN
case NDP_OPT_AR:
_handle_aro(iface, ipv6, (const icmpv6_hdr_t *)nbr_adv,
_handle_aro(netif, ipv6, (const icmpv6_hdr_t *)nbr_adv,
(const sixlowpan_nd_opt_ar_t *)opt, opt, nce);
break;
#endif
@ -531,11 +585,11 @@ static void _handle_nbr_adv(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
if (!tl2ao_avail && (nbr_adv->flags & NDP_NBR_ADV_FLAGS_S) &&
(_get_nud_state(nce) != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE)) {
/* reachability confirmed without TL2AO */
_set_reachable(iface, nce);
_set_reachable(netif, nce);
}
if (!(netif->flags & GNRC_NETIF2_FLAGS_HAS_L2ADDR)) {
_handle_adv_l2(netif, nce, (icmpv6_hdr_t *)nbr_adv, NULL);
}
/* TODO: handling for of advertised link-layer with link-layers without
* addresses */
/* _handle_adv_l2(iface, nce, (icmpv6_hdr_t *)nbr_adv, NULL); */
#endif
}
}
@ -567,7 +621,7 @@ static gnrc_pktqueue_t *_alloc_queue_entry(gnrc_pktsnip_t *pkt)
}
#endif
static bool _resolve_addr(const ipv6_addr_t *dst, kernel_pid_t iface,
static bool _resolve_addr(const ipv6_addr_t *dst, gnrc_netif2_t *netif,
gnrc_pktsnip_t *pkt, gnrc_ipv6_nib_nc_t *nce,
_nib_onl_entry_t *entry)
{
@ -575,29 +629,44 @@ static bool _resolve_addr(const ipv6_addr_t *dst, kernel_pid_t iface,
#if GNRC_IPV6_NIB_CONF_ARSM
if ((entry != NULL) && (entry->mode & _NC) && _is_reachable(entry)) {
if (_get_nud_state(entry) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE) {
_set_nud_state(entry, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY);
_set_nud_state(netif, entry, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY);
_evtimer_add(entry, GNRC_IPV6_NIB_DELAY_TIMEOUT,
&entry->nud_timeout, NDP_DELAY_FIRST_PROBE_MS);
}
DEBUG("nib: resolve address %s%%%u from neighbor cache\n",
ipv6_addr_to_str(addr_str, &entry->ipv6, sizeof(addr_str)),
_nib_onl_get_if(entry));
_nib_nc_get(entry, nce);
res = true;
}
#else
if (entry != NULL) {
DEBUG("nib: resolve address %s%%%u from neighbor cache\n",
ipv6_addr_to_str(addr_str, &entry->ipv6, sizeof(addr_str)),
_nib_onl_get_if(entry));
_nib_nc_get(entry, nce);
res = true;
}
#endif
else if (!(res = _resolve_addr_from_ipv6(dst, iface, nce))) {
else if (!(res = _resolve_addr_from_ipv6(dst, netif, nce))) {
#if GNRC_IPV6_NIB_CONF_ARSM
bool reset = false;
#endif
DEBUG("nib: resolve address %s by probing neighbors\n",
ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)));
if ((entry == NULL) || !(entry->mode & _NC)) {
entry = _nib_nc_add(dst, iface,
entry = _nib_nc_add(dst, (netif != NULL) ? netif->pid : 0,
GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE);
if (entry == NULL) {
return false;
}
#if GNRC_IPV6_NIB_CONF_ROUTER
if ((netif != NULL) && (netif->ipv6.route_info_cb != NULL)) {
netif->ipv6.route_info_cb(GNRC_IPV6_NIB_ROUTE_INFO_TYPE_NSC,
dst, (void *)GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE);
}
#endif
#if GNRC_IPV6_NIB_CONF_ARSM
reset = true;
#endif

View File

@ -18,7 +18,7 @@
#include <stdio.h>
#include "net/gnrc/ipv6.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/netif2.h"
#include "net/gnrc/ipv6/nib/nc.h"
@ -127,15 +127,16 @@ static const char *_ar_str[] = {
void gnrc_ipv6_nib_nc_print(gnrc_ipv6_nib_nc_t *entry)
{
char addr_str[IPV6_ADDR_MAX_STR_LEN];
char addr_str[(IPV6_ADDR_MAX_STR_LEN > GNRC_IPV6_NIB_L2ADDR_MAX_LEN) ?
IPV6_ADDR_MAX_STR_LEN : GNRC_IPV6_NIB_L2ADDR_MAX_LEN];
printf("%s ", ipv6_addr_to_str(addr_str, &entry->ipv6, sizeof(addr_str)));
if (gnrc_ipv6_nib_nc_get_iface(entry) != KERNEL_PID_UNDEF) {
printf("dev #%u ", gnrc_ipv6_nib_nc_get_iface(entry));
}
printf("lladdr %s ", gnrc_netif_addr_to_str(addr_str, sizeof(addr_str),
entry->l2addr,
entry->l2addr_len));
printf("lladdr %s ", gnrc_netif2_addr_to_str(entry->l2addr,
entry->l2addr_len,
addr_str));
if (gnrc_ipv6_nib_nc_is_router(entry)) {
printf("router");
}

View File

@ -15,7 +15,7 @@
#include "net/gnrc/icmpv6.h"
#include "net/gnrc/ipv6.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/netif2/internal.h"
#ifdef MODULE_GNRC_SIXLOWPAN_ND
#include "net/gnrc/sixlowpan/nd.h"
#endif
@ -167,8 +167,7 @@ gnrc_pktsnip_t *gnrc_ndp2_opt_sl2a_build(const uint8_t *l2addr,
{
assert((l2addr != NULL) && (l2addr_len != 0));
DEBUG("ndp2: building source link-layer address option (l2addr: %s)\n",
gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), l2addr,
l2addr_len));
gnrc_netif2_addr_to_str(l2addr, l2addr_len, addr_str));
return _opt_l2a_build(l2addr, l2addr_len, next, NDP_OPT_SL2A);
}
@ -178,8 +177,7 @@ gnrc_pktsnip_t *gnrc_ndp2_opt_tl2a_build(const uint8_t *l2addr,
{
assert((l2addr != NULL) && (l2addr_len != 0));
DEBUG("ndp2: building target link-layer address option (l2addr: %s)\n",
gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), l2addr,
l2addr_len));
gnrc_netif2_addr_to_str(l2addr, l2addr_len, addr_str));
return _opt_l2a_build(l2addr, l2addr_len, next, NDP_OPT_TL2A);
}
@ -223,14 +221,13 @@ gnrc_pktsnip_t *gnrc_ndp2_opt_mtu_build(uint32_t mtu, gnrc_pktsnip_t *next)
return pkt;
}
static gnrc_pktsnip_t *_build_headers(gnrc_ipv6_netif_t *netif,
static gnrc_pktsnip_t *_build_headers(gnrc_netif2_t *netif,
const ipv6_addr_t *src,
const ipv6_addr_t *dst,
gnrc_pktsnip_t *payload);
static size_t _get_l2src(gnrc_ipv6_netif_t *netif, uint8_t *l2src,
size_t l2src_maxlen);
static inline size_t _get_l2src(const gnrc_netif2_t *netif, uint8_t *l2src);
void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_netif2_t *netif,
const ipv6_addr_t *src, const ipv6_addr_t *dst,
gnrc_pktsnip_t *ext_opts)
{
@ -250,14 +247,16 @@ void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
sizeof(addr_str)));
DEBUG("tgt: %s, ", ipv6_addr_to_str(addr_str, tgt, sizeof(addr_str)));
DEBUG("dst: %s)\n", ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)));
gnrc_netif2_acquire(netif);
do { /* XXX hidden goto */
/* check if there is a fitting source address to target */
if (src == NULL) {
src = gnrc_ipv6_netif_find_best_src_addr(netif->pid, tgt, false);
src = gnrc_netif2_ipv6_addr_best_src(netif, tgt, false);
}
/* add SL2AO based on interface and source address */
if ((src != NULL) && !ipv6_addr_is_unspecified(src)) {
l2src_len = _get_l2src(netif, l2src, sizeof(l2src));
l2src_len = _get_l2src(netif, l2src);
if (l2src_len > 0) {
/* 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) {
DEBUG("ndp2: error allocating SL2AO.\n");
gnrc_pktbuf_release(pkt);
return;
break;
}
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);
if (hdr == NULL) {
DEBUG("ndp2: error allocating neighbor solicitation.\n");
gnrc_pktbuf_release(pkt);
return;
break;
}
pkt = hdr;
/* add remaining headers */
hdr = _build_headers(netif, src, dst, pkt);
if (hdr == NULL) {
DEBUG("ndp2: error adding lower-layer headers.\n");
gnrc_pktbuf_release(pkt);
break;
}
else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) {
else {
pkt = hdr;
if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
GNRC_NETREG_DEMUX_CTX_ALL,
pkt) == 0) {
DEBUG("ndp2: unable to send neighbor solicitation\n");
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,
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)));
DEBUG("dst: %s, supply_tl2a: %d)\n",
ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), supply_tl2a);
if ((netif->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) &&
(netif->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV)) {
gnrc_netif2_acquire(netif);
do { /* XXX: hidden goto */
int tgt_idx;
if ((tgt_idx = gnrc_netif2_ipv6_addr_idx(netif, tgt)) < 0) {
DEBUG("ndp2: tgt not assigned to interface. Abort sending\n");
break;
}
if (gnrc_netif2_is_rtr(netif) && gnrc_netif2_is_rtr_adv(netif)) {
adv_flags |= NDP_NBR_ADV_FLAGS_R;
}
if (ipv6_addr_is_unspecified(dst)) {
memcpy(&real_dst, &ipv6_addr_all_nodes_link_local, sizeof(ipv6_addr_t));
memcpy(&real_dst, &ipv6_addr_all_nodes_link_local,
sizeof(ipv6_addr_t));
supply_tl2a = true;
}
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];
size_t l2tgt_len;
/* we previously checked if we are the target, so we can take our L2tgt */
l2tgt_len = _get_l2src(netif, l2tgt, sizeof(l2tgt));
l2tgt_len = _get_l2src(netif, l2tgt);
if (l2tgt_len > 0) {
/* 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) {
DEBUG("ndp2: error allocating TL2AO.\n");
gnrc_pktbuf_release(ext_opts);
return;
break;
}
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) &&
(!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 */
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);
if (hdr == NULL) {
DEBUG("ndp2: error allocating neighbor advertisement.\n");
gnrc_pktbuf_release(pkt);
return;
break;
}
pkt = hdr;
/* add remaining headers */
hdr = _build_headers(netif, NULL, &real_dst, pkt);
if (hdr == NULL) {
DEBUG("ndp2: error adding lower-layer headers.\n");
gnrc_pktbuf_release(pkt);
break;
}
else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) {
else {
pkt = hdr;
if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
GNRC_NETREG_DEMUX_CTX_ALL,
pkt) == 0) {
DEBUG("ndp2: unable to send neighbor advertisement\n");
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;
ipv6_addr_t *src = NULL;
assert(netif != 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
", dst: %s)\n", netif->pid,
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 */
if ((src = gnrc_ipv6_netif_find_best_src_addr(netif->pid, dst,
false)) != NULL) {
if ((src = gnrc_netif2_ipv6_addr_best_src(netif, dst, false)) != NULL) {
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) {
/* add source address link-layer address option */
pkt = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, NULL);
if (pkt == NULL) {
DEBUG("ndp2: error allocating SL2AO.\n");
gnrc_pktbuf_release(pkt);
return;
break;
}
}
}
@ -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);
if (hdr == NULL) {
DEBUG("ndp2: error allocating router solicitation.\n");
gnrc_pktbuf_release(pkt);
return;
break;
}
pkt = hdr;
/* add remaining headers */
hdr = _build_headers(netif, src, dst, pkt);
if (hdr == NULL) {
DEBUG("ndp2: error adding lower-layer headers.\n");
gnrc_pktbuf_release(pkt);
break;
}
else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) {
else {
pkt = hdr;
if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
GNRC_NETREG_DEMUX_CTX_ALL,
pkt) == 0) {
DEBUG("ndp2: unable to send router advertisement\n");
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,
gnrc_pktsnip_t *ext_opts)
{
@ -422,6 +453,7 @@ void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src,
uint32_t reach_time = 0, retrans_timer = 0;
uint16_t adv_ltime = 0;
uint8_t cur_hl = 0;
uint8_t flags = 0;
if (dst == NULL) {
dst = &ipv6_addr_all_nodes_link_local;
@ -429,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",
netif->pid, ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)),
fin ? ", final" : "");
if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_MTU) {
if ((hdr = gnrc_ndp2_opt_mtu_build(netif->mtu, pkt)) == NULL) {
gnrc_netif2_acquire(netif);
do { /* XXX: hidden goto */
if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_MTU) {
if ((hdr = gnrc_ndp2_opt_mtu_build(netif->ipv6.mtu, pkt)) == NULL) {
DEBUG("ndp rtr: no space left in packet buffer\n");
return;
break;
}
pkt = hdr;
}
if (src == NULL) {
/* get address from source selection algorithm.
* Only link local addresses may be used (RFC 4861 section 4.1) */
src = gnrc_ipv6_netif_find_best_src_addr(netif->pid, dst, true);
src = gnrc_netif2_ipv6_addr_best_src(netif, dst, true);
}
/* add SL2A for source address */
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
* replicated interfaces.
* 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) {
/* add source address link-layer address option */
hdr = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, pkt);
if (hdr == NULL) {
DEBUG("ndp2: error allocating Source Link-layer address option.\n");
gnrc_pktbuf_release(pkt);
return;
DEBUG("ndp2: error allocating Source Link-layer address "
"option.\n");
break;
}
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;
}
if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_REACH_TIME) {
if (netif->reach_time > (3600 * US_PER_SEC)) { /* reach_time > 1 hour */
if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_REACH_TIME) {
if (netif->ipv6.reach_time_base > (3600 * MS_PER_SEC)) {
/* reach_time > 1 hour */
reach_time = (3600 * MS_PER_SEC);
}
else {
reach_time = netif->reach_time / US_PER_MS;
reach_time = netif->ipv6.reach_time_base;
}
}
if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_RETRANS_TIMER) {
retrans_timer = netif->retrans_timer / US_PER_MS;
if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_RETRANS_TIMER) {
retrans_timer = netif->ipv6.retrans_time;
}
if (!fin) {
/* TODO set netif dependent adv_ltime */
adv_ltime = 1800U;
adv_ltime = netif->ipv6.rtr_ltime;
}
hdr = gnrc_ndp2_rtr_adv_build(cur_hl,
(netif->flags & (GNRC_IPV6_NETIF_FLAGS_OTHER_CONF |
GNRC_IPV6_NETIF_FLAGS_MANAGED)) >> 8,
adv_ltime, reach_time, retrans_timer, pkt);
if (netif->ipv6.aac_mode == GNRC_NETIF2_AAC_DHCP) {
flags |= NDP_RTR_ADV_FLAGS_M;
if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_O_FLAG) {
flags |= NDP_RTR_ADV_FLAGS_O;
}
}
hdr = gnrc_ndp2_rtr_adv_build(cur_hl, flags, adv_ltime, reach_time,
retrans_timer, pkt);
if (hdr == NULL) {
DEBUG("ndp2: error allocating router advertisement.\n");
gnrc_pktbuf_release(pkt);
return;
break;
}
pkt = hdr;
hdr = _build_headers(netif, src, dst, pkt);
if (hdr == NULL) {
DEBUG("ndp2: error adding lower-layer headers.\n");
gnrc_pktbuf_release(pkt);
break;
}
else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) {
else {
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");
gnrc_pktbuf_release(hdr);
break;
}
}
gnrc_netif2_release(netif);
return;
} while (0);
gnrc_pktbuf_release(pkt);
gnrc_netif2_release(netif);
#else
(void)netif;
(void)src;
@ -511,7 +556,7 @@ void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src,
#endif /* GNRC_IPV6_NIB_CONF_ROUTER */
}
static gnrc_pktsnip_t *_build_headers(gnrc_ipv6_netif_t *netif,
static gnrc_pktsnip_t *_build_headers(gnrc_netif2_t *netif,
const ipv6_addr_t *src,
const ipv6_addr_t *dst,
gnrc_pktsnip_t *payload)
@ -536,37 +581,16 @@ static gnrc_pktsnip_t *_build_headers(gnrc_ipv6_netif_t *netif,
return l2hdr;
}
static size_t _get_l2src(gnrc_ipv6_netif_t *netif, uint8_t *l2src,
size_t l2src_maxlen)
static inline size_t _get_l2src(const gnrc_netif2_t *netif, uint8_t *l2src)
{
bool try_long = false;
int res;
uint16_t l2src_len;
/* maximum address length that fits into a minimum length (8) S/TL2A option */
const uint16_t max_short_len = 6;
/* try getting source address */
if ((gnrc_netapi_get(netif->pid, NETOPT_SRC_LEN, 0, &l2src_len,
sizeof(l2src_len)) >= 0) &&
(l2src_len > max_short_len)) {
try_long = true;
}
if (try_long && ((res = gnrc_netapi_get(netif->pid, NETOPT_ADDRESS_LONG, 0,
l2src,
l2src_maxlen)) > max_short_len)) {
l2src_len = (uint16_t)res;
}
else if ((res = gnrc_netapi_get(netif->pid, NETOPT_ADDRESS, 0, l2src,
l2src_maxlen)) >= 0) {
l2src_len = (uint16_t)res;
}
else {
DEBUG("ndp2: no link-layer address found.\n");
l2src_len = 0;
}
return l2src_len;
#if GNRC_NETIF2_L2ADDR_MAXLEN > 0
memcpy(l2src, netif->l2addr, netif->l2addr_len);
return netif->l2addr_len;
#else
(void)netif;
(void)l2src;
return 0;
#endif
}
/** @} */

View File

@ -106,8 +106,7 @@ static int _nib_neigh(int argc, char **argv)
return 1;
}
if ((argc > 5) && /* TODO also check if interface supports link-layers or not */
(l2addr_len = gnrc_netif_addr_from_str(l2addr, sizeof(l2addr),
argv[5])) == 0) {
(l2addr_len = gnrc_netif2_addr_from_str(argv[5], l2addr)) == 0) {
_usage_nib_neigh(argv);
return 1;
}
@ -150,7 +149,7 @@ static int _nib_prefix(int argc, char **argv)
ipv6_addr_t pfx;
unsigned iface = atoi(argv[3]);
unsigned pfx_len = ipv6_addr_split_prefix(argv[4]);
unsigned valid_ltime = UINT32_MAX, pref_ltime = UINT32_MAX;
uint32_t valid_ltime = UINT32_MAX, pref_ltime = UINT32_MAX;
if (ipv6_addr_from_str(&pfx, argv[4]) == NULL) {
_usage_nib_prefix(argv);

View File

@ -44,27 +44,13 @@ static bool _is_number(char *str)
return true;
}
static bool _is_iface(kernel_pid_t dev)
{
kernel_pid_t ifs[GNRC_NETIF_NUMOF];
size_t numof = gnrc_netif_get(ifs);
for (size_t i = 0; i < numof && i < GNRC_NETIF_NUMOF; i++) {
if (ifs[i] == dev) {
return true;
}
}
return false;
}
static void _set_test_mode(int argc, char **argv, uint8_t mode)
{
(void) argc;
if (_is_number(argv[1])) {
kernel_pid_t dev = atoi(argv[1]);
if (_is_iface(dev)) {
if (gnrc_netif2_get_by_pid(dev)) {
gnrc_netapi_set(dev, NETOPT_RF_TESTMODE, 0, (void *)&mode, sizeof(mode));
return;
}

View File

@ -6,7 +6,10 @@ BOARD_INSUFFICIENT_MEMORY := chronos nucleo32-f031 nucleo32-f042
USEMODULE += gnrc_ipv6
USEMODULE += gnrc_ipv6_nib
USEMODULE += gnrc_netif2
USEMODULE += embunit
USEMODULE += netdev_eth
USEMODULE += netdev_test
CFLAGS += -DDEVELHELP
CFLAGS += -DGNRC_NETTYPE_NDP2=GNRC_NETTYPE_TEST

View File

@ -22,14 +22,20 @@
#include <stdio.h>
#include "net/gnrc.h"
#include "net/gnrc/netif2.h"
#ifdef __cplusplus
extern "C" {
#endif
#define _CALL(fn) _common_set_up(); _set_up(); puts("Calling " # fn); fn()
#define _LL0 (0xce)
#define _LL1 (0xab)
#define _LL2 (0xfe)
#define _LL3 (0xad)
#define _LL4 (0xf7)
#define _LL5 (0x26)
extern kernel_pid_t _mock_netif_pid;
extern gnrc_netif2_t *_mock_netif;
void _tests_init(void);
int _mock_netif_get(gnrc_netapi_opt_t *opt);

View File

@ -33,12 +33,6 @@
#include "sched.h"
#define _BUFFER_SIZE (128)
#define _LL0 (0xce)
#define _LL1 (0xab)
#define _LL2 (0xfe)
#define _LL3 (0xad)
#define _LL4 (0xf7)
#define _LL5 (0x26)
static const uint8_t _loc_l2[] = { _LL0, _LL1, _LL2, _LL3, _LL4, _LL5 };
static const ipv6_addr_t _loc_ll = { {
@ -74,7 +68,7 @@ static void _set_up(void)
}
}
static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH(kernel_pid_t iface)
static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH(gnrc_netif2_t *netif)
{
msg_t msg;
gnrc_ipv6_nib_nc_t nce;
@ -82,9 +76,9 @@ static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH(kernel_pid_t iface
gnrc_pktsnip_t *pkt;
TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH,
gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll, iface,
gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll, netif,
NULL, &nce));
if (iface != KERNEL_PID_UNDEF) {
if (netif != NULL) {
ndp_nbr_sol_t *nbr_sol;
bool contains_sl2ao = false;
@ -96,7 +90,7 @@ static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH(kernel_pid_t iface
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE,
gnrc_ipv6_nib_nc_get_nud_state(&nce));
TEST_ASSERT(!gnrc_ipv6_nib_nc_is_router(&nce));
TEST_ASSERT_EQUAL_INT(iface, gnrc_ipv6_nib_nc_get_iface(&nce));
TEST_ASSERT_EQUAL_INT(netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce));
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_GC,
gnrc_ipv6_nib_nc_get_ar_state(&nce));
TEST_ASSERT_EQUAL_INT(1, msg_avail());
@ -128,22 +122,22 @@ static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH(kernel_pid_t iface
static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH_no_iface(void)
{
test_get_next_hop_l2addr__link_local_EHOSTUNREACH(KERNEL_PID_UNDEF);
test_get_next_hop_l2addr__link_local_EHOSTUNREACH(NULL);
}
static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH_iface(void)
{
test_get_next_hop_l2addr__link_local_EHOSTUNREACH(_mock_netif_pid);
test_get_next_hop_l2addr__link_local_EHOSTUNREACH(_mock_netif);
}
static void test_get_next_hop_l2addr__link_local_static_conf(void)
{
gnrc_ipv6_nib_nc_t nce;
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_nc_set(&_rem_ll, _mock_netif_pid,
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_nc_set(&_rem_ll, _mock_netif->pid,
_rem_l2, sizeof(_rem_l2)));
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
_mock_netif_pid,
_mock_netif,
NULL, &nce));
TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0),
"_rem_ll != nce.ipv6");
@ -152,7 +146,7 @@ static void test_get_next_hop_l2addr__link_local_static_conf(void)
"_rem_l2 != nce.l2addr");
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED,
gnrc_ipv6_nib_nc_get_nud_state(&nce));
TEST_ASSERT_EQUAL_INT(_mock_netif_pid, gnrc_ipv6_nib_nc_get_iface(&nce));
TEST_ASSERT_EQUAL_INT(_mock_netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce));
TEST_ASSERT(!gnrc_ipv6_nib_nc_is_router(&nce));
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_MANUAL,
gnrc_ipv6_nib_nc_get_ar_state(&nce));
@ -172,7 +166,7 @@ void _simulate_ndp_handshake(const ipv6_addr_t *src, const ipv6_addr_t *dst,
/* trigger sending of neighbor discovery */
TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH,
gnrc_ipv6_nib_get_next_hop_l2addr(dst,
_mock_netif_pid,
_mock_netif,
NULL, &nce));
TEST_ASSERT_EQUAL_INT(1, msg_avail());
/* clear message queue */
@ -192,7 +186,7 @@ void _simulate_ndp_handshake(const ipv6_addr_t *src, const ipv6_addr_t *dst,
tl2ao->type = NDP_OPT_TL2A;
tl2ao->len = 1;
memcpy(tl2ao + 1, _rem_l2, sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, (icmpv6_hdr_t *)nbr_adv,
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, (icmpv6_hdr_t *)nbr_adv,
sizeof(ndp_nbr_adv_t) + 8U);
}
@ -202,7 +196,7 @@ static void test_get_next_hop_l2addr__link_local_after_handshake(uint8_t adv_fla
_simulate_ndp_handshake(&_loc_ll, &_rem_ll, adv_flags);
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
_mock_netif_pid,
_mock_netif,
NULL, &nce));
TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0),
"_rem_ll != nce.ipv6");
@ -211,7 +205,7 @@ static void test_get_next_hop_l2addr__link_local_after_handshake(uint8_t adv_fla
"_rem_l2 != nce.l2addr");
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE,
gnrc_ipv6_nib_nc_get_nud_state(&nce));
TEST_ASSERT_EQUAL_INT(_mock_netif_pid, gnrc_ipv6_nib_nc_get_iface(&nce));
TEST_ASSERT_EQUAL_INT(_mock_netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce));
if (adv_flags & NDP_NBR_ADV_FLAGS_R) {
TEST_ASSERT(gnrc_ipv6_nib_nc_is_router(&nce));
}
@ -242,7 +236,7 @@ static void test_get_next_hop_l2addr__link_local_after_handshake_no_iface(void)
_simulate_ndp_handshake(&_loc_ll, &_rem_ll, NDP_NBR_ADV_FLAGS_S);
TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH,
gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
KERNEL_PID_UNDEF,
NULL,
NULL, &nce));
}
@ -257,7 +251,7 @@ static void test_handle_pkt__unknown_type(void)
memcpy(&ipv6->dst, &_rem_ll, sizeof(ipv6->dst));
icmpv6->type = ICMPV6_ECHO_REQ;
icmpv6->code = 0;
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6,
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6,
sizeof(icmpv6_hdr_t));
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
@ -301,7 +295,7 @@ static void test_handle_pkt__nbr_sol__invalid_hl(void)
size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_sol_nodes, 194U, 0U,
&_loc_ll, _rem_l2, sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -315,7 +309,7 @@ static void test_handle_pkt__nbr_sol__invalid_code(void)
size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_sol_nodes, 255U, 201U,
&_loc_ll, _rem_l2, sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -330,7 +324,7 @@ static void test_handle_pkt__nbr_sol__invalid_icmpv6_len(void)
_set_nbr_sol(&_rem_ll, &_loc_sol_nodes, 255U, 0U, &_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6,
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6,
sizeof(ndp_nbr_sol_t) - 1);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
@ -346,7 +340,7 @@ static void test_handle_pkt__nbr_sol__invalid_tgt(void)
&ipv6_addr_all_routers_site_local, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -364,7 +358,7 @@ static void test_handle_pkt__nbr_sol__invalid_opt_len(void)
opt->type = NDP_OPT_SL2A;
opt->len = 0U;
icmpv6_len += sizeof(ndp_opt_t);
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -378,7 +372,7 @@ static void test_handle_pkt__nbr_sol__invalid_dst(void)
size_t icmpv6_len = _set_nbr_sol(&ipv6_addr_unspecified, &_loc_ll, 255U, 0U,
&_loc_ll, NULL, 0);
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -393,7 +387,7 @@ static void test_handle_pkt__nbr_sol__invalid_sl2ao(void)
255U, 0U, &_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -408,7 +402,7 @@ static void test_handle_pkt__nbr_sol__tgt_not_assigned(void)
255U, 0U, &_rem_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -425,12 +419,12 @@ static void test_pkt_is_nbr_adv(gnrc_pktsnip_t *pkt, const ipv6_addr_t *dst,
ndp_nbr_adv_t *nbr_adv;
ndp_opt_t *tl2ao;
/* first snip is a netif header to _mock_netif_pid */
/* first snip is a netif header to _mock_netif */
TEST_ASSERT_NOT_NULL(pkt);
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_NETIF, pkt->type);
TEST_ASSERT(sizeof(gnrc_netif_hdr_t) <= pkt->size);
netif_hdr = pkt->data;
TEST_ASSERT_EQUAL_INT(_mock_netif_pid, netif_hdr->if_pid);
TEST_ASSERT_EQUAL_INT(_mock_netif->pid, netif_hdr->if_pid);
/* second snip is an IPv6 header to dst */
TEST_ASSERT_NOT_NULL(pkt->next);
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_IPV6, pkt->next->type);
@ -475,7 +469,7 @@ static void test_handle_pkt__nbr_sol__ll_src(unsigned exp_nud_state,
255U, 0U, &_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"Expected neighbor cache entry");
TEST_ASSERT_MESSAGE(ipv6_addr_equal(&_rem_ll, &nce.ipv6),
@ -485,7 +479,7 @@ static void test_handle_pkt__nbr_sol__ll_src(unsigned exp_nud_state,
"_rem_l2 != nce.l2addr");
TEST_ASSERT_EQUAL_INT(exp_nud_state, gnrc_ipv6_nib_nc_get_nud_state(&nce));
TEST_ASSERT(!gnrc_ipv6_nib_nc_is_router(&nce));
TEST_ASSERT_EQUAL_INT(_mock_netif_pid, gnrc_ipv6_nib_nc_get_iface(&nce));
TEST_ASSERT_EQUAL_INT(_mock_netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce));
TEST_ASSERT_EQUAL_INT(exp_ar_state, gnrc_ipv6_nib_nc_get_ar_state(&nce));
TEST_ASSERT_EQUAL_INT(1, msg_avail());
msg_receive(&msg);
@ -518,7 +512,7 @@ static void test_handle_pkt__nbr_sol__ll_src_no_sl2ao(void)
size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_sol_nodes,
255U, 0U, &_loc_ll, NULL, 0);
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
TEST_ASSERT_EQUAL_INT(1, msg_avail());
@ -570,7 +564,7 @@ static void test_handle_pkt__nbr_adv__invalid_hl(void)
NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -585,7 +579,7 @@ static void test_handle_pkt__nbr_adv__invalid_code(void)
NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -601,7 +595,7 @@ static void test_handle_pkt__nbr_adv__invalid_icmpv6_len(void)
&_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6,
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6,
sizeof(ndp_nbr_adv_t) - 1);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
@ -618,7 +612,7 @@ static void test_handle_pkt__nbr_adv__invalid_tgt(void)
&ipv6_addr_all_routers_site_local, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -633,7 +627,7 @@ static void test_handle_pkt__nbr_adv__invalid_flags(void)
255U, 0U, NDP_NBR_ADV_FLAGS_S, &_loc_ll,
NULL, 0);
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -652,7 +646,7 @@ static void test_handle_pkt__nbr_adv__invalid_opt_len(void)
opt->type = NDP_OPT_SL2A;
opt->len = 0U;
icmpv6_len += sizeof(ndp_opt_t);
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -667,7 +661,7 @@ static void test_handle_pkt__nbr_adv__unspecified_src(void)
NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -682,7 +676,7 @@ static void test_handle_pkt__nbr_adv__unsolicited(void)
NDP_NBR_ADV_FLAGS_S, &_loc_ll,
_rem_l2, sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
TEST_ASSERT_EQUAL_INT(0, msg_avail());
@ -752,20 +746,6 @@ int _mock_netif_get(gnrc_netapi_opt_t *opt)
}
memcpy(opt->data, _loc_l2, sizeof(_loc_l2));
return sizeof(_loc_l2);
case NETOPT_SRC_LEN: {
uint16_t *val = opt->data;
if (opt->data_len != sizeof(uint16_t)) {
return -EOVERFLOW;
}
*val = sizeof(_loc_l2);
return sizeof(uint16_t);
}
case NETOPT_IPV6_IID:
if (opt->data_len < sizeof(_loc_iid)) {
return -EOVERFLOW;
}
memcpy(opt->data, _loc_iid, sizeof(_loc_iid));
return sizeof(_loc_iid);
case NETOPT_IS_WIRED:
return 1;
case NETOPT_MAX_PACKET_SIZE: {

View File

@ -16,63 +16,73 @@
#include "common.h"
#include "msg.h"
#include "net/gnrc.h"
#include "net/ethernet.h"
#include "net/gnrc/ipv6/nib.h"
#include "net/gnrc/ipv6/netif.h"
#include "net/gnrc/netdev.h"
#include "net/gnrc/netif2/ethernet.h"
#include "net/gnrc/netif2/internal.h"
#include "net/netdev_test.h"
#include "sched.h"
#include "thread.h"
#define _MSG_QUEUE_SIZE (2)
kernel_pid_t _mock_netif_pid = KERNEL_PID_UNDEF;
gnrc_netif2_t *_mock_netif = NULL;
static netdev_test_t _mock_netdev;
static char _mock_netif_stack[THREAD_STACKSIZE_DEFAULT];
static gnrc_netreg_entry_t dumper;
static msg_t _main_msg_queue[_MSG_QUEUE_SIZE];
static msg_t _mock_netif_msg_queue[_MSG_QUEUE_SIZE];
static void *_mock_netif_thread(void *args)
{
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)
{
assert(_mock_netif != NULL);
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)
{
msg_init_queue(_main_msg_queue, _MSG_QUEUE_SIZE);
_mock_netif_pid = thread_create(_mock_netif_stack,
sizeof(_mock_netif_stack),
GNRC_NETDEV_MAC_PRIO,
THREAD_CREATE_STACKTEST,
_mock_netif_thread, NULL, "mock_netif");
assert(_mock_netif_pid > KERNEL_PID_UNDEF);
gnrc_netif_add(_mock_netif_pid);
gnrc_ipv6_netif_init_by_dev();
thread_yield();
netdev_test_setup(&_mock_netdev, 0);
netdev_test_set_get_cb(&_mock_netdev, NETOPT_DEVICE_TYPE,
_get_device_type);
netdev_test_set_get_cb(&_mock_netdev, NETOPT_MAX_PACKET_SIZE,
_get_max_packet_size);
netdev_test_set_get_cb(&_mock_netdev, NETOPT_ADDRESS,
_get_address);
_mock_netif = gnrc_netif2_ethernet_create(
_mock_netif_stack, THREAD_STACKSIZE_DEFAULT, GNRC_NETIF2_PRIO,
"mockup_eth", &_mock_netdev.netdev
);
assert(_mock_netif != NULL);
gnrc_netreg_entry_init_pid(&dumper, GNRC_NETREG_DEMUX_CTX_ALL,
sched_active_pid);
gnrc_netreg_register(GNRC_NETTYPE_NDP2, &dumper);

View File

@ -8,8 +8,10 @@ BOARD_INSUFFICIENT_MEMORY := chronos nucleo-f030 nucleo-l053 nucleo32-f031 \
USEMODULE += gnrc_ipv6
USEMODULE += gnrc_sixlowpan
USEMODULE += gnrc_ipv6_nib_6ln
USEMODULE += gnrc_netif2
USEMODULE += embunit
USEMODULE += netopt
USEMODULE += netdev_ieee802154
USEMODULE += netdev_test
CFLAGS += -DDEVELHELP
CFLAGS += -DGNRC_NETTYPE_NDP2=GNRC_NETTYPE_TEST

View File

@ -22,14 +22,22 @@
#include <stdio.h>
#include "net/gnrc.h"
#include "net/gnrc/netif2.h"
#ifdef __cplusplus
extern "C" {
#endif
#define _CALL(fn) _common_set_up(); _set_up(); puts("Calling " # fn); fn()
#define _LL0 (0xce)
#define _LL1 (0xab)
#define _LL2 (0xfe)
#define _LL3 (0xad)
#define _LL4 (0xf7)
#define _LL5 (0x26)
#define _LL6 (0xef)
#define _LL7 (0xa4)
extern kernel_pid_t _mock_netif_pid;
extern gnrc_netif2_t *_mock_netif;
void _tests_init(void);
int _mock_netif_get(gnrc_netapi_opt_t *opt);

View File

@ -33,14 +33,6 @@
#include "sched.h"
#define _BUFFER_SIZE (128)
#define _LL0 (0xce)
#define _LL1 (0xab)
#define _LL2 (0xfe)
#define _LL3 (0xad)
#define _LL4 (0xf7)
#define _LL5 (0x26)
#define _LL6 (0xef)
#define _LL7 (0xa4)
static const uint8_t _loc_l2[] = { _LL0, _LL1, _LL2, _LL3,
_LL4, _LL5, _LL6, _LL7 };
@ -79,8 +71,7 @@ static void test_get_next_hop_l2addr__link_local_EHOSTUNREACH(void)
gnrc_ipv6_nib_nc_t nce;
TEST_ASSERT_EQUAL_INT(-EHOSTUNREACH,
gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
KERNEL_PID_UNDEF,
gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll, NULL,
NULL, &nce));
TEST_ASSERT_EQUAL_INT(0, msg_avail());
TEST_ASSERT(gnrc_pktbuf_is_empty());
@ -90,10 +81,10 @@ static void test_get_next_hop_l2addr__link_local_static_conf(void)
{
gnrc_ipv6_nib_nc_t nce;
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_nc_set(&_rem_ll, _mock_netif_pid,
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_nc_set(&_rem_ll, _mock_netif->pid,
_rem_l2, sizeof(_rem_l2)));
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
_mock_netif_pid,
_mock_netif,
NULL, &nce));
TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0),
"_rem_ll != nce.ipv6");
@ -102,7 +93,7 @@ static void test_get_next_hop_l2addr__link_local_static_conf(void)
"_rem_l2 != nce.l2addr");
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED,
gnrc_ipv6_nib_nc_get_nud_state(&nce));
TEST_ASSERT_EQUAL_INT(_mock_netif_pid, gnrc_ipv6_nib_nc_get_iface(&nce));
TEST_ASSERT_EQUAL_INT(_mock_netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce));
TEST_ASSERT(!gnrc_ipv6_nib_nc_is_router(&nce));
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_MANUAL,
gnrc_ipv6_nib_nc_get_ar_state(&nce));
@ -115,7 +106,7 @@ static void test_get_next_hop_l2addr__link_local(void)
gnrc_ipv6_nib_nc_t nce;
TEST_ASSERT_EQUAL_INT(0, gnrc_ipv6_nib_get_next_hop_l2addr(&_rem_ll,
_mock_netif_pid,
_mock_netif,
NULL, &nce));
TEST_ASSERT_MESSAGE((memcmp(&_rem_ll, &nce.ipv6, sizeof(_rem_ll)) == 0),
"_rem_ll != nce.ipv6");
@ -124,7 +115,7 @@ static void test_get_next_hop_l2addr__link_local(void)
"_rem_l2 != nce.l2addr");
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE,
gnrc_ipv6_nib_nc_get_nud_state(&nce));
TEST_ASSERT_EQUAL_INT(_mock_netif_pid, gnrc_ipv6_nib_nc_get_iface(&nce));
TEST_ASSERT_EQUAL_INT(_mock_netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce));
TEST_ASSERT(!gnrc_ipv6_nib_nc_is_router(&nce));
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED,
gnrc_ipv6_nib_nc_get_ar_state(&nce));
@ -143,7 +134,7 @@ static void test_handle_pkt__unknown_type(void)
memcpy(&ipv6->dst, &_rem_ll, sizeof(ipv6->dst));
icmpv6->type = ICMPV6_ECHO_REQ;
icmpv6->code = 0;
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6,
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6,
sizeof(icmpv6_hdr_t));
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
@ -187,7 +178,7 @@ static void test_handle_pkt__nbr_sol__invalid_hl(void)
size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_ll, 194U, 0U,
&_loc_ll, _rem_l2, sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -201,7 +192,7 @@ static void test_handle_pkt__nbr_sol__invalid_code(void)
size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_ll, 255U, 201U,
&_loc_ll, _rem_l2, sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -216,7 +207,7 @@ static void test_handle_pkt__nbr_sol__invalid_icmpv6_len(void)
_set_nbr_sol(&_rem_ll, &_loc_ll, 255U, 0U, &_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6,
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6,
sizeof(ndp_nbr_sol_t) - 1);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
@ -232,7 +223,7 @@ static void test_handle_pkt__nbr_sol__invalid_tgt(void)
&ipv6_addr_all_routers_site_local, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -250,7 +241,7 @@ static void test_handle_pkt__nbr_sol__invalid_opt_len(void)
opt->type = NDP_OPT_SL2A;
opt->len = 0U;
icmpv6_len += sizeof(ndp_opt_t);
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -264,7 +255,7 @@ static void test_handle_pkt__nbr_sol__invalid_dst(void)
size_t icmpv6_len = _set_nbr_sol(&ipv6_addr_unspecified, &_loc_ll, 255U, 0U,
&_loc_ll, NULL, 0);
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -279,7 +270,7 @@ static void test_handle_pkt__nbr_sol__invalid_sl2ao(void)
255U, 0U, &_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -294,7 +285,7 @@ static void test_handle_pkt__nbr_sol__tgt_not_assigned(void)
255U, 0U, &_rem_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -308,12 +299,12 @@ static void test_pkt_is_nbr_adv(gnrc_pktsnip_t *pkt, const ipv6_addr_t *dst,
ipv6_hdr_t *ipv6_hdr;
ndp_nbr_adv_t *nbr_adv;
/* first snip is a netif header to _mock_netif_pid */
/* first snip is a netif header to _mock_netif */
TEST_ASSERT_NOT_NULL(pkt);
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_NETIF, pkt->type);
TEST_ASSERT(sizeof(gnrc_netif_hdr_t) <= pkt->size);
netif_hdr = pkt->data;
TEST_ASSERT_EQUAL_INT(_mock_netif_pid, netif_hdr->if_pid);
TEST_ASSERT_EQUAL_INT(_mock_netif->pid, netif_hdr->if_pid);
/* second snip is an IPv6 header to dst */
TEST_ASSERT_NOT_NULL(pkt->next);
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_IPV6, pkt->next->type);
@ -348,7 +339,7 @@ static void test_handle_pkt__nbr_sol__ll_src(unsigned exp_nud_state,
255U, 0U, &_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"Expected neighbor cache entry");
TEST_ASSERT_MESSAGE(ipv6_addr_equal(&_rem_ll, &nce.ipv6),
@ -358,7 +349,7 @@ static void test_handle_pkt__nbr_sol__ll_src(unsigned exp_nud_state,
"_rem_l2 != nce.l2addr");
TEST_ASSERT_EQUAL_INT(exp_nud_state, gnrc_ipv6_nib_nc_get_nud_state(&nce));
TEST_ASSERT(!gnrc_ipv6_nib_nc_is_router(&nce));
TEST_ASSERT_EQUAL_INT(_mock_netif_pid, gnrc_ipv6_nib_nc_get_iface(&nce));
TEST_ASSERT_EQUAL_INT(_mock_netif->pid, gnrc_ipv6_nib_nc_get_iface(&nce));
TEST_ASSERT_EQUAL_INT(exp_ar_state, gnrc_ipv6_nib_nc_get_ar_state(&nce));
TEST_ASSERT_EQUAL_INT(1, msg_avail());
msg_receive(&msg);
@ -390,7 +381,7 @@ static void test_handle_pkt__nbr_sol__ll_src_no_sl2ao(void)
size_t icmpv6_len = _set_nbr_sol(&_rem_ll, &_loc_ll,
255U, 0U, &_loc_ll, NULL, 0);
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
TEST_ASSERT_EQUAL_INT(1, msg_avail());
@ -441,7 +432,7 @@ static void test_handle_pkt__nbr_adv__invalid_hl(void)
NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -456,7 +447,7 @@ static void test_handle_pkt__nbr_adv__invalid_code(void)
NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -472,7 +463,7 @@ static void test_handle_pkt__nbr_adv__invalid_icmpv6_len(void)
&_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6,
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6,
sizeof(ndp_nbr_adv_t) - 1);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
@ -489,7 +480,7 @@ static void test_handle_pkt__nbr_adv__invalid_tgt(void)
&ipv6_addr_all_routers_site_local, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -504,7 +495,7 @@ static void test_handle_pkt__nbr_adv__invalid_flags(void)
255U, 0U, NDP_NBR_ADV_FLAGS_S, &_loc_ll,
NULL, 0);
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -523,7 +514,7 @@ static void test_handle_pkt__nbr_adv__invalid_opt_len(void)
opt->type = NDP_OPT_SL2A;
opt->len = 0U;
icmpv6_len += sizeof(ndp_opt_t);
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -538,7 +529,7 @@ static void test_handle_pkt__nbr_adv__unspecified_src(void)
NDP_NBR_ADV_FLAGS_S, &_loc_ll, _rem_l2,
sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
/* TODO: check other views as well */
@ -553,7 +544,7 @@ static void test_handle_pkt__nbr_adv__unsolicited(void)
NDP_NBR_ADV_FLAGS_S, &_loc_ll,
_rem_l2, sizeof(_rem_l2));
gnrc_ipv6_nib_handle_pkt(_mock_netif_pid, ipv6, icmpv6, icmpv6_len);
gnrc_ipv6_nib_handle_pkt(_mock_netif, ipv6, icmpv6, icmpv6_len);
TEST_ASSERT_MESSAGE(!gnrc_ipv6_nib_nc_iter(0, &state, &nce),
"There is an unexpected neighbor cache entry");
TEST_ASSERT_EQUAL_INT(0, msg_avail());

View File

@ -16,63 +16,84 @@
#include "common.h"
#include "msg.h"
#include "net/gnrc.h"
#include "net/ethernet.h"
#include "net/gnrc/ipv6/nib.h"
#include "net/gnrc/ipv6/netif.h"
#include "net/gnrc/netdev.h"
#include "net/gnrc/netif2/ieee802154.h"
#include "net/gnrc/netif2/internal.h"
#include "net/netdev_test.h"
#include "sched.h"
#include "thread.h"
#define _MSG_QUEUE_SIZE (2)
kernel_pid_t _mock_netif_pid = KERNEL_PID_UNDEF;
gnrc_netif2_t *_mock_netif = NULL;
static netdev_test_t _mock_netdev;
static char _mock_netif_stack[THREAD_STACKSIZE_DEFAULT];
static gnrc_netreg_entry_t dumper;
static msg_t _main_msg_queue[_MSG_QUEUE_SIZE];
static msg_t _mock_netif_msg_queue[_MSG_QUEUE_SIZE];
static void *_mock_netif_thread(void *args)
{
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)
{
assert(_mock_netif != NULL);
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)
{
msg_init_queue(_main_msg_queue, _MSG_QUEUE_SIZE);
_mock_netif_pid = thread_create(_mock_netif_stack,
sizeof(_mock_netif_stack),
GNRC_NETDEV_MAC_PRIO,
THREAD_CREATE_STACKTEST,
_mock_netif_thread, NULL, "mock_netif");
assert(_mock_netif_pid > KERNEL_PID_UNDEF);
gnrc_netif_add(_mock_netif_pid);
gnrc_ipv6_netif_init_by_dev();
thread_yield();
netdev_test_setup(&_mock_netdev, 0);
netdev_test_set_get_cb(&_mock_netdev, NETOPT_DEVICE_TYPE,
_get_device_type);
netdev_test_set_get_cb(&_mock_netdev, NETOPT_MAX_PACKET_SIZE,
_get_max_packet_size);
netdev_test_set_get_cb(&_mock_netdev, NETOPT_SRC_LEN,
_get_src_len);
netdev_test_set_get_cb(&_mock_netdev, NETOPT_ADDRESS_LONG,
_get_address_long);
_mock_netif = gnrc_netif2_ieee802154_create(
_mock_netif_stack, THREAD_STACKSIZE_DEFAULT, GNRC_NETIF2_PRIO,
"mockup_wpan", &_mock_netdev.netdev.netdev
);
assert(_mock_netif != NULL);
gnrc_netreg_entry_init_pid(&dumper, GNRC_NETREG_DEMUX_CTX_ALL,
sched_active_pid);
gnrc_netreg_register(GNRC_NETTYPE_NDP2, &dumper);

View File

@ -4,8 +4,11 @@ include ../Makefile.tests_common
BOARD_INSUFFICIENT_MEMORY := nucleo32-f031 nucleo32-f042
USEMODULE += gnrc_ipv6_nib
USEMODULE += gnrc_ndp2
USEMODULE += gnrc_netif2
USEMODULE += embunit
USEMODULE += netdev_test
CFLAGS += -DGNRC_NETTYPE_NDP2=GNRC_NETTYPE_TEST
CFLAGS += -DGNRC_PKTBUF_SIZE=512

View File

@ -25,12 +25,15 @@
#include "embUnit.h"
#include "embUnit/embUnit.h"
#include "msg.h"
#include "net/gnrc/ipv6/nib/conf.h"
#include "net/gnrc/netapi.h"
#include "net/gnrc/netdev.h"
#include "net/gnrc/netif/hdr.h"
#include "net/gnrc/netif2/internal.h"
#include "net/gnrc/netreg.h"
#include "net/gnrc/pktbuf.h"
#include "net/icmpv6.h"
#include "net/ndp.h"
#include "net/netdev_test.h"
#include "net/netopt.h"
#include "sched.h"
@ -63,7 +66,7 @@ static const ipv6_addr_t test_pfx = { { 0x47, 0x25, 0xd9, 0x3b, 0x7f, 0xcc, 0x15
0x64, 0x3e, 0x76, 0x0d, 0x30, 0x10, 0x0d, 0xc8 } };
static const uint8_t test_src_l2[] = { 0xe7, 0x43, 0xb7, 0x74, 0xd7, 0xa9, 0x30, 0x74 };
static kernel_pid_t test_iface = KERNEL_PID_UNDEF;
static gnrc_netif2_t *test_netif = NULL;
static void init_pkt_handler(void);
static inline size_t ceil8(size_t size);
@ -405,11 +408,11 @@ static inline ipv6_addr_t *_get_ipv6_dst(ipv6_hdr_t *hdr)
return &hdr->dst;
}
#define ASSERT_NETIF_HDR(iface, pkt) \
#define ASSERT_NETIF_HDR(netif, pkt) \
TEST_ASSERT_NOT_NULL(pkt); \
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_NETIF, pkt->type); \
TEST_ASSERT_NOT_NULL(pkt->data); \
TEST_ASSERT_EQUAL_INT(iface, _get_iface(pkt->data))
TEST_ASSERT_EQUAL_INT(netif->pid, _get_iface(pkt->data))
#define ASSERT_IPV6_HDR(src, dst, pkt) \
TEST_ASSERT_NOT_NULL(pkt); \
@ -428,7 +431,6 @@ static inline ipv6_addr_t *_get_ipv6_dst(ipv6_hdr_t *hdr)
static void test_nbr_sol_send(const ipv6_addr_t *src)
{
msg_t msg;
gnrc_ipv6_netif_t *test_netif = gnrc_ipv6_netif_get(test_iface);
gnrc_pktsnip_t *pkt;
ndp_nbr_sol_t *nbr_sol;
@ -438,7 +440,7 @@ static void test_nbr_sol_send(const ipv6_addr_t *src)
TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type);
pkt = msg.content.ptr;
/* check packet */
ASSERT_NETIF_HDR(test_iface, pkt);
ASSERT_NETIF_HDR(test_netif, pkt);
if ((src != NULL) && ipv6_addr_is_unspecified(src)) {
ASSERT_IPV6_HDR(&ipv6_addr_unspecified, &test_dst, pkt->next);
}
@ -488,7 +490,6 @@ static void test_nbr_adv_send(const ipv6_addr_t *tgt, const ipv6_addr_t *dst,
bool supply_tl2a, gnrc_pktsnip_t *exp_ext_opts)
{
msg_t msg;
gnrc_ipv6_netif_t *test_netif = gnrc_ipv6_netif_get(test_iface);
gnrc_pktsnip_t *pkt;
ndp_nbr_adv_t *nbr_adv;
@ -498,7 +499,7 @@ static void test_nbr_adv_send(const ipv6_addr_t *tgt, const ipv6_addr_t *dst,
TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type);
pkt = msg.content.ptr;
/* check packet */
ASSERT_NETIF_HDR(test_iface, pkt);
ASSERT_NETIF_HDR(test_netif, pkt);
if (ipv6_addr_is_unspecified(dst)) {
ASSERT_IPV6_HDR(&ipv6_addr_unspecified, &ipv6_addr_all_nodes_link_local,
pkt->next);
@ -548,46 +549,46 @@ static void test_nbr_adv_send(const ipv6_addr_t *tgt, const ipv6_addr_t *dst,
static void test_nbr_adv_send__foreign_tgt_unspecified_dst_no_supply_tl2a_no_ext_opts(void)
{
test_nbr_adv_send(&test_tgt, &ipv6_addr_unspecified, false, NULL);
test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, false, NULL);
}
static void test_nbr_adv_send__foreign_tgt_unspecified_dst_no_supply_tl2a_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_nbr_adv_send(&test_tgt, &ipv6_addr_unspecified, false, ext_opts);
test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, false, ext_opts);
}
static void test_nbr_adv_send__foreign_tgt_unspecified_dst_supply_tl2a_no_ext_opts(void)
{
test_nbr_adv_send(&test_tgt, &ipv6_addr_unspecified, true, NULL);
test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, true, NULL);
}
static void test_nbr_adv_send__foreign_tgt_unspecified_dst_supply_tl2a_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_nbr_adv_send(&test_tgt, &ipv6_addr_unspecified, true, ext_opts);
test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, true, ext_opts);
}
static void test_nbr_adv_send__foreign_tgt_specified_dst_no_supply_tl2a_no_ext_opts(void)
{
test_nbr_adv_send(&test_tgt, &test_dst, false, NULL);
test_nbr_adv_send(&test_src, &test_dst, false, NULL);
}
static void test_nbr_adv_send__foreign_tgt_specified_dst_no_supply_tl2a_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_nbr_adv_send(&test_tgt, &test_dst, false, ext_opts);
test_nbr_adv_send(&test_src, &test_dst, false, ext_opts);
}
static void test_nbr_adv_send__foreign_tgt_specified_dst_supply_tl2a_no_ext_opts(void)
{
test_nbr_adv_send(&test_tgt, &test_dst, true, NULL);
test_nbr_adv_send(&test_src, &test_dst, true, NULL);
}
static void test_nbr_adv_send__foreign_tgt_specified_dst_supply_tl2a_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_nbr_adv_send(&test_tgt, &test_dst, true, ext_opts);
test_nbr_adv_send(&test_src, &test_dst, true, ext_opts);
}
static void test_nbr_adv_send__src_tgt_unspecified_dst_no_supply_tl2a_no_ext_opts(void)
@ -637,7 +638,6 @@ static void test_nbr_adv_send__src_tgt_specified_dst_supply_tl2a_ext_opts(void)
static void test_rtr_sol_send(const ipv6_addr_t *dst)
{
msg_t msg;
gnrc_ipv6_netif_t *test_netif = gnrc_ipv6_netif_get(test_iface);
gnrc_pktsnip_t *pkt;
ndp_rtr_sol_t *rtr_sol;
@ -647,7 +647,7 @@ static void test_rtr_sol_send(const ipv6_addr_t *dst)
TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type);
pkt = msg.content.ptr;
/* check packet */
ASSERT_NETIF_HDR(test_iface, pkt);
ASSERT_NETIF_HDR(test_netif, pkt);
if (dst != NULL) {
ASSERT_IPV6_HDR(&test_src, dst, pkt->next);
}
@ -701,7 +701,6 @@ static void test_rtr_adv_send(const ipv6_addr_t *src, const ipv6_addr_t *dst,
bool fin, gnrc_pktsnip_t *exp_ext_opts)
{
msg_t msg;
gnrc_ipv6_netif_t *test_netif = gnrc_ipv6_netif_get(test_iface);
gnrc_pktsnip_t *pkt;
ndp_rtr_adv_t *rtr_adv;
@ -711,7 +710,7 @@ static void test_rtr_adv_send(const ipv6_addr_t *src, const ipv6_addr_t *dst,
TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type);
pkt = msg.content.ptr;
/* check packet */
ASSERT_NETIF_HDR(test_iface, pkt);
ASSERT_NETIF_HDR(test_netif, pkt);
/* testing for unspecified source is complicated so we skip it here and
* do it in later integration tests */
if (dst != NULL) {
@ -930,11 +929,25 @@ int main(void)
static char test_netif_stack[THREAD_STACKSIZE_DEFAULT];
static msg_t msg_queue_main[MSG_QUEUE_SIZE];
static msg_t msg_queue_netif[MSG_QUEUE_SIZE];
static gnrc_netreg_entry_t netreg_entry;
static netdev_test_t dev;
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) {
case NETOPT_ADDRESS_LONG:
if (opt->data_len < sizeof(test_src_l2)) {
@ -971,44 +984,37 @@ int test_iface_get(gnrc_netapi_opt_t *opt)
}
}
static void *test_iface_thread(void *args)
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)args;
msg_init_queue(msg_queue_netif, MSG_QUEUE_SIZE);
while (1) {
msg_receive(&msg);
switch (msg.type) {
case GNRC_NETAPI_MSG_TYPE_SND:
case GNRC_NETAPI_MSG_TYPE_RCV:
gnrc_pktbuf_release(msg.content.ptr);
continue;
case GNRC_NETAPI_MSG_TYPE_GET:
reply.content.value = (uint32_t)test_iface_get(msg.content.ptr);
break;
case GNRC_NETAPI_MSG_TYPE_SET:
reply.content.value = (uint32_t)(-ENOTSUP);
break;
}
msg_reply(&msg, &reply);
}
return NULL;
(void)netif;
(void)opt;
return -ENOTSUP;
}
static const gnrc_netif2_ops_t _test_netif_ops = {
.send = _test_netif_send,
.recv = _test_netif_recv,
.get = _test_netif_get,
.set = _test_netif_set,
};
static void init_pkt_handler(void)
{
msg_init_queue(msg_queue_main, MSG_QUEUE_SIZE);
gnrc_netreg_entry_init_pid(&netreg_entry, GNRC_NETREG_DEMUX_CTX_ALL,
sched_active_pid);
gnrc_netreg_register(GNRC_NETTYPE_NDP2, &netreg_entry);
test_iface = thread_create(test_netif_stack, sizeof(test_netif_stack),
GNRC_NETDEV_MAC_PRIO, THREAD_CREATE_STACKTEST,
test_iface_thread, NULL, "test-iface");
TEST_ASSERT_MESSAGE(test_iface > KERNEL_PID_UNDEF,
netdev_test_setup(&dev, NULL);
test_netif = gnrc_netif2_create(test_netif_stack, sizeof(test_netif_stack),
GNRC_NETIF2_PRIO, "test-netif",
&dev.netdev, &_test_netif_ops);
TEST_ASSERT_MESSAGE(test_netif != NULL,
"Unable to start test interface");
gnrc_netif_add(test_iface);
gnrc_ipv6_netif_init_by_dev();
memcpy(&test_netif->ipv6.addrs[0], &test_src,
sizeof(test_netif->ipv6.addrs[0]));
test_netif->ipv6.addrs_flags[0] = GNRC_NETIF2_IPV6_ADDRS_FLAGS_STATE_VALID;
memcpy(test_netif->l2addr, test_src_l2, sizeof(test_netif->l2addr));
test_netif->l2addr_len = sizeof(test_src_l2);
}
static inline size_t ceil8(size_t size)

View File

@ -1910,33 +1910,6 @@ static void test_nib_abr_iter__three_elem_middle_removed(void)
}
#endif
/*
* Creates GNRC_NETIF_NUMOF interfaces and then tries to add another.
* Expected result: should return NULL
*/
static void test_nib_iface_get__no_space_left(void)
{
unsigned iface = 1;
for (int i = 0; i < GNRC_NETIF_NUMOF; i++) {
TEST_ASSERT_NOT_NULL(_nib_iface_get(iface++));
}
TEST_ASSERT_NULL(_nib_iface_get(iface));
}
/*
* Creates an interface and then gets the same interface.
* Expected result: interface pointers should equal
*/
static void test_nib_iface_get__success(void)
{
_nib_iface_t *ni1, *ni2;
TEST_ASSERT_NOT_NULL((ni1 = _nib_iface_get(IFACE)));
TEST_ASSERT_NOT_NULL((ni2 = _nib_iface_get(IFACE)));
TEST_ASSERT(ni1 == ni2);
}
Test *tests_gnrc_ipv6_nib_internal_tests(void)
{
EMB_UNIT_TESTFIXTURES(fixtures) {
@ -2035,8 +2008,6 @@ Test *tests_gnrc_ipv6_nib_internal_tests(void)
new_TestFixture(test_nib_abr_iter__three_elem),
new_TestFixture(test_nib_abr_iter__three_elem_middle_removed),
#endif
new_TestFixture(test_nib_iface_get__no_space_left),
new_TestFixture(test_nib_iface_get__success),
};
EMB_UNIT_TESTCALLER(tests, set_up, NULL,

View File

@ -276,20 +276,12 @@ static void test_nib_nc_mark_reachable__unmanaged(void)
static void test_nib_nc_mark_reachable__success(void)
{
void *iter_state = NULL;
_nib_onl_entry_t *node;
#if GNRC_IPV6_NIB_CONF_ARSM
evtimer_msg_event_t *event;
#endif
_nib_iface_t *iface;
static const ipv6_addr_t addr = { .u64 = { { .u8 = GLOBAL_PREFIX },
{ .u64 = TEST_UINT64 } } };
gnrc_ipv6_nib_nc_t nce;
TEST_ASSERT_NOT_NULL((node = _nib_nc_add(&addr, IFACE,
GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE)));
/* set an "infinite" reachability time */
iface = _nib_iface_get(_nib_onl_get_if(node));
iface->reach_time = UINT32_MAX;
TEST_ASSERT_NOT_NULL(_nib_nc_add(&addr, IFACE,
GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE));
/* check pre-state */
TEST_ASSERT(gnrc_ipv6_nib_nc_iter(0, &iter_state, &nce));
@ -306,11 +298,6 @@ static void test_nib_nc_mark_reachable__success(void)
/* check if entry is reachable */
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE,
gnrc_ipv6_nib_nc_get_nud_state(&nce));
/* check if there now is an event for reachability timeout of node */
TEST_ASSERT_NOT_NULL((event = (evtimer_msg_event_t *)_nib_evtimer.events));
TEST_ASSERT_EQUAL_INT(GNRC_IPV6_NIB_REACH_TIMEOUT, event->msg.type);
TEST_ASSERT_MESSAGE(node == event->msg.content.ptr,
"event's context is not node");
#endif
/* check if still the only entry */
TEST_ASSERT(!gnrc_ipv6_nib_nc_iter(0, &iter_state, &nce));