1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

gnrc_ipv6_nib: port to gnrc_netif2

This commit is contained in:
Martine Lenders 2017-07-31 17:51:20 +02:00
parent 8fac66eb03
commit a7d2c65b36
No known key found for this signature in database
GPG Key ID: 8E97A9FE55F25D62
21 changed files with 572 additions and 677 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,18 +207,6 @@ 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
@ -302,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

@ -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) {
memcpy(&nce->ipv6, dst, sizeof(nce->ipv6));
memcpy(&nce->l2addr, &dst->u64[1], sizeof(dst->u64[1]));
nce->l2addr[0] ^= 0x02;
nce->info = 0;
nce->info |= (iface << GNRC_IPV6_NIB_NC_INFO_IFACE_POS) &
GNRC_IPV6_NIB_NC_INFO_IFACE_MASK;
nce->info |= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE;
nce->info |= GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED;
nce->l2addr_len = sizeof(dst->u64[1]);
uint8_t l2addr_len;
if ((l2addr_len = _reverse_iid(dst, netif, nce->l2addr)) > 0) {
DEBUG("nib: resolve address %s%%%u by reverse translating to ",
ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)),
(unsigned)netif->pid);
nce->l2addr_len = l2addr_len;
DEBUG("%s\n",
gnrc_netif2_addr_to_str(nce->l2addr, nce->l2addr_len,
addr_str));
memcpy(&nce->ipv6, dst, sizeof(nce->ipv6));
nce->info = 0;
nce->info |= (netif->pid << GNRC_IPV6_NIB_NC_INFO_IFACE_POS) &
GNRC_IPV6_NIB_NC_INFO_IFACE_MASK;
nce->info |= GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE;
nce->info |= GNRC_IPV6_NIB_NC_INFO_AR_STATE_REGISTERED;
}
else {
res = false;
}
}
return res;
}
uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
uint8_t _handle_aro(gnrc_netif2_t *netif, const ipv6_hdr_t *ipv6,
const icmpv6_hdr_t *icmpv6,
const sixlowpan_nd_opt_ar_t *aro, const ndp_opt_t *sl2ao,
_nib_onl_entry_t *nce)
{
gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(iface);
#if !GNRC_IPV6_NIB_CONF_6LR
(void)sl2ao;
#endif
assert(netif != NULL);
if (_is_6ln(netif) && (aro->len == SIXLOWPAN_ND_OPT_AR_LEN)) {
if (gnrc_netif2_is_6ln(netif) && (aro->len == SIXLOWPAN_ND_OPT_AR_LEN)) {
DEBUG("nib: valid ARO received\n");
DEBUG(" - length: %u\n", aro->len);
DEBUG(" - status: %u\n", aro->status);
@ -78,7 +118,7 @@ uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
aro->eui64.uint8[3], aro->eui64.uint8[4], aro->eui64.uint8[5],
aro->eui64.uint8[6], aro->eui64.uint8[7]);
if (icmpv6->type == ICMPV6_NBR_ADV) {
if (!_is_iface_eui64(iface, &aro->eui64)) {
if (!_is_iface_eui64(netif, &aro->eui64)) {
DEBUG("nib: ARO EUI-64 is not mine, ignoring ARO\n");
return _ADDR_REG_STATUS_IGNORE;
}
@ -92,7 +132,7 @@ uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
(byteorder_ntohs(aro->ltime) - 1U) *
SEC_PER_MIN * MS_PER_SEC;
DEBUG("nib: Address registration successful. "
"Scheduling re-registration in %ums\n",
"Scheduling re-registration in %" PRIu32 "ms\n",
next_ns);
assert(nce != NULL);
_evtimer_add(nce, GNRC_IPV6_NIB_SND_UC_NS, &nce->nud_timeout,
@ -103,22 +143,19 @@ uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
DEBUG("nib: Address registration reports duplicate. "
"Removing address %s%%%u\n",
ipv6_addr_to_str(addr_str,
&((ndp_nbr_adv_t *)icmpv6)->tgt,
sizeof(addr_str)),
iface);
gnrc_ipv6_netif_remove_addr(iface,
&((ndp_nbr_adv_t *)icmpv6)->tgt);
&ipv6->dst,
sizeof(addr_str)), netif->pid);
gnrc_netif2_ipv6_addr_remove(netif, &ipv6->dst);
/* TODO: generate new address */
break;
case SIXLOWPAN_ND_STATUS_NC_FULL: {
DEBUG("nib: Router's neighbor cache is full. "
"Searching new router for DAD\n");
_nib_dr_entry_t *dr = _nib_drl_get(&ipv6->src, iface);
_nib_dr_entry_t *dr = _nib_drl_get(&ipv6->src, netif->pid);
assert(dr != NULL); /* otherwise we wouldn't be here */
_nib_drl_remove(dr);
if (_nib_drl_iter(NULL) == NULL) { /* no DRL left */
_nib_iface_t *nib_iface = _nib_iface_get(iface);
nib_iface->rs_sent = 0;
netif->ipv6.rs_sent = 0;
/* TODO: search new router */
}
else {
@ -131,8 +168,9 @@ uint8_t _handle_aro(kernel_pid_t iface, const ipv6_hdr_t *ipv6,
return aro->status;
}
#if GNRC_IPV6_NIB_CONF_6LR
else if (_is_6lr(netif) && (icmpv6->type == ICMPV6_NBR_SOL)) {
return _reg_addr_upstream(iface, ipv6, icmpv6, aro, sl2ao);
else if (gnrc_netif2_is_6lr(netif) &&
(icmpv6->type == ICMPV6_NBR_SOL)) {
return _reg_addr_upstream(netif, ipv6, icmpv6, aro, sl2ao);
}
#endif
}

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 (opt->len) {
case 1U:
return 2U;
case 2U:
return 8U;
default:
return 0U;
}
switch (netif->device_type) {
#ifdef MODULE_CC110X
case NETDEV_TYPE_CC110X:
(void)opt;
return sizeof(uint8_t);
#endif
#ifdef MODULE_NETDEV_ETH
case NETDEV_TYPE_ETHERNET:
(void)opt;
return ETHERNET_ADDR_LEN;
#endif
#ifdef MODULE_NETDEV_NRFMIN
case NETDEV_TYPE_NRFMIN:
(void)opt;
return sizeof(uint16_t);
#endif
#ifdef MODULE_NETDEV_IEEE802154
case NETDEV_TYPE_IEEE802154:
switch (opt->len) {
case 1U:
return IEEE802154_SHORT_ADDRESS_LEN;
case 2U:
return IEEE802154_LONG_ADDRESS_LEN;
default:
return 0U;
}
#endif
default:
(void)opt;
return 0U;
}
#else
(void)netif;
#endif /* GNRC_IPV6_NIB_CONF_6LN */
if (opt->len == 1U) {
return 6U;
}
return 0U;
}
#if GNRC_IPV6_NIB_CONF_ARSM
@ -207,7 +249,7 @@ static inline bool _rflag_set(const ndp_nbr_adv_t *nbr_adv);
*
* @param[in] nce A neighbor cache entry.
* @param[in] tl2ao The TL2AO.
* @param[in] iface The interface the TL2AO came over.
* @param[in] netif The interface the TL2AO came over.
* @param[in] tl2ao_addr_len Length of the L2 address in the TL2AO.
*
* @return `true`, if the TL2AO changes the NCE.
@ -215,7 +257,7 @@ static inline bool _rflag_set(const ndp_nbr_adv_t *nbr_adv);
*/
static inline bool _tl2ao_changes_nce(_nib_onl_entry_t *nce,
const ndp_opt_t *tl2ao,
kernel_pid_t iface,
gnrc_netif2_t *netif,
unsigned tl2ao_addr_len);
void _handle_snd_ns(_nib_onl_entry_t *nbr)
@ -233,7 +275,10 @@ void _handle_snd_ns(_nib_onl_entry_t *nbr)
break;
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE:
if (nbr->ns_sent >= NDP_MAX_UC_SOL_NUMOF) {
_set_nud_state(nbr, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE);
gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(nbr));
_set_nud_state(netif, nbr,
GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE);
}
/* falls through intentionally */
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE:
@ -253,13 +298,16 @@ void _handle_state_timeout(_nib_onl_entry_t *nbr)
DEBUG("nib: Timeout reachability\n");
new_state = GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE;
/* falls through intentionally */
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY:
_set_nud_state(nbr, new_state);
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_DELAY: {
gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(nbr));
_set_nud_state(netif, nbr, new_state);
if (new_state == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE) {
DEBUG("nib: Timeout DELAY state\n");
_probe_nbr(nbr, true);
}
break;
}
}
}
@ -274,24 +322,25 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset)
break;
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE:
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE: {
_nib_iface_t *iface = _nib_iface_get(_nib_onl_get_if(nbr));
gnrc_netif2_t *netif = gnrc_netif2_get_by_pid(_nib_onl_get_if(nbr));
uint32_t next_ns = _evtimer_lookup(nbr,
GNRC_IPV6_NIB_SND_MC_NS);
if (next_ns > iface->retrans_time) {
gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(_nib_onl_get_if(nbr));
assert(netif != NULL);
gnrc_netif2_acquire(netif);
if (next_ns > netif->ipv6.retrans_time) {
ipv6_addr_t sol_nodes;
uint32_t retrans_time = iface->retrans_time;
uint32_t retrans_time = netif->ipv6.retrans_time;
DEBUG("multicast to %s's solicited nodes ",
ipv6_addr_to_str(addr_str, &nbr->ipv6,
sizeof(addr_str)));
assert(netif != NULL);
if (reset) {
nbr->ns_sent = 0;
}
if (state == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNREACHABLE) {
/* first 3 retransmissions in PROBE, assume 1 higher to
* not send after iface->retrans_timer sec again,
* not send after netif->ipv6.retrans_timer sec again,
* but the next backoff after that => subtract 2 */
retrans_time = _exp_backoff_retrans_timer(nbr->ns_sent - 2,
retrans_time);
@ -312,9 +361,10 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset)
"a multicast NS within %ums)\n",
ipv6_addr_to_str(addr_str, &nbr->ipv6,
sizeof(addr_str)),
(unsigned)iface->retrans_time);
(unsigned)netif->ipv6.retrans_time);
}
#endif
gnrc_netif2_release(netif);
}
break;
case GNRC_IPV6_NIB_NC_INFO_NUD_STATE_PROBE:
@ -324,10 +374,9 @@ void _probe_nbr(_nib_onl_entry_t *nbr, bool reset)
}
}
void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce,
void _handle_adv_l2(gnrc_netif2_t *netif, _nib_onl_entry_t *nce,
const icmpv6_hdr_t *icmpv6, const ndp_opt_t *tl2ao)
{
gnrc_ipv6_netif_t *netif = gnrc_ipv6_netif_get(iface);
unsigned l2addr_len = 0;
assert(nce != NULL);
@ -342,7 +391,7 @@ void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce,
if ((_get_nud_state(nce) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE) ||
_oflag_set((ndp_nbr_adv_t *)icmpv6) ||
_redirect_with_tl2ao(icmpv6, tl2ao) ||
_tl2ao_changes_nce(nce, tl2ao, iface, l2addr_len)) {
_tl2ao_changes_nce(nce, tl2ao, netif, l2addr_len)) {
bool nce_was_incomplete =
(_get_nud_state(nce) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE);
if (tl2ao != NULL) {
@ -353,17 +402,17 @@ void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce,
nce->l2addr_len = 0;
}
if (_sflag_set((ndp_nbr_adv_t *)icmpv6)) {
_set_reachable(iface, nce);
_set_reachable(netif, nce);
}
else if ((icmpv6->type != ICMPV6_NBR_ADV) ||
!_sflag_set((ndp_nbr_adv_t *)icmpv6) ||
(!nce_was_incomplete &&
_tl2ao_changes_nce(nce, tl2ao, iface, l2addr_len))) {
_tl2ao_changes_nce(nce, tl2ao, netif, l2addr_len))) {
DEBUG("nib: Set %s%%%u to STALE\n",
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
iface);
(unsigned)netif->pid);
evtimer_del(&_nib_evtimer, &nce->nud_timeout.event);
_set_nud_state(nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
_set_nud_state(netif, nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
}
if (_oflag_set((ndp_nbr_adv_t *)icmpv6) ||
((icmpv6->type == ICMPV6_NBR_ADV) && nce_was_incomplete)) {
@ -391,30 +440,57 @@ void _handle_adv_l2(kernel_pid_t iface, _nib_onl_entry_t *nce,
if ((icmpv6->type == ICMPV6_NBR_ADV) &&
!_sflag_set((ndp_nbr_adv_t *)icmpv6) &&
(_get_nud_state(nce) == GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE) &&
_tl2ao_changes_nce(nce, tl2ao, iface, l2addr_len)) {
_tl2ao_changes_nce(nce, tl2ao, netif, l2addr_len)) {
evtimer_del(&_nib_evtimer, &nce->nud_timeout.event);
_set_nud_state(nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
_set_nud_state(netif, nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_STALE);
}
}
else if ((icmpv6->type == ICMPV6_NBR_ADV) &&
(_get_nud_state(nce) != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_INCOMPLETE) &&
(_get_nud_state(nce) != GNRC_IPV6_NIB_NC_INFO_NUD_STATE_UNMANAGED) &&
_sflag_set((ndp_nbr_adv_t *)icmpv6) &&
!_tl2ao_changes_nce(nce, tl2ao, iface, l2addr_len)) {
_set_reachable(iface, nce);
!_tl2ao_changes_nce(nce, tl2ao, netif, l2addr_len)) {
_set_reachable(netif, nce);
}
}
void _set_reachable(unsigned iface, _nib_onl_entry_t *nce)
void _recalc_reach_time(gnrc_netif2_ipv6_t *netif)
{
_nib_iface_t *nib_netif = _nib_iface_get(iface);
const uint32_t half = (netif->reach_time_base >> 1);
netif->reach_time = random_uint32_range(half,
netif->reach_time_base + half);
_evtimer_add(netif, GNRC_IPV6_NIB_RECALC_REACH_TIME,
&netif->recalc_reach_time,
GNRC_IPV6_NIB_CONF_REACH_TIME_RESET);
}
void _set_reachable(gnrc_netif2_t *netif, _nib_onl_entry_t *nce)
{
DEBUG("nib: Set %s%%%u to REACHABLE for %ums\n",
ipv6_addr_to_str(addr_str, &nce->ipv6, sizeof(addr_str)),
iface, (unsigned)nib_netif->reach_time);
_set_nud_state(nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE);
netif->pid, (unsigned)netif->ipv6.reach_time);
_set_nud_state(netif, nce, GNRC_IPV6_NIB_NC_INFO_NUD_STATE_REACHABLE);
_evtimer_add(nce, GNRC_IPV6_NIB_REACH_TIMEOUT, &nce->nud_timeout,
nib_netif->reach_time);
netif->ipv6.reach_time);
}
void _set_nud_state(gnrc_netif2_t *netif, _nib_onl_entry_t *nce,
uint16_t state)
{
nce->info &= ~GNRC_IPV6_NIB_NC_INFO_NUD_STATE_MASK;
nce->info |= state;
#if GNRC_IPV6_NIB_CONF_ROUTER
gnrc_netif2_acquire(netif);
if ((netif != NULL) && (netif->ipv6.route_info_cb)) {
netif->ipv6.route_info_cb(GNRC_IPV6_NIB_ROUTE_INFO_TYPE_NSC,
&nce->ipv6, (void *)((intptr_t)state));
}
gnrc_netif2_release(netif);
#else
(void)netif;
#endif
}
/* internal functions */
@ -443,13 +519,13 @@ static inline bool _redirect_with_tl2ao(icmpv6_hdr_t *icmpv6, ndp_opt_t *tl2ao)
static inline bool _tl2ao_changes_nce(_nib_onl_entry_t *nce,
const ndp_opt_t *tl2ao,
kernel_pid_t iface,
gnrc_netif2_t *netif,
unsigned tl2ao_addr_len)
{
return ((tl2ao != NULL) &&
(((nce->l2addr_len != tl2ao_addr_len) &&
(memcmp(nce->l2addr, tl2ao + 1, tl2ao_addr_len) != 0)) ||
(_nib_onl_get_if(nce) != (unsigned)iface)));
(_nib_onl_get_if(nce) != (unsigned)netif->pid)));
}
static inline bool _oflag_set(const ndp_nbr_adv_t *nbr_adv)

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

@ -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);