From ae8ce224fc814d45bfa3ac57e6fb2db51eb03431 Mon Sep 17 00:00:00 2001 From: Nico Schottelius Date: Wed, 10 Jul 2019 13:38:59 +0200 Subject: [PATCH] [delta checksum] in theory finish for v4-udp => v6-udp --- p4src/actions_delta_checksum.p4 | 61 ++++++++------- p4src/actions_nat64_generic.p4 | 127 ++++++++++++++++---------------- p4src/checksum_diff.p4 | 16 +++- p4src/headers.p4 | 5 ++ 4 files changed, 111 insertions(+), 98 deletions(-) diff --git a/p4src/actions_delta_checksum.p4 b/p4src/actions_delta_checksum.p4 index 4dfe624..e7522cc 100644 --- a/p4src/actions_delta_checksum.p4 +++ b/p4src/actions_delta_checksum.p4 @@ -1,41 +1,40 @@ #ifndef NICO_DELTA_CHECKSUM #define NICO_DELTA_CHECKSUM - action v4sum() { - bit<16> localsum = 0; +action v4sum() { + hdr.meta.v4sum = 0; - localsum = localsum + hdr.ipv4.src_addr[15:0]; // 16 bit - localsum = localsum + hdr.ipv4.src_addr[31:16]; // 16 bit - localsum = localsum + hdr.ipv4.dst_addr[15:0]; // 16 bit - localsum = localsum + hdr.ipv4.dst_addr[31:16]; // 16 bit + hdr.meta.v4sum = hdr.meta.v4sum + hdr.ipv4.src_addr[15:0]; // 16 bit + hdr.meta.v4sum = hdr.meta.v4sum + hdr.ipv4.src_addr[31:16]; // 16 bit + hdr.meta.v4sum = hdr.meta.v4sum + hdr.ipv4.dst_addr[15:0]; // 16 bit + hdr.meta.v4sum = hdr.meta.v4sum + hdr.ipv4.dst_addr[31:16]; // 16 bit - localsum = localsum + hdr.ipv4.totalLen -20; // 16 bit - localsum = localsum + (bit<16>) hdr.ipv4.protocol; // 8 bit - } + hdr.meta.v4sum = hdr.meta.v4sum + hdr.ipv4.totalLen -20; // 16 bit + hdr.meta.v4sum = hdr.meta.v4sum + (bit<16>) hdr.ipv4.protocol; // 8 bit +} - action v6sum() { - bit<16> localsum = 0; +action v6sum() { + hdr.meta.v6sum = 0; + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.src_addr[15:0]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.src_addr[31:16]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.src_addr[47:32]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.src_addr[63:48]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.src_addr[79:64]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.src_addr[95:80]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.src_addr[111:96]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.src_addr[127:112]; // 16 bit - localsum = localsum + hdr.ipv6.src_addr[15:0]; // 16 bit - localsum = localsum + hdr.ipv6.src_addr[31:16]; // 16 bit - localsum = localsum + hdr.ipv6.src_addr[47:32]; // 16 bit - localsum = localsum + hdr.ipv6.src_addr[63:48]; // 16 bit - localsum = localsum + hdr.ipv6.src_addr[79:64]; // 16 bit - localsum = localsum + hdr.ipv6.src_addr[95:80]; // 16 bit - localsum = localsum + hdr.ipv6.src_addr[111:96]; // 16 bit - localsum = localsum + hdr.ipv6.src_addr[127:112]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.dst_addr[15:0]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.dst_addr[31:16]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.dst_addr[47:32]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.dst_addr[63:48]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.dst_addr[79:64]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.dst_addr[95:80]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.dst_addr[111:96]; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.dst_addr[127:112]; // 16 bit - localsum = localsum + hdr.ipv6.dst_addr[15:0]; // 16 bit - localsum = localsum + hdr.ipv6.dst_addr[31:16]; // 16 bit - localsum = localsum + hdr.ipv6.dst_addr[47:32]; // 16 bit - localsum = localsum + hdr.ipv6.dst_addr[63:48]; // 16 bit - localsum = localsum + hdr.ipv6.dst_addr[79:64]; // 16 bit - localsum = localsum + hdr.ipv6.dst_addr[95:80]; // 16 bit - localsum = localsum + hdr.ipv6.dst_addr[111:96]; // 16 bit - localsum = localsum + hdr.ipv6.dst_addr[127:112]; // 16 bit - - localsum = localsum + hdr.ipv6.payload_length; // 16 bit - localsum = localsum + (bit<16>) hdr.ipv6.next_header; // 8 bit - } + hdr.meta.v6sum = hdr.meta.v6sum + hdr.ipv6.payload_length; // 16 bit + hdr.meta.v6sum = hdr.meta.v6sum + (bit<16>) hdr.ipv6.next_header; // 8 bit +} #endif \ No newline at end of file diff --git a/p4src/actions_nat64_generic.p4 b/p4src/actions_nat64_generic.p4 index 16dbeba..1a68d51 100644 --- a/p4src/actions_nat64_generic.p4 +++ b/p4src/actions_nat64_generic.p4 @@ -5,67 +5,69 @@ /********************** NAT64 / NAT46 ACTIONS GENERIC ***********************************/ - /* changes for icmp6 -> icmp */ - action nat64_icmp6_generic() - { - hdr.icmp.setValid(); - hdr.ipv4.protocol = PROTO_ICMP; // overwrite generic same protocol assumption +/* changes for icmp6 -> icmp */ +action nat64_icmp6_generic() +{ + hdr.icmp.setValid(); + hdr.ipv4.protocol = PROTO_ICMP; // overwrite generic same protocol assumption - /* trigger checksumming */ - meta.switch_task = TASK_CHECKSUM_ICMP; + /* trigger checksumming */ + meta.switch_task = TASK_CHECKSUM_ICMP; - meta.chk_icmp = 1; + /* FIXME: for delta */ + meta.chk_icmp = 1; - hdr.icmp6.setInvalid(); + 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(); - } + /* not needed, as we don't translate them (yet/ever) */ + hdr.icmp6_na_ns.setInvalid(); + hdr.icmp6_option_link_layer_addr.setInvalid(); +} - /* NAT64 protocol unspecific changes */ - action nat64_generic(ipv4_addr_t src, ipv4_addr_t dst) { - hdr.ipv4.setValid(); - meta.chk_ipv4 = 1; /* need to calculate the hdrchecksum */ +/* NAT64 protocol unspecific changes */ +action nat64_generic(ipv4_addr_t src, ipv4_addr_t dst) { + hdr.ipv4.setValid(); - /* Stuff that might need to be fixed */ - hdr.ipv4.version = (bit<4>)4; - hdr.ipv4.diff_serv = (bit<6>)0; // no ToS - hdr.ipv4.ecn = (bit<2>)0; // unsupported + meta.chk_ipv4 = 1; /* need to calculate the hdrchecksum */ - /* 5 is ok as long as we don't use options / padding / - anything after the destination address */ - hdr.ipv4.ihl = (bit<4>) 5; // internet header length: 4*5 = 20 - hdr.ipv4.totalLen = (bit<16>) hdr.ipv6.payload_length + 20; // ok under above constraints + /* Stuff that might need to be fixed */ + hdr.ipv4.version = (bit<4>)4; + hdr.ipv4.diff_serv = (bit<6>)0; // no ToS + hdr.ipv4.ecn = (bit<2>)0; // unsupported - hdr.ipv4.identification = (bit<16>) 0; // no support for fragments - hdr.ipv4.flags = (bit<3>) 0; // DF bit and more fragments - hdr.ipv4.fragOffset = (bit<13>) 0; // 0 as there are no fragments + /* 5 is ok as long as we don't use options / padding / + anything after the destination address */ + hdr.ipv4.ihl = (bit<4>) 5; // internet header length: 4*5 = 20 + hdr.ipv4.totalLen = (bit<16>) hdr.ipv6.payload_length + 20; // ok under above constraints - /* Stuff that should be fine */ - hdr.ethernet.ethertype = TYPE_IPV4; + hdr.ipv4.identification = (bit<16>) 0; // no support for fragments + hdr.ipv4.flags = (bit<3>) 0; // DF bit and more fragments + hdr.ipv4.fragOffset = (bit<13>) 0; // 0 as there are no fragments - hdr.ipv4.dst_addr = dst; - hdr.ipv4.src_addr = src; + /* Stuff that should be fine */ + hdr.ethernet.ethertype = TYPE_IPV4; - hdr.ipv4.ttl = hdr.ipv6.hop_limit; + hdr.ipv4.dst_addr = dst; + hdr.ipv4.src_addr = src; - hdr.ipv4.protocol = hdr.ipv6.next_header; + hdr.ipv4.ttl = hdr.ipv6.hop_limit; - hdr.ipv6.setInvalid(); - } + hdr.ipv4.protocol = hdr.ipv6.next_header; - /* nat64_prefix is the same as the matching key, but without the mask */ - action nat64_static(ipv6_addr_t v6_src, ipv4_addr_t v4_dst, ipv6_addr_t nat64_prefix) { - ipv6_addr_t src_offset = hdr.ipv6.src_addr - v6_src; - ipv4_addr_t src = v4_dst + (ipv4_addr_t) src_offset; + hdr.ipv6.setInvalid(); +} - ipv4_addr_t dst = (ipv4_addr_t) (hdr.ipv6.dst_addr - nat64_prefix); +/* nat64_prefix is the same as the matching key, but without the mask */ +action nat64_static(ipv6_addr_t v6_src, ipv4_addr_t v4_dst, ipv6_addr_t nat64_prefix) { + ipv6_addr_t src_offset = hdr.ipv6.src_addr - v6_src; + ipv4_addr_t src = v4_dst + (ipv4_addr_t) src_offset; - nat64_generic(src, dst); - } + ipv4_addr_t dst = (ipv4_addr_t) (hdr.ipv6.dst_addr - nat64_prefix); - /* From https://tools.ietf.org/html/rfc792 (IPv4) + nat64_generic(src, dst); +} + +/* From https://tools.ietf.org/html/rfc792 (IPv4) Echo or Echo Reply Message @@ -112,36 +114,33 @@ Echo or Echo Reply Message */ - /* changes for icmp6 -> icmp */ - action nat46_icmp_generic() - { - hdr.icmp6.setValid(); - hdr.ipv6.next_header = PROTO_ICMP6; +/* changes for icmp6 -> icmp */ +action nat46_icmp_generic() +{ + hdr.icmp6.setValid(); + hdr.ipv6.next_header = PROTO_ICMP6; - meta.chk_icmp6 = 1; - meta.cast_length = (bit<32>) hdr.ipv6.payload_length; + meta.chk_icmp6 = 1; + meta.cast_length = (bit<32>) hdr.ipv6.payload_length; - hdr.icmp.setInvalid(); - } + hdr.icmp.setInvalid(); +} /* NAT46: protocol unspecific changes */ action nat46_generic(ipv6_addr_t src, ipv6_addr_t dst) { hdr.ipv6.setValid(); hdr.ipv4.setInvalid(); - hdr.ethernet.ethertype = TYPE_IPV6; + hdr.ethernet.ethertype = TYPE_IPV6; - hdr.ipv6.dst_addr = dst; - hdr.ipv6.src_addr = src; - - hdr.ipv6.version = (bit<4>)6; - hdr.ipv6.traffic_class = (bit<8>) hdr.ipv4.diff_serv; - hdr.ipv6.flow_label = (bit<20>) 0; + hdr.ipv6.dst_addr = dst; + hdr.ipv6.src_addr = src; + hdr.ipv6.version = (bit<4>) 6; + hdr.ipv6.traffic_class = (bit<8>) hdr.ipv4.diff_serv; + hdr.ipv6.flow_label = (bit<20>) 0; hdr.ipv6.payload_length = (bit<16>) hdr.ipv4.totalLen - 20; - - hdr.ipv6.next_header = hdr.ipv4.protocol; - hdr.ipv6.hop_limit = hdr.ipv4.ttl; - + hdr.ipv6.next_header = hdr.ipv4.protocol; + hdr.ipv6.hop_limit = hdr.ipv4.ttl; } diff --git a/p4src/checksum_diff.p4 b/p4src/checksum_diff.p4 index 3226b9e..2bb501e 100644 --- a/p4src/checksum_diff.p4 +++ b/p4src/checksum_diff.p4 @@ -22,6 +22,8 @@ parser MyParser(packet_in packet, meta.chk_udp_v4 = 0; meta.chk_tcp_v6 = 0; meta.chk_tcp_v4 = 0; + meta.v4sum = 0; + meta.v6sum = 0; packet.extract(hdr.ethernet); transition select(hdr.ethernet.ethertype){ @@ -141,9 +143,9 @@ control MyIngress(inout headers hdr, #include "actions_egress.p4" #include "actions_icmp6_ndp_icmp.p4" #include "actions_arp.p4" + #include "actions_delta_checksum.p4" /* only used if enabled at compile time */ - - /********************** APPLYING TABLES ***********************************/ + /********************** APPLYING TABLES / MAIN LOGIC **************************/ apply { if(hdr.ipv6.isValid()) { if(nat64.apply().hit) { /* generic / static nat64 done */ @@ -170,7 +172,7 @@ control MyIngress(inout headers hdr, exit; /* no further v6 processing */ } - icmp6.apply(); /* icmp6 echo, icmp6 ndp */ + icmp6.apply(); /* icmp6 echo, icmp6 ndp */ v6_networks.apply(); /* regular egress / routing */ } else if(hdr.ipv4.isValid()) { @@ -189,7 +191,15 @@ control MyIngress(inout headers hdr, } } if(hdr.udp.isValid()) { + #ifdef NICO_DELTA_CHECKSUM + v4sum(); + v6sum(); + bit<16> diff = hdr.meta.v6sum - hdr.meta.v4sum; + hdr.udp.checksum = hdr.udp.checksum + diff; + + #else meta.chk_udp_v6 = 1; + #endif } if(hdr.tcp.isValid()) { meta.chk_tcp_v6 = 1; diff --git a/p4src/headers.p4 b/p4src/headers.p4 index b6c30f4..36ee76d 100644 --- a/p4src/headers.p4 +++ b/p4src/headers.p4 @@ -230,6 +230,11 @@ struct metadata { bit<16> length_without_ip_header; bit<32> cast_length; + + /* for delta checksums */ + bit<16> v4sum; + bit<16> v6sum; + table_t table_id; }