Skip to content
Snippets Groups Projects
Unverified Commit f597c6a6 authored by Martine Lenders's avatar Martine Lenders Committed by GitHub
Browse files

Merge pull request #10226 from miri64/gnrc_pktbuf/enh/reverse-snips

 gnrc_pktbuf: add gnrc_pktbuf_reverse_snips() helper function
parents 85733a75 d6ea335b
Branches
No related tags found
No related merge requests found
...@@ -225,6 +225,24 @@ gnrc_pktsnip_t *gnrc_pktbuf_remove_snip(gnrc_pktsnip_t *pkt, gnrc_pktsnip_t *sni ...@@ -225,6 +225,24 @@ gnrc_pktsnip_t *gnrc_pktbuf_remove_snip(gnrc_pktsnip_t *pkt, gnrc_pktsnip_t *sni
*/ */
gnrc_pktsnip_t *gnrc_pktbuf_replace_snip(gnrc_pktsnip_t *pkt, gnrc_pktsnip_t *old, gnrc_pktsnip_t *add); gnrc_pktsnip_t *gnrc_pktbuf_replace_snip(gnrc_pktsnip_t *pkt, gnrc_pktsnip_t *old, gnrc_pktsnip_t *add);
/**
* @brief Reverses snip order of a packet in a write-protected manner.
*
* This can be used to change the send/receive order of a packet (see
* @ref gnrc_pktsnip_t)
*
* @note @p pkt is released on failure.
*
* @param[in] pkt A packet. When this function fails (due to a full packet
* packet buffer) @p pkt will be released.
*
* @return The reversed version of @p pkt on success
* @return NULL, when there is not enough space in the packet buffer to reverse
* the packet in a write-protected manner. @p pkt is released in that
* case.
*/
gnrc_pktsnip_t *gnrc_pktbuf_reverse_snips(gnrc_pktsnip_t *pkt);
/** /**
* @brief Duplicates pktsnip chain upto (including) a snip with the given type * @brief Duplicates pktsnip chain upto (including) a snip with the given type
* as a continuous snip. * as a continuous snip.
......
...@@ -839,8 +839,6 @@ static void _receive(gnrc_pktsnip_t *pkt) ...@@ -839,8 +839,6 @@ static void _receive(gnrc_pktsnip_t *pkt)
} }
/* TODO: check if receiving interface is router */ /* TODO: check if receiving interface is router */
else if (--(hdr->hl) > 0) { /* drop packets that *reach* Hop Limit 0 */ else if (--(hdr->hl) > 0) { /* drop packets that *reach* Hop Limit 0 */
gnrc_pktsnip_t *reversed_pkt = NULL, *ptr = pkt;
DEBUG("ipv6: forward packet to next hop\n"); DEBUG("ipv6: forward packet to next hop\n");
/* pkt might not be writable yet, if header was given above */ /* pkt might not be writable yet, if header was given above */
...@@ -856,23 +854,14 @@ static void _receive(gnrc_pktsnip_t *pkt) ...@@ -856,23 +854,14 @@ static void _receive(gnrc_pktsnip_t *pkt)
if (netif_hdr != NULL) { if (netif_hdr != NULL) {
gnrc_pktbuf_remove_snip(pkt, netif_hdr); gnrc_pktbuf_remove_snip(pkt, netif_hdr);
} }
pkt = gnrc_pktbuf_reverse_snips(pkt);
/* reverse packet snip list order */ if (pkt != NULL) {
while (ptr != NULL) { _send(pkt, false);
gnrc_pktsnip_t *next; }
ptr = gnrc_pktbuf_start_write(ptr); /* duplicate if not already done */ else {
if (ptr == NULL) { DEBUG("ipv6: unable to reverse pkt from receive order to send "
DEBUG("ipv6: unable to get write access to packet: dropping it\n"); "order; dropping it\n");
gnrc_pktbuf_release(reversed_pkt);
gnrc_pktbuf_release(pkt);
return;
}
next = ptr->next;
ptr->next = reversed_pkt;
reversed_pkt = ptr;
ptr = next;
} }
_send(reversed_pkt, false);
return; return;
} }
else { else {
......
...@@ -86,5 +86,28 @@ gnrc_pktsnip_t *gnrc_pktbuf_replace_snip(gnrc_pktsnip_t *pkt, ...@@ -86,5 +86,28 @@ gnrc_pktsnip_t *gnrc_pktbuf_replace_snip(gnrc_pktsnip_t *pkt,
return pkt; return pkt;
} }
gnrc_pktsnip_t *gnrc_pktbuf_reverse_snips(gnrc_pktsnip_t *pkt)
{
gnrc_pktsnip_t *reversed = NULL, *ptr = pkt;
while (ptr != NULL) {
gnrc_pktsnip_t *next;
/* try to write-protect snip as its next-pointer is changed below */
pkt = gnrc_pktbuf_start_write(ptr); /* use pkt as temporary variable */
if (pkt == NULL) {
gnrc_pktbuf_release(reversed);
gnrc_pktbuf_release(ptr);
return NULL;
}
/* switch around pointers */
next = pkt->next;
pkt->next = reversed;
reversed = pkt;
ptr = next;
}
return reversed;
}
/** @} */ /** @} */
...@@ -818,6 +818,43 @@ static void test_pktbuf_get_iovec__null(void) ...@@ -818,6 +818,43 @@ static void test_pktbuf_get_iovec__null(void)
TEST_ASSERT_EQUAL_INT(0, len); TEST_ASSERT_EQUAL_INT(0, len);
} }
static void test_pktbuf_reverse_snips__too_full(void)
{
gnrc_pktsnip_t *pkt, *pkt_next, *pkt_huge;
const size_t pkt_huge_size = GNRC_PKTBUF_SIZE - (3 * 8) -
(3 * sizeof(gnrc_pktsnip_t)) - 4;
pkt_next = gnrc_pktbuf_add(NULL, TEST_STRING8, 8, GNRC_NETTYPE_TEST);
TEST_ASSERT_NOT_NULL(pkt_next);
/* hold to enforce duplication */
gnrc_pktbuf_hold(pkt_next, 1);
pkt = gnrc_pktbuf_add(pkt_next, TEST_STRING8, 8, GNRC_NETTYPE_TEST);
TEST_ASSERT_NOT_NULL(pkt);
/* filling up rest of packet buffer */
pkt_huge = gnrc_pktbuf_add(NULL, NULL, pkt_huge_size, GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(pkt_huge);
TEST_ASSERT_NULL(gnrc_pktbuf_reverse_snips(pkt));
gnrc_pktbuf_release(pkt_huge);
/* release because of hold above */
gnrc_pktbuf_release(pkt_next);
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_pktbuf_reverse_snips__success(void)
{
gnrc_pktsnip_t *pkt, *pkt_next, *pkt_reversed;
pkt_next = gnrc_pktbuf_add(NULL, TEST_STRING8, 8, GNRC_NETTYPE_TEST);
TEST_ASSERT_NOT_NULL(pkt_next);
pkt = gnrc_pktbuf_add(pkt_next, TEST_STRING8, 8, GNRC_NETTYPE_TEST);
TEST_ASSERT_NOT_NULL(pkt);
pkt_reversed = gnrc_pktbuf_reverse_snips(pkt);
TEST_ASSERT(pkt_reversed == pkt_next);
TEST_ASSERT(pkt_reversed->next == pkt);
gnrc_pktbuf_release(pkt_reversed);
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
Test *tests_pktbuf_tests(void) Test *tests_pktbuf_tests(void)
{ {
EMB_UNIT_TESTFIXTURES(fixtures) { EMB_UNIT_TESTFIXTURES(fixtures) {
...@@ -870,6 +907,8 @@ Test *tests_pktbuf_tests(void) ...@@ -870,6 +907,8 @@ Test *tests_pktbuf_tests(void)
new_TestFixture(test_pktbuf_get_iovec__1_elem), new_TestFixture(test_pktbuf_get_iovec__1_elem),
new_TestFixture(test_pktbuf_get_iovec__3_elem), new_TestFixture(test_pktbuf_get_iovec__3_elem),
new_TestFixture(test_pktbuf_get_iovec__null), new_TestFixture(test_pktbuf_get_iovec__null),
new_TestFixture(test_pktbuf_reverse_snips__too_full),
new_TestFixture(test_pktbuf_reverse_snips__success),
}; };
EMB_UNIT_TESTCALLER(gnrc_pktbuf_tests, set_up, NULL, fixtures); EMB_UNIT_TESTCALLER(gnrc_pktbuf_tests, set_up, NULL, fixtures);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment