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

gnrc_sixlowpan_frag: initial import of minimal forwarding

See https://tools.ietf.org/html/draft-ietf-6lo-minimal-fragment-04
This commit is contained in:
Martine Lenders 2019-02-12 12:24:51 +01:00
parent f1af602952
commit 4ce2d01cb9
No known key found for this signature in database
GPG Key ID: CCD317364F63286F
5 changed files with 168 additions and 0 deletions

View File

@ -292,6 +292,13 @@ ifneq (,$(filter gnrc_sixlowpan_frag_fb,$(USEMODULE)))
USEMODULE += core_msg
endif
ifneq (,$(filter gnrc_sixlowpan_frag_minfwd,$(USEMODULE)))
USEMODULE += gnrc_netif_pktq
USEMODULE += gnrc_sixlowpan_frag
USEMODULE += gnrc_sixlowpan_frag_hint
USEMODULE += gnrc_sixlowpan_frag_vrb
endif
ifneq (,$(filter gnrc_sixlowpan_frag_rb,$(USEMODULE)))
USEMODULE += xtimer
endif

View File

@ -0,0 +1,66 @@
/*
* Copyright (C) 2019 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup net_gnrc_sixlowpan_frag_minfwd Minimal fragment forwarding
* @ingroup net_gnrc_sixlowpan_frag
* @brief Provides minimal fragment forwarding using the VRB
* @see [RFC 8930](https://tools.ietf.org/html/rfc8930)
* @see @ref net_gnrc_sixlowpan_frag_vrb
* @experimental
* @{
*
* @file
* @brief Minimal fragment forwarding definitions
*
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#ifndef NET_GNRC_SIXLOWPAN_FRAG_MINFWD_H
#define NET_GNRC_SIXLOWPAN_FRAG_MINFWD_H
#include <stddef.h>
#include "net/gnrc/pkt.h"
#include "net/gnrc/netif.h"
#include "net/gnrc/sixlowpan/frag.h"
#include "net/gnrc/sixlowpan/frag/vrb.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Forwards a fragment according to a VRB entry
*
* @param[in] pkt The fragment to forward (without fragmentation header).
* Is consumed by this function.
* @param[in] frag The originally received fragmentation header.
* @param[in] vrbe Virtual reassembly buffer containing the forwarding
* information. Removed when datagram was completely
* forwarded.
* @param[in] page Current 6Lo dispatch parsing page.
*
* @pre `vrbe != NULL`
* @pre `pkt != NULL`
* @pre `frag != NULL`
*
* @return 0 on success.
* @return -ENOMEM, when packet buffer is too full to prepare packet for
* forwarding.
*/
int gnrc_sixlowpan_frag_minfwd_forward(gnrc_pktsnip_t *pkt,
const sixlowpan_frag_n_t *frag,
gnrc_sixlowpan_frag_vrb_t *vrbe,
unsigned page);
#ifdef __cplusplus
}
#endif
#endif /* NET_GNRC_SIXLOWPAN_FRAG_MINFWD_H */
/** @} */

View File

@ -100,6 +100,9 @@ endif
ifneq (,$(filter gnrc_sixlowpan_frag_fb,$(USEMODULE)))
DIRS += network_layer/sixlowpan/frag/fb
endif
ifneq (,$(filter gnrc_sixlowpan_frag_minfwd,$(USEMODULE)))
DIRS += network_layer/sixlowpan/frag/minfwd
endif
ifneq (,$(filter gnrc_sixlowpan_frag_rb,$(USEMODULE)))
DIRS += network_layer/sixlowpan/frag/rb
endif

View File

@ -0,0 +1,3 @@
MODULE := gnrc_sixlowpan_frag_minfwd
include $(RIOTBASE)/Makefile.base

View File

@ -0,0 +1,89 @@
/*
* Copyright (C) 2019 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @{
*
* @file
* @author Martine Lenders <m.lenders@fu-berlin.de>
*/
#include <errno.h>
#include <stdbool.h>
#include "net/gnrc/netif/hdr.h"
#include "net/gnrc/pktbuf.h"
#include "net/gnrc/sixlowpan/internal.h"
#include "utlist.h"
#include "net/gnrc/sixlowpan/frag/minfwd.h"
#define ENABLE_DEBUG 0
#include "debug.h"
static gnrc_pktsnip_t *_netif_hdr_from_vrbe(const gnrc_sixlowpan_frag_vrb_t *vrbe)
{
gnrc_pktsnip_t *res = gnrc_netif_hdr_build(NULL, 0, vrbe->super.dst,
vrbe->super.dst_len);
if (res == NULL) {
DEBUG("6lo minfwd: can't allocate netif header for forwarding.\n");
return NULL;
}
gnrc_netif_hdr_set_netif(res->data, vrbe->out_netif);
return res;
}
static inline bool _is_last_frag(const gnrc_sixlowpan_frag_vrb_t *vrbe)
{
return (vrbe->super.current_size >= vrbe->super.datagram_size);
}
int gnrc_sixlowpan_frag_minfwd_forward(gnrc_pktsnip_t *pkt,
const sixlowpan_frag_n_t *frag,
gnrc_sixlowpan_frag_vrb_t *vrbe,
unsigned page)
{
sixlowpan_frag_t *new;
gnrc_pktsnip_t *tmp;
const size_t fragsnip_size = sizeof(sixlowpan_frag_t) +
((sixlowpan_frag_1_is((sixlowpan_frag_t *)frag))
? 0U : sizeof(frag->offset));
assert(vrbe != NULL);
assert(pkt != NULL);
assert(frag != NULL);
if ((tmp = gnrc_pktbuf_add(pkt, frag, fragsnip_size,
GNRC_NETTYPE_SIXLOWPAN)) == NULL) {
DEBUG("6lo minfwd: unable to allocate new fragmentation header.\n");
gnrc_pktbuf_release(pkt);
return -ENOMEM;
}
pkt = tmp;
new = pkt->data;
new->tag = byteorder_htons(vrbe->out_tag);
tmp = _netif_hdr_from_vrbe(vrbe);
if (tmp == NULL) {
gnrc_pktbuf_release(pkt);
return -ENOMEM;
}
if (_is_last_frag(vrbe)) {
DEBUG("6lo minfwd: current_size (%u) >= datagram_size (%u)\n",
vrbe->super.current_size, vrbe->super.datagram_size);
gnrc_sixlowpan_frag_vrb_rm(vrbe);
}
else {
gnrc_netif_hdr_t *netif_hdr = tmp->data;
netif_hdr->flags |= GNRC_NETIF_HDR_FLAGS_MORE_DATA;
}
pkt = gnrc_pkt_prepend(pkt, tmp);
gnrc_sixlowpan_dispatch_send(pkt, NULL, page);
return 0;
}
/** @} */