/* -*- P4_16 -*- */ #include #include #include "headers.p4" #include "settings.p4" #define USE_NICO_DELTA_CHECKSUM 1 /************************************************************************* * Parser */ parser MyParser(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { #include "parsers.p4" } control MyDeparser(packet_out packet, in headers hdr) { #include "deparser.p4" } // OK-UNTIL-HERE /************************************************************************* ************** I N G R E S S P R O C E S S I N G ******************* *************************************************************************/ control MyIngress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { #include "actions_nat64_generic.p4" #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 / MAIN LOGIC **************************/ apply { if(hdr.ipv6.isValid()) { if(nat64.apply().hit) { /* generic / static nat64 done */ if(hdr.icmp6.isValid()) { nat64_icmp6_generic(); if(hdr.icmp6.type == ICMP6_ECHO_REPLY) { hdr.icmp.type = ICMP_ECHO_REPLY; hdr.icmp.code = 0; } if(hdr.icmp6.type == ICMP6_ECHO_REQUEST) { hdr.icmp.type = ICMP_ECHO_REQUEST; hdr.icmp.code = 0; } } if(hdr.udp.isValid()) { meta.chk_udp_v4 = 1; } if(hdr.tcp.isValid()) { meta.chk_tcp_v4 = 1; } v4_networks.apply(); /* apply egress for IPv4 */ exit; /* no further v6 processing */ } icmp6.apply(); /* icmp6 echo, icmp6 ndp */ v6_networks.apply(); /* regular egress / routing */ } else if(hdr.ipv4.isValid()) { if(icmp.apply().hit) { v4_networks.apply(); exit; } else if(nat46.apply().hit) { if(hdr.icmp.isValid()) { nat46_icmp_generic(); if(hdr.icmp.type == ICMP_ECHO_REPLY) { hdr.icmp6.type = ICMP6_ECHO_REPLY; } if(hdr.icmp.type == ICMP_ECHO_REQUEST) { hdr.icmp6.type = ICMP6_ECHO_REQUEST; } } if(hdr.udp.isValid()) { #ifdef USE_NICO_DELTA_CHECKSUM v4sum(); v6sum(); bit<16> diff = meta.v6sum - meta.v4sum; hdr.udp.checksum = hdr.udp.checksum + ~diff +1; // hdr.udp.checksum = ~diff; #else meta.chk_udp_v6 = 1; #endif } if(hdr.tcp.isValid()) { #ifdef USE_NICO_DELTA_CHECKSUM v4sum(); v6sum(); bit<16> diff = meta.v6sum - meta.v4sum; hdr.tcp.checksum = hdr.tcp.checksum + ~diff +1; #else meta.chk_tcp_v6 = 1; #endif } v6_networks.apply(); exit; } v4_networks.apply(); /* regular routing, egress */ } else if(hdr.arp.isValid()) { if(v4_arp.apply().hit) { v4_arp_egress.apply(); } } } } /************************************************************************* **************** E G R E S S P R O C E S S I N G ******************* *************************************************************************/ control MyEgress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) { apply { // ingress clone if (standard_metadata.instance_type == 1){ hdr.cpu.setValid(); hdr.cpu.task = meta.task; hdr.cpu.ethertype = hdr.ethernet.ethertype; hdr.cpu.ingress_port = (bit<16>) meta.ingress_port; hdr.cpu.table_id = meta.table_id; hdr.ethernet.ethertype = TYPE_CPU; } } } /************************************************************************* * Checksums */ control MyVerifyChecksum(inout headers hdr, inout metadata meta) { apply {} } control MyComputeChecksum(inout headers hdr, inout metadata meta) { apply { update_checksum(meta.chk_icmp6 == 1, { hdr.ipv6.src_addr, /* 128 */ hdr.ipv6.dst_addr, /* 128 */ meta.cast_length, /* 32 */ 24w0, /* 24 0's */ PROTO_ICMP6, /* 8 */ hdr.icmp6.type, /* 8 */ hdr.icmp6.code /* 8 */ }, hdr.icmp6.checksum, HashAlgorithm.csum16 ); } } /************************************************************************* *********************** S W I T C H ******************************* *************************************************************************/ V1Switch( MyParser(), MyVerifyChecksum(), MyIngress(), MyEgress(), MyComputeChecksum(), MyDeparser() ) main;