Merge pull request #10238 from miri64/gnrc_ipv6_ext/cleanup/merge-handle-rh
gnrc_ipv6_ext: merge _handle_rh and gnrc_ipv6_ext_rh_process
This commit is contained in:
commit
13e66ce3f2
@ -20,9 +20,7 @@
|
|||||||
#ifndef NET_GNRC_IPV6_EXT_RH_H
|
#ifndef NET_GNRC_IPV6_EXT_RH_H
|
||||||
#define NET_GNRC_IPV6_EXT_RH_H
|
#define NET_GNRC_IPV6_EXT_RH_H
|
||||||
|
|
||||||
#include "net/ipv6/hdr.h"
|
#include "net/gnrc/pkt.h"
|
||||||
|
|
||||||
#include "net/ipv6/ext/rh.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -56,14 +54,14 @@ enum {
|
|||||||
/**
|
/**
|
||||||
* @brief Process the routing header of an IPv6 packet.
|
* @brief Process the routing header of an IPv6 packet.
|
||||||
*
|
*
|
||||||
* @param[in, out] ipv6 An IPv6 packet.
|
* @param[in] pkt An IPv6 packet containing the routing header in the first
|
||||||
* @param[in] ext A routing header of @p ipv6.
|
* snip
|
||||||
*
|
*
|
||||||
* @return @ref GNRC_IPV6_EXT_RH_AT_DST, on success
|
* @return @ref GNRC_IPV6_EXT_RH_AT_DST, on success
|
||||||
* @return @ref GNRC_IPV6_EXT_RH_FORWARDED, when @p pkt was forwarded
|
* @return @ref GNRC_IPV6_EXT_RH_FORWARDED, when @p pkt was forwarded
|
||||||
* @return @ref GNRC_IPV6_EXT_RH_ERROR, on error
|
* @return @ref GNRC_IPV6_EXT_RH_ERROR, on error
|
||||||
*/
|
*/
|
||||||
int gnrc_ipv6_ext_rh_process(ipv6_hdr_t *ipv6, ipv6_ext_rh_t *ext);
|
int gnrc_ipv6_ext_rh_process(gnrc_pktsnip_t *pkt);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@ -148,75 +148,6 @@ static bool _duplicate_hopopt(gnrc_pktsnip_t *pkt, unsigned protnum)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MODULE_GNRC_IPV6_EXT_RH
|
|
||||||
/* unchecked precondition: hdr is gnrc_pktsnip_t::data of the
|
|
||||||
* GNRC_NETTYPE_IPV6 snip within pkt */
|
|
||||||
static void _forward_pkt(gnrc_pktsnip_t *pkt, ipv6_hdr_t *hdr)
|
|
||||||
{
|
|
||||||
gnrc_pktsnip_t *netif_snip;
|
|
||||||
|
|
||||||
if (--(hdr->hl) == 0) {
|
|
||||||
DEBUG("ipv6_ext_rh: hop limit reached 0: drop packet\n");
|
|
||||||
gnrc_pktbuf_release(pkt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* remove L2 headers around IPV6 */
|
|
||||||
netif_snip = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_NETIF);
|
|
||||||
if (netif_snip != NULL) {
|
|
||||||
pkt = gnrc_pktbuf_remove_snip(pkt, netif_snip);
|
|
||||||
}
|
|
||||||
/* reverse packet into send order */
|
|
||||||
pkt = gnrc_pktbuf_reverse_snips(pkt);
|
|
||||||
if (pkt == NULL) {
|
|
||||||
DEBUG("ipv6_ext_rh: can't reverse snip order in packet");
|
|
||||||
/* gnrc_pktbuf_reverse_snips() releases pkt on error */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* forward packet */
|
|
||||||
if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_IPV6,
|
|
||||||
GNRC_NETREG_DEMUX_CTX_ALL,
|
|
||||||
pkt)) {
|
|
||||||
DEBUG("ipv6_ext_rh: could not dispatch packet to the IPv6 "
|
|
||||||
"thread\n");
|
|
||||||
gnrc_pktbuf_release(pkt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* handle routing header at pkt->data */
|
|
||||||
static int _handle_rh(gnrc_pktsnip_t *pkt)
|
|
||||||
{
|
|
||||||
gnrc_pktsnip_t *ipv6;
|
|
||||||
ipv6_ext_t *ext = (ipv6_ext_t *)pkt->data;
|
|
||||||
ipv6_hdr_t *hdr;
|
|
||||||
int res;
|
|
||||||
|
|
||||||
/* check seg_left early to to exit quickly */
|
|
||||||
if (((ipv6_ext_rh_t *)ext)->seg_left == 0) {
|
|
||||||
return GNRC_IPV6_EXT_RH_AT_DST;
|
|
||||||
}
|
|
||||||
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 */
|
|
||||||
gnrc_pktbuf_release(pkt);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GNRC_IPV6_EXT_RH_FORWARDED:
|
|
||||||
_forward_pkt(pkt, hdr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GNRC_IPV6_EXT_RH_AT_DST:
|
|
||||||
/* this should not happen since we checked seg_left early */
|
|
||||||
gnrc_pktbuf_release(pkt);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
#endif /* MODULE_GNRC_IPV6_EXT_RH */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Marks an IPv6 extension header according to the length field
|
* @brief Marks an IPv6 extension header according to the length field
|
||||||
* provided by the extension header itself.
|
* provided by the extension header itself.
|
||||||
@ -297,8 +228,8 @@ static gnrc_pktsnip_t *_demux(gnrc_pktsnip_t *pkt, unsigned protnum)
|
|||||||
}
|
}
|
||||||
switch (protnum) {
|
switch (protnum) {
|
||||||
case PROTNUM_IPV6_EXT_RH:
|
case PROTNUM_IPV6_EXT_RH:
|
||||||
#ifdef MODULE_GNRC_RPL_SRH
|
#ifdef MODULE_GNRC_IPV6_EXT_RH
|
||||||
switch (_handle_rh(pkt)) {
|
switch (gnrc_ipv6_ext_rh_process(pkt)) {
|
||||||
case GNRC_IPV6_EXT_RH_AT_DST:
|
case GNRC_IPV6_EXT_RH_AT_DST:
|
||||||
/* We are the final destination of the route laid out in
|
/* We are the final destination of the route laid out in
|
||||||
* the routing header. So proceeds like normal packet. */
|
* the routing header. So proceeds like normal packet. */
|
||||||
@ -314,14 +245,15 @@ static gnrc_pktsnip_t *_demux(gnrc_pktsnip_t *pkt, unsigned protnum)
|
|||||||
gnrc_pktbuf_release(pkt);
|
gnrc_pktbuf_release(pkt);
|
||||||
/* Intentionally falls through */
|
/* Intentionally falls through */
|
||||||
case GNRC_IPV6_EXT_RH_ERROR:
|
case GNRC_IPV6_EXT_RH_ERROR:
|
||||||
/* already released by _handle_rh, so no release here */
|
/* already released by gnrc_ipv6_ext_rh_process, so no
|
||||||
|
* release here */
|
||||||
case GNRC_IPV6_EXT_RH_FORWARDED:
|
case GNRC_IPV6_EXT_RH_FORWARDED:
|
||||||
/* the packet is forwarded and released. finish processing */
|
/* the packet is forwarded and released. finish processing */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif /* MODULE_GNRC_IPV6_EXT_RH */
|
||||||
|
|
||||||
case PROTNUM_IPV6_EXT_HOPOPT:
|
case PROTNUM_IPV6_EXT_HOPOPT:
|
||||||
case PROTNUM_IPV6_EXT_DST:
|
case PROTNUM_IPV6_EXT_DST:
|
||||||
@ -385,5 +317,4 @@ gnrc_pktsnip_t *gnrc_ipv6_ext_build(gnrc_pktsnip_t *ipv6, gnrc_pktsnip_t *next,
|
|||||||
return snip;
|
return snip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2015 Martine Lenders <mlenders@inf.fu-berlin.de>
|
* Copyright (C) 2015 Cenk Gündoğan <cenk.guendogan@fu-berlin.de>
|
||||||
|
* Copyright (C) 2018 Freie Universität Berlin
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU Lesser
|
* 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
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
@ -10,29 +11,90 @@
|
|||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* @file
|
* @file
|
||||||
|
* @author Cenk Gündoğan <cenk.guendogan@fu-berlin.de>
|
||||||
|
* @author Martine Lenders <m.lenders@fu-berlin.de>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include "net/ipv6/ext/rh.h"
|
||||||
|
#include "net/gnrc.h"
|
||||||
|
|
||||||
#include "net/protnum.h"
|
#ifdef MODULE_GNRC_RPL_SRH
|
||||||
#include "net/ipv6/ext.h"
|
|
||||||
#include "net/gnrc/ipv6/ext/rh.h"
|
|
||||||
#include "net/gnrc/rpl/srh.h"
|
#include "net/gnrc/rpl/srh.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
int gnrc_ipv6_ext_rh_process(ipv6_hdr_t *hdr, ipv6_ext_rh_t *ext)
|
#include "net/gnrc/ipv6/ext/rh.h"
|
||||||
|
|
||||||
|
#define ENABLE_DEBUG (0)
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
/* unchecked precondition: hdr is gnrc_pktsnip_t::data of the
|
||||||
|
* GNRC_NETTYPE_IPV6 snip within pkt */
|
||||||
|
static void _forward_pkt(gnrc_pktsnip_t *pkt, ipv6_hdr_t *hdr)
|
||||||
{
|
{
|
||||||
(void) hdr;
|
gnrc_pktsnip_t *netif_snip;
|
||||||
|
|
||||||
|
if (--(hdr->hl) == 0) {
|
||||||
|
DEBUG("ipv6_ext_rh: hop limit reached 0: drop packet\n");
|
||||||
|
gnrc_pktbuf_release(pkt);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* remove L2 headers around IPV6 */
|
||||||
|
netif_snip = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_NETIF);
|
||||||
|
if (netif_snip != NULL) {
|
||||||
|
pkt = gnrc_pktbuf_remove_snip(pkt, netif_snip);
|
||||||
|
}
|
||||||
|
/* reverse packet into send order */
|
||||||
|
pkt = gnrc_pktbuf_reverse_snips(pkt);
|
||||||
|
if (pkt == NULL) {
|
||||||
|
DEBUG("ipv6_ext_rh: can't reverse snip order in packet");
|
||||||
|
/* gnrc_pktbuf_reverse_snips() releases pkt on error */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* forward packet */
|
||||||
|
if (!gnrc_netapi_dispatch_send(GNRC_NETTYPE_IPV6,
|
||||||
|
GNRC_NETREG_DEMUX_CTX_ALL,
|
||||||
|
pkt)) {
|
||||||
|
DEBUG("ipv6_ext_rh: could not dispatch packet to the IPv6 "
|
||||||
|
"thread\n");
|
||||||
|
gnrc_pktbuf_release(pkt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int gnrc_ipv6_ext_rh_process(gnrc_pktsnip_t *pkt)
|
||||||
|
{
|
||||||
|
gnrc_pktsnip_t *ipv6;
|
||||||
|
ipv6_ext_rh_t *ext = pkt->data;
|
||||||
|
ipv6_hdr_t *hdr;
|
||||||
|
int res = GNRC_IPV6_EXT_RH_AT_DST;
|
||||||
|
|
||||||
|
/* check seg_left early to avoid duplicating the packet */
|
||||||
|
if (ext->seg_left == 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
ipv6 = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6);
|
||||||
|
assert(ipv6 != NULL);
|
||||||
|
hdr = ipv6->data;
|
||||||
switch (ext->type) {
|
switch (ext->type) {
|
||||||
#ifdef MODULE_GNRC_RPL_SRH
|
#ifdef MODULE_GNRC_RPL_SRH
|
||||||
case IPV6_EXT_RH_TYPE_RPL_SRH:
|
case IPV6_EXT_RH_TYPE_RPL_SRH:
|
||||||
return gnrc_rpl_srh_process(hdr, (gnrc_rpl_srh_t *)ext);
|
res = gnrc_rpl_srh_process(hdr, (gnrc_rpl_srh_t *)ext);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
res = GNRC_IPV6_EXT_RH_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return GNRC_IPV6_EXT_RH_ERROR;
|
switch (res) {
|
||||||
|
case GNRC_IPV6_EXT_RH_FORWARDED:
|
||||||
|
_forward_pkt(pkt, hdr);
|
||||||
|
break;
|
||||||
|
case GNRC_IPV6_EXT_RH_AT_DST:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
gnrc_pktbuf_release(pkt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user