gnrc_ndp2: port to gnrc_netif2
This commit is contained in:
parent
fb7fcfdd10
commit
c3141c46b6
@ -256,6 +256,7 @@ endif
|
|||||||
|
|
||||||
ifneq (,$(filter gnrc_ndp2,$(USEMODULE)))
|
ifneq (,$(filter gnrc_ndp2,$(USEMODULE)))
|
||||||
USEMODULE += gnrc_icmpv6
|
USEMODULE += gnrc_icmpv6
|
||||||
|
USEMODULE += gnrc_netif2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter gnrc_icmpv6_echo,$(USEMODULE)))
|
ifneq (,$(filter gnrc_icmpv6_echo,$(USEMODULE)))
|
||||||
|
|||||||
@ -24,8 +24,9 @@
|
|||||||
|
|
||||||
#include "kernel_types.h"
|
#include "kernel_types.h"
|
||||||
#include "net/gnrc/pkt.h"
|
#include "net/gnrc/pkt.h"
|
||||||
#include "net/gnrc/ipv6/netif.h"
|
#include "net/gnrc/netif2.h"
|
||||||
#include "net/ipv6/addr.h"
|
#include "net/ipv6/addr.h"
|
||||||
|
#include "net/ipv6/hdr.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -269,7 +270,7 @@ gnrc_pktsnip_t *gnrc_ndp2_opt_mtu_build(uint32_t mtu, gnrc_pktsnip_t *next);
|
|||||||
* for a neighbor solicitation so be sure to check that.
|
* for a neighbor solicitation so be sure to check that.
|
||||||
* **Will be released** in an error case.
|
* **Will be released** in an error case.
|
||||||
*/
|
*/
|
||||||
void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_netif2_t *netif,
|
||||||
const ipv6_addr_t *src, const ipv6_addr_t *dst,
|
const ipv6_addr_t *src, const ipv6_addr_t *dst,
|
||||||
gnrc_pktsnip_t *ext_opts);
|
gnrc_pktsnip_t *ext_opts);
|
||||||
|
|
||||||
@ -315,7 +316,7 @@ void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
|||||||
* check that.
|
* check that.
|
||||||
* **Will be released** in an error case.
|
* **Will be released** in an error case.
|
||||||
*/
|
*/
|
||||||
void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_netif2_t *netif,
|
||||||
const ipv6_addr_t *dst, bool supply_tl2a,
|
const ipv6_addr_t *dst, bool supply_tl2a,
|
||||||
gnrc_pktsnip_t *ext_opts);
|
gnrc_pktsnip_t *ext_opts);
|
||||||
|
|
||||||
@ -328,7 +329,7 @@ void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
|||||||
* @param[in] netif Interface to send over. May not be NULL.
|
* @param[in] netif Interface to send over. May not be NULL.
|
||||||
* @param[in] dst Destination for the router solicitation. ff02::2 if NULL.
|
* @param[in] dst Destination for the router solicitation. ff02::2 if NULL.
|
||||||
*/
|
*/
|
||||||
void gnrc_ndp2_rtr_sol_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *dst);
|
void gnrc_ndp2_rtr_sol_send(gnrc_netif2_t *netif, const ipv6_addr_t *dst);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send pre-compiled router advertisement depending on a given network
|
* @brief Send pre-compiled router advertisement depending on a given network
|
||||||
@ -355,7 +356,7 @@ void gnrc_ndp2_rtr_sol_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *dst);
|
|||||||
* for a neighbor advertisement so be sure to check that.
|
* for a neighbor advertisement so be sure to check that.
|
||||||
* **Will be released** in an error case.
|
* **Will be released** in an error case.
|
||||||
*/
|
*/
|
||||||
void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src,
|
void gnrc_ndp2_rtr_adv_send(gnrc_netif2_t *netif, const ipv6_addr_t *src,
|
||||||
const ipv6_addr_t *dst, bool fin,
|
const ipv6_addr_t *dst, bool fin,
|
||||||
gnrc_pktsnip_t *ext_opts);
|
gnrc_pktsnip_t *ext_opts);
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
#include "net/gnrc/icmpv6.h"
|
#include "net/gnrc/icmpv6.h"
|
||||||
#include "net/gnrc/ipv6.h"
|
#include "net/gnrc/ipv6.h"
|
||||||
#include "net/gnrc/netif.h"
|
#include "net/gnrc/netif2/internal.h"
|
||||||
#ifdef MODULE_GNRC_SIXLOWPAN_ND
|
#ifdef MODULE_GNRC_SIXLOWPAN_ND
|
||||||
#include "net/gnrc/sixlowpan/nd.h"
|
#include "net/gnrc/sixlowpan/nd.h"
|
||||||
#endif
|
#endif
|
||||||
@ -167,8 +167,7 @@ gnrc_pktsnip_t *gnrc_ndp2_opt_sl2a_build(const uint8_t *l2addr,
|
|||||||
{
|
{
|
||||||
assert((l2addr != NULL) && (l2addr_len != 0));
|
assert((l2addr != NULL) && (l2addr_len != 0));
|
||||||
DEBUG("ndp2: building source link-layer address option (l2addr: %s)\n",
|
DEBUG("ndp2: building source link-layer address option (l2addr: %s)\n",
|
||||||
gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), l2addr,
|
gnrc_netif2_addr_to_str(l2addr, l2addr_len, addr_str));
|
||||||
l2addr_len));
|
|
||||||
return _opt_l2a_build(l2addr, l2addr_len, next, NDP_OPT_SL2A);
|
return _opt_l2a_build(l2addr, l2addr_len, next, NDP_OPT_SL2A);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,8 +177,7 @@ gnrc_pktsnip_t *gnrc_ndp2_opt_tl2a_build(const uint8_t *l2addr,
|
|||||||
{
|
{
|
||||||
assert((l2addr != NULL) && (l2addr_len != 0));
|
assert((l2addr != NULL) && (l2addr_len != 0));
|
||||||
DEBUG("ndp2: building target link-layer address option (l2addr: %s)\n",
|
DEBUG("ndp2: building target link-layer address option (l2addr: %s)\n",
|
||||||
gnrc_netif_addr_to_str(addr_str, sizeof(addr_str), l2addr,
|
gnrc_netif2_addr_to_str(l2addr, l2addr_len, addr_str));
|
||||||
l2addr_len));
|
|
||||||
return _opt_l2a_build(l2addr, l2addr_len, next, NDP_OPT_TL2A);
|
return _opt_l2a_build(l2addr, l2addr_len, next, NDP_OPT_TL2A);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,14 +221,13 @@ gnrc_pktsnip_t *gnrc_ndp2_opt_mtu_build(uint32_t mtu, gnrc_pktsnip_t *next)
|
|||||||
return pkt;
|
return pkt;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gnrc_pktsnip_t *_build_headers(gnrc_ipv6_netif_t *netif,
|
static gnrc_pktsnip_t *_build_headers(gnrc_netif2_t *netif,
|
||||||
const ipv6_addr_t *src,
|
const ipv6_addr_t *src,
|
||||||
const ipv6_addr_t *dst,
|
const ipv6_addr_t *dst,
|
||||||
gnrc_pktsnip_t *payload);
|
gnrc_pktsnip_t *payload);
|
||||||
static size_t _get_l2src(gnrc_ipv6_netif_t *netif, uint8_t *l2src,
|
static inline size_t _get_l2src(const gnrc_netif2_t *netif, uint8_t *l2src);
|
||||||
size_t l2src_maxlen);
|
|
||||||
|
|
||||||
void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_netif2_t *netif,
|
||||||
const ipv6_addr_t *src, const ipv6_addr_t *dst,
|
const ipv6_addr_t *src, const ipv6_addr_t *dst,
|
||||||
gnrc_pktsnip_t *ext_opts)
|
gnrc_pktsnip_t *ext_opts)
|
||||||
{
|
{
|
||||||
@ -250,49 +247,58 @@ void gnrc_ndp2_nbr_sol_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
|||||||
sizeof(addr_str)));
|
sizeof(addr_str)));
|
||||||
DEBUG("tgt: %s, ", ipv6_addr_to_str(addr_str, tgt, sizeof(addr_str)));
|
DEBUG("tgt: %s, ", ipv6_addr_to_str(addr_str, tgt, sizeof(addr_str)));
|
||||||
DEBUG("dst: %s)\n", ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)));
|
DEBUG("dst: %s)\n", ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)));
|
||||||
/* check if there is a fitting source address to target */
|
gnrc_netif2_acquire(netif);
|
||||||
if (src == NULL) {
|
do { /* XXX hidden goto */
|
||||||
src = gnrc_ipv6_netif_find_best_src_addr(netif->pid, tgt, false);
|
/* check if there is a fitting source address to target */
|
||||||
}
|
if (src == NULL) {
|
||||||
|
src = gnrc_netif2_ipv6_addr_best_src(netif, tgt, false);
|
||||||
/* add SL2AO based on interface and source address */
|
|
||||||
if ((src != NULL) && !ipv6_addr_is_unspecified(src)) {
|
|
||||||
l2src_len = _get_l2src(netif, l2src, sizeof(l2src));
|
|
||||||
|
|
||||||
if (l2src_len > 0) {
|
|
||||||
/* add source address link-layer address option */
|
|
||||||
hdr = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, pkt);
|
|
||||||
|
|
||||||
if (hdr == NULL) {
|
|
||||||
DEBUG("ndp2: error allocating SL2AO.\n");
|
|
||||||
gnrc_pktbuf_release(pkt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pkt = hdr;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/* add neighbor solicitation header */
|
/* add SL2AO based on interface and source address */
|
||||||
hdr = gnrc_ndp2_nbr_sol_build(tgt, pkt);
|
if ((src != NULL) && !ipv6_addr_is_unspecified(src)) {
|
||||||
if (hdr == NULL) {
|
l2src_len = _get_l2src(netif, l2src);
|
||||||
DEBUG("ndp2: error allocating neighbor solicitation.\n");
|
|
||||||
gnrc_pktbuf_release(pkt);
|
if (l2src_len > 0) {
|
||||||
|
/* add source address link-layer address option */
|
||||||
|
hdr = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, pkt);
|
||||||
|
|
||||||
|
if (hdr == NULL) {
|
||||||
|
DEBUG("ndp2: error allocating SL2AO.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pkt = hdr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* add neighbor solicitation header */
|
||||||
|
hdr = gnrc_ndp2_nbr_sol_build(tgt, pkt);
|
||||||
|
if (hdr == NULL) {
|
||||||
|
DEBUG("ndp2: error allocating neighbor solicitation.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pkt = hdr;
|
||||||
|
/* add remaining headers */
|
||||||
|
hdr = _build_headers(netif, src, dst, pkt);
|
||||||
|
if (hdr == NULL) {
|
||||||
|
DEBUG("ndp2: error adding lower-layer headers.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pkt = hdr;
|
||||||
|
if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
|
||||||
|
GNRC_NETREG_DEMUX_CTX_ALL,
|
||||||
|
pkt) == 0) {
|
||||||
|
DEBUG("ndp2: unable to send neighbor solicitation\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gnrc_netif2_release(netif);
|
||||||
return;
|
return;
|
||||||
}
|
} while (0);
|
||||||
pkt = hdr;
|
gnrc_pktbuf_release(pkt);
|
||||||
/* add remaining headers */
|
gnrc_netif2_release(netif);
|
||||||
hdr = _build_headers(netif, src, dst, pkt);
|
|
||||||
if (hdr == NULL) {
|
|
||||||
DEBUG("ndp2: error adding lower-layer headers.\n");
|
|
||||||
gnrc_pktbuf_release(pkt);
|
|
||||||
}
|
|
||||||
else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
|
|
||||||
GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) {
|
|
||||||
DEBUG("ndp2: unable to send neighbor solicitation\n");
|
|
||||||
gnrc_pktbuf_release(hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_netif2_t *netif,
|
||||||
const ipv6_addr_t *dst, bool supply_tl2a,
|
const ipv6_addr_t *dst, bool supply_tl2a,
|
||||||
gnrc_pktsnip_t *ext_opts)
|
gnrc_pktsnip_t *ext_opts)
|
||||||
{
|
{
|
||||||
@ -307,68 +313,83 @@ void gnrc_ndp2_nbr_adv_send(const ipv6_addr_t *tgt, gnrc_ipv6_netif_t *netif,
|
|||||||
ipv6_addr_to_str(addr_str, tgt, sizeof(addr_str)));
|
ipv6_addr_to_str(addr_str, tgt, sizeof(addr_str)));
|
||||||
DEBUG("dst: %s, supply_tl2a: %d)\n",
|
DEBUG("dst: %s, supply_tl2a: %d)\n",
|
||||||
ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), supply_tl2a);
|
ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)), supply_tl2a);
|
||||||
if ((netif->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) &&
|
gnrc_netif2_acquire(netif);
|
||||||
(netif->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV)) {
|
do { /* XXX: hidden goto */
|
||||||
adv_flags |= NDP_NBR_ADV_FLAGS_R;
|
int tgt_idx;
|
||||||
}
|
|
||||||
if (ipv6_addr_is_unspecified(dst)) {
|
|
||||||
memcpy(&real_dst, &ipv6_addr_all_nodes_link_local, sizeof(ipv6_addr_t));
|
|
||||||
supply_tl2a = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
memcpy(&real_dst, dst, sizeof(real_dst));
|
|
||||||
adv_flags |= NDP_NBR_ADV_FLAGS_S;
|
|
||||||
}
|
|
||||||
/* add SL2AO based on target address */
|
|
||||||
if (supply_tl2a) {
|
|
||||||
uint8_t l2tgt[8];
|
|
||||||
size_t l2tgt_len;
|
|
||||||
/* we previously checked if we are the target, so we can take our L2tgt */
|
|
||||||
l2tgt_len = _get_l2src(netif, l2tgt, sizeof(l2tgt));
|
|
||||||
|
|
||||||
if (l2tgt_len > 0) {
|
if ((tgt_idx = gnrc_netif2_ipv6_addr_idx(netif, tgt)) < 0) {
|
||||||
/* add target address link-layer address option */
|
DEBUG("ndp2: tgt not assigned to interface. Abort sending\n");
|
||||||
hdr = gnrc_ndp2_opt_tl2a_build(l2tgt, l2tgt_len, pkt);
|
break;
|
||||||
|
|
||||||
if (hdr == NULL) {
|
|
||||||
DEBUG("ndp2: error allocating TL2AO.\n");
|
|
||||||
gnrc_pktbuf_release(ext_opts);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pkt = hdr;
|
|
||||||
}
|
}
|
||||||
}
|
if (gnrc_netif2_is_rtr(netif) && gnrc_netif2_is_rtr_adv(netif)) {
|
||||||
/* TODO: also check if the node provides proxy services for tgt */
|
adv_flags |= NDP_NBR_ADV_FLAGS_R;
|
||||||
if ((pkt != NULL) &&
|
}
|
||||||
(!gnrc_ipv6_netif_addr_is_non_unicast(tgt) || supply_tl2a)) {
|
if (ipv6_addr_is_unspecified(dst)) {
|
||||||
/* TL2A is not supplied and tgt is not anycast */
|
memcpy(&real_dst, &ipv6_addr_all_nodes_link_local,
|
||||||
adv_flags |= NDP_NBR_ADV_FLAGS_O;
|
sizeof(ipv6_addr_t));
|
||||||
}
|
supply_tl2a = true;
|
||||||
/* add neighbor advertisement header */
|
}
|
||||||
hdr = gnrc_ndp2_nbr_adv_build(tgt, adv_flags, pkt);
|
else {
|
||||||
if (hdr == NULL) {
|
memcpy(&real_dst, dst, sizeof(real_dst));
|
||||||
DEBUG("ndp2: error allocating neighbor advertisement.\n");
|
adv_flags |= NDP_NBR_ADV_FLAGS_S;
|
||||||
gnrc_pktbuf_release(pkt);
|
}
|
||||||
|
/* add SL2AO based on target address */
|
||||||
|
if (supply_tl2a) {
|
||||||
|
uint8_t l2tgt[8];
|
||||||
|
size_t l2tgt_len;
|
||||||
|
/* we previously checked if we are the target, so we can take our L2tgt */
|
||||||
|
l2tgt_len = _get_l2src(netif, l2tgt);
|
||||||
|
|
||||||
|
if (l2tgt_len > 0) {
|
||||||
|
/* add target address link-layer address option */
|
||||||
|
hdr = gnrc_ndp2_opt_tl2a_build(l2tgt, l2tgt_len, pkt);
|
||||||
|
|
||||||
|
if (hdr == NULL) {
|
||||||
|
DEBUG("ndp2: error allocating TL2AO.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pkt = hdr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* TODO: also check if the node provides proxy servies for tgt */
|
||||||
|
if ((pkt != NULL) &&
|
||||||
|
(netif->ipv6.addrs_flags[tgt_idx] &
|
||||||
|
GNRC_NETIF2_IPV6_ADDRS_FLAGS_ANYCAST)) {
|
||||||
|
/* TL2A is not supplied and tgt is not anycast */
|
||||||
|
adv_flags |= NDP_NBR_ADV_FLAGS_O;
|
||||||
|
}
|
||||||
|
/* add neighbor advertisement header */
|
||||||
|
hdr = gnrc_ndp2_nbr_adv_build(tgt, adv_flags, pkt);
|
||||||
|
if (hdr == NULL) {
|
||||||
|
DEBUG("ndp2: error allocating neighbor advertisement.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pkt = hdr;
|
||||||
|
/* add remaining headers */
|
||||||
|
hdr = _build_headers(netif, NULL, &real_dst, pkt);
|
||||||
|
if (hdr == NULL) {
|
||||||
|
DEBUG("ndp2: error adding lower-layer headers.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pkt = hdr;
|
||||||
|
if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
|
||||||
|
GNRC_NETREG_DEMUX_CTX_ALL,
|
||||||
|
pkt) == 0) {
|
||||||
|
DEBUG("ndp2: unable to send neighbor advertisement\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gnrc_netif2_release(netif);
|
||||||
return;
|
return;
|
||||||
}
|
} while (0);
|
||||||
pkt = hdr;
|
gnrc_pktbuf_release(pkt);
|
||||||
/* add remaining headers */
|
gnrc_netif2_release(netif);
|
||||||
hdr = _build_headers(netif, NULL, &real_dst, pkt);
|
|
||||||
if (hdr == NULL) {
|
|
||||||
DEBUG("ndp2: error adding lower-layer headers.\n");
|
|
||||||
gnrc_pktbuf_release(pkt);
|
|
||||||
}
|
|
||||||
else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
|
|
||||||
GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) {
|
|
||||||
DEBUG("ndp2: unable to send neighbor advertisement\n");
|
|
||||||
gnrc_pktbuf_release(hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gnrc_ndp2_rtr_sol_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *dst)
|
void gnrc_ndp2_rtr_sol_send(gnrc_netif2_t *netif, const ipv6_addr_t *dst)
|
||||||
{
|
{
|
||||||
gnrc_pktsnip_t *hdr, *pkt = NULL;
|
gnrc_pktsnip_t *hdr, *pkt = NULL;
|
||||||
ipv6_addr_t *src = NULL;
|
|
||||||
|
|
||||||
assert(netif != NULL);
|
assert(netif != NULL);
|
||||||
if (dst == NULL) {
|
if (dst == NULL) {
|
||||||
@ -377,43 +398,53 @@ void gnrc_ndp2_rtr_sol_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *dst)
|
|||||||
DEBUG("ndp2: send router solicitation (iface: %" PRIkernel_pid
|
DEBUG("ndp2: send router solicitation (iface: %" PRIkernel_pid
|
||||||
", dst: %s)\n", netif->pid,
|
", dst: %s)\n", netif->pid,
|
||||||
ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)));
|
ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)));
|
||||||
/* add SL2AO => check if there is a fitting source address to target */
|
gnrc_netif2_acquire(netif);
|
||||||
if ((src = gnrc_ipv6_netif_find_best_src_addr(netif->pid, dst,
|
do { /* XXX: hidden goto */
|
||||||
false)) != NULL) {
|
ipv6_addr_t *src = NULL;
|
||||||
uint8_t l2src[8];
|
|
||||||
size_t l2src_len = _get_l2src(netif, l2src, sizeof(l2src));
|
/* add SL2AO => check if there is a fitting source address to target */
|
||||||
if (l2src_len > 0) {
|
if ((src = gnrc_netif2_ipv6_addr_best_src(netif, dst, false)) != NULL) {
|
||||||
/* add source address link-layer address option */
|
uint8_t l2src[8];
|
||||||
pkt = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, NULL);
|
size_t l2src_len = _get_l2src(netif, l2src);
|
||||||
if (pkt == NULL) {
|
if (l2src_len > 0) {
|
||||||
DEBUG("ndp2: error allocating SL2AO.\n");
|
/* add source address link-layer address option */
|
||||||
gnrc_pktbuf_release(pkt);
|
pkt = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, NULL);
|
||||||
return;
|
if (pkt == NULL) {
|
||||||
|
DEBUG("ndp2: error allocating SL2AO.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
/* add router solicitation header */
|
||||||
/* add router solicitation header */
|
hdr = gnrc_ndp2_rtr_sol_build(pkt);
|
||||||
hdr = gnrc_ndp2_rtr_sol_build(pkt);
|
if (hdr == NULL) {
|
||||||
if (hdr == NULL) {
|
DEBUG("ndp2: error allocating router solicitation.\n");
|
||||||
DEBUG("ndp2: error allocating router solicitation.\n");
|
break;
|
||||||
gnrc_pktbuf_release(pkt);
|
}
|
||||||
|
pkt = hdr;
|
||||||
|
/* add remaining headers */
|
||||||
|
hdr = _build_headers(netif, src, dst, pkt);
|
||||||
|
if (hdr == NULL) {
|
||||||
|
DEBUG("ndp2: error adding lower-layer headers.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pkt = hdr;
|
||||||
|
if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
|
||||||
|
GNRC_NETREG_DEMUX_CTX_ALL,
|
||||||
|
pkt) == 0) {
|
||||||
|
DEBUG("ndp2: unable to send router advertisement\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gnrc_netif2_release(netif);
|
||||||
return;
|
return;
|
||||||
}
|
} while (0);
|
||||||
pkt = hdr;
|
gnrc_pktbuf_release(pkt);
|
||||||
/* add remaining headers */
|
gnrc_netif2_release(netif);
|
||||||
hdr = _build_headers(netif, src, dst, pkt);
|
|
||||||
if (hdr == NULL) {
|
|
||||||
DEBUG("ndp2: error adding lower-layer headers.\n");
|
|
||||||
gnrc_pktbuf_release(pkt);
|
|
||||||
}
|
|
||||||
else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
|
|
||||||
GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) {
|
|
||||||
DEBUG("ndp2: unable to send router advertisement\n");
|
|
||||||
gnrc_pktbuf_release(hdr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src,
|
void gnrc_ndp2_rtr_adv_send(gnrc_netif2_t *netif, const ipv6_addr_t *src,
|
||||||
const ipv6_addr_t *dst, bool fin,
|
const ipv6_addr_t *dst, bool fin,
|
||||||
gnrc_pktsnip_t *ext_opts)
|
gnrc_pktsnip_t *ext_opts)
|
||||||
{
|
{
|
||||||
@ -422,6 +453,7 @@ void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src,
|
|||||||
uint32_t reach_time = 0, retrans_timer = 0;
|
uint32_t reach_time = 0, retrans_timer = 0;
|
||||||
uint16_t adv_ltime = 0;
|
uint16_t adv_ltime = 0;
|
||||||
uint8_t cur_hl = 0;
|
uint8_t cur_hl = 0;
|
||||||
|
uint8_t flags = 0;
|
||||||
|
|
||||||
if (dst == NULL) {
|
if (dst == NULL) {
|
||||||
dst = &ipv6_addr_all_nodes_link_local;
|
dst = &ipv6_addr_all_nodes_link_local;
|
||||||
@ -429,78 +461,91 @@ void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src,
|
|||||||
DEBUG("ndp2: send router advertisement (iface: %" PRIkernel_pid ", dst: %s%s\n",
|
DEBUG("ndp2: send router advertisement (iface: %" PRIkernel_pid ", dst: %s%s\n",
|
||||||
netif->pid, ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)),
|
netif->pid, ipv6_addr_to_str(addr_str, dst, sizeof(addr_str)),
|
||||||
fin ? ", final" : "");
|
fin ? ", final" : "");
|
||||||
if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_MTU) {
|
gnrc_netif2_acquire(netif);
|
||||||
if ((hdr = gnrc_ndp2_opt_mtu_build(netif->mtu, pkt)) == NULL) {
|
do { /* XXX: hidden goto */
|
||||||
DEBUG("ndp rtr: no space left in packet buffer\n");
|
if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_MTU) {
|
||||||
return;
|
if ((hdr = gnrc_ndp2_opt_mtu_build(netif->ipv6.mtu, pkt)) == NULL) {
|
||||||
}
|
DEBUG("ndp rtr: no space left in packet buffer\n");
|
||||||
pkt = hdr;
|
break;
|
||||||
}
|
|
||||||
if (src == NULL) {
|
|
||||||
/* get address from source selection algorithm.
|
|
||||||
* Only link local addresses may be used (RFC 4861 section 4.1) */
|
|
||||||
src = gnrc_ipv6_netif_find_best_src_addr(netif->pid, dst, true);
|
|
||||||
}
|
|
||||||
/* add SL2A for source address */
|
|
||||||
if (src != NULL) {
|
|
||||||
DEBUG(" - SL2A\n");
|
|
||||||
uint8_t l2src[8];
|
|
||||||
size_t l2src_len;
|
|
||||||
/* optimization note: MAY also be omitted to facilitate in-bound load balancing over
|
|
||||||
* replicated interfaces.
|
|
||||||
* source: https://tools.ietf.org/html/rfc4861#section-6.2.3 */
|
|
||||||
l2src_len = _get_l2src(netif, l2src, sizeof(l2src));
|
|
||||||
if (l2src_len > 0) {
|
|
||||||
/* add source address link-layer address option */
|
|
||||||
hdr = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, pkt);
|
|
||||||
|
|
||||||
if (hdr == NULL) {
|
|
||||||
DEBUG("ndp2: error allocating Source Link-layer address option.\n");
|
|
||||||
gnrc_pktbuf_release(pkt);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
pkt = hdr;
|
pkt = hdr;
|
||||||
}
|
}
|
||||||
}
|
if (src == NULL) {
|
||||||
if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_CUR_HL) {
|
/* get address from source selection algorithm.
|
||||||
cur_hl = netif->cur_hl;
|
* Only link local addresses may be used (RFC 4861 section 4.1) */
|
||||||
}
|
src = gnrc_netif2_ipv6_addr_best_src(netif, dst, true);
|
||||||
if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_REACH_TIME) {
|
}
|
||||||
|
/* add SL2A for source address */
|
||||||
|
if (src != NULL) {
|
||||||
|
DEBUG(" - SL2A\n");
|
||||||
|
uint8_t l2src[8];
|
||||||
|
size_t l2src_len;
|
||||||
|
/* optimization note: MAY also be omitted to facilitate in-bound load balancing over
|
||||||
|
* replicated interfaces.
|
||||||
|
* source: https://tools.ietf.org/html/rfc4861#section-6.2.3 */
|
||||||
|
l2src_len = _get_l2src(netif, l2src);
|
||||||
|
if (l2src_len > 0) {
|
||||||
|
/* add source address link-layer address option */
|
||||||
|
hdr = gnrc_ndp2_opt_sl2a_build(l2src, l2src_len, pkt);
|
||||||
|
|
||||||
if (netif->reach_time > (3600 * US_PER_SEC)) { /* reach_time > 1 hour */
|
if (hdr == NULL) {
|
||||||
reach_time = (3600 * MS_PER_SEC);
|
DEBUG("ndp2: error allocating Source Link-layer address "
|
||||||
|
"option.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pkt = hdr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_CUR_HL) {
|
||||||
|
cur_hl = netif->cur_hl;
|
||||||
|
}
|
||||||
|
if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_REACH_TIME) {
|
||||||
|
if (netif->ipv6.reach_time_base > (3600 * MS_PER_SEC)) {
|
||||||
|
/* reach_time > 1 hour */
|
||||||
|
reach_time = (3600 * MS_PER_SEC);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reach_time = netif->ipv6.reach_time_base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_RETRANS_TIMER) {
|
||||||
|
retrans_timer = netif->ipv6.retrans_time;
|
||||||
|
}
|
||||||
|
if (!fin) {
|
||||||
|
adv_ltime = netif->ipv6.rtr_ltime;
|
||||||
|
}
|
||||||
|
if (netif->ipv6.aac_mode == GNRC_NETIF2_AAC_DHCP) {
|
||||||
|
flags |= NDP_RTR_ADV_FLAGS_M;
|
||||||
|
if (netif->flags & GNRC_NETIF2_FLAGS_IPV6_ADV_O_FLAG) {
|
||||||
|
flags |= NDP_RTR_ADV_FLAGS_O;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hdr = gnrc_ndp2_rtr_adv_build(cur_hl, flags, adv_ltime, reach_time,
|
||||||
|
retrans_timer, pkt);
|
||||||
|
if (hdr == NULL) {
|
||||||
|
DEBUG("ndp2: error allocating router advertisement.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pkt = hdr;
|
||||||
|
hdr = _build_headers(netif, src, dst, pkt);
|
||||||
|
if (hdr == NULL) {
|
||||||
|
DEBUG("ndp2: error adding lower-layer headers.\n");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
reach_time = netif->reach_time / US_PER_MS;
|
pkt = hdr;
|
||||||
|
if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
|
||||||
|
GNRC_NETREG_DEMUX_CTX_ALL,
|
||||||
|
pkt) == 0) {
|
||||||
|
DEBUG("ndp2: unable to send router solicitation\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
gnrc_netif2_release(netif);
|
||||||
if (netif->flags & GNRC_IPV6_NETIF_FLAGS_ADV_RETRANS_TIMER) {
|
|
||||||
retrans_timer = netif->retrans_timer / US_PER_MS;
|
|
||||||
}
|
|
||||||
if (!fin) {
|
|
||||||
/* TODO set netif dependent adv_ltime */
|
|
||||||
adv_ltime = 1800U;
|
|
||||||
}
|
|
||||||
hdr = gnrc_ndp2_rtr_adv_build(cur_hl,
|
|
||||||
(netif->flags & (GNRC_IPV6_NETIF_FLAGS_OTHER_CONF |
|
|
||||||
GNRC_IPV6_NETIF_FLAGS_MANAGED)) >> 8,
|
|
||||||
adv_ltime, reach_time, retrans_timer, pkt);
|
|
||||||
if (hdr == NULL) {
|
|
||||||
DEBUG("ndp2: error allocating router advertisement.\n");
|
|
||||||
gnrc_pktbuf_release(pkt);
|
|
||||||
return;
|
return;
|
||||||
}
|
} while (0);
|
||||||
pkt = hdr;
|
gnrc_pktbuf_release(pkt);
|
||||||
hdr = _build_headers(netif, src, dst, pkt);
|
gnrc_netif2_release(netif);
|
||||||
if (hdr == NULL) {
|
|
||||||
DEBUG("ndp2: error adding lower-layer headers.\n");
|
|
||||||
gnrc_pktbuf_release(pkt);
|
|
||||||
}
|
|
||||||
else if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_NDP2,
|
|
||||||
GNRC_NETREG_DEMUX_CTX_ALL, hdr) == 0) {
|
|
||||||
DEBUG("ndp2: unable to send router solicitation\n");
|
|
||||||
gnrc_pktbuf_release(hdr);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
(void)netif;
|
(void)netif;
|
||||||
(void)src;
|
(void)src;
|
||||||
@ -511,7 +556,7 @@ void gnrc_ndp2_rtr_adv_send(gnrc_ipv6_netif_t *netif, const ipv6_addr_t *src,
|
|||||||
#endif /* GNRC_IPV6_NIB_CONF_ROUTER */
|
#endif /* GNRC_IPV6_NIB_CONF_ROUTER */
|
||||||
}
|
}
|
||||||
|
|
||||||
static gnrc_pktsnip_t *_build_headers(gnrc_ipv6_netif_t *netif,
|
static gnrc_pktsnip_t *_build_headers(gnrc_netif2_t *netif,
|
||||||
const ipv6_addr_t *src,
|
const ipv6_addr_t *src,
|
||||||
const ipv6_addr_t *dst,
|
const ipv6_addr_t *dst,
|
||||||
gnrc_pktsnip_t *payload)
|
gnrc_pktsnip_t *payload)
|
||||||
@ -536,37 +581,16 @@ static gnrc_pktsnip_t *_build_headers(gnrc_ipv6_netif_t *netif,
|
|||||||
return l2hdr;
|
return l2hdr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t _get_l2src(gnrc_ipv6_netif_t *netif, uint8_t *l2src,
|
static inline size_t _get_l2src(const gnrc_netif2_t *netif, uint8_t *l2src)
|
||||||
size_t l2src_maxlen)
|
|
||||||
{
|
{
|
||||||
bool try_long = false;
|
#if GNRC_NETIF2_L2ADDR_MAXLEN > 0
|
||||||
int res;
|
memcpy(l2src, netif->l2addr, netif->l2addr_len);
|
||||||
uint16_t l2src_len;
|
return netif->l2addr_len;
|
||||||
/* maximum address length that fits into a minimum length (8) S/TL2A option */
|
#else
|
||||||
const uint16_t max_short_len = 6;
|
(void)netif;
|
||||||
|
(void)l2src;
|
||||||
/* try getting source address */
|
return 0;
|
||||||
if ((gnrc_netapi_get(netif->pid, NETOPT_SRC_LEN, 0, &l2src_len,
|
#endif
|
||||||
sizeof(l2src_len)) >= 0) &&
|
|
||||||
(l2src_len > max_short_len)) {
|
|
||||||
try_long = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (try_long && ((res = gnrc_netapi_get(netif->pid, NETOPT_ADDRESS_LONG, 0,
|
|
||||||
l2src,
|
|
||||||
l2src_maxlen)) > max_short_len)) {
|
|
||||||
l2src_len = (uint16_t)res;
|
|
||||||
}
|
|
||||||
else if ((res = gnrc_netapi_get(netif->pid, NETOPT_ADDRESS, 0, l2src,
|
|
||||||
l2src_maxlen)) >= 0) {
|
|
||||||
l2src_len = (uint16_t)res;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DEBUG("ndp2: no link-layer address found.\n");
|
|
||||||
l2src_len = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return l2src_len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user