1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

Merge pull request #10233 from miri64/gnrc_ipv6/enh/assume-no-preparsed-pkt

gnrc_ipv6: assume no preparsed packets
This commit is contained in:
José Alamos 2018-12-10 14:21:17 +01:00 committed by GitHub
commit 970bec1d1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 30 additions and 226 deletions

View File

@ -72,9 +72,6 @@ static void _send(gnrc_pktsnip_t *pkt, bool prep_hdr);
/* Main event loop for IPv6 */
static void *_event_loop(void *args);
/* Handles encapsulated IPv6 packets: http://tools.ietf.org/html/rfc2473 */
static void _decapsulate(gnrc_pktsnip_t *pkt);
kernel_pid_t gnrc_ipv6_init(void)
{
if (gnrc_ipv6_pid == KERNEL_PID_UNDEF) {
@ -128,11 +125,6 @@ void gnrc_ipv6_demux(gnrc_netif_t *netif, gnrc_pktsnip_t *current,
break;
#endif
case PROTNUM_IPV6:
assert(current == pkt);
interested = true;
break;
default:
(void)netif;
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC_NHC
@ -181,10 +173,6 @@ void gnrc_ipv6_demux(gnrc_netif_t *netif, gnrc_pktsnip_t *current,
return;
#endif
case PROTNUM_IPV6:
DEBUG("ipv6: handle encapsulated IPv6 packet (nh = %u)\n", nh);
_decapsulate(pkt);
return;
default:
assert(false);
break;
@ -213,11 +201,9 @@ static void _dispatch_next_header(gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt,
{
#ifdef MODULE_GNRC_IPV6_EXT
const bool should_dispatch_current_type = ((current->type != GNRC_NETTYPE_IPV6_EXT) ||
(current->next->type == GNRC_NETTYPE_IPV6)) &&
(current->type != GNRC_NETTYPE_IPV6);
(current->next->type == GNRC_NETTYPE_IPV6));
#else
const bool should_dispatch_current_type = (current->next->type == GNRC_NETTYPE_IPV6) &&
(current->type != GNRC_NETTYPE_IPV6);
const bool should_dispatch_current_type = (current->next->type == GNRC_NETTYPE_IPV6);
#endif
DEBUG("ipv6: forward nh = %u to other threads\n", nh);
@ -717,7 +703,7 @@ static inline bool _pkt_not_for_me(gnrc_netif_t **netif, ipv6_hdr_t *hdr)
static void _receive(gnrc_pktsnip_t *pkt)
{
gnrc_netif_t *netif = NULL;
gnrc_pktsnip_t *ipv6, *netif_hdr, *first_ext;
gnrc_pktsnip_t *ipv6, *netif_hdr;
ipv6_hdr_t *hdr;
assert(pkt != NULL);
@ -734,64 +720,14 @@ static void _receive(gnrc_pktsnip_t *pkt)
#endif
}
first_ext = pkt;
for (ipv6 = pkt; ipv6 != NULL; ipv6 = ipv6->next) { /* find IPv6 header if already marked */
if ((ipv6->type == GNRC_NETTYPE_IPV6) && (ipv6->size == sizeof(ipv6_hdr_t)) &&
(ipv6->data != NULL) && (ipv6_hdr_is(ipv6->data))) {
break;
}
first_ext = ipv6;
}
if (ipv6 == NULL) {
if ((pkt->data == NULL) || !ipv6_hdr_is(pkt->data)) {
DEBUG("ipv6: Received packet was not IPv6, dropping packet\n");
gnrc_pktbuf_release(pkt);
return;
}
#ifdef MODULE_GNRC_IPV6_WHITELIST
if (!gnrc_ipv6_whitelisted(&((ipv6_hdr_t *)(pkt->data))->src)) {
DEBUG("ipv6: Source address not whitelisted, dropping packet\n");
gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_PROHIB, pkt);
gnrc_pktbuf_release(pkt);
return;
}
#endif
#ifdef MODULE_GNRC_IPV6_BLACKLIST
if (gnrc_ipv6_blacklisted(&((ipv6_hdr_t *)(pkt->data))->src)) {
DEBUG("ipv6: Source address blacklisted, dropping packet\n");
gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_PROHIB, pkt);
gnrc_pktbuf_release(pkt);
return;
}
#endif
/* seize ipv6 as a temporary variable */
ipv6 = gnrc_pktbuf_start_write(pkt);
if (ipv6 == NULL) {
DEBUG("ipv6: unable to get write access to packet, drop it\n");
gnrc_pktbuf_release(pkt);
return;
}
pkt = ipv6; /* reset pkt from temporary variable */
ipv6 = gnrc_pktbuf_mark(pkt, sizeof(ipv6_hdr_t), GNRC_NETTYPE_IPV6);
first_ext = pkt;
pkt->type = GNRC_NETTYPE_UNDEF; /* snip is no longer IPv6 */
if (ipv6 == NULL) {
DEBUG("ipv6: error marking IPv6 header, dropping packet\n");
gnrc_pktbuf_release(pkt);
return;
}
if ((pkt->data == NULL) || (pkt->size < sizeof(ipv6_hdr_t)) ||
!ipv6_hdr_is(pkt->data)) {
DEBUG("ipv6: Received packet was not IPv6, dropping packet\n");
gnrc_pktbuf_release(pkt);
return;
}
#ifdef MODULE_GNRC_IPV6_WHITELIST
else if (!gnrc_ipv6_whitelisted(&((ipv6_hdr_t *)(ipv6->data))->src)) {
/* if ipv6 header already marked*/
else if (!gnrc_ipv6_whitelisted(&((ipv6_hdr_t *)(pkt->data))->src)) {
DEBUG("ipv6: Source address not whitelisted, dropping packet\n");
gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_PROHIB, pkt);
gnrc_pktbuf_release(pkt);
@ -799,15 +735,33 @@ static void _receive(gnrc_pktsnip_t *pkt)
}
#endif
#ifdef MODULE_GNRC_IPV6_BLACKLIST
else if (gnrc_ipv6_blacklisted(&((ipv6_hdr_t *)(ipv6->data))->src)) {
/* if ipv6 header already marked*/
else if (gnrc_ipv6_blacklisted(&((ipv6_hdr_t *)(pkt->data))->src)) {
DEBUG("ipv6: Source address blacklisted, dropping packet\n");
gnrc_icmpv6_error_dst_unr_send(ICMPV6_ERROR_DST_UNR_PROHIB, pkt);
gnrc_pktbuf_release(pkt);
return;
}
#endif
/* seize ipv6 as a temporary variable */
ipv6 = gnrc_pktbuf_start_write(pkt);
if (ipv6 == NULL) {
DEBUG("ipv6: unable to get write access to packet, drop it\n");
gnrc_pktbuf_release(pkt);
return;
}
pkt = ipv6; /* reset pkt from temporary variable */
ipv6 = gnrc_pktbuf_mark(pkt, sizeof(ipv6_hdr_t), GNRC_NETTYPE_IPV6);
pkt->type = GNRC_NETTYPE_UNDEF; /* snip is no longer IPv6 */
if (ipv6 == NULL) {
DEBUG("ipv6: error marking IPv6 header, dropping packet\n");
gnrc_pktbuf_release(pkt);
return;
}
/* extract header */
hdr = (ipv6_hdr_t *)ipv6->data;
@ -919,27 +873,7 @@ static void _receive(gnrc_pktsnip_t *pkt)
}
/* IPv6 internal demuxing (ICMPv6, Extension headers etc.) */
gnrc_ipv6_demux(netif, first_ext, pkt, hdr->nh);
}
static void _decapsulate(gnrc_pktsnip_t *pkt)
{
gnrc_pktsnip_t *ptr = pkt;
pkt->type = GNRC_NETTYPE_UNDEF; /* prevent payload (the encapsulated packet)
* from being removed */
/* Remove encapsulating IPv6 header */
while ((ptr->next != NULL) && (ptr->next->type == GNRC_NETTYPE_IPV6)) {
gnrc_pktbuf_remove_snip(pkt, pkt->next);
}
pkt->type = GNRC_NETTYPE_IPV6;
if (gnrc_netapi_dispatch_receive(GNRC_NETTYPE_IPV6,
GNRC_NETREG_DEMUX_CTX_ALL, pkt) == 0) {
gnrc_pktbuf_release(pkt);
}
gnrc_ipv6_demux(netif, pkt, pkt, hdr->nh);
}
/** @} */

View File

@ -161,119 +161,12 @@ static void _send_packet_raw(void)
assert(pkt->users == 0);
}
static void _send_packet_parsed(void)
{
gnrc_netif_t *iface = gnrc_netif_iter(NULL);
gnrc_netif_hdr_t netif_hdr;
gnrc_netif_hdr_init(&netif_hdr, 8, 8);
netif_hdr.if_pid = iface->pid;
uint8_t ipv6_data[] = {
/* IPv6 Header */
0x60, 0x00, 0x00, 0x00, /* version, traffic class, flow label */
0x00, 0x2a, /* payload length: 42 */
0x00, /* next header: Hop-by-Hop Option */
0x10, /* hop limit: 16 */
/* source address: fd01::1 */
0xfd, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01,
/* destination address: fd01::2 */
0xfd, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02,
};
uint8_t hop_by_hop_options_data[] = {
/* Hop-by-Hop Options Header */
/* https://tools.ietf.org/html/rfc6553 */
0x2b, /* next header: IPv6-Route */
0x00, /* hdr ext len: 0 * 8 + 8 = 8 */
0x63, /* option type: RPL Option */
0x04, /* opt data len: 4 */
0x80, /* flags, Down: 1, Rank-Error: 0, Forwarding-Error: 0 */
0x00, /* RPLInstanceID */
0x80, 0x00, /* SenderRank */
};
uint8_t rpl_routing_data[] = {
/* RPL Routing Header */
/* https://tools.ietf.org/html/rfc6554 */
0x11, /* next header: UDP */
0x02, /* hdr ext len: 2 * 8 + 8 = 24 */
0x03, /* routing type: SRH */
0x02, /* segments left: 2 */
0xef, /* ComprI: 14, ComprE: 15 */
0xd0, 0x00, 0x00, /* pad and reserved */
/* address: fd01::3, fd01::2 */
0x00, 0x03, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
};
uint8_t udp_data[] = {
/* UDP (ignored) */
0x1f, 0x90, /* source port: 8080 */
0x1f, 0x90, /* destination port: 8080 */
0x00, 0x0a, /* length: 10 */
0xff, 0xff, /* checksum */
};
uint8_t udp_payload[] = {
0x00, 0x00,
};
gnrc_pktsnip_t *netif =
gnrc_pktbuf_add(NULL,
&netif_hdr,
sizeof(netif_hdr),
GNRC_NETTYPE_NETIF);
gnrc_pktsnip_t *ipv6 =
gnrc_pktbuf_add(netif,
&ipv6_data,
sizeof(ipv6_data),
GNRC_NETTYPE_IPV6);
gnrc_pktsnip_t *hop_by_hop_options =
gnrc_pktbuf_add(ipv6,
&hop_by_hop_options_data,
sizeof(hop_by_hop_options_data),
GNRC_NETTYPE_IPV6_EXT);
gnrc_pktsnip_t *rpl_routing =
gnrc_pktbuf_add(hop_by_hop_options,
&rpl_routing_data,
sizeof(rpl_routing_data),
GNRC_NETTYPE_IPV6_EXT);
gnrc_pktsnip_t *udp =
gnrc_pktbuf_add(rpl_routing,
udp_data,
sizeof(udp_data),
GNRC_NETTYPE_UDP);
gnrc_pktsnip_t *pkt =
gnrc_pktbuf_add(udp,
&udp_payload,
sizeof(udp_payload),
GNRC_NETTYPE_UNDEF);
gnrc_netapi_dispatch_receive(GNRC_NETTYPE_IPV6, GNRC_NETREG_DEMUX_CTX_ALL, pkt);
printf("pkt->users: %d\n", pkt->users);
assert(pkt->users == 0);
}
int main(void)
{
puts("RIOT network stack example application");
_init_interface();
_send_packet_raw();
_send_packet_parsed();
/* should be never reached */
return 0;

View File

@ -12,29 +12,6 @@ from testrunner import run
def testfunc(child):
index = child.expect_exact([
"ipv6: Received (src = fd01::1, dst = fd01::2, next header = 0, length = 42)",
"pkt->users: 0"
])
if index == 1:
# debug is disabled
child.expect_exact("pkt->users: 0")
return
child.expect_exact("ipv6: handle extension header (nh = 0)")
child.expect_exact("ipv6: Received (src = fd01::1, dst = fd01::3, next header = 0, length = 42)")
child.expect_exact("ipv6: handle extension header (nh = 0)")
child.expect_exact("ipv6: Received (src = fd01::1, dst = fd01::2, next header = 0, length = 42)")
child.expect_exact("ipv6: handle extension header (nh = 0)")
child.expect_exact("ipv6: forward nh = 17 to other threads")
child.expect_exact("pkt->users: 0")
child.expect_exact("ipv6: handle extension header (nh = 0)")
child.expect_exact("ipv6: Received (src = fd01::1, dst = fd01::3, next header = 0, length = 42)")
child.expect_exact("ipv6: handle extension header (nh = 0)")
child.expect_exact("ipv6: Received (src = fd01::1, dst = fd01::2, next header = 0, length = 42)")
child.expect_exact("ipv6: handle extension header (nh = 0)")
child.expect_exact("ipv6: forward nh = 17 to other threads")
child.expect_exact("pkt->users: 0")