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:
parent
8fac66eb03
commit
a7d2c65b36
57
Makefile.dep
57
Makefile.dep
@ -136,29 +136,30 @@ endif
|
||||
|
||||
ifneq (,$(filter gnrc_sixlowpan_default,$(USEMODULE)))
|
||||
USEMODULE += gnrc_ipv6_default
|
||||
USEMODULE += gnrc_ipv6_nib_6ln
|
||||
USEMODULE += gnrc_sixlowpan
|
||||
USEMODULE += gnrc_sixlowpan_nd
|
||||
USEMODULE += gnrc_sixlowpan_frag
|
||||
USEMODULE += gnrc_sixlowpan_iphc
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_sixlowpan_router_default,$(USEMODULE)))
|
||||
USEMODULE += gnrc_ipv6_router_default
|
||||
USEMODULE += gnrc_ipv6_nib_6lr
|
||||
USEMODULE += gnrc_sixlowpan_router
|
||||
USEMODULE += gnrc_sixlowpan_frag
|
||||
USEMODULE += gnrc_sixlowpan_iphc
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_sixlowpan_border_router_default,$(USEMODULE)))
|
||||
USEMODULE += gnrc_ipv6_nib_6lbr
|
||||
USEMODULE += gnrc_ipv6_router_default
|
||||
USEMODULE += gnrc_sixlowpan_nd_border_router
|
||||
USEMODULE += gnrc_sixlowpan_router
|
||||
USEMODULE += gnrc_sixlowpan_frag
|
||||
USEMODULE += gnrc_sixlowpan_iphc
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_sixlowpan_router,$(USEMODULE)))
|
||||
USEMODULE += gnrc_sixlowpan_nd_router
|
||||
USEMODULE += gnrc_ipv6_router
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_sixlowpan_frag,$(USEMODULE)))
|
||||
@ -182,50 +183,14 @@ ifneq (,$(filter gnrc_sixlowpan_ctx,$(USEMODULE)))
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_sixlowpan_nd_border_router,$(USEMODULE)))
|
||||
USEMODULE += gnrc_sixlowpan_nd_router
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_sixlowpan_nd_router,$(USEMODULE)))
|
||||
USEMODULE += gnrc_sixlowpan_nd
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_sixlowpan_nd,$(USEMODULE)))
|
||||
USEMODULE += gnrc_ndp
|
||||
USEMODULE += gnrc_ndp_internal
|
||||
USEMODULE += gnrc_sixlowpan_ctx
|
||||
USEMODULE += random
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_ipv6_default,$(USEMODULE)))
|
||||
USEMODULE += gnrc_ipv6
|
||||
USEMODULE += gnrc_icmpv6
|
||||
ifeq (1,$(GNRC_NETIF_NUMOF))
|
||||
ifeq (,$(filter gnrc_sixlowpan_nd,$(USEMODULE)))
|
||||
USEMODULE += gnrc_ndp_host
|
||||
endif
|
||||
else
|
||||
USEMODULE += gnrc_ndp_host
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_ipv6_router_default,$(USEMODULE)))
|
||||
USEMODULE += gnrc_ipv6_router
|
||||
USEMODULE += gnrc_icmpv6
|
||||
ifeq (1,$(GNRC_NETIF_NUMOF))
|
||||
ifeq (,$(filter gnrc_sixlowpan_nd_router,$(USEMODULE)))
|
||||
USEMODULE += gnrc_ndp_router
|
||||
endif
|
||||
else
|
||||
USEMODULE += gnrc_ndp_router
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_ndp_host,$(USEMODULE)))
|
||||
USEMODULE += gnrc_ndp_node
|
||||
USEMODULE += random
|
||||
USEMODULE += xtimer
|
||||
endif
|
||||
|
||||
ifneq (,$(filter gnrc_ndp_router,$(USEMODULE)))
|
||||
@ -242,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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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) &&
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user