Merge pull request #12347 from miri64/gnrc_sixlowpan_frag_rb/enh/externalize-dispatch
gnrc_sixlowpan_frag_rb: externalize dispatch_when_complete
This commit is contained in:
commit
970b5935a6
@ -102,13 +102,17 @@ typedef struct {
|
|||||||
* @param[in] netif_hdr The interface header of the fragment, with
|
* @param[in] netif_hdr The interface header of the fragment, with
|
||||||
* gnrc_netif_hdr_t::if_pid and its source and
|
* gnrc_netif_hdr_t::if_pid and its source and
|
||||||
* destination address set.
|
* destination address set.
|
||||||
* @param[in] frag The fragment to add.
|
* @param[in] frag The fragment to add. Will be released by the
|
||||||
|
* function.
|
||||||
* @param[in] offset The fragment's offset.
|
* @param[in] offset The fragment's offset.
|
||||||
* @param[in] page Current 6Lo dispatch parsing page.
|
* @param[in] page Current 6Lo dispatch parsing page.
|
||||||
|
*
|
||||||
|
* @return The reassembly buffer entry the fragment was added to on success.
|
||||||
|
* @return NULL on error.
|
||||||
*/
|
*/
|
||||||
void gnrc_sixlowpan_frag_rb_add(gnrc_netif_hdr_t *netif_hdr,
|
gnrc_sixlowpan_frag_rb_t *gnrc_sixlowpan_frag_rb_add(gnrc_netif_hdr_t *netif_hdr,
|
||||||
gnrc_pktsnip_t *frag, size_t offset,
|
gnrc_pktsnip_t *frag,
|
||||||
unsigned page);
|
size_t offset, unsigned page);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks if a reassembly buffer entry is unset
|
* @brief Checks if a reassembly buffer entry is unset
|
||||||
@ -155,24 +159,6 @@ void gnrc_sixlowpan_frag_rb_base_rm(gnrc_sixlowpan_frag_rb_base_t *entry);
|
|||||||
*/
|
*/
|
||||||
void gnrc_sixlowpan_frag_rb_gc(void);
|
void gnrc_sixlowpan_frag_rb_gc(void);
|
||||||
|
|
||||||
#if defined(MODULE_GNRC_SIXLOWPAN_FRAG_RB) || defined(DOXYGEN)
|
|
||||||
/**
|
|
||||||
* @brief Unsets a reassembly buffer entry (but does not free
|
|
||||||
* rbuf_t::super::pkt)
|
|
||||||
*
|
|
||||||
* @pre `rbuf != NULL`
|
|
||||||
*
|
|
||||||
* This functions sets rbuf_t::super::pkt to NULL and removes all rbuf::ints.
|
|
||||||
*
|
|
||||||
* @param[in] rbuf A reassembly buffer entry. Must not be NULL.
|
|
||||||
*/
|
|
||||||
static inline void gnrc_sixlowpan_frag_rb_remove(gnrc_sixlowpan_frag_rb_t *rbuf)
|
|
||||||
{
|
|
||||||
assert(rbuf != NULL);
|
|
||||||
gnrc_sixlowpan_frag_rb_base_rm(&rbuf->super);
|
|
||||||
rbuf->pkt = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Checks if a reassembly buffer entry is complete and dispatches it
|
* @brief Checks if a reassembly buffer entry is complete and dispatches it
|
||||||
* to the next layer if that is the case
|
* to the next layer if that is the case
|
||||||
@ -184,15 +170,42 @@ static inline void gnrc_sixlowpan_frag_rb_remove(gnrc_sixlowpan_frag_rb_t *rbuf)
|
|||||||
* @param[in] netif Original @ref gnrc_netif_hdr_t of the last received frame.
|
* @param[in] netif Original @ref gnrc_netif_hdr_t of the last received frame.
|
||||||
* Used to construct the @ref gnrc_netif_hdr_t of the completed
|
* Used to construct the @ref gnrc_netif_hdr_t of the completed
|
||||||
* datagram. Must not be NULL.
|
* datagram. Must not be NULL.
|
||||||
|
*
|
||||||
|
* @return >0, when the datagram in @p rbuf was complete and dispatched.
|
||||||
|
* @return 0, when the datagram in @p rbuf is not complete.
|
||||||
|
* @return -1, if the the reassembled datagram was not dispatched. @p rbuf is
|
||||||
|
* destroyed either way.
|
||||||
*/
|
*/
|
||||||
void gnrc_sixlowpan_frag_rb_dispatch_when_complete(gnrc_sixlowpan_frag_rb_t *rbuf,
|
int gnrc_sixlowpan_frag_rb_dispatch_when_complete(gnrc_sixlowpan_frag_rb_t *rbuf,
|
||||||
gnrc_netif_hdr_t *netif);
|
gnrc_netif_hdr_t *netif);
|
||||||
|
|
||||||
|
#if defined(MODULE_GNRC_SIXLOWPAN_FRAG_RB) || defined(DOXYGEN)
|
||||||
|
/**
|
||||||
|
* @brief Unsets a reassembly buffer entry (but does not free
|
||||||
|
* rbuf_t::super::pkt)
|
||||||
|
*
|
||||||
|
* @pre `rbuf != NULL`
|
||||||
|
*
|
||||||
|
* This functions sets rbuf_t::super::pkt to NULL and removes all rbuf::ints.
|
||||||
|
*
|
||||||
|
* @note Does nothing if module `gnrc_sixlowpan_frag_rb` is not included.
|
||||||
|
*
|
||||||
|
* @param[in] rbuf A reassembly buffer entry. Must not be NULL.
|
||||||
|
*/
|
||||||
|
static inline void gnrc_sixlowpan_frag_rb_remove(gnrc_sixlowpan_frag_rb_t *rbuf)
|
||||||
|
{
|
||||||
|
assert(rbuf != NULL);
|
||||||
|
gnrc_sixlowpan_frag_rb_base_rm(&rbuf->super);
|
||||||
|
rbuf->pkt = NULL;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
/* NOPs to be used with gnrc_sixlowpan_iphc if gnrc_sixlowpan_frag_rb is not
|
/* NOPs to be used with gnrc_sixlowpan_iphc if gnrc_sixlowpan_frag_rb is not
|
||||||
* compiled in */
|
* compiled in */
|
||||||
#define gnrc_sixlowpan_frag_rb_remove(rbuf) (void)(rbuf)
|
static inline void gnrc_sixlowpan_frag_rb_remove(gnrc_sixlowpan_frag_rb_t *rbuf)
|
||||||
#define gnrc_sixlowpan_frag_rb_dispatch_when_complete(rbuf, netif) \
|
{
|
||||||
(void)(rbuf); (void)(netif)
|
(void)rbuf;
|
||||||
|
return;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@ -339,8 +339,10 @@ error:
|
|||||||
|
|
||||||
void gnrc_sixlowpan_frag_recv(gnrc_pktsnip_t *pkt, void *ctx, unsigned page)
|
void gnrc_sixlowpan_frag_recv(gnrc_pktsnip_t *pkt, void *ctx, unsigned page)
|
||||||
{
|
{
|
||||||
gnrc_netif_hdr_t *hdr = pkt->next->data;
|
gnrc_pktsnip_t *netif_hdr = pkt->next;
|
||||||
|
gnrc_netif_hdr_t *hdr = netif_hdr->data;
|
||||||
sixlowpan_frag_t *frag = pkt->data;
|
sixlowpan_frag_t *frag = pkt->data;
|
||||||
|
gnrc_sixlowpan_frag_rb_t *rbe;
|
||||||
uint16_t offset = 0;
|
uint16_t offset = 0;
|
||||||
|
|
||||||
(void)ctx;
|
(void)ctx;
|
||||||
@ -359,7 +361,14 @@ void gnrc_sixlowpan_frag_recv(gnrc_pktsnip_t *pkt, void *ctx, unsigned page)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gnrc_sixlowpan_frag_rb_add(hdr, pkt, offset, page);
|
gnrc_pktbuf_hold(netif_hdr, 1); /* hold netif header to use it with
|
||||||
|
* dispatch_when_complete()
|
||||||
|
* (rb_add() releases `pkt`) */
|
||||||
|
rbe = gnrc_sixlowpan_frag_rb_add(hdr, pkt, offset, page);
|
||||||
|
if (rbe != NULL) {
|
||||||
|
gnrc_sixlowpan_frag_rb_dispatch_when_complete(rbe, hdr);
|
||||||
|
}
|
||||||
|
gnrc_pktbuf_release(netif_hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t gnrc_sixlowpan_frag_next_tag(void)
|
uint16_t gnrc_sixlowpan_frag_next_tag(void)
|
||||||
|
|||||||
@ -69,7 +69,7 @@ static gnrc_sixlowpan_frag_rb_int_t *_rbuf_int_get_free(void);
|
|||||||
static bool _rbuf_update_ints(gnrc_sixlowpan_frag_rb_base_t *entry,
|
static bool _rbuf_update_ints(gnrc_sixlowpan_frag_rb_base_t *entry,
|
||||||
uint16_t offset, size_t frag_size);
|
uint16_t offset, size_t frag_size);
|
||||||
/* gets an entry identified by its tupel */
|
/* gets an entry identified by its tupel */
|
||||||
static gnrc_sixlowpan_frag_rb_t *_rbuf_get(const void *src, size_t src_len,
|
static int _rbuf_get(const void *src, size_t src_len,
|
||||||
const void *dst, size_t dst_len,
|
const void *dst, size_t dst_len,
|
||||||
size_t size, uint16_t tag,
|
size_t size, uint16_t tag,
|
||||||
unsigned page);
|
unsigned page);
|
||||||
@ -79,10 +79,10 @@ static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
|||||||
|
|
||||||
/* status codes for _rbuf_add() */
|
/* status codes for _rbuf_add() */
|
||||||
enum {
|
enum {
|
||||||
RBUF_ADD_SUCCESS,
|
RBUF_ADD_SUCCESS = 0,
|
||||||
RBUF_ADD_ERROR,
|
RBUF_ADD_ERROR = -1,
|
||||||
RBUF_ADD_REPEAT,
|
RBUF_ADD_REPEAT = -2,
|
||||||
RBUF_ADD_DUPLICATE,
|
RBUF_ADD_DUPLICATE = -3,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS
|
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS
|
||||||
@ -120,13 +120,22 @@ static int _check_fragments(gnrc_sixlowpan_frag_rb_base_t *entry,
|
|||||||
return RBUF_ADD_SUCCESS;
|
return RBUF_ADD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gnrc_sixlowpan_frag_rb_add(gnrc_netif_hdr_t *netif_hdr,
|
gnrc_sixlowpan_frag_rb_t *gnrc_sixlowpan_frag_rb_add(gnrc_netif_hdr_t *netif_hdr,
|
||||||
gnrc_pktsnip_t *pkt, size_t offset,
|
gnrc_pktsnip_t *pkt,
|
||||||
unsigned page)
|
size_t offset, unsigned page)
|
||||||
{
|
{
|
||||||
if (_rbuf_add(netif_hdr, pkt, offset, page) == RBUF_ADD_REPEAT) {
|
int res;
|
||||||
_rbuf_add(netif_hdr, pkt, offset, page);
|
if ((res = _rbuf_add(netif_hdr, pkt, offset, page)) == RBUF_ADD_REPEAT) {
|
||||||
|
/* there was an overlap with existing fragments detected when trying to
|
||||||
|
* add the new fragment.
|
||||||
|
* https://tools.ietf.org/html/rfc4944#section-5.3 states "A fresh
|
||||||
|
* reassembly may be commenced with the most recently received link
|
||||||
|
* fragment.", so let's do that. Since the reassembly buffer entry was
|
||||||
|
* deleted another overlap should not be detected (so _rbuf_add() won't
|
||||||
|
* return RBUF_ADD_REPEAT again) */
|
||||||
|
res = _rbuf_add(netif_hdr, pkt, offset, page);
|
||||||
}
|
}
|
||||||
|
return (res < 0) ? NULL : &rbuf[res];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
@ -172,6 +181,7 @@ static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
|||||||
gnrc_sixlowpan_frag_rb_t *entry;
|
gnrc_sixlowpan_frag_rb_t *entry;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
size_t frag_size;
|
size_t frag_size;
|
||||||
|
int res;
|
||||||
uint16_t datagram_size;
|
uint16_t datagram_size;
|
||||||
uint16_t datagram_tag;
|
uint16_t datagram_tag;
|
||||||
|
|
||||||
@ -183,16 +193,16 @@ static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
|||||||
datagram_tag = sixlowpan_frag_datagram_tag(pkt->data);
|
datagram_tag = sixlowpan_frag_datagram_tag(pkt->data);
|
||||||
|
|
||||||
gnrc_sixlowpan_frag_rb_gc();
|
gnrc_sixlowpan_frag_rb_gc();
|
||||||
entry = _rbuf_get(gnrc_netif_hdr_get_src_addr(netif_hdr), netif_hdr->src_l2addr_len,
|
res = _rbuf_get(gnrc_netif_hdr_get_src_addr(netif_hdr), netif_hdr->src_l2addr_len,
|
||||||
gnrc_netif_hdr_get_dst_addr(netif_hdr), netif_hdr->dst_l2addr_len,
|
gnrc_netif_hdr_get_dst_addr(netif_hdr), netif_hdr->dst_l2addr_len,
|
||||||
datagram_size, datagram_tag, page);
|
datagram_size, datagram_tag, page);
|
||||||
|
|
||||||
if (entry == NULL) {
|
if (res < 0) {
|
||||||
DEBUG("6lo rbuf: reassembly buffer full.\n");
|
DEBUG("6lo rbuf: reassembly buffer full.\n");
|
||||||
gnrc_pktbuf_release(pkt);
|
gnrc_pktbuf_release(pkt);
|
||||||
return RBUF_ADD_ERROR;
|
return RBUF_ADD_ERROR;
|
||||||
}
|
}
|
||||||
|
entry = &rbuf[res];
|
||||||
if ((offset + frag_size) > entry->super.datagram_size) {
|
if ((offset + frag_size) > entry->super.datagram_size) {
|
||||||
DEBUG("6lo rfrag: fragment too big for resulting datagram, discarding datagram\n");
|
DEBUG("6lo rfrag: fragment too big for resulting datagram, discarding datagram\n");
|
||||||
gnrc_pktbuf_release(entry->pkt);
|
gnrc_pktbuf_release(entry->pkt);
|
||||||
@ -209,7 +219,7 @@ static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
|||||||
return RBUF_ADD_REPEAT;
|
return RBUF_ADD_REPEAT;
|
||||||
case RBUF_ADD_DUPLICATE:
|
case RBUF_ADD_DUPLICATE:
|
||||||
gnrc_pktbuf_release(pkt);
|
gnrc_pktbuf_release(pkt);
|
||||||
return RBUF_ADD_SUCCESS;
|
return res;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -220,29 +230,41 @@ static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
|||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
|
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
|
||||||
if (sixlowpan_iphc_is(data)) {
|
if (sixlowpan_iphc_is(data)) {
|
||||||
|
DEBUG("6lo rbuf: detected IPHC header.\n");
|
||||||
gnrc_pktsnip_t *frag_hdr = gnrc_pktbuf_mark(pkt,
|
gnrc_pktsnip_t *frag_hdr = gnrc_pktbuf_mark(pkt,
|
||||||
sizeof(sixlowpan_frag_t), GNRC_NETTYPE_SIXLOWPAN);
|
sizeof(sixlowpan_frag_t), GNRC_NETTYPE_SIXLOWPAN);
|
||||||
if (frag_hdr == NULL) {
|
if (frag_hdr == NULL) {
|
||||||
|
DEBUG("6lo rbuf: unable to mark fragment header. "
|
||||||
|
"aborting reassembly.\n");
|
||||||
gnrc_pktbuf_release(entry->pkt);
|
gnrc_pktbuf_release(entry->pkt);
|
||||||
gnrc_pktbuf_release(pkt);
|
gnrc_pktbuf_release(pkt);
|
||||||
gnrc_sixlowpan_frag_rb_remove(entry);
|
gnrc_sixlowpan_frag_rb_remove(entry);
|
||||||
return RBUF_ADD_ERROR;
|
return RBUF_ADD_ERROR;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
DEBUG("6lo rbuf: handing over to IPHC reception.\n");
|
||||||
|
/* `pkt` released in IPHC */
|
||||||
gnrc_sixlowpan_iphc_recv(pkt, entry, 0);
|
gnrc_sixlowpan_iphc_recv(pkt, entry, 0);
|
||||||
return RBUF_ADD_SUCCESS;
|
/* check if entry was deleted in IPHC (error case) */
|
||||||
|
if (gnrc_sixlowpan_frag_rb_entry_empty(entry)) {
|
||||||
|
res = RBUF_ADD_ERROR;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (data[0] == SIXLOWPAN_UNCOMP) {
|
if (data[0] == SIXLOWPAN_UNCOMP) {
|
||||||
|
DEBUG("6lo rbuf: detected uncompressed datagram\n");
|
||||||
data++;
|
data++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memcpy(((uint8_t *)entry->pkt->data) + offset, data,
|
memcpy(((uint8_t *)entry->pkt->data) + offset, data,
|
||||||
frag_size);
|
frag_size);
|
||||||
}
|
}
|
||||||
gnrc_sixlowpan_frag_rb_dispatch_when_complete(entry, netif_hdr);
|
/* no errors and not consumed => release packet */
|
||||||
gnrc_pktbuf_release(pkt);
|
gnrc_pktbuf_release(pkt);
|
||||||
return RBUF_ADD_SUCCESS;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool _rbuf_int_overlap_partially(gnrc_sixlowpan_frag_rb_int_t *i,
|
static inline bool _rbuf_int_overlap_partially(gnrc_sixlowpan_frag_rb_int_t *i,
|
||||||
@ -329,7 +351,7 @@ static inline void _set_rbuf_timeout(void)
|
|||||||
&_gc_timer_msg, sched_active_pid);
|
&_gc_timer_msg, sched_active_pid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gnrc_sixlowpan_frag_rb_t *_rbuf_get(const void *src, size_t src_len,
|
static int _rbuf_get(const void *src, size_t src_len,
|
||||||
const void *dst, size_t dst_len,
|
const void *dst, size_t dst_len,
|
||||||
size_t size, uint16_t tag,
|
size_t size, uint16_t tag,
|
||||||
unsigned page)
|
unsigned page)
|
||||||
@ -355,7 +377,7 @@ static gnrc_sixlowpan_frag_rb_t *_rbuf_get(const void *src, size_t src_len,
|
|||||||
(unsigned)rbuf[i].super.datagram_size, rbuf[i].super.tag);
|
(unsigned)rbuf[i].super.datagram_size, rbuf[i].super.tag);
|
||||||
rbuf[i].super.arrival = now_usec;
|
rbuf[i].super.arrival = now_usec;
|
||||||
_set_rbuf_timeout();
|
_set_rbuf_timeout();
|
||||||
return &(rbuf[i]);
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if there is a free spot: remember it */
|
/* if there is a free spot: remember it */
|
||||||
@ -393,7 +415,7 @@ static gnrc_sixlowpan_frag_rb_t *_rbuf_get(const void *src, size_t src_len,
|
|||||||
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS
|
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_STATS
|
||||||
_stats.rbuf_full++;
|
_stats.rbuf_full++;
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,7 +435,7 @@ static gnrc_sixlowpan_frag_rb_t *_rbuf_get(const void *src, size_t src_len,
|
|||||||
res->pkt = gnrc_pktbuf_add(NULL, NULL, size, reass_type);
|
res->pkt = gnrc_pktbuf_add(NULL, NULL, size, reass_type);
|
||||||
if (res->pkt == NULL) {
|
if (res->pkt == NULL) {
|
||||||
DEBUG("6lo rfrag: can not allocate reassembly buffer space.\n");
|
DEBUG("6lo rfrag: can not allocate reassembly buffer space.\n");
|
||||||
return NULL;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*((uint64_t *)res->pkt->data) = 0; /* clean first few bytes for later
|
*((uint64_t *)res->pkt->data) = 0; /* clean first few bytes for later
|
||||||
@ -437,7 +459,7 @@ static gnrc_sixlowpan_frag_rb_t *_rbuf_get(const void *src, size_t src_len,
|
|||||||
|
|
||||||
_set_rbuf_timeout();
|
_set_rbuf_timeout();
|
||||||
|
|
||||||
return res;
|
return res - &(rbuf[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TEST_SUITES
|
#ifdef TEST_SUITES
|
||||||
@ -473,12 +495,14 @@ void gnrc_sixlowpan_frag_rb_base_rm(gnrc_sixlowpan_frag_rb_base_t *entry)
|
|||||||
entry->datagram_size = 0;
|
entry->datagram_size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gnrc_sixlowpan_frag_rb_dispatch_when_complete(gnrc_sixlowpan_frag_rb_t *rbuf,
|
int gnrc_sixlowpan_frag_rb_dispatch_when_complete(gnrc_sixlowpan_frag_rb_t *rbuf,
|
||||||
gnrc_netif_hdr_t *netif_hdr)
|
gnrc_netif_hdr_t *netif_hdr)
|
||||||
{
|
{
|
||||||
assert(rbuf);
|
assert(rbuf);
|
||||||
assert(netif_hdr);
|
assert(netif_hdr);
|
||||||
if (rbuf->super.current_size == rbuf->super.datagram_size) {
|
int res = (rbuf->super.current_size == rbuf->super.datagram_size);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(rbuf->super.src,
|
gnrc_pktsnip_t *netif = gnrc_netif_hdr_build(rbuf->super.src,
|
||||||
rbuf->super.src_len,
|
rbuf->super.src_len,
|
||||||
rbuf->super.dst,
|
rbuf->super.dst,
|
||||||
@ -488,7 +512,7 @@ void gnrc_sixlowpan_frag_rb_dispatch_when_complete(gnrc_sixlowpan_frag_rb_t *rbu
|
|||||||
DEBUG("6lo rbuf: error allocating netif header\n");
|
DEBUG("6lo rbuf: error allocating netif header\n");
|
||||||
gnrc_pktbuf_release(rbuf->pkt);
|
gnrc_pktbuf_release(rbuf->pkt);
|
||||||
gnrc_sixlowpan_frag_rb_remove(rbuf);
|
gnrc_sixlowpan_frag_rb_remove(rbuf);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy the transmit information of the latest fragment into the newly
|
/* copy the transmit information of the latest fragment into the newly
|
||||||
@ -504,6 +528,7 @@ void gnrc_sixlowpan_frag_rb_dispatch_when_complete(gnrc_sixlowpan_frag_rb_t *rbu
|
|||||||
gnrc_sixlowpan_dispatch_recv(rbuf->pkt, NULL, 0);
|
gnrc_sixlowpan_dispatch_recv(rbuf->pkt, NULL, 0);
|
||||||
gnrc_sixlowpan_frag_rb_remove(rbuf);
|
gnrc_sixlowpan_frag_rb_remove(rbuf);
|
||||||
}
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -582,7 +582,6 @@ void gnrc_sixlowpan_iphc_recv(gnrc_pktsnip_t *sixlo, void *rbuf_ptr,
|
|||||||
sixlo->size - payload_offset);
|
sixlo->size - payload_offset);
|
||||||
if (rbuf != NULL) {
|
if (rbuf != NULL) {
|
||||||
rbuf->super.current_size += (uncomp_hdr_len - payload_offset);
|
rbuf->super.current_size += (uncomp_hdr_len - payload_offset);
|
||||||
gnrc_sixlowpan_frag_rb_dispatch_when_complete(rbuf, netif_hdr);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LL_DELETE(sixlo, netif);
|
LL_DELETE(sixlo, netif);
|
||||||
|
|||||||
@ -256,9 +256,9 @@ static void test_rbuf_add__success_first_fragment(void)
|
|||||||
const gnrc_sixlowpan_frag_rb_t *entry;
|
const gnrc_sixlowpan_frag_rb_t *entry;
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(pkt);
|
TEST_ASSERT_NOT_NULL(pkt);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt,
|
TEST_ASSERT_NOT_NULL((entry = gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT1_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt, TEST_FRAGMENT1_OFFSET, TEST_PAGE
|
||||||
entry = _first_non_empty_rbuf();
|
)));
|
||||||
/* current_size must be the offset of fragment 2, not the size of
|
/* current_size must be the offset of fragment 2, not the size of
|
||||||
* fragment 1 (fragment dispatch was removed, IPHC was applied etc.). */
|
* fragment 1 (fragment dispatch was removed, IPHC was applied etc.). */
|
||||||
_test_entry(entry, TEST_FRAGMENT2_OFFSET,
|
_test_entry(entry, TEST_FRAGMENT2_OFFSET,
|
||||||
@ -273,9 +273,9 @@ static void test_rbuf_add__success_subsequent_fragment(void)
|
|||||||
const gnrc_sixlowpan_frag_rb_t *entry;
|
const gnrc_sixlowpan_frag_rb_t *entry;
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(pkt);
|
TEST_ASSERT_NOT_NULL(pkt);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt,
|
TEST_ASSERT_NOT_NULL((entry = gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT2_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt, TEST_FRAGMENT2_OFFSET, TEST_PAGE
|
||||||
entry = _first_non_empty_rbuf();
|
)));
|
||||||
/* current_size must be the offset of fragment 3, not the size of
|
/* current_size must be the offset of fragment 3, not the size of
|
||||||
* fragment 2 (fragment dispatch was removed, IPHC was applied etc.). */
|
* fragment 2 (fragment dispatch was removed, IPHC was applied etc.). */
|
||||||
_test_entry(entry, TEST_FRAGMENT3_OFFSET - TEST_FRAGMENT2_OFFSET,
|
_test_entry(entry, TEST_FRAGMENT3_OFFSET - TEST_FRAGMENT2_OFFSET,
|
||||||
@ -292,12 +292,13 @@ static void test_rbuf_add__success_duplicate_fragments(void)
|
|||||||
const gnrc_sixlowpan_frag_rb_t *entry;
|
const gnrc_sixlowpan_frag_rb_t *entry;
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(pkt1);
|
TEST_ASSERT_NOT_NULL(pkt1);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt1,
|
TEST_ASSERT_NOT_NULL(gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT3_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt1, TEST_FRAGMENT3_OFFSET, TEST_PAGE
|
||||||
|
));
|
||||||
TEST_ASSERT_NOT_NULL(pkt2);
|
TEST_ASSERT_NOT_NULL(pkt2);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt2,
|
TEST_ASSERT_NOT_NULL((entry = gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT3_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt2, TEST_FRAGMENT3_OFFSET, TEST_PAGE
|
||||||
entry = _first_non_empty_rbuf();
|
)));
|
||||||
/* current_size must be the offset of fragment 4, not the size of
|
/* current_size must be the offset of fragment 4, not the size of
|
||||||
* fragment 3 (fragment dispatch was removed, IPHC was applied etc.). */
|
* fragment 3 (fragment dispatch was removed, IPHC was applied etc.). */
|
||||||
_test_entry(entry, TEST_FRAGMENT4_OFFSET - TEST_FRAGMENT3_OFFSET,
|
_test_entry(entry, TEST_FRAGMENT4_OFFSET - TEST_FRAGMENT3_OFFSET,
|
||||||
@ -316,6 +317,7 @@ static void test_rbuf_add__success_complete(void)
|
|||||||
gnrc_pktsnip_t *pkt4 = gnrc_pktbuf_add(NULL, _fragment4, sizeof(_fragment4),
|
gnrc_pktsnip_t *pkt4 = gnrc_pktbuf_add(NULL, _fragment4, sizeof(_fragment4),
|
||||||
GNRC_NETTYPE_SIXLOWPAN);
|
GNRC_NETTYPE_SIXLOWPAN);
|
||||||
gnrc_pktsnip_t *datagram;
|
gnrc_pktsnip_t *datagram;
|
||||||
|
gnrc_sixlowpan_frag_rb_t *entry1, *entry2;
|
||||||
msg_t msg = { .type = 0U };
|
msg_t msg = { .type = 0U };
|
||||||
gnrc_netreg_entry_t reg = GNRC_NETREG_ENTRY_INIT_PID(
|
gnrc_netreg_entry_t reg = GNRC_NETREG_ENTRY_INIT_PID(
|
||||||
GNRC_NETREG_DEMUX_CTX_ALL,
|
GNRC_NETREG_DEMUX_CTX_ALL,
|
||||||
@ -325,17 +327,36 @@ static void test_rbuf_add__success_complete(void)
|
|||||||
gnrc_netreg_register(TEST_DATAGRAM_NETTYPE, ®);
|
gnrc_netreg_register(TEST_DATAGRAM_NETTYPE, ®);
|
||||||
/* Mixing up things. Order decided by fair dice-rolls ;-) */
|
/* Mixing up things. Order decided by fair dice-rolls ;-) */
|
||||||
TEST_ASSERT_NOT_NULL(pkt2);
|
TEST_ASSERT_NOT_NULL(pkt2);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt2,
|
TEST_ASSERT_NOT_NULL((entry1 = gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT2_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt2, TEST_FRAGMENT2_OFFSET, TEST_PAGE
|
||||||
|
)));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, gnrc_sixlowpan_frag_rb_dispatch_when_complete(
|
||||||
|
entry1, &_test_netif_hdr.hdr
|
||||||
|
));
|
||||||
TEST_ASSERT_NOT_NULL(pkt4);
|
TEST_ASSERT_NOT_NULL(pkt4);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt4,
|
TEST_ASSERT_NOT_NULL((entry2 = gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT4_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt4, TEST_FRAGMENT4_OFFSET, TEST_PAGE
|
||||||
|
)));
|
||||||
|
TEST_ASSERT(entry1 == entry2);
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, gnrc_sixlowpan_frag_rb_dispatch_when_complete(
|
||||||
|
entry1, &_test_netif_hdr.hdr
|
||||||
|
));
|
||||||
TEST_ASSERT_NOT_NULL(pkt1);
|
TEST_ASSERT_NOT_NULL(pkt1);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt1,
|
TEST_ASSERT_NOT_NULL((entry2 = gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT1_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt1, TEST_FRAGMENT1_OFFSET, TEST_PAGE
|
||||||
|
)));
|
||||||
|
TEST_ASSERT(entry1 == entry2);
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, gnrc_sixlowpan_frag_rb_dispatch_when_complete(
|
||||||
|
entry1, &_test_netif_hdr.hdr
|
||||||
|
));
|
||||||
TEST_ASSERT_NOT_NULL(pkt3);
|
TEST_ASSERT_NOT_NULL(pkt3);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt3,
|
TEST_ASSERT_NOT_NULL((entry2 = gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT3_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt3, TEST_FRAGMENT3_OFFSET, TEST_PAGE
|
||||||
|
)));
|
||||||
|
TEST_ASSERT(entry1 == entry2);
|
||||||
|
TEST_ASSERT(0 < gnrc_sixlowpan_frag_rb_dispatch_when_complete(
|
||||||
|
entry1, &_test_netif_hdr.hdr
|
||||||
|
));
|
||||||
TEST_ASSERT_MESSAGE(
|
TEST_ASSERT_MESSAGE(
|
||||||
xtimer_msg_receive_timeout(&msg, TEST_RECEIVE_TIMEOUT) >= 0,
|
xtimer_msg_receive_timeout(&msg, TEST_RECEIVE_TIMEOUT) >= 0,
|
||||||
"Receiving reassembled datagram timed out"
|
"Receiving reassembled datagram timed out"
|
||||||
@ -362,16 +383,18 @@ static void test_rbuf_add__full_rbuf(void)
|
|||||||
pkt = gnrc_pktbuf_add(NULL, _fragment1, sizeof(_fragment1),
|
pkt = gnrc_pktbuf_add(NULL, _fragment1, sizeof(_fragment1),
|
||||||
GNRC_NETTYPE_SIXLOWPAN);
|
GNRC_NETTYPE_SIXLOWPAN);
|
||||||
TEST_ASSERT_NOT_NULL(pkt);
|
TEST_ASSERT_NOT_NULL(pkt);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt,
|
TEST_ASSERT_NOT_NULL(gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT1_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt, TEST_FRAGMENT1_OFFSET, TEST_PAGE
|
||||||
|
));
|
||||||
_set_fragment_tag(_fragment1, TEST_TAG + i + 1);
|
_set_fragment_tag(_fragment1, TEST_TAG + i + 1);
|
||||||
/* pkt is released in gnrc_sixlowpan_frag_rb_add() */
|
/* pkt is released in gnrc_sixlowpan_frag_rb_add() */
|
||||||
}
|
}
|
||||||
pkt = gnrc_pktbuf_add(NULL, _fragment1, sizeof(_fragment1),
|
pkt = gnrc_pktbuf_add(NULL, _fragment1, sizeof(_fragment1),
|
||||||
GNRC_NETTYPE_SIXLOWPAN);
|
GNRC_NETTYPE_SIXLOWPAN);
|
||||||
TEST_ASSERT_NOT_NULL(pkt);
|
TEST_ASSERT_NOT_NULL(pkt);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt,
|
TEST_ASSERT_NOT_NULL(gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT1_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt, TEST_FRAGMENT1_OFFSET, TEST_PAGE
|
||||||
|
));
|
||||||
rbuf = gnrc_sixlowpan_frag_rb_array();
|
rbuf = gnrc_sixlowpan_frag_rb_array();
|
||||||
for (unsigned i = 0; i < GNRC_SIXLOWPAN_FRAG_RBUF_SIZE; i++) {
|
for (unsigned i = 0; i < GNRC_SIXLOWPAN_FRAG_RBUF_SIZE; i++) {
|
||||||
const gnrc_sixlowpan_frag_rb_t *entry = &rbuf[i];
|
const gnrc_sixlowpan_frag_rb_t *entry = &rbuf[i];
|
||||||
@ -404,8 +427,9 @@ static void test_rbuf_add__too_big_fragment(void)
|
|||||||
GNRC_NETTYPE_SIXLOWPAN);
|
GNRC_NETTYPE_SIXLOWPAN);
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(pkt);
|
TEST_ASSERT_NOT_NULL(pkt);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt,
|
TEST_ASSERT_NULL(gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT1_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt, TEST_FRAGMENT1_OFFSET, TEST_PAGE
|
||||||
|
));
|
||||||
/* packet buffer is empty*/
|
/* packet buffer is empty*/
|
||||||
TEST_ASSERT_NULL(_first_non_empty_rbuf());
|
TEST_ASSERT_NULL(_first_non_empty_rbuf());
|
||||||
_check_pktbuf(NULL);
|
_check_pktbuf(NULL);
|
||||||
@ -424,11 +448,13 @@ static void test_rbuf_add__overlap_lhs(void)
|
|||||||
pkt2 = gnrc_pktbuf_add(NULL, _fragment2, sizeof(_fragment2),
|
pkt2 = gnrc_pktbuf_add(NULL, _fragment2, sizeof(_fragment2),
|
||||||
GNRC_NETTYPE_SIXLOWPAN);
|
GNRC_NETTYPE_SIXLOWPAN);
|
||||||
TEST_ASSERT_NOT_NULL(pkt1);
|
TEST_ASSERT_NOT_NULL(pkt1);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt1,
|
TEST_ASSERT_NOT_NULL(gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT1_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt1, TEST_FRAGMENT1_OFFSET, TEST_PAGE
|
||||||
|
));
|
||||||
TEST_ASSERT_NOT_NULL(pkt2);
|
TEST_ASSERT_NOT_NULL(pkt2);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt2, pkt2_offset,
|
TEST_ASSERT_NOT_NULL(gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt2, pkt2_offset, TEST_PAGE
|
||||||
|
));
|
||||||
rbuf = gnrc_sixlowpan_frag_rb_array();
|
rbuf = gnrc_sixlowpan_frag_rb_array();
|
||||||
for (unsigned i = 0; i < GNRC_SIXLOWPAN_FRAG_RBUF_SIZE; i++) {
|
for (unsigned i = 0; i < GNRC_SIXLOWPAN_FRAG_RBUF_SIZE; i++) {
|
||||||
const gnrc_sixlowpan_frag_rb_t *entry = &rbuf[i];
|
const gnrc_sixlowpan_frag_rb_t *entry = &rbuf[i];
|
||||||
@ -467,14 +493,17 @@ static void test_rbuf_add__overlap_rhs(void)
|
|||||||
pkt2 = gnrc_pktbuf_add(NULL, _fragment2, sizeof(_fragment2),
|
pkt2 = gnrc_pktbuf_add(NULL, _fragment2, sizeof(_fragment2),
|
||||||
GNRC_NETTYPE_SIXLOWPAN);
|
GNRC_NETTYPE_SIXLOWPAN);
|
||||||
TEST_ASSERT_NOT_NULL(pkt1);
|
TEST_ASSERT_NOT_NULL(pkt1);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt1,
|
TEST_ASSERT_NOT_NULL(gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT1_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt1, TEST_FRAGMENT1_OFFSET, TEST_PAGE
|
||||||
|
));
|
||||||
TEST_ASSERT_NOT_NULL(pkt3);
|
TEST_ASSERT_NOT_NULL(pkt3);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt3,
|
TEST_ASSERT_NOT_NULL(gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT3_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt3, TEST_FRAGMENT3_OFFSET, TEST_PAGE
|
||||||
|
));
|
||||||
TEST_ASSERT_NOT_NULL(pkt2);
|
TEST_ASSERT_NOT_NULL(pkt2);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt2, pkt2_offset,
|
TEST_ASSERT_NOT_NULL(gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt2, pkt2_offset, TEST_PAGE
|
||||||
|
));
|
||||||
rbuf = gnrc_sixlowpan_frag_rb_array();
|
rbuf = gnrc_sixlowpan_frag_rb_array();
|
||||||
for (unsigned i = 0; i < GNRC_SIXLOWPAN_FRAG_RBUF_SIZE; i++) {
|
for (unsigned i = 0; i < GNRC_SIXLOWPAN_FRAG_RBUF_SIZE; i++) {
|
||||||
const gnrc_sixlowpan_frag_rb_t *entry = &rbuf[i];
|
const gnrc_sixlowpan_frag_rb_t *entry = &rbuf[i];
|
||||||
@ -521,10 +550,9 @@ static void test_rbuf_gc__manually(void)
|
|||||||
gnrc_sixlowpan_frag_rb_t *entry;
|
gnrc_sixlowpan_frag_rb_t *entry;
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(pkt);
|
TEST_ASSERT_NOT_NULL(pkt);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt,
|
TEST_ASSERT_NOT_NULL((entry = gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT1_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt, TEST_FRAGMENT1_OFFSET, TEST_PAGE
|
||||||
/* discarding const qualifier intentionally to override `arrival` */
|
)));
|
||||||
entry = (gnrc_sixlowpan_frag_rb_t *)_first_non_empty_rbuf();
|
|
||||||
TEST_ASSERT_NOT_NULL(entry);
|
TEST_ASSERT_NOT_NULL(entry);
|
||||||
/* set arrival GNRC_SIXLOWPAN_FRAG_RBUF_TIMEOUT_US into the past */
|
/* set arrival GNRC_SIXLOWPAN_FRAG_RBUF_TIMEOUT_US into the past */
|
||||||
entry->super.arrival -= GNRC_SIXLOWPAN_FRAG_RBUF_TIMEOUT_US;
|
entry->super.arrival -= GNRC_SIXLOWPAN_FRAG_RBUF_TIMEOUT_US;
|
||||||
@ -542,10 +570,9 @@ static void test_rbuf_gc__timed(void)
|
|||||||
gnrc_sixlowpan_frag_rb_t *entry;
|
gnrc_sixlowpan_frag_rb_t *entry;
|
||||||
|
|
||||||
TEST_ASSERT_NOT_NULL(pkt);
|
TEST_ASSERT_NOT_NULL(pkt);
|
||||||
gnrc_sixlowpan_frag_rb_add(&_test_netif_hdr.hdr, pkt,
|
TEST_ASSERT_NOT_NULL((entry = gnrc_sixlowpan_frag_rb_add(
|
||||||
TEST_FRAGMENT1_OFFSET, TEST_PAGE);
|
&_test_netif_hdr.hdr, pkt, TEST_FRAGMENT1_OFFSET, TEST_PAGE
|
||||||
/* discarding const qualifier intentionally to override `arrival` */
|
)));
|
||||||
entry = (gnrc_sixlowpan_frag_rb_t *)_first_non_empty_rbuf();
|
|
||||||
TEST_ASSERT_NOT_NULL(entry);
|
TEST_ASSERT_NOT_NULL(entry);
|
||||||
TEST_ASSERT_MESSAGE(
|
TEST_ASSERT_MESSAGE(
|
||||||
xtimer_msg_receive_timeout(&msg, TEST_GC_TIMEOUT) >= 0,
|
xtimer_msg_receive_timeout(&msg, TEST_GC_TIMEOUT) >= 0,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user