From 404d4ff0df7da505efdeaf22d90a1e009ddb6937 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 27 Mar 2019 18:01:11 +0100 Subject: [PATCH] Begin checksumming icmp4 --- doc/plan.org | 7 +++++-- p4src/checksums.p4 | 8 ++++++++ p4src/headers.p4 | 6 +++++- p4src/static-mapping.p4 | 17 +++++++++++++++-- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/doc/plan.org b/doc/plan.org index 8affa87..6bdd04d 100644 --- a/doc/plan.org +++ b/doc/plan.org @@ -479,8 +479,10 @@ INFO:main:unhandled reassambled= pings h3 ***** DONE egress is correct, comes out at h3 -***** TODO protocol 58 is wrong -> should be 1 -**** TODO transform protocol specific: icmp6 -> icmp +***** DONE protocol 58 is wrong -> should be 1 +***** DONE figure out switch() syntax +***** TODO Calculate ICMP checksum +***** TODO transform protocol specific: icmp6 -> icmp **** TODO transform protocol specific: icmp -> icmp6 **** TODO Make switch answer IPv4 icmp echo request for **** TODO Add / check default route for v4 hosts @@ -1402,6 +1404,7 @@ Only the destination network is matched for deciding on NAT64, as priority based double LPM is not supported. This limits a prefix to be used only in one network. *** References / Follow up +**** RFC 1017 ICMP checksum https://tools.ietf.org/html/rfc1071 **** RFC 2460 IPv6 (Checksum https://tools.ietf.org/html/rfc2460#section-8.1) **** RFC 3810 MLD2 https://tools.ietf.org/html/rfc3810 **** RFC 4443 ICMPv6 https://tools.ietf.org/html/rfc4443 diff --git a/p4src/checksums.p4 b/p4src/checksums.p4 index 1f38867..72818cf 100644 --- a/p4src/checksums.p4 +++ b/p4src/checksums.p4 @@ -60,6 +60,14 @@ control MyComputeChecksum(inout headers hdr, inout metadata meta) { HashAlgorithm.csum16 ); + update_checksum_with_payload(meta.switch_task == TASK_CHECKSUM_ICMP, + { + hdr.icmp.type, + hdr.icmp.code + }, + hdr.icmp.checksum, + HashAlgorithm.csum16 + ); } } diff --git a/p4src/headers.p4 b/p4src/headers.p4 index dd8fe16..abc0920 100644 --- a/p4src/headers.p4 +++ b/p4src/headers.p4 @@ -38,6 +38,10 @@ const bit<8> ICMP6_ECHO_REPLY = 129; const bit<8> ICMP6_NS = 135; const bit<8> ICMP6_NA = 136; +const bit<8> ICMP_ECHO_REPLY = 0; +const bit<8> ICMP_ECHO_REQUEST = 8; + + /* RFC4861, Section 4.6 */ const bit<8> ICMP6_NDP_OPT_SOURCE_LL = 1; const bit<8> ICMP6_NDP_OPT_TARGET_LL = 2; @@ -52,6 +56,7 @@ const task_t TASK_DEBUG = 3; const task_t TASK_ICMP6_REPLY = 4; const task_t TASK_CHECKSUM_ICMP6 = 5; /* data plane */ const task_t TASK_CHECKSUM_ICMP6_NA = 6; /* data plane */ +const task_t TASK_CHECKSUM_ICMP = 7; /* data plane */ /* 48+48+16 = 112 */ @@ -147,7 +152,6 @@ header icmp_t { bit<8> type; bit<8> code; bit<16> checksum; - bit<32> rest; } diff --git a/p4src/static-mapping.p4 b/p4src/static-mapping.p4 index 100ff92..ecddf2b 100644 --- a/p4src/static-mapping.p4 +++ b/p4src/static-mapping.p4 @@ -54,7 +54,22 @@ control MyIngress(inout headers hdr, */ action nat64_icmp6() { + hdr.icmp.setValid(); hdr.ipv4.protocol = PROTO_ICMP; // overwrite generic same protocol assumption + + switch(hdr.icmp6.type) { + ICMP6_ECHO_REQUEST: hdr.icmp.type = ICMP_ECHO_REQUEST; + ICMP6_ECHO_REPLY: hdr.icmp.type = ICMP_ECHO_REPLY; + } + + /* trigger checksumming */ + meta.switch_task = TASK_CHECKSUM_ICMP; + + hdr.icmp6.setInvalid(); + + /* not needed, as we don't translate them (yet/ever) */ + hdr.icmp6_na_ns.setInvalid(); + hdr.icmp6_option_link_layer_addr.setInvalid(); } @@ -120,8 +135,6 @@ control MyIngress(inout headers hdr, nat64_generic(src, dst); - /* fix the protocol specific translations */ - // switch() ... } /* matching key: v4_network specified again */