mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-16 18:13:49 +01:00
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,
|
gnrc_pktsnip_t *gnrc_ipv6_ext_build(gnrc_pktsnip_t *ipv6, gnrc_pktsnip_t *next,
|
||||||
uint8_t nh, size_t size);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -28,6 +28,38 @@
|
|||||||
#define ENABLE_DEBUG (0)
|
#define ENABLE_DEBUG (0)
|
||||||
#include "debug.h"
|
#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
|
#ifdef MODULE_GNRC_IPV6_EXT_RH
|
||||||
/* unchecked precondition: hdr is gnrc_pktsnip_t::data of the
|
/* unchecked precondition: hdr is gnrc_pktsnip_t::data of the
|
||||||
* GNRC_NETTYPE_IPV6 snip within pkt */
|
* 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,
|
static void _dispatch_next_header(gnrc_pktsnip_t *pkt, unsigned nh,
|
||||||
bool interested);
|
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)
|
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);
|
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) {
|
switch (nh) {
|
||||||
#ifdef MODULE_GNRC_ICMPV6
|
#ifdef MODULE_GNRC_ICMPV6
|
||||||
case PROTNUM_ICMPV6:
|
case PROTNUM_ICMPV6:
|
||||||
@ -661,6 +631,7 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
|||||||
gnrc_netif_t *netif = NULL;
|
gnrc_netif_t *netif = NULL;
|
||||||
gnrc_pktsnip_t *ipv6, *netif_hdr;
|
gnrc_pktsnip_t *ipv6, *netif_hdr;
|
||||||
ipv6_hdr_t *hdr;
|
ipv6_hdr_t *hdr;
|
||||||
|
uint8_t first_nh;
|
||||||
|
|
||||||
assert(pkt != NULL);
|
assert(pkt != NULL);
|
||||||
|
|
||||||
@ -732,8 +703,9 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint16_t ipv6_len = byteorder_ntohs(hdr->len);
|
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 */
|
/* this doesn't even make sense */
|
||||||
DEBUG("ipv6: payload length 0, but next header not NONXT\n");
|
DEBUG("ipv6: payload length 0, but next header not NONXT\n");
|
||||||
gnrc_pktbuf_release(pkt);
|
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)));
|
ipv6_addr_to_str(addr_str, &(hdr->src), sizeof(addr_str)));
|
||||||
DEBUG("dst = %s, next header = %u, length = %" PRIu16 ")\n",
|
DEBUG("dst = %s, next header = %u, length = %" PRIu16 ")\n",
|
||||||
ipv6_addr_to_str(addr_str, &(hdr->dst), sizeof(addr_str)),
|
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 */
|
if (_pkt_not_for_me(&netif, hdr)) { /* if packet is not for me */
|
||||||
DEBUG("ipv6: packet destination not this host\n");
|
DEBUG("ipv6: packet destination not this host\n");
|
||||||
@ -827,8 +799,11 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
|||||||
return;
|
return;
|
||||||
#endif /* MODULE_GNRC_IPV6_ROUTER */
|
#endif /* MODULE_GNRC_IPV6_ROUTER */
|
||||||
}
|
}
|
||||||
|
if ((pkt = gnrc_ipv6_ext_process_all(pkt, &first_nh)) == NULL) {
|
||||||
_demux(netif, pkt, hdr->nh);
|
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