mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
Merge pull request #12349 from miri64/gnrc_sixlowpan_frag_rb/enh/new-functions
gnrc_sixlowpan_frag_rb: add new functions for SFR
This commit is contained in:
commit
267dd0b73d
@ -114,6 +114,45 @@ gnrc_sixlowpan_frag_rb_t *gnrc_sixlowpan_frag_rb_add(gnrc_netif_hdr_t *netif_hdr
|
||||
gnrc_pktsnip_t *frag,
|
||||
size_t offset, unsigned page);
|
||||
|
||||
/**
|
||||
* @brief Checks if a reassembly buffer entry with a given link-layer address
|
||||
* pair and tag exists
|
||||
*
|
||||
* @pre `netif_hdr != NULL`
|
||||
*
|
||||
* @param[in] netif_hdr An interface header to provide the (source, destination)
|
||||
* link-layer address pair. Must not be NULL.
|
||||
* @param[in] tag Tag to search for.
|
||||
*
|
||||
* @note datagram_size is not a search parameter as the primary use case
|
||||
* for this function is [Selective Fragment Recovery]
|
||||
* (https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-05)
|
||||
* where this information only exists in the first fragment.
|
||||
*
|
||||
* @return true, if an entry with the given tuple exist.
|
||||
* @return false, if no entry with the given tuple exist.
|
||||
*/
|
||||
bool gnrc_sixlowpan_frag_rb_exists(const gnrc_netif_hdr_t *netif_hdr,
|
||||
uint16_t tag);
|
||||
|
||||
/**
|
||||
* @brief Removes a reassembly buffer entry with a given link-layer address
|
||||
* pair and tag
|
||||
*
|
||||
* @pre `netif_hdr != NULL`
|
||||
*
|
||||
* @param[in] netif_hdr An interface header to provide the (source, destination)
|
||||
* link-layer address pair. Must not be NULL.
|
||||
* @param[in] tag Tag to search for.
|
||||
*
|
||||
* @note datagram_size is not a search parameter as the primary use case
|
||||
* for this function is [Selective Fragment Recovery]
|
||||
* (https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-05)
|
||||
* where this information only exists in the first fragment.
|
||||
*/
|
||||
void gnrc_sixlowpan_frag_rb_rm_by_datagram(const gnrc_netif_hdr_t *netif_hdr,
|
||||
uint16_t tag);
|
||||
|
||||
/**
|
||||
* @brief Checks if a reassembly buffer entry is unset
|
||||
*
|
||||
|
@ -68,11 +68,14 @@ static gnrc_sixlowpan_frag_rb_int_t *_rbuf_int_get_free(void);
|
||||
/* update interval buffer of entry */
|
||||
static bool _rbuf_update_ints(gnrc_sixlowpan_frag_rb_base_t *entry,
|
||||
uint16_t offset, size_t frag_size);
|
||||
/* gets an entry identified by its tupel */
|
||||
/* gets an entry identified by its tuple */
|
||||
static int _rbuf_get(const void *src, size_t src_len,
|
||||
const void *dst, size_t dst_len,
|
||||
size_t size, uint16_t tag,
|
||||
unsigned page);
|
||||
/* gets an entry only by link-layer information and tag */
|
||||
static gnrc_sixlowpan_frag_rb_t *_rbuf_get_by_tag(const gnrc_netif_hdr_t *netif_hdr,
|
||||
uint16_t tag);
|
||||
/* internal add to repeat add when fragments overlapped */
|
||||
static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
||||
size_t offset, unsigned page);
|
||||
@ -138,6 +141,47 @@ gnrc_sixlowpan_frag_rb_t *gnrc_sixlowpan_frag_rb_add(gnrc_netif_hdr_t *netif_hdr
|
||||
return (res < 0) ? NULL : &rbuf[res];
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool gnrc_sixlowpan_frag_rb_exists(const gnrc_netif_hdr_t *netif_hdr,
|
||||
uint16_t tag)
|
||||
{
|
||||
return (_rbuf_get_by_tag(netif_hdr, tag) != NULL);
|
||||
}
|
||||
|
||||
void gnrc_sixlowpan_frag_rb_rm_by_datagram(const gnrc_netif_hdr_t *netif_hdr,
|
||||
uint16_t tag)
|
||||
{
|
||||
gnrc_sixlowpan_frag_rb_t *e = _rbuf_get_by_tag(netif_hdr, tag);
|
||||
|
||||
if (e != NULL) {
|
||||
gnrc_sixlowpan_frag_rb_remove(e);
|
||||
}
|
||||
}
|
||||
|
||||
static gnrc_sixlowpan_frag_rb_t *_rbuf_get_by_tag(const gnrc_netif_hdr_t *netif_hdr,
|
||||
uint16_t tag)
|
||||
{
|
||||
assert(netif_hdr != NULL);
|
||||
const uint8_t *src = gnrc_netif_hdr_get_src_addr(netif_hdr);
|
||||
const uint8_t *dst = gnrc_netif_hdr_get_dst_addr(netif_hdr);
|
||||
const uint8_t src_len = netif_hdr->src_l2addr_len;
|
||||
const uint8_t dst_len = netif_hdr->dst_l2addr_len;
|
||||
|
||||
for (unsigned i = 0; i < GNRC_SIXLOWPAN_FRAG_RBUF_SIZE; i++) {
|
||||
gnrc_sixlowpan_frag_rb_t *e = &rbuf[i];
|
||||
|
||||
if ((e->pkt != NULL) && (e->super.tag == tag) &&
|
||||
(e->super.src_len == src_len) &&
|
||||
(e->super.dst_len == dst_len) &&
|
||||
(memcmp(e->super.src, src, src_len) == 0) &&
|
||||
(memcmp(e->super.dst, dst, dst_len) == 0)) {
|
||||
return e;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
static bool _valid_offset(gnrc_pktsnip_t *pkt, size_t offset)
|
||||
{
|
||||
|
@ -417,7 +417,7 @@ static void test_rbuf_add__full_rbuf(void)
|
||||
static void test_rbuf_add__too_big_fragment(void)
|
||||
{
|
||||
gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, _fragment1,
|
||||
/* something definetely bigger than
|
||||
/* something definitely bigger than
|
||||
* the datagram size noted in
|
||||
* _fragment1, can't just be + 1,
|
||||
* since fragment dispatch and other
|
||||
@ -527,6 +527,22 @@ static void test_rbuf_add__overlap_rhs(void)
|
||||
_check_pktbuf(NULL);
|
||||
}
|
||||
|
||||
static void test_rbuf_exists(void)
|
||||
{
|
||||
TEST_ASSERT(!gnrc_sixlowpan_frag_rb_exists(&_test_netif_hdr.hdr, TEST_TAG));
|
||||
/* add a fragment */
|
||||
test_rbuf_add__success_first_fragment();
|
||||
TEST_ASSERT(gnrc_sixlowpan_frag_rb_exists(&_test_netif_hdr.hdr, TEST_TAG));
|
||||
}
|
||||
|
||||
static void test_rbuf_rm_by_dg(void)
|
||||
{
|
||||
/* add a fragment */
|
||||
test_rbuf_add__success_first_fragment();
|
||||
gnrc_sixlowpan_frag_rb_rm_by_datagram(&_test_netif_hdr.hdr, TEST_TAG);
|
||||
TEST_ASSERT(!gnrc_sixlowpan_frag_rb_exists(&_test_netif_hdr.hdr, TEST_TAG));
|
||||
}
|
||||
|
||||
static void test_rbuf_rm(void)
|
||||
{
|
||||
const gnrc_sixlowpan_frag_rb_t *entry;
|
||||
@ -596,6 +612,8 @@ static void run_unittests(void)
|
||||
new_TestFixture(test_rbuf_add__too_big_fragment),
|
||||
new_TestFixture(test_rbuf_add__overlap_lhs),
|
||||
new_TestFixture(test_rbuf_add__overlap_rhs),
|
||||
new_TestFixture(test_rbuf_exists),
|
||||
new_TestFixture(test_rbuf_rm_by_dg),
|
||||
new_TestFixture(test_rbuf_rm),
|
||||
new_TestFixture(test_rbuf_gc__manually),
|
||||
new_TestFixture(test_rbuf_gc__timed),
|
||||
|
Loading…
Reference in New Issue
Block a user