gnrc_sixlowpan_frag_rb: behavioral change to add()

Rather than dispatching the packet automatically once it is complete,
`gnrc_sixlowpan_frag_rb_add()` now only returns success, and leaves it
to the caller to dispatch the packet.
This commit is contained in:
Martine S. Lenders 2019-09-30 16:26:33 +02:00 committed by Martine Lenders
parent df484926a2
commit f8d75d7add
5 changed files with 66 additions and 37 deletions

View File

@ -102,7 +102,8 @@ 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.
* *
@ -158,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
@ -195,6 +178,24 @@ static inline void gnrc_sixlowpan_frag_rb_remove(gnrc_sixlowpan_frag_rb_t *rbuf)
*/ */
int 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.
*
* @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 */
@ -203,14 +204,6 @@ static inline void gnrc_sixlowpan_frag_rb_remove(gnrc_sixlowpan_frag_rb_t *rbuf)
(void)rbuf; (void)rbuf;
return; return;
} }
static inline int gnrc_sixlowpan_frag_rb_dispatch_when_complete(
gnrc_sixlowpan_frag_rb_t *rbuf, gnrc_netif_hdr_t *netif)
{
(void)rbuf;
(void)netif;
return -1;
}
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -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)

View File

@ -223,27 +223,39 @@ 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;
} }
gnrc_sixlowpan_iphc_recv(pkt, entry, 0); else {
return res; DEBUG("6lo rbuf: handing over to IPHC reception.\n");
/* `pkt` released in IPHC */
gnrc_sixlowpan_iphc_recv(pkt, entry, 0);
/* 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 res; return res;
} }

View File

@ -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);

View File

@ -317,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,
@ -326,20 +327,35 @@ static void test_rbuf_add__success_complete(void)
gnrc_netreg_register(TEST_DATAGRAM_NETTYPE, &reg); gnrc_netreg_register(TEST_DATAGRAM_NETTYPE, &reg);
/* 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);
TEST_ASSERT_NOT_NULL(gnrc_sixlowpan_frag_rb_add( TEST_ASSERT_NOT_NULL((entry1 = gnrc_sixlowpan_frag_rb_add(
&_test_netif_hdr.hdr, pkt2, 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);
TEST_ASSERT_NOT_NULL(gnrc_sixlowpan_frag_rb_add( TEST_ASSERT_NOT_NULL((entry2 = gnrc_sixlowpan_frag_rb_add(
&_test_netif_hdr.hdr, pkt4, 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);
TEST_ASSERT_NOT_NULL(gnrc_sixlowpan_frag_rb_add( TEST_ASSERT_NOT_NULL((entry2 = gnrc_sixlowpan_frag_rb_add(
&_test_netif_hdr.hdr, pkt1, 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);
TEST_ASSERT_NOT_NULL(gnrc_sixlowpan_frag_rb_add( TEST_ASSERT_NOT_NULL((entry2 = gnrc_sixlowpan_frag_rb_add(
&_test_netif_hdr.hdr, pkt3, 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,