gnrc_ipv6: move ext. hdr handling out of general demux
They are handled separately anyway and this allows us to handle the Hop-by-hop option *before* forwarding in a later step.
This commit is contained in:
parent
17eee216b6
commit
5c0d18b25f
@ -66,6 +66,33 @@ gnrc_pktsnip_t *gnrc_ipv6_ext_demux(gnrc_pktsnip_t *pkt, unsigned nh);
|
||||
gnrc_pktsnip_t *gnrc_ipv6_ext_build(gnrc_pktsnip_t *ipv6, gnrc_pktsnip_t *next,
|
||||
uint8_t nh, size_t size);
|
||||
|
||||
#if defined(MODULE_GNRC_IPV6_EXT) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Processes a packet's extension headers.
|
||||
*
|
||||
* @param[in] pkt An IPv6 packet in receive order.
|
||||
* @param[in,out] nh **In:** The @ref net_protnum of gnrc_pktsnip_t::data of
|
||||
* @p pkt (i.e. the first extension header to be
|
||||
* processed). <br />
|
||||
* **Out:** The @ref net_protnum of header in
|
||||
* gnrc_pktsnip_t::data of @p pkt. The extension headers
|
||||
* are now marked, so their data can be found in
|
||||
* gnrc_pktsnip_t::next of @p pkt and the following. <br />
|
||||
* If the return value is NULL, the value of @p nh is
|
||||
* undefined.
|
||||
*
|
||||
* @return @p pkt with all extension headers marked until the first
|
||||
* non-extension header.
|
||||
* @return NULL, if packet was consumed by the extension header handling.
|
||||
* @return NULL, on error. @p pkt is released with EINVAL in that case.
|
||||
*/
|
||||
gnrc_pktsnip_t *gnrc_ipv6_ext_process_all(gnrc_pktsnip_t *pkt,
|
||||
uint8_t *nh);
|
||||
#else /* defined(MODULE_GNRC_IPV6_EXT) || defined(DOXYGEN) */
|
||||
/* NOPs to make the usage code more readable */
|
||||
#define gnrc_ipv6_ext_process_all(pkt, first_nh) (pkt);
|
||||
#endif /* defined(MODULE_GNRC_IPV6_EXT) || defined(DOXYGEN) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -28,6 +28,38 @@
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
gnrc_pktsnip_t *gnrc_ipv6_ext_process_all(gnrc_pktsnip_t *pkt,
|
||||
uint8_t *nh)
|
||||
{
|
||||
bool is_ext = true;
|
||||
while (is_ext) {
|
||||
switch (*nh) {
|
||||
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 NULL;
|
||||
}
|
||||
*nh = ext_hdr->nh;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
is_ext = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return pkt;
|
||||
}
|
||||
|
||||
#ifdef MODULE_GNRC_IPV6_EXT_RH
|
||||
/* unchecked precondition: hdr is gnrc_pktsnip_t::data of the
|
||||
* GNRC_NETTYPE_IPV6 snip within pkt */
|
||||
|
||||
@ -93,48 +93,18 @@ kernel_pid_t gnrc_ipv6_init(void)
|
||||
static void _dispatch_next_header(gnrc_pktsnip_t *pkt, unsigned nh,
|
||||
bool interested);
|
||||
|
||||
static inline bool _gnrc_ipv6_is_interested(unsigned nh) {
|
||||
#ifdef MODULE_GNRC_ICMPV6
|
||||
return (nh == PROTNUM_ICMPV6);
|
||||
#else /* MODULE_GNRC_ICMPV6 */
|
||||
return false;
|
||||
#endif /* MODULE_GNRC_ICMPV6 */
|
||||
}
|
||||
|
||||
static void _demux(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt, unsigned nh)
|
||||
{
|
||||
bool interested;
|
||||
|
||||
#ifdef MODULE_GNRC_IPV6_EXT
|
||||
bool is_ext = true;
|
||||
|
||||
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 */
|
||||
pkt->type = gnrc_nettype_from_protnum(nh);
|
||||
_dispatch_next_header(pkt, nh, interested);
|
||||
_dispatch_next_header(pkt, nh, _gnrc_ipv6_is_interested(nh));
|
||||
switch (nh) {
|
||||
#ifdef MODULE_GNRC_ICMPV6
|
||||
case PROTNUM_ICMPV6:
|
||||
@ -661,6 +631,7 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
||||
gnrc_netif_t *netif = NULL;
|
||||
gnrc_pktsnip_t *ipv6, *netif_hdr;
|
||||
ipv6_hdr_t *hdr;
|
||||
uint8_t first_nh;
|
||||
|
||||
assert(pkt != NULL);
|
||||
|
||||
@ -732,8 +703,9 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
||||
}
|
||||
|
||||
uint16_t ipv6_len = byteorder_ntohs(hdr->len);
|
||||
first_nh = hdr->nh;
|
||||
|
||||
if ((ipv6_len == 0) && (hdr->nh != PROTNUM_IPV6_NONXT)) {
|
||||
if ((ipv6_len == 0) && (first_nh != PROTNUM_IPV6_NONXT)) {
|
||||
/* this doesn't even make sense */
|
||||
DEBUG("ipv6: payload length 0, but next header not NONXT\n");
|
||||
gnrc_pktbuf_release(pkt);
|
||||
@ -758,7 +730,7 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
||||
ipv6_addr_to_str(addr_str, &(hdr->src), sizeof(addr_str)));
|
||||
DEBUG("dst = %s, next header = %u, length = %" PRIu16 ")\n",
|
||||
ipv6_addr_to_str(addr_str, &(hdr->dst), sizeof(addr_str)),
|
||||
hdr->nh, byteorder_ntohs(hdr->len));
|
||||
first_nh, byteorder_ntohs(hdr->len));
|
||||
|
||||
if (_pkt_not_for_me(&netif, hdr)) { /* if packet is not for me */
|
||||
DEBUG("ipv6: packet destination not this host\n");
|
||||
@ -827,8 +799,11 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
||||
return;
|
||||
#endif /* MODULE_GNRC_IPV6_ROUTER */
|
||||
}
|
||||
|
||||
_demux(netif, pkt, hdr->nh);
|
||||
if ((pkt = gnrc_ipv6_ext_process_all(pkt, &first_nh)) == NULL) {
|
||||
DEBUG("ipv6: packet was consumed in extension header handling\n");
|
||||
return;
|
||||
}
|
||||
_demux(netif, pkt, first_nh);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user