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:
commit
970bec1d1b
@ -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);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
@ -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;
|
||||
|
@ -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")
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user