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:
parent
f1af602952
commit
4ce2d01cb9
@ -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
|
||||
|
66
sys/include/net/gnrc/sixlowpan/frag/minfwd.h
Normal file
66
sys/include/net/gnrc/sixlowpan/frag/minfwd.h
Normal 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 */
|
||||
/** @} */
|
@ -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
|
||||
|
@ -0,0 +1,3 @@
|
||||
MODULE := gnrc_sixlowpan_frag_minfwd
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
@ -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;
|
||||
}
|
||||
|
||||
/** @} */
|
Loading…
Reference in New Issue
Block a user