gnrc_sixlowpan_frag_vrb: add gnrc_sixlowpan_frag_vrb_from_route()

This adds a new VRB function that receives a header with forwarding
information and creates a VRB entry from it. Currently, only IPv6 is
supported.
This commit is contained in:
Martine S. Lenders 2019-10-07 18:00:38 +02:00
parent 900ca3ff9e
commit f6686e92f1
2 changed files with 75 additions and 0 deletions

View File

@ -75,6 +75,28 @@ gnrc_sixlowpan_frag_vrb_t *gnrc_sixlowpan_frag_vrb_add(
const gnrc_sixlowpan_frag_rb_base_t *base,
gnrc_netif_t *out_netif, const uint8_t *out_dst, size_t out_dst_len);
/**
* @brief Generate reassembly buffer from a header's forwarding information.
*
* @param[in] base Base data of the datagram. Must not be `NULL`.
* @param[in] netif Restict route to this interface. May be `NULL` for any
* interface.
* @param[in] hdr Header from which to take the forwarding information from
* (e.g. IPv6 header implies `hdr->type == GNRC_NETTYPE_IPV6`).
*
* @pre `base != NULL`
* @pre `(hdr != NULL) && (hdr->data != NULL) && (hdr->size > 0)`
*
* @return The VRB entry pointing to the next hop based on the forwarding
* information provided in @p hdr and present in the respective
* forwarding information base for `hdr->type`.
* @return NULL, if VRB is full or if there is no route to destination in
* @p hdr.
*/
gnrc_sixlowpan_frag_vrb_t *gnrc_sixlowpan_frag_vrb_from_route(
const gnrc_sixlowpan_frag_rb_base_t *base,
gnrc_netif_t *netif, const gnrc_pktsnip_t *hdr);
/**
* @brief Checks timeouts and removes entries if necessary
*/

View File

@ -14,6 +14,11 @@
*/
#include "net/ieee802154.h"
#ifdef MODULE_GNRC_IPV6_NIB
#include "net/ipv6/addr.h"
#include "net/gnrc/ipv6/nib.h"
#endif /* MODULE_GNRC_IPV6_NIB */
#include "net/gnrc/netif.h"
#include "xtimer.h"
#include "net/gnrc/sixlowpan/frag/vrb.h"
@ -22,7 +27,11 @@
#include "debug.h"
static gnrc_sixlowpan_frag_vrb_t _vrb[GNRC_SIXLOWPAN_FRAG_VRB_SIZE];
#ifdef MODULE_GNRC_IPV6_NIB
static char addr_str[IPV6_ADDR_MAX_STR_LEN];
#else /* MODULE_GNRC_IPV6_NIB */
static char addr_str[3 * IEEE802154_LONG_ADDRESS_LEN];
#endif /* MODULE_GNRC_IPV6_NIB */
#if !defined(MODULE_GNRC_SIXLOWPAN_FRAG) && defined(TEST_SUITES)
/* mock for e.g. testing */
@ -91,6 +100,50 @@ gnrc_sixlowpan_frag_vrb_t *gnrc_sixlowpan_frag_vrb_add(
return vrbe;
}
gnrc_sixlowpan_frag_vrb_t *gnrc_sixlowpan_frag_vrb_from_route(
const gnrc_sixlowpan_frag_rb_base_t *base,
gnrc_netif_t *netif, const gnrc_pktsnip_t *hdr)
{
gnrc_sixlowpan_frag_vrb_t *res = NULL;
assert(base != NULL);
assert((hdr != NULL) && (hdr->data != NULL) && (hdr->size > 0));
switch (hdr->type) {
#ifdef MODULE_GNRC_IPV6_NIB
case GNRC_NETTYPE_IPV6: {
assert(hdr->size >= sizeof(ipv6_hdr_t));
const ipv6_addr_t *addr = &((const ipv6_hdr_t *)hdr->data)->dst;
gnrc_ipv6_nib_nc_t nce;
if (!ipv6_addr_is_link_local(addr) &&
(gnrc_netif_get_by_ipv6_addr(addr) == NULL) &&
(gnrc_ipv6_nib_get_next_hop_l2addr(addr, netif, NULL,
&nce) == 0)) {
DEBUG("6lo vrb: FIB entry for IPv6 destination %s found\n",
ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)));
res = gnrc_sixlowpan_frag_vrb_add(
base,
gnrc_netif_get_by_pid(gnrc_ipv6_nib_nc_get_iface(&nce)),
nce.l2addr, nce.l2addr_len
);
}
else {
DEBUG("6lo vrb: no FIB entry for IPv6 destination %s found\n",
ipv6_addr_to_str(addr_str, addr, sizeof(addr_str)));
}
break;
}
#endif /* MODULE_GNRC_IPV6_NIB */
default:
(void)base;
(void)netif;
DEBUG("6lo vrb: unknown forwarding header type %d\n", hdr->type);
break;
}
return res;
}
gnrc_sixlowpan_frag_vrb_t *gnrc_sixlowpan_frag_vrb_get(
const uint8_t *src, size_t src_len, unsigned src_tag)
{