mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #12593 from miri64/gnrc_sixlowpan_frag_rb/enh/deletion-timer
gnrc_sixlowpan_frag_rb: allow for deletion timer after completion
This commit is contained in:
commit
02295ce5c7
@ -97,6 +97,21 @@ extern "C" {
|
||||
#define GNRC_SIXLOWPAN_FRAG_RBUF_AGGRESSIVE_OVERRIDE (1)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Deletion timer for reassembly buffer entries in microseconds
|
||||
*
|
||||
* @note Only applicable with
|
||||
* [gnrc_sixlowpan_frag_rb](@ref net_gnrc_sixlowpan_frag_rb) module
|
||||
*
|
||||
* Time to pass between completion of a datagram and the deletion of its
|
||||
* reassembly buffer entry. If this value is 0, the entry is dropped
|
||||
* immediately. Use this value to prevent re-creation of a reassembly buffer
|
||||
* entry on late arriving link-layer duplicates.
|
||||
*/
|
||||
#ifndef GNRC_SIXLOWPAN_FRAG_RBUF_DEL_TIMER
|
||||
#define GNRC_SIXLOWPAN_FRAG_RBUF_DEL_TIMER (0U)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Registration lifetime in minutes for the address registration option
|
||||
*
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "net/ipv6/hdr.h"
|
||||
#include "net/gnrc.h"
|
||||
#include "net/gnrc/sixlowpan.h"
|
||||
#include "net/gnrc/sixlowpan/config.h"
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_VRB
|
||||
#include "net/gnrc/sixlowpan/frag/vrb.h"
|
||||
#endif /* MODULE_GNRC_SIXLOWPAN_FRAG_VRB */
|
||||
@ -115,7 +116,7 @@ static int _check_fragments(gnrc_sixlowpan_frag_rb_base_t *entry,
|
||||
}
|
||||
/* End was already checked in overlap check */
|
||||
if (ptr->start == offset) {
|
||||
DEBUG("6lo rbuf: fragment already in reassembly buffer");
|
||||
DEBUG("6lo rbuf: fragment already in reassembly buffer\n");
|
||||
return RBUF_ADD_DUPLICATE;
|
||||
}
|
||||
ptr = ptr->next;
|
||||
@ -360,6 +361,18 @@ static bool _rbuf_update_ints(gnrc_sixlowpan_frag_rb_base_t *entry,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void _gc_pkt(gnrc_sixlowpan_frag_rb_t *rbuf)
|
||||
{
|
||||
#if GNRC_SIXLOWPAN_FRAG_RBUF_DEL_TIMER > 0
|
||||
if (rbuf->super.current_size == 0) {
|
||||
/* packet is scheduled for deletion, but was complete, i.e. pkt is
|
||||
* already handed up to other layer, i.e. no need to release */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
gnrc_pktbuf_release(rbuf->pkt);
|
||||
}
|
||||
|
||||
void gnrc_sixlowpan_frag_rb_gc(void)
|
||||
{
|
||||
uint32_t now_usec = xtimer_now_usec();
|
||||
@ -380,7 +393,7 @@ void gnrc_sixlowpan_frag_rb_gc(void)
|
||||
l2addr_str),
|
||||
(unsigned)rbuf[i].super.datagram_size, rbuf[i].super.tag);
|
||||
|
||||
gnrc_pktbuf_release(rbuf[i].pkt);
|
||||
_gc_pkt(&rbuf[i]);
|
||||
gnrc_sixlowpan_frag_rb_remove(&(rbuf[i]));
|
||||
}
|
||||
}
|
||||
@ -419,6 +432,14 @@ static int _rbuf_get(const void *src, size_t src_len,
|
||||
rbuf[i].super.dst_len,
|
||||
l2addr_str),
|
||||
(unsigned)rbuf[i].super.datagram_size, rbuf[i].super.tag);
|
||||
#if GNRC_SIXLOWPAN_FRAG_RBUF_DEL_TIMER > 0
|
||||
if (rbuf[i].super.current_size == 0) {
|
||||
/* ensure that only empty reassembly buffer entries and entries
|
||||
* scheduled for deletion have `current_size == 0` */
|
||||
DEBUG("6lo rfrag: scheduled for deletion, don't add fragment\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
rbuf[i].super.arrival = now_usec;
|
||||
_set_rbuf_timeout();
|
||||
return i;
|
||||
@ -514,7 +535,7 @@ void gnrc_sixlowpan_frag_rb_reset(void)
|
||||
for (unsigned int i = 0; i < GNRC_SIXLOWPAN_FRAG_RBUF_SIZE; i++) {
|
||||
if ((rbuf[i].pkt != NULL) &&
|
||||
(rbuf[i].pkt->users > 0)) {
|
||||
gnrc_pktbuf_release(rbuf[i].pkt);
|
||||
_gc_pkt(&rbuf[i]);
|
||||
}
|
||||
}
|
||||
memset(rbuf, 0, sizeof(rbuf));
|
||||
@ -539,6 +560,25 @@ void gnrc_sixlowpan_frag_rb_base_rm(gnrc_sixlowpan_frag_rb_base_t *entry)
|
||||
entry->datagram_size = 0;
|
||||
}
|
||||
|
||||
static void _tmp_rm(gnrc_sixlowpan_frag_rb_t *rbuf)
|
||||
{
|
||||
#if GNRC_SIXLOWPAN_FRAG_RBUF_DEL_TIMER > 0U
|
||||
/* use garbage-collection to leave the entry for at least
|
||||
* GNRC_SIXLOWPAN_FRAG_RBUF_DEL_TIMER in the reassembly buffer by
|
||||
* setting the arrival time to
|
||||
* (GNRC_SIXLOWPAN_FRAG_RBUF_TIMEOUT_US - GNRC_SIXLOWPAN_FRAG_RBUF_DEL_TIMER)
|
||||
* microseconds in the past */
|
||||
rbuf->super.arrival = xtimer_now_usec() -
|
||||
(GNRC_SIXLOWPAN_FRAG_RBUF_TIMEOUT_US -
|
||||
GNRC_SIXLOWPAN_FRAG_RBUF_DEL_TIMER);
|
||||
/* reset current size to prevent late duplicates to trigger another
|
||||
* dispatch */
|
||||
rbuf->super.current_size = 0;
|
||||
#else /* GNRC_SIXLOWPAN_FRAG_RBUF_DEL_TIMER == 0U */
|
||||
gnrc_sixlowpan_frag_rb_remove(rbuf);
|
||||
#endif /* GNRC_SIXLOWPAN_FRAG_RBUF_DEL_TIMER */
|
||||
}
|
||||
|
||||
int gnrc_sixlowpan_frag_rb_dispatch_when_complete(gnrc_sixlowpan_frag_rb_t *rbuf,
|
||||
gnrc_netif_hdr_t *netif_hdr)
|
||||
{
|
||||
@ -555,7 +595,7 @@ int gnrc_sixlowpan_frag_rb_dispatch_when_complete(gnrc_sixlowpan_frag_rb_t *rbuf
|
||||
if (netif == NULL) {
|
||||
DEBUG("6lo rbuf: error allocating netif header\n");
|
||||
gnrc_pktbuf_release(rbuf->pkt);
|
||||
gnrc_sixlowpan_frag_rb_remove(rbuf);
|
||||
_tmp_rm(rbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -570,7 +610,7 @@ int gnrc_sixlowpan_frag_rb_dispatch_when_complete(gnrc_sixlowpan_frag_rb_t *rbuf
|
||||
new_netif_hdr->rssi = netif_hdr->rssi;
|
||||
LL_APPEND(rbuf->pkt, netif);
|
||||
gnrc_sixlowpan_dispatch_recv(rbuf->pkt, NULL, 0);
|
||||
gnrc_sixlowpan_frag_rb_remove(rbuf);
|
||||
_tmp_rm(rbuf);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user