diff --git a/sys/include/net/gnrc/sixlowpan/frag.h b/sys/include/net/gnrc/sixlowpan/frag.h index 606cb84dbe..fc1611b456 100644 --- a/sys/include/net/gnrc/sixlowpan/frag.h +++ b/sys/include/net/gnrc/sixlowpan/frag.h @@ -75,24 +75,19 @@ typedef struct gnrc_sixlowpan_rbuf_int { } gnrc_sixlowpan_rbuf_int_t; /** - * @brief An entry in the 6LoWPAN reassembly buffer. - * - * A recipient of a fragment SHALL use + * @brief Base class for both reassembly buffer and virtual reassembly buffer * * 1. the source address, * 2. the destination address, - * 3. the datagram size (gnrc_pktsnip_t::size of rbuf_t::pkt), and + * 3. the datagram size, and * 4. the datagram tag * * to identify all fragments that belong to the given datagram. * * @see [RFC 4944, section 5.3](https://tools.ietf.org/html/rfc4944#section-5.3) + * @see https://tools.ietf.org/html/draft-ietf-lwig-6lowpan-virtual-reassembly-01 */ typedef struct { - /** - * @brief The reassembled packet in the packet buffer - */ - gnrc_pktsnip_t *pkt; gnrc_sixlowpan_rbuf_int_t *ints; /**< intervals of already received fragments */ uint8_t src[IEEE802154_LONG_ADDRESS_LEN]; /**< source address */ uint8_t dst[IEEE802154_LONG_ADDRESS_LEN]; /**< destination address */ @@ -105,6 +100,20 @@ typedef struct { * @brief The number of bytes currently received of the complete datagram */ uint16_t current_size; +} gnrc_sixlowpan_rbuf_base_t; + +/** + * @brief An entry in the 6LoWPAN reassembly buffer. + * + * A recipient of a fragment SHALL use + * + */ +typedef struct { + gnrc_sixlowpan_rbuf_base_t super; /**< base class */ + /** + * @brief The reassembled packet in the packet buffer + */ + gnrc_pktsnip_t *pkt; } gnrc_sixlowpan_rbuf_t; /** diff --git a/sys/net/gnrc/network_layer/sixlowpan/frag/gnrc_sixlowpan_frag.c b/sys/net/gnrc/network_layer/sixlowpan/frag/gnrc_sixlowpan_frag.c index cfa96ec2dc..c5dcb77928 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/frag/gnrc_sixlowpan_frag.c +++ b/sys/net/gnrc/network_layer/sixlowpan/frag/gnrc_sixlowpan_frag.c @@ -345,11 +345,11 @@ void gnrc_sixlowpan_frag_rbuf_dispatch_when_complete(gnrc_sixlowpan_rbuf_t *rbuf { assert(rbuf); assert(netif_hdr); - if (rbuf->current_size == rbuf->pkt->size) { - gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(rbuf->src, - rbuf->src_len, - rbuf->dst, - rbuf->dst_len); + if (rbuf->super.current_size == rbuf->pkt->size) { + gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(rbuf->super.src, + rbuf->super.src_len, + rbuf->super.dst, + rbuf->super.dst_len); if (netif == NULL) { DEBUG("6lo rbuf: error allocating netif header\n"); diff --git a/sys/net/gnrc/network_layer/sixlowpan/frag/rbuf.c b/sys/net/gnrc/network_layer/sixlowpan/frag/rbuf.c index 47588e2c00..635a88555b 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/frag/rbuf.c +++ b/sys/net/gnrc/network_layer/sixlowpan/frag/rbuf.c @@ -112,7 +112,7 @@ static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt, return RBUF_ADD_ERROR; } - ptr = entry->ints; + ptr = entry->super.ints; /* dispatches in the first fragment are ignored */ if (offset == 0) { @@ -159,7 +159,7 @@ static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt, if (_rbuf_update_ints(entry, offset, frag_size)) { DEBUG("6lo rbuf: add fragment data\n"); - entry->current_size += (uint16_t)frag_size; + entry->super.current_size += (uint16_t)frag_size; if (offset == 0) { #ifdef MODULE_GNRC_SIXLOWPAN_IPHC if (sixlowpan_iphc_is(data)) { @@ -209,13 +209,13 @@ static gnrc_sixlowpan_rbuf_int_t *_rbuf_int_get_free(void) void rbuf_rm(gnrc_sixlowpan_rbuf_t *entry) { - while (entry->ints != NULL) { - gnrc_sixlowpan_rbuf_int_t *next = entry->ints->next; + while (entry->super.ints != NULL) { + gnrc_sixlowpan_rbuf_int_t *next = entry->super.ints->next; - entry->ints->start = 0; - entry->ints->end = 0; - entry->ints->next = NULL; - entry->ints = next; + entry->super.ints->start = 0; + entry->super.ints->end = 0; + entry->super.ints->next = NULL; + entry->super.ints = next; } entry->pkt = NULL; @@ -238,15 +238,15 @@ static bool _rbuf_update_ints(gnrc_sixlowpan_rbuf_t *entry, uint16_t offset, new->end = end; DEBUG("6lo rfrag: add interval (%" PRIu16 ", %" PRIu16 ") to entry (%s, ", - new->start, new->end, gnrc_netif_addr_to_str(entry->src, - entry->src_len, + new->start, new->end, gnrc_netif_addr_to_str(entry->super.src, + entry->super.src_len, l2addr_str)); - DEBUG("%s, %u, %u)\n", gnrc_netif_addr_to_str(entry->dst, - entry->dst_len, + DEBUG("%s, %u, %u)\n", gnrc_netif_addr_to_str(entry->super.dst, + entry->super.dst_len, l2addr_str), - (unsigned)entry->pkt->size, entry->tag); + (unsigned)entry->pkt->size, entry->super.tag); - LL_PREPEND(entry->ints, new); + LL_PREPEND(entry->super.ints, new); return true; } @@ -259,16 +259,16 @@ void rbuf_gc(void) for (i = 0; i < RBUF_SIZE; i++) { /* since pkt occupies pktbuf, aggressivly collect garbage */ if ((rbuf[i].pkt != NULL) && - ((now_usec - rbuf[i].arrival) > RBUF_TIMEOUT)) { + ((now_usec - rbuf[i].super.arrival) > RBUF_TIMEOUT)) { DEBUG("6lo rfrag: entry (%s, ", - gnrc_netif_addr_to_str(rbuf[i].src, - rbuf[i].src_len, + gnrc_netif_addr_to_str(rbuf[i].super.src, + rbuf[i].super.src_len, l2addr_str)); DEBUG("%s, %u, %u) timed out\n", - gnrc_netif_addr_to_str(rbuf[i].dst, - rbuf[i].dst_len, + gnrc_netif_addr_to_str(rbuf[i].super.dst, + rbuf[i].super.dst_len, l2addr_str), - (unsigned)rbuf[i].pkt->size, rbuf[i].tag); + (unsigned)rbuf[i].pkt->size, rbuf[i].super.tag); gnrc_pktbuf_release(rbuf[i].pkt); rbuf_rm(&(rbuf[i])); @@ -292,20 +292,20 @@ static gnrc_sixlowpan_rbuf_t *_rbuf_get(const void *src, size_t src_len, for (unsigned int i = 0; i < RBUF_SIZE; i++) { /* check first if entry already available */ if ((rbuf[i].pkt != NULL) && (rbuf[i].pkt->size == size) && - (rbuf[i].tag == tag) && (rbuf[i].src_len == src_len) && - (rbuf[i].dst_len == dst_len) && - (memcmp(rbuf[i].src, src, src_len) == 0) && - (memcmp(rbuf[i].dst, dst, dst_len) == 0)) { + (rbuf[i].super.tag == tag) && (rbuf[i].super.src_len == src_len) && + (rbuf[i].super.dst_len == dst_len) && + (memcmp(rbuf[i].super.src, src, src_len) == 0) && + (memcmp(rbuf[i].super.dst, dst, dst_len) == 0)) { DEBUG("6lo rfrag: entry %p (%s, ", (void *)(&rbuf[i]), - gnrc_netif_addr_to_str(rbuf[i].src, - rbuf[i].src_len, + gnrc_netif_addr_to_str(rbuf[i].super.src, + rbuf[i].super.src_len, l2addr_str)); DEBUG("%s, %u, %u) found\n", - gnrc_netif_addr_to_str(rbuf[i].dst, - rbuf[i].dst_len, + gnrc_netif_addr_to_str(rbuf[i].super.dst, + rbuf[i].super.dst_len, l2addr_str), - (unsigned)rbuf[i].pkt->size, rbuf[i].tag); - rbuf[i].arrival = now_usec; + (unsigned)rbuf[i].pkt->size, rbuf[i].super.tag); + rbuf[i].super.arrival = now_usec; _set_rbuf_timeout(); return &(rbuf[i]); } @@ -318,7 +318,7 @@ static gnrc_sixlowpan_rbuf_t *_rbuf_get(const void *src, size_t src_len, /* remember oldest slot */ /* note that xtimer_now will overflow in ~1.2 hours */ if ((oldest == NULL) || - (oldest->arrival - rbuf[i].arrival < UINT32_MAX / 2)) { + (oldest->super.arrival - rbuf[i].super.arrival < UINT32_MAX / 2)) { oldest = &(rbuf[i]); } } @@ -330,7 +330,7 @@ static gnrc_sixlowpan_rbuf_t *_rbuf_get(const void *src, size_t src_len, * oldest could have been picked as res) */ assert(!rbuf_entry_empty(oldest)); if (GNRC_SIXLOWPAN_FRAG_RBUF_AGGRESSIVE_OVERRIDE || - ((now_usec - oldest->arrival) > + ((now_usec - oldest->super.arrival) > GNRC_SIXLOWPAN_FRAG_RBUF_TIMEOUT_US)) { DEBUG("6lo rfrag: reassembly buffer full, remove oldest entry\n"); gnrc_pktbuf_release(oldest->pkt); @@ -363,21 +363,21 @@ static gnrc_sixlowpan_rbuf_t *_rbuf_get(const void *src, size_t src_len, *((uint64_t *)res->pkt->data) = 0; /* clean first few bytes for later * look-ups */ - res->arrival = now_usec; - memcpy(res->src, src, src_len); - memcpy(res->dst, dst, dst_len); - res->src_len = src_len; - res->dst_len = dst_len; - res->tag = tag; - res->current_size = 0; + res->super.arrival = now_usec; + memcpy(res->super.src, src, src_len); + memcpy(res->super.dst, dst, dst_len); + res->super.src_len = src_len; + res->super.dst_len = dst_len; + res->super.tag = tag; + res->super.current_size = 0; DEBUG("6lo rfrag: entry %p (%s, ", (void *)res, - gnrc_netif_addr_to_str(res->src, res->src_len, + gnrc_netif_addr_to_str(res->super.src, res->super.src_len, l2addr_str)); DEBUG("%s, %u, %u) created\n", - gnrc_netif_addr_to_str(res->dst, res->dst_len, + gnrc_netif_addr_to_str(res->super.dst, res->super.dst_len, l2addr_str), (unsigned)res->pkt->size, - res->tag); + res->super.tag); _set_rbuf_timeout(); diff --git a/sys/net/gnrc/network_layer/sixlowpan/iphc/gnrc_sixlowpan_iphc.c b/sys/net/gnrc/network_layer/sixlowpan/iphc/gnrc_sixlowpan_iphc.c index dd2a052b75..f84d6bc83f 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/iphc/gnrc_sixlowpan_iphc.c +++ b/sys/net/gnrc/network_layer/sixlowpan/iphc/gnrc_sixlowpan_iphc.c @@ -577,7 +577,7 @@ void gnrc_sixlowpan_iphc_recv(gnrc_pktsnip_t *sixlo, void *rbuf_ptr, ((uint8_t *)sixlo->data) + payload_offset, sixlo->size - payload_offset); if (rbuf != NULL) { - rbuf->current_size += (uncomp_hdr_len - payload_offset); + rbuf->super.current_size += (uncomp_hdr_len - payload_offset); gnrc_sixlowpan_frag_rbuf_dispatch_when_complete(rbuf, netif_hdr); } else { diff --git a/tests/gnrc_sixlowpan_frag/main.c b/tests/gnrc_sixlowpan_frag/main.c index 84b35c3476..59e8b39b81 100644 --- a/tests/gnrc_sixlowpan_frag/main.c +++ b/tests/gnrc_sixlowpan_frag/main.c @@ -223,20 +223,22 @@ static void _test_entry(const gnrc_sixlowpan_rbuf_t *entry, TEST_ASSERT_NOT_NULL(entry); TEST_ASSERT_NOT_NULL(entry->pkt); TEST_ASSERT_EQUAL_INT(TEST_DATAGRAM_SIZE, entry->pkt->size); - TEST_ASSERT_EQUAL_INT(sizeof(_test_netif_hdr_src), entry->src_len); - TEST_ASSERT_MESSAGE(memcmp(entry->src, _test_netif_hdr_src, - entry->src_len) == 0, - "entry->src != TEST_NETIF_HDR_SRC"); - TEST_ASSERT_EQUAL_INT(sizeof(_test_netif_hdr_dst), entry->dst_len); - TEST_ASSERT_MESSAGE(memcmp(entry->dst, _test_netif_hdr_dst, - entry->dst_len) == 0, - "entry->dst != TEST_NETIF_HDR_DST"); - TEST_ASSERT_EQUAL_INT(TEST_TAG, entry->tag); - TEST_ASSERT_EQUAL_INT(exp_current_size, entry->current_size); - TEST_ASSERT_NOT_NULL(entry->ints); - TEST_ASSERT_NULL(entry->ints->next); - TEST_ASSERT_EQUAL_INT(exp_int_start, entry->ints->start); - TEST_ASSERT_EQUAL_INT(exp_int_end, entry->ints->end); + TEST_ASSERT_EQUAL_INT(sizeof(_test_netif_hdr_src), + entry->super.src_len); + TEST_ASSERT_MESSAGE(memcmp(entry->super.src, _test_netif_hdr_src, + entry->super.src_len) == 0, + "entry->super.src != TEST_NETIF_HDR_SRC"); + TEST_ASSERT_EQUAL_INT(sizeof(_test_netif_hdr_dst), + entry->super.dst_len); + TEST_ASSERT_MESSAGE(memcmp(entry->super.dst, _test_netif_hdr_dst, + entry->super.dst_len) == 0, + "entry->super.dst != TEST_NETIF_HDR_DST"); + TEST_ASSERT_EQUAL_INT(TEST_TAG, entry->super.tag); + TEST_ASSERT_EQUAL_INT(exp_current_size, entry->super.current_size); + TEST_ASSERT_NOT_NULL(entry->super.ints); + TEST_ASSERT_NULL(entry->super.ints->next); + TEST_ASSERT_EQUAL_INT(exp_int_start, entry->super.ints->start); + TEST_ASSERT_EQUAL_INT(exp_int_end, entry->super.ints->end); } static void _check_pktbuf(const gnrc_sixlowpan_rbuf_t *entry) @@ -513,7 +515,7 @@ static void test_rbuf_gc__manually(void) entry = (gnrc_sixlowpan_rbuf_t *)_first_non_empty_rbuf(); TEST_ASSERT_NOT_NULL(entry); /* set arrival RBUF_TIMEOUT into the past */ - entry->arrival -= RBUF_TIMEOUT; + entry->super.arrival -= RBUF_TIMEOUT; rbuf_gc(); /* reassembly buffer is now empty */ TEST_ASSERT_NULL(_first_non_empty_rbuf());