From 02a7bc252a299454f334e6297e95ab759ab424d1 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 24 Oct 2018 00:03:13 +0200 Subject: [PATCH 1/6] gnrc_ipv6: move ipv6_ext iteration out of ext_demux() Since with #10233 we now assume IPv6 packets always to not be pre-parsed, we can iterate over the extension headers by gradually "eating" them away. This allows us to move the iteration over them out of `gnrc_ipv6_ext_demux()` and into `gnrc_ipv6_demux()`. By moving the iteration over all extension headers out of `gnrc_ipv6_ext_demux()` we also can 1. simplify the extension header handling a lot, as it now just a loop inside `gnrc_ipv6_demux()`, 2. remove the recursion to `gnrc_ipv6_demux()` within `gnrc_ipv6_ext_demux()`. --- sys/include/net/gnrc/ipv6/ext.h | 29 +-- .../network_layer/ipv6/ext/gnrc_ipv6_ext.c | 202 +++++++----------- sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c | 96 ++++----- 3 files changed, 117 insertions(+), 210 deletions(-) diff --git a/sys/include/net/gnrc/ipv6/ext.h b/sys/include/net/gnrc/ipv6/ext.h index e772e7f7eb..a52c88046f 100644 --- a/sys/include/net/gnrc/ipv6/ext.h +++ b/sys/include/net/gnrc/ipv6/ext.h @@ -27,7 +27,6 @@ #include #include -#include "net/gnrc/netif.h" #include "net/gnrc/pkt.h" #include "net/ipv6/ext.h" @@ -40,29 +39,17 @@ extern "C" { #endif /** - * @brief Demultiplex extension headers according to @p nh. + * @brief Demultiplex an extension header according to @p nh. * - * About `current` and `pkt`: + * @param[in] pkt A packet with the first snip pointing to the extension + * header to process. + * @param[in] nh Protocol number of @p pkt. * - * current pkt - * | | - * v v - * IPv6 <- IPv6_EXT <- IPv6_EXT <- UNDEF - * - * This situation may happen when the packet has a source routing extension - * header (RFC 6554), and the packet is forwarded from an interface to another. - * - * @internal - * - * @param[in] netif The receiving interface. - * @param[in] current A snip to process. - * @param[in] pkt A packet. - * @param[in] nh A protocol number (see @ref net_protnum) of the current snip. + * @return The packet for further processing. + * @return NULL, on error or if packet was consumed (by e.g. forwarding via + * a routing header). @p pkt is released in case of error. */ -void gnrc_ipv6_ext_demux(gnrc_netif_t *netif, - gnrc_pktsnip_t *current, - gnrc_pktsnip_t *pkt, - uint8_t nh); +gnrc_pktsnip_t *gnrc_ipv6_ext_demux(gnrc_pktsnip_t *pkt, unsigned nh); /** * @brief Builds an extension header for sending. diff --git a/sys/net/gnrc/network_layer/ipv6/ext/gnrc_ipv6_ext.c b/sys/net/gnrc/network_layer/ipv6/ext/gnrc_ipv6_ext.c index 4afb709b96..a4a1e2035a 100644 --- a/sys/net/gnrc/network_layer/ipv6/ext/gnrc_ipv6_ext.c +++ b/sys/net/gnrc/network_layer/ipv6/ext/gnrc_ipv6_ext.c @@ -59,9 +59,11 @@ static void _forward_pkt(gnrc_pktsnip_t *pkt, ipv6_hdr_t *hdr) } } -static int _handle_rh(gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt) +/* handle routing header at pkt->data */ +static int _handle_rh(gnrc_pktsnip_t *pkt) { gnrc_pktsnip_t *ipv6; + gnrc_pktsnip_t *current = pkt; ipv6_ext_t *ext = (ipv6_ext_t *) current->data; size_t current_offset; ipv6_hdr_t *hdr; @@ -114,53 +116,29 @@ static int _handle_rh(gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt) #endif /* MODULE_GNRC_IPV6_EXT_RH */ /** - * @brief marks IPv6 extension header if needed. - * updates pkt and returns next header. - * @param[in] current The current header - * @param[in,out] pkt The whole packet - * @return The next header - * @return NULL on error + * @brief Marks an IPv6 extension header according to the length field + * provided by the extension header itself. + * + * @param[in] pkt The packet, with the extension header that is to be marked + * as first snip + * + * @return The marked snip + * @return NULL when no space in packet buffer left or the length field of + * the extension header results in a number of bytes greater than + * gnrc_pktsnip_t::size of @p pkt. In both error cases, @p pkt is + * released. */ -static gnrc_pktsnip_t *_mark_extension_header(gnrc_pktsnip_t *current, - gnrc_pktsnip_t **pkt) +static gnrc_pktsnip_t *_mark_extension_header(gnrc_pktsnip_t *pkt) { - gnrc_pktsnip_t *tmp, *next; - ipv6_ext_t *ext = (ipv6_ext_t *) current->data; - size_t offset = ((ext->len * IPV6_EXT_LEN_UNIT) + IPV6_EXT_LEN_UNIT); + ipv6_ext_t *ext = (ipv6_ext_t *)pkt->data; + size_t hdr_size = ((ext->len * IPV6_EXT_LEN_UNIT) + IPV6_EXT_LEN_UNIT); + gnrc_pktsnip_t *ext_snip = gnrc_pktbuf_mark(pkt, hdr_size, + GNRC_NETTYPE_IPV6_EXT); - if (current == *pkt) { - gnrc_pktsnip_t *ext_snip; - if ((tmp = gnrc_pktbuf_start_write(*pkt)) == NULL) { - DEBUG("ipv6: could not get a copy of pkt\n"); - gnrc_pktbuf_release(*pkt); - return NULL; - } - *pkt = tmp; - - ext_snip = gnrc_pktbuf_mark(*pkt, offset, GNRC_NETTYPE_IPV6_EXT); - next = *pkt; - - if (ext_snip == NULL) { - gnrc_pktbuf_release(*pkt); - return NULL; - } + if (ext_snip == NULL) { + gnrc_pktbuf_release(pkt); } - else { - /* the header is already marked */ - - next = NULL; - - for (tmp = *pkt; tmp != NULL; tmp = tmp->next) { - if (tmp->next == current) { - next = tmp; - break; - } - } - - assert(next != NULL); - } - - return next; + return ext_snip; } static inline bool _has_valid_size(gnrc_pktsnip_t *pkt, uint8_t nh) @@ -188,94 +166,60 @@ static inline bool _has_valid_size(gnrc_pktsnip_t *pkt, uint8_t nh) } } -/* - * current pkt - * | | - * v v - * IPv6 <- IPv6_EXT <- IPv6_EXT <- UNDEF - */ -void gnrc_ipv6_ext_demux(gnrc_netif_t *netif, - gnrc_pktsnip_t *current, - gnrc_pktsnip_t *pkt, - uint8_t nh) +gnrc_pktsnip_t *gnrc_ipv6_ext_demux(gnrc_pktsnip_t *pkt, unsigned nh) { - ipv6_ext_t *ext; - - while (true) { - ext = (ipv6_ext_t *) current->data; - - switch (nh) { - case PROTNUM_IPV6_EXT_RH: -#ifdef MODULE_GNRC_IPV6_EXT_RH - /* if current != pkt, size is already checked */ - if (current == pkt && !_has_valid_size(pkt, nh)) { - DEBUG("ipv6_ext: invalid size\n"); - gnrc_pktbuf_release(pkt); - return; - } - - switch (_handle_rh(current, pkt)) { - case GNRC_IPV6_EXT_RH_AT_DST: - /* We are the final destination. So proceeds like normal packet. */ - nh = ext->nh; - DEBUG("ipv6_ext: next header = %" PRIu8 "\n", nh); - - if ((current = _mark_extension_header(current, &pkt)) == NULL) { - return; - } - - gnrc_ipv6_demux(netif, current, pkt, nh); /* demultiplex next header */ - - return; - - case GNRC_IPV6_EXT_RH_ERROR: - /* already released by _handle_rh, so no release here */ - return; - - case GNRC_IPV6_EXT_RH_FORWARDED: - /* the packet is forwarded and released. finish processing */ - return; - } - - break; -#endif /* MODULE_GNRC_IPV6_EXT_RH */ - - case PROTNUM_IPV6_EXT_HOPOPT: - case PROTNUM_IPV6_EXT_DST: - case PROTNUM_IPV6_EXT_FRAG: - case PROTNUM_IPV6_EXT_AH: - case PROTNUM_IPV6_EXT_ESP: - case PROTNUM_IPV6_EXT_MOB: - /* TODO: add handling of types */ - - /* if current != pkt, size is already checked */ - if (current == pkt && !_has_valid_size(pkt, nh)) { - DEBUG("ipv6_ext: invalid size\n"); - gnrc_pktbuf_release(pkt); - return; - } - - nh = ext->nh; - DEBUG("ipv6_ext: next header = %" PRIu8 "\n", nh); - - if ((current = _mark_extension_header(current, &pkt)) == NULL) { - return; - } - - gnrc_pktbuf_hold(pkt, 1); /* don't release on next dispatch */ - if (gnrc_netapi_dispatch_receive(GNRC_NETTYPE_IPV6, nh, pkt) == 0) { - gnrc_pktbuf_release(pkt); - } - - break; - - default: - gnrc_ipv6_demux(netif, current, pkt, nh); /* demultiplex next header */ - return; - } + DEBUG("ipv6_ext: next header = %u", nh); + if (!_has_valid_size(pkt, nh)) { + DEBUG("ipv6_ext: invalid size\n"); + gnrc_pktbuf_release(pkt); + return NULL; } + switch (nh) { + case PROTNUM_IPV6_EXT_RH: +#ifdef MODULE_GNRC_RPL_SRH + switch (_handle_rh(pkt)) { + case GNRC_IPV6_EXT_RH_AT_DST: + /* We are the final destination of the route laid out in + * the routing header. So proceeds like normal packet. */ + if (_mark_extension_header(pkt) == NULL) { + /* we couldn't mark the routing header though, return + * an error */ + return NULL; + } + break; - assert(false); /* never reaches here */ + default: + /* unexpected return value => error */ + gnrc_pktbuf_release(pkt); + /* Intentionally falls through */ + case GNRC_IPV6_EXT_RH_ERROR: + /* already released by _handle_rh, so no release here */ + case GNRC_IPV6_EXT_RH_FORWARDED: + /* the packet is forwarded and released. finish processing */ + return NULL; + } + + break; +#endif + + case PROTNUM_IPV6_EXT_HOPOPT: + case PROTNUM_IPV6_EXT_DST: + case PROTNUM_IPV6_EXT_FRAG: + case PROTNUM_IPV6_EXT_AH: + case PROTNUM_IPV6_EXT_ESP: + case PROTNUM_IPV6_EXT_MOB: + DEBUG("ipv6_ext: skipping over unsupported extension header\n"); + if (_mark_extension_header(pkt) == NULL) { + /* unable mark it though to get it out of the way of the + * payload, so return an error */ + return NULL; + } + break; + + default: + break; + } + return pkt; } gnrc_pktsnip_t *gnrc_ipv6_ext_build(gnrc_pktsnip_t *ipv6, gnrc_pktsnip_t *next, diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index 514f757f60..6ebcde40f1 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -93,58 +93,48 @@ kernel_pid_t gnrc_ipv6_init(void) static void _dispatch_next_header(gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt, uint8_t nh, bool interested); -/* - * current pkt - * | | - * v v - * IPv6 <- IPv6_EXT <- IPv6_EXT <- UNDEF - */ void gnrc_ipv6_demux(gnrc_netif_t *netif, gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt, uint8_t nh) { - bool interested = false; + bool interested; - current->type = gnrc_nettype_from_protnum(nh); - - switch (nh) { -#ifdef MODULE_GNRC_ICMPV6 - case PROTNUM_ICMPV6: - assert(current == pkt); - interested = true; - break; -#endif #ifdef MODULE_GNRC_IPV6_EXT - case PROTNUM_IPV6_EXT_HOPOPT: - case PROTNUM_IPV6_EXT_DST: - case PROTNUM_IPV6_EXT_RH: - case PROTNUM_IPV6_EXT_FRAG: - case PROTNUM_IPV6_EXT_AH: - case PROTNUM_IPV6_EXT_ESP: - case PROTNUM_IPV6_EXT_MOB: - interested = true; + bool is_ext = true; - break; -#endif - default: - (void)netif; -#ifdef MODULE_GNRC_SIXLOWPAN_IPHC_NHC - /* second statement is true for small 6LoWPAN NHC decompressed frames - * since in this case it looks like - * - * * GNRC_NETTYPE_UNDEF <- pkt - * v - * * GNRC_NETTYPE_UDP <- current - * v - * * GNRC_NETTYPE_EXT - * v - * * GNRC_NETTYPE_IPV6 - */ - assert((current == pkt) || (current == pkt->next)); -#else - assert(current == pkt); -#endif - break; + while (is_ext) { + switch (nh) { + case PROTNUM_IPV6_EXT_HOPOPT: + case PROTNUM_IPV6_EXT_DST: + case PROTNUM_IPV6_EXT_RH: + case PROTNUM_IPV6_EXT_FRAG: + case PROTNUM_IPV6_EXT_AH: + case PROTNUM_IPV6_EXT_ESP: + case PROTNUM_IPV6_EXT_MOB: { + ipv6_ext_t *ext_hdr; + + DEBUG("ipv6: handle extension header (nh = %u)\n", nh); + ext_hdr = pkt->data; + if ((pkt = gnrc_ipv6_ext_demux(pkt, nh)) == NULL) { + DEBUG("ipv6: packet was consumed by extension header " + "handling\n"); + return; + } + nh = ext_hdr->nh; + break; + } + default: + is_ext = false; + break; + } } +#endif /* MODULE_GNRC_IPV6_EXT */ + +#ifdef MODULE_GNRC_ICMPV6 + interested = (nh == PROTNUM_ICMPV6); +#else /* MODULE_GNRC_ICMPV6 */ + interested = false; +#endif /* MODULE_GNRC_ICMPV6 */ + current->type = gnrc_nettype_from_protnum(nh); _dispatch_next_header(current, pkt, nh, interested); @@ -158,21 +148,7 @@ void gnrc_ipv6_demux(gnrc_netif_t *netif, gnrc_pktsnip_t *current, DEBUG("ipv6: handle ICMPv6 packet (nh = %u)\n", nh); gnrc_icmpv6_demux(netif, pkt); return; -#endif -#ifdef MODULE_GNRC_IPV6_EXT - case PROTNUM_IPV6_EXT_HOPOPT: - case PROTNUM_IPV6_EXT_DST: - case PROTNUM_IPV6_EXT_RH: - case PROTNUM_IPV6_EXT_FRAG: - case PROTNUM_IPV6_EXT_AH: - case PROTNUM_IPV6_EXT_ESP: - case PROTNUM_IPV6_EXT_MOB: - DEBUG("ipv6: handle extension header (nh = %u)\n", nh); - - gnrc_ipv6_ext_demux(netif, current, pkt, nh); - - return; -#endif +#endif /* MODULE_GNRC_ICMPV6 */ default: assert(false); break; From f671a87fe2c539c3aecd595ae03fa4f6f209d042 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 24 Oct 2018 00:17:38 +0200 Subject: [PATCH 2/6] gnrc_ipv6_ext: remove unnecessary pkt write-protection As `pkt` isn't pre-parsed the write-protection of *the whole* packet (except the netif-header) comes for free, when this was done in the receive routine of IPv6. --- .../network_layer/ipv6/ext/gnrc_ipv6_ext.c | 36 +++++-------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/sys/net/gnrc/network_layer/ipv6/ext/gnrc_ipv6_ext.c b/sys/net/gnrc/network_layer/ipv6/ext/gnrc_ipv6_ext.c index a4a1e2035a..53accf24a7 100644 --- a/sys/net/gnrc/network_layer/ipv6/ext/gnrc_ipv6_ext.c +++ b/sys/net/gnrc/network_layer/ipv6/ext/gnrc_ipv6_ext.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2015 Martine Lenders + * Copyright (C) 2015 Cenk Gündoğan + * Copyright (C) 2018 Freie Universität Berlin * * This file is subject to the terms and conditions of the GNU Lesser * General Public License v2.1. See the file LICENSE in the top level @@ -10,6 +11,8 @@ * @{ * * @file + * @author Cenk Gündoğan + * @author Martine Lenders */ #include @@ -63,38 +66,17 @@ static void _forward_pkt(gnrc_pktsnip_t *pkt, ipv6_hdr_t *hdr) static int _handle_rh(gnrc_pktsnip_t *pkt) { gnrc_pktsnip_t *ipv6; - gnrc_pktsnip_t *current = pkt; - ipv6_ext_t *ext = (ipv6_ext_t *) current->data; - size_t current_offset; + ipv6_ext_t *ext = (ipv6_ext_t *)pkt->data; ipv6_hdr_t *hdr; int res; - /* check seg_left early to avoid duplicating the packet */ + /* check seg_left early to to exit quickly */ if (((ipv6_ext_rh_t *)ext)->seg_left == 0) { return GNRC_IPV6_EXT_RH_AT_DST; } - - /* We cannot use `gnrc_pktbuf_start_write` since it duplicates only - the head. `ipv6_ext_rh_process` modifies the IPv6 header as well as - the extension header */ - - current_offset = gnrc_pkt_len_upto(current->next, GNRC_NETTYPE_IPV6); - - if (pkt->users != 1) { - if ((ipv6 = gnrc_pktbuf_duplicate_upto(pkt, GNRC_NETTYPE_IPV6)) == NULL) { - DEBUG("ipv6: could not get a copy of pkt\n"); - gnrc_pktbuf_release(pkt); - return GNRC_IPV6_EXT_RH_ERROR; - } - pkt = ipv6; - hdr = ipv6->data; - ext = (ipv6_ext_t *)(((uint8_t *)ipv6->data) + current_offset); - } - else { - ipv6 = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6); - hdr = ipv6->data; - } - + ipv6 = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6); + assert(ipv6 != NULL); + hdr = ipv6->data; switch ((res = gnrc_ipv6_ext_rh_process(hdr, (ipv6_ext_rh_t *)ext))) { case GNRC_IPV6_EXT_RH_ERROR: /* TODO: send ICMPv6 error codes */ From 764ed8c30074e813eb84ee0159095745912e5c74 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 24 Oct 2018 00:19:49 +0200 Subject: [PATCH 3/6] gnrc_ipv6: make next-header demuxer private Since the recursion into `gnrc_ipv6_demux()` was removed in `gnrc_ipv6_ext`, `gnrc_ipv6.c` is the only user of this function, so it can be made private. It was only made public so it can be used from `gnrc_ipv6_ext`. --- sys/include/net/gnrc/ipv6.h | 26 --------------------- sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c | 7 +++--- 2 files changed, 3 insertions(+), 30 deletions(-) diff --git a/sys/include/net/gnrc/ipv6.h b/sys/include/net/gnrc/ipv6.h index 6e42b8abf3..9113d887f6 100644 --- a/sys/include/net/gnrc/ipv6.h +++ b/sys/include/net/gnrc/ipv6.h @@ -127,32 +127,6 @@ extern fib_table_t gnrc_ipv6_fib_table; */ kernel_pid_t gnrc_ipv6_init(void); -/** - * @brief Demultiplexes a packet according to @p nh. - * - * @internal - * - * **Do not use outside this module or its submodules!!!** - * Public access needed for Extension Headers. - * - * About `current` and `pkt`: - * - * current pkt - * | | - * v v - * IPv6 <- IPv6_EXT <- IPv6_EXT <- UNDEF - * - * This situation may happen when the packet has a source routing extension - * header (RFC 6554), and the packet is forwarded from an interface to another. - * - * @param[in] netif The receiving interface. - * @param[in] current A snip to process. - * @param[in] pkt A packet. - * @param[in] nh A protocol number (see @ref net_protnum) of the current snip. - */ -void gnrc_ipv6_demux(gnrc_netif_t *netif, gnrc_pktsnip_t *current, - gnrc_pktsnip_t *pkt, uint8_t nh); - /** * @brief Get the IPv6 header from a given list of @ref gnrc_pktsnip_t * diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index 6ebcde40f1..165cf9475d 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -93,8 +93,8 @@ kernel_pid_t gnrc_ipv6_init(void) static void _dispatch_next_header(gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt, uint8_t nh, bool interested); -void gnrc_ipv6_demux(gnrc_netif_t *netif, gnrc_pktsnip_t *current, - gnrc_pktsnip_t *pkt, uint8_t nh) +static void _demux(gnrc_netif_t *netif, gnrc_pktsnip_t *current, + gnrc_pktsnip_t *pkt, uint8_t nh) { bool interested; @@ -848,8 +848,7 @@ static void _receive(gnrc_pktsnip_t *pkt) #endif /* MODULE_GNRC_IPV6_ROUTER */ } - /* IPv6 internal demuxing (ICMPv6, Extension headers etc.) */ - gnrc_ipv6_demux(netif, pkt, pkt, hdr->nh); + _demux(netif, pkt, pkt, hdr->nh); } /** @} */ From e6df40dbde5d139856a627966b2ae69a5c9bfba2 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 24 Oct 2018 00:26:26 +0200 Subject: [PATCH 4/6] gnrc_ipv6: clean-up unrequired stuff after demux rework --- sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c | 66 +++++++-------------- 1 file changed, 23 insertions(+), 43 deletions(-) diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index 165cf9475d..c0588b3e93 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -90,11 +90,10 @@ kernel_pid_t gnrc_ipv6_init(void) return gnrc_ipv6_pid; } -static void _dispatch_next_header(gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt, - uint8_t nh, bool interested); +static void _dispatch_next_header(gnrc_pktsnip_t *pkt, unsigned nh, + bool interested); -static void _demux(gnrc_netif_t *netif, gnrc_pktsnip_t *current, - gnrc_pktsnip_t *pkt, uint8_t nh) +static void _demux(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt, unsigned nh) { bool interested; @@ -134,27 +133,18 @@ static void _demux(gnrc_netif_t *netif, gnrc_pktsnip_t *current, #else /* MODULE_GNRC_ICMPV6 */ interested = false; #endif /* MODULE_GNRC_ICMPV6 */ - current->type = gnrc_nettype_from_protnum(nh); - - _dispatch_next_header(current, pkt, nh, interested); - - if (!interested) { - return; - } - + pkt->type = gnrc_nettype_from_protnum(nh); + _dispatch_next_header(pkt, nh, interested); switch (nh) { #ifdef MODULE_GNRC_ICMPV6 case PROTNUM_ICMPV6: DEBUG("ipv6: handle ICMPv6 packet (nh = %u)\n", nh); gnrc_icmpv6_demux(netif, pkt); - return; + break; #endif /* MODULE_GNRC_ICMPV6 */ default: - assert(false); break; } - - assert(false); } ipv6_hdr_t *gnrc_ipv6_get_header(gnrc_pktsnip_t *pkt) @@ -172,36 +162,26 @@ ipv6_hdr_t *gnrc_ipv6_get_header(gnrc_pktsnip_t *pkt) } /* internal functions */ -static void _dispatch_next_header(gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt, - uint8_t nh, bool interested) +static void _dispatch_next_header(gnrc_pktsnip_t *pkt, unsigned nh, + bool interested) { -#ifdef MODULE_GNRC_IPV6_EXT - const bool should_dispatch_current_type = ((current->type != GNRC_NETTYPE_IPV6_EXT) || - (current->next->type == GNRC_NETTYPE_IPV6)); -#else - const bool should_dispatch_current_type = (current->next->type == GNRC_NETTYPE_IPV6); -#endif + const bool should_release = (gnrc_netreg_num(GNRC_NETTYPE_IPV6, nh) == 0) && + (!interested); DEBUG("ipv6: forward nh = %u to other threads\n", nh); - /* dispatch IPv6 extension header only once */ - if (should_dispatch_current_type) { - bool should_release = (!gnrc_netreg_lookup(GNRC_NETTYPE_IPV6, nh)) && - (!interested); - - if (!should_release) { - gnrc_pktbuf_hold(pkt, 1); /* don't remove from packet buffer in - * next dispatch */ - } - if (gnrc_netapi_dispatch_receive(current->type, - GNRC_NETREG_DEMUX_CTX_ALL, - pkt) == 0) { - gnrc_pktbuf_release(pkt); - } - - if (should_release) { - return; - } + if (!should_release) { + gnrc_pktbuf_hold(pkt, 1); /* don't remove from packet buffer in + * next dispatch */ + } + if (gnrc_netapi_dispatch_receive(pkt->type, + GNRC_NETREG_DEMUX_CTX_ALL, + pkt) == 0) { + gnrc_pktbuf_release(pkt); + } + if (should_release) { + /* we should exit early. pkt was already released above */ + return; } if (interested) { gnrc_pktbuf_hold(pkt, 1); /* don't remove from packet buffer in @@ -848,7 +828,7 @@ static void _receive(gnrc_pktsnip_t *pkt) #endif /* MODULE_GNRC_IPV6_ROUTER */ } - _demux(netif, pkt, pkt, hdr->nh); + _demux(netif, pkt, hdr->nh); } /** @} */ From b8f71c37ffd024ca7e940968c8e6cfab03d3c6b1 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 30 Oct 2018 17:52:15 +0100 Subject: [PATCH 5/6] gnrc_ipv6: rename should_release for clarity --- sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index c0588b3e93..cd697f8df0 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -165,12 +165,12 @@ ipv6_hdr_t *gnrc_ipv6_get_header(gnrc_pktsnip_t *pkt) static void _dispatch_next_header(gnrc_pktsnip_t *pkt, unsigned nh, bool interested) { - const bool should_release = (gnrc_netreg_num(GNRC_NETTYPE_IPV6, nh) == 0) && - (!interested); + const bool has_nh_subs = (gnrc_netreg_num(GNRC_NETTYPE_IPV6, nh) > 0) || + interested; DEBUG("ipv6: forward nh = %u to other threads\n", nh); - if (!should_release) { + if (has_nh_subs) { gnrc_pktbuf_hold(pkt, 1); /* don't remove from packet buffer in * next dispatch */ } @@ -179,7 +179,7 @@ static void _dispatch_next_header(gnrc_pktsnip_t *pkt, unsigned nh, pkt) == 0) { gnrc_pktbuf_release(pkt); } - if (should_release) { + if (!has_nh_subs) { /* we should exit early. pkt was already released above */ return; } From 4257b70c6fe36a8e7984d3b5fd5b09f9a15c17eb Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Wed, 14 Nov 2018 17:09:29 +0100 Subject: [PATCH 6/6] gnrc_pktbuf: update tense of deprecation note ;-) With the preceding changes the subject of the deprecation note on `gnrc_pktbuf_duplicate_upto()` becomes actual and thus doesn't need to be referred to in future but past tense. --- sys/include/net/gnrc/pktbuf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/include/net/gnrc/pktbuf.h b/sys/include/net/gnrc/pktbuf.h index ad109bb3ef..f6d4eac552 100644 --- a/sys/include/net/gnrc/pktbuf.h +++ b/sys/include/net/gnrc/pktbuf.h @@ -286,8 +286,8 @@ gnrc_pktsnip_t *gnrc_pktbuf_reverse_snips(gnrc_pktsnip_t *pkt); * The original snip is keeped as is except `users` decremented. * * @deprecated This function breaks the abstraction of `gnrc_pktbuf` and its - * only user within the RIOT code base `gnrc_ipv6_ext` is going to - * be reworked so it isn't needed anymore. + * only user within the RIOT code base `gnrc_ipv6_ext` was reworked + * so it isn't needed anymore. * It will be removed after the 2019.04 release. * * @param[in,out] pkt The snip to duplicate.