-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13275 from miri64/gnrc_ipv6_ext_opt/feat/initial
gnrc_ipv6_ext_opt: initial import
- Loading branch information
Showing
13 changed files
with
1,108 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
* Copyright (C) 2020 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 | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @defgroup net_gnrc_ipv6_ext_opt Support for IPv6 option extension headers | ||
* @ingroup net_gnrc_ipv6_ext | ||
* @brief GNRC implementation of IPv6 hop-by-hop and destination option | ||
* header extension | ||
* @{ | ||
* | ||
* @file | ||
* @brief GNRC hop-by-hop and destination option header definitions. | ||
* | ||
* @author Martine Lenders <[email protected]> | ||
*/ | ||
#ifndef NET_GNRC_IPV6_EXT_OPT_H | ||
#define NET_GNRC_IPV6_EXT_OPT_H | ||
|
||
#include <stdint.h> | ||
|
||
#include "net/gnrc/pkt.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @brief Processes all options within an IPv6 option header | ||
* | ||
* @pre `pkt != NULL` | ||
* @pre `(protnum == PROTNUM_IPV6_EXT_HOPOPT) || (protnum == PROTNUM_IPV6_EXT_DST)` | ||
* | ||
* @param[in] pkt The packet containing the option header. The option | ||
* must be contained in the first snip, with all | ||
* preceding headers marked (in receive order). | ||
* Must not be NULL. | ||
* @param[in] protnum The protocol number of the option header. Must be | ||
* @ref PROTNUM_IPV6_EXT_HOPOPT or @ref | ||
* PROTNUM_IPV6_EXT_DST | ||
* | ||
* @return @p pkt with the option header marked on success. | ||
* @return NULL, if the packet was consumed by the option handling. | ||
* @return NULL, on error. @p pkt is released with EINVAL in that case and if | ||
* necessary and [`gnrc_icmpv6_error`](@ref net_gnrc_icmpv6_error) is | ||
* used, the according ICMPv6 error message is sent. | ||
*/ | ||
gnrc_pktsnip_t *gnrc_ipv6_ext_opt_process(gnrc_pktsnip_t *pkt, | ||
uint8_t protnum); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* NET_GNRC_IPV6_EXT_OPT_H */ | ||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
* Copyright (C) 2020 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 | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @defgroup net_ipv6_ext_opt IPv6 destination and hop-by-hop options | ||
* @ingroup net_ipv6_ext | ||
* @brief Definitions for IPv6 destination and hop-by-hop options | ||
* extension headers | ||
* @{ | ||
* | ||
* @file | ||
* @brief Destination and hop-by-hop options extension header definitions. | ||
* | ||
* @author Martine Lenders <[email protected]> | ||
*/ | ||
#ifndef NET_IPV6_EXT_OPT_H | ||
#define NET_IPV6_EXT_OPT_H | ||
|
||
#include <stdint.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/** | ||
* @name Destination and hop-by-hop option types | ||
* @see [IANA, IPv6 parameters] | ||
* (https://www.iana.org/assignments/ipv6-parameters/ipv6-parameters.xhtml#ipv6-parameters-2) | ||
* @{ | ||
*/ | ||
#define IPV6_EXT_OPT_PAD1 (0x00U) /**< Pad1 */ | ||
#define IPV6_EXT_OPT_PADN (0x01U) /**< PadN */ | ||
#define IPV6_EXT_OPT_JUMBO (0xC2U) /**< Jumbo payload */ | ||
#define IPV6_EXT_OPT_RPL (0x63U) /**< RPL Option */ | ||
#define IPV6_EXT_OPT_TEL (0x04U) /**< Tunnel Encapsulation Limit */ | ||
#define IPV6_EXT_OPT_RTR_ALERT (0x05U) /**< Router Alert */ | ||
#define IPV6_EXT_OPT_QUICK_START (0x26U) /**< Quick-Start */ | ||
#define IPV6_EXT_OPT_CALIPSO (0x07U) /**< CALIPSO */ | ||
#define IPV6_EXT_OPT_SMF_DPD (0x08U) /**< SMF_DPD */ | ||
#define IPV6_EXT_OPT_HOME_ADDR (0xC9U) /**< Home Address */ | ||
#define IPV6_EXT_OPT_ILNP_NONCE (0x8BU) /**< ILNP Nonce */ | ||
#define IPV6_EXT_OPT_LIO (0x8CU) /**< Line-Identification Option */ | ||
#define IPV6_EXT_OPT_MPL (0x6DU) /**< MPL Option */ | ||
#define IPV6_EXT_OPT_IP_DFF (0xEEU) /**< IP_DFF */ | ||
#define IPV6_EXT_OPT_PDM (0x0FU) /**< Performance and Diagnostic Metrics */ | ||
/** @} */ | ||
|
||
/** | ||
* @name Processing actions | ||
* @see [RFC 8200, section 4.2](https://tools.ietf.org/html/rfc8200#section-4.2) | ||
* | ||
* > The Option Type identifiers are internally encoded such that their | ||
* > highest-order 2 bits specify the action that must be taken if the | ||
* > processing IPv6 node does not recognize the Option Type | ||
* @{ | ||
*/ | ||
/** | ||
* @brief mask to decode action from type | ||
*/ | ||
#define IPV6_EXT_OPT_ACTION_MASK (0xc0) | ||
/** | ||
* @brief skip over this option and continue processing the header | ||
*/ | ||
#define IPV6_EXT_OPT_ACTION_SKIP (0x00) | ||
#define IPV6_EXT_OPT_ACTION_DISC (0x40) /**< discard the packet */ | ||
/** | ||
* @brief discard the packet | ||
* | ||
* > and, regardless of whether or not the packet's Destination Address | ||
* > was a multicast address, send an ICMP Parameter Problem, Code 2, | ||
* > message to the packet's Source Address, pointing to the | ||
* > unrecognized Option Type. | ||
*/ | ||
#define IPV6_EXT_OPT_ACTION_DISC_ERR_MCAST (0x80) | ||
|
||
/** | ||
* @brief discard the packet | ||
* | ||
* > and, only if the packet's Destination Address was not a multicast | ||
* > address, send an ICMP Parameter Problem, Code 2, message to the | ||
* > packet's Source Address, pointing to the unrecognized Option Type. | ||
*/ | ||
#define IPV6_EXT_OPT_ACTION_DISC_ERR (0xc0) | ||
/** @} */ | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif /* NET_IPV6_EXT_OPT_H */ | ||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
MODULE := gnrc_ipv6_ext_opt | ||
|
||
include $(RIOTBASE)/Makefile.base |
133 changes: 133 additions & 0 deletions
133
sys/net/gnrc/network_layer/ipv6/ext/opt/gnrc_ipv6_ext_opt.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/* | ||
* Copyright (C) 2020 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 | ||
* directory for more details. | ||
*/ | ||
|
||
/** | ||
* @{ | ||
* | ||
* @file | ||
* @author Martine Lenders <[email protected]> | ||
*/ | ||
|
||
#include "net/ipv6.h" | ||
#include "net/ipv6/ext.h" | ||
#include "net/ipv6/ext/opt.h" | ||
#include "net/gnrc/icmpv6/error.h" | ||
#include "net/gnrc/pktbuf.h" | ||
|
||
#include "net/gnrc/ipv6/ext/opt.h" | ||
|
||
#define ENABLE_DEBUG (0) | ||
#include "debug.h" | ||
|
||
/** | ||
* @brief Determine what action to do, when option is not recognized | ||
* | ||
* @see https://tools.ietf.org/html/rfc8200#section-4.2 | ||
* | ||
* @param[in] type Type of the option | ||
*/ | ||
static inline uint8_t _unrec_action(uint8_t type) | ||
{ | ||
return (type & IPV6_EXT_OPT_ACTION_MASK); | ||
} | ||
|
||
static bool _multicast_dst(gnrc_pktsnip_t *pkt) | ||
{ | ||
gnrc_pktsnip_t *ipv6 = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6); | ||
ipv6_hdr_t *ipv6_hdr; | ||
|
||
assert(ipv6 != NULL); | ||
ipv6_hdr = ipv6->data; | ||
return ipv6_addr_is_multicast(&ipv6_hdr->dst); | ||
} | ||
|
||
gnrc_pktsnip_t *gnrc_ipv6_ext_opt_process(gnrc_pktsnip_t *pkt, | ||
uint8_t protnum) | ||
{ | ||
assert(pkt != NULL); | ||
assert((protnum == PROTNUM_IPV6_EXT_HOPOPT) || | ||
(protnum == PROTNUM_IPV6_EXT_DST)); | ||
gnrc_pktsnip_t *hdr; | ||
ipv6_ext_t *opt_hdr = pkt->data; | ||
uint8_t *opts; | ||
size_t hdr_len; | ||
|
||
if (pkt->size < sizeof(ipv6_ext_t)) { | ||
DEBUG("gnrc_ipv6_ext_opt: packet of invalid size\n"); | ||
goto error; | ||
} | ||
hdr_len = ((opt_hdr->len * IPV6_EXT_LEN_UNIT) + IPV6_EXT_LEN_UNIT); | ||
hdr = gnrc_pktbuf_mark(pkt, hdr_len, GNRC_NETTYPE_IPV6_EXT); | ||
if (hdr == NULL) { | ||
DEBUG("gnrc_ipv6_ext_opt: unable to mark option header\n"); | ||
goto error; | ||
} | ||
opts = hdr->data; | ||
for (unsigned offset = sizeof(ipv6_ext_t); offset < hdr_len;) { | ||
uint8_t opt_type = opts[offset++]; | ||
uint8_t opt_len; | ||
|
||
if (opt_type == IPV6_EXT_OPT_PAD1) { | ||
/* nothing more to do */ | ||
continue; | ||
} | ||
opt_len = opts[offset++]; | ||
if (opt_len > (hdr_len - offset)) { | ||
DEBUG("gnrc_ipv6_ext_opt: invalid option size\n"); | ||
goto error; | ||
} | ||
switch (opt_type) { | ||
/* IPV6_EXT_OPT_PAD1 already handled before length check due | ||
* to special format */ | ||
case IPV6_EXT_OPT_PADN: | ||
/* nothing to do, offset will be progressed below */ | ||
break; | ||
default: { | ||
bool send_error = false; | ||
|
||
switch (_unrec_action(opt_type)) { | ||
case IPV6_EXT_OPT_ACTION_SKIP: | ||
DEBUG("gnrc_ipv6_ext_opt: skipping unknown " | ||
"option %02x\n", opt_type); | ||
/* skip here already, as we don't reach the | ||
* incrementation of offset below */ | ||
offset += opt_len; | ||
continue; | ||
case IPV6_EXT_OPT_ACTION_DISC: | ||
break; | ||
case IPV6_EXT_OPT_ACTION_DISC_ERR_MCAST: | ||
send_error = IS_USED(MODULE_GNRC_ICMPV6_ERROR); | ||
break; | ||
case IPV6_EXT_OPT_ACTION_DISC_ERR: | ||
send_error = IS_USED(MODULE_GNRC_ICMPV6_ERROR) && | ||
!_multicast_dst(pkt); | ||
break; | ||
} | ||
DEBUG("gnrc_ipv6_ext_opt: discarding packet with unknown " | ||
"option %02x\n", opt_type); | ||
if (send_error) { | ||
DEBUG("gnrc_ipv6_ext_opt: reporting parameter problem " | ||
"for option %02x (pos at %02x)\n", opts[offset - 2U], | ||
opt_type); | ||
gnrc_icmpv6_error_param_prob_send( | ||
ICMPV6_ERROR_PARAM_PROB_OPT, | ||
/* offset was already progressed to opt data*/ | ||
&opts[offset - 2U], pkt); | ||
} | ||
goto error; | ||
} | ||
} | ||
offset += opt_len; | ||
} | ||
return pkt; | ||
error: | ||
gnrc_pktbuf_release_error(pkt, EINVAL); | ||
return NULL; | ||
} | ||
|
||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
DEVELHELP = 1 | ||
# name of your application | ||
include ../Makefile.tests_common | ||
|
||
export TAP ?= tap0 | ||
|
||
# use Ethernet as link-layer protocol | ||
ifeq (native,$(BOARD)) | ||
TERMFLAGS ?= $(TAP) | ||
else | ||
ETHOS_BAUDRATE ?= 115200 | ||
CFLAGS += -DETHOS_BAUDRATE=$(ETHOS_BAUDRATE) | ||
TERMDEPS += ethos | ||
TERMPROG ?= sudo $(RIOTTOOLS)/ethos/ethos | ||
TERMFLAGS ?= $(TAP) $(PORT) $(ETHOS_BAUDRATE) | ||
endif | ||
USEMODULE += auto_init_gnrc_netif | ||
USEMODULE += gnrc_ipv6_default | ||
USEMODULE += gnrc_icmpv6_error | ||
USEMODULE += gnrc_pktdump | ||
USEMODULE += gnrc_pktbuf_cmd | ||
# IPv6 extension headers | ||
USEMODULE += gnrc_ipv6_ext_opt | ||
USEMODULE += od | ||
# Add also the shell, some shell commands | ||
USEMODULE += shell | ||
USEMODULE += shell_commands | ||
USEMODULE += ps | ||
|
||
# The test requires some setup and to be run as root | ||
# So it cannot currently be run | ||
TEST_ON_CI_BLACKLIST += all | ||
|
||
.PHONY: ethos | ||
|
||
ethos: | ||
$(Q)env -u CC -u CFLAGS make -C $(RIOTTOOLS)/ethos | ||
|
||
include $(RIOTBASE)/Makefile.include |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Put board specific dependencies here | ||
ifeq (native,$(BOARD)) | ||
USEMODULE += netdev_tap | ||
else | ||
USEMODULE += stdio_ethos | ||
endif |
Oops, something went wrong.