diff --git a/backends/dpdk/backend.cpp b/backends/dpdk/backend.cpp index 849467ba42..e0b3431638 100644 --- a/backends/dpdk/backend.cpp +++ b/backends/dpdk/backend.cpp @@ -56,8 +56,9 @@ void DpdkBackend::convert(const IR::ToplevelBlock* tlb) { new P4::ClearTypeMap(typeMap), new P4::TypeChecking(refMap, typeMap), new ByteAlignment(typeMap, refMap, &structure), - new P4::SimplifyKey(refMap, typeMap, - new P4::OrPolicy(new P4::IsValid(refMap, typeMap), new P4::IsMask())), + new P4::SimplifyKey( + refMap, typeMap, + new P4::OrPolicy(new P4::IsValid(refMap, typeMap), new P4::IsLikeLeftValue())), new P4::TypeChecking(refMap, typeMap), // TBD: implement dpdk lowering passes instead of reusing bmv2's lowering pass. new PassRepeated({new BMV2::LowerExpressions(typeMap, DPDK_MAX_SHIFT_AMOUNT)}, 2), diff --git a/backends/dpdk/midend.cpp b/backends/dpdk/midend.cpp index 60f9847a1c..6729db0f32 100644 --- a/backends/dpdk/midend.cpp +++ b/backends/dpdk/midend.cpp @@ -181,7 +181,7 @@ DpdkMidEnd::DpdkMidEnd(CompilerOptions& options, std::ostream* outStream) { new P4::TypeChecking(&refMap, &typeMap), new P4::SimplifyKey( &refMap, &typeMap, - new P4::OrPolicy(new P4::IsValid(&refMap, &typeMap), new P4::IsMask())), + new P4::OrPolicy(new P4::IsValid(&refMap, &typeMap), new P4::IsLikeLeftValue())), new P4::RemoveExits(&refMap, &typeMap), new P4::ConstantFolding(&refMap, &typeMap), new P4::StrengthReduction(&refMap, &typeMap), diff --git a/testdata/p4_16_samples/pna-example-bAnd-in-tableKey.p4 b/testdata/p4_16_samples/pna-example-bAnd-in-tableKey.p4 new file mode 100644 index 0000000000..8ed207d68d --- /dev/null +++ b/testdata/p4_16_samples/pna-example-bAnd-in-tableKey.p4 @@ -0,0 +1,179 @@ +/* +Copyright 2023 Intel Corporation + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include +#include "pna.p4" + + +typedef bit<48> EthernetAddress; + +header ethernet_t { + EthernetAddress dstAddr; + EthernetAddress srcAddr; + bit<16> etherType; +} + +header ipv4_t { + bit<4> version; + bit<4> ihl; + bit<8> diffserv; + bit<16> totalLen; + bit<16> identification; + bit<3> flags; + bit<13> fragOffset; + bit<8> ttl; + bit<8> protocol; + bit<16> hdrChecksum; + bit<32> srcAddr; + bit<32> dstAddr; +} + +struct empty_metadata_t { +} + +// BEGIN:Counter_Example_Part1 +typedef bit<48> ByteCounter_t; +typedef bit<32> PacketCounter_t; +typedef bit<80> PacketByteCounter_t; + +const bit<32> NUM_PORTS = 4; +// END:Counter_Example_Part1 + + +////////////////////////////////////////////////////////////////////// +// Struct types for holding user-defined collections of headers and +// metadata in the P4 developer's program. +// +// Note: The names of these struct types are completely up to the P4 +// developer, as are their member fields, with the only restriction +// being that the structs intended to contain headers should only +// contain members whose types are header, header stack, or +// header_union. +////////////////////////////////////////////////////////////////////// + +struct main_metadata_t { + // empty for this skeleton +} + +// User-defined struct containing all of those headers parsed in the +// main parser. +struct headers_t { + ethernet_t ethernet; + ipv4_t ipv4; +} + +control PreControlImpl( + in headers_t hdr, + inout main_metadata_t meta, + in pna_pre_input_metadata_t istd, + inout pna_pre_output_metadata_t ostd) +{ + apply { + // Note: This program does not demonstrate all of the code + // that would be necessary if you were implementing IPsec + // packet decryption. + + // If it did, then this pre control implementation would do + // one or more table lookups in order to determine whether the + // packet was IPsec encapsulated, and if so, whether it is + // part of a security association that was established by the + // control plane software. + + // It would also likely perform anti-replay attack detection + // on the IPsec sequence number, which is in the unencrypted + // part of the packet. + + // Any headers parsed by the pre parser in pre_hdr will be + // forgotten after this point. The main parser will start + // parsing over from the beginning, either on the same packet + // if the inline extern block did nothing, or on the packet as + // modified by the inline extern block. + } +} + +parser MainParserImpl( + packet_in pkt, + out headers_t hdr, + inout main_metadata_t main_meta, + in pna_main_parser_input_metadata_t istd) +{ + state start { + pkt.extract(hdr.ethernet); + transition select(hdr.ethernet.etherType) { + 0x0800: parse_ipv4; + default: accept; + } + } + state parse_ipv4 { + pkt.extract(hdr.ipv4); + transition accept; + } +} + +// BEGIN:Counter_Example_Part2 +control MainControlImpl( + inout headers_t hdr, // from main parser + inout main_metadata_t user_meta, // from main parser, to "next block" + in pna_main_input_metadata_t istd, + inout pna_main_output_metadata_t ostd) +{ + action next_hop(PortId_t vport) { + send_to_port(vport); + } + action default_route_drop() { + drop_packet(); + } + table ipv4_da_lpm { + key = { + hdr.ipv4.dstAddr & 0xf: exact; + } + actions = { + next_hop; + default_route_drop; + } + const default_action = default_route_drop; + } + apply { + if (hdr.ipv4.isValid()) { + ipv4_da_lpm.apply(); + } + } +} +// END:Counter_Example_Part2 + +control MainDeparserImpl( + packet_out pkt, + in headers_t hdr, // from main control + in main_metadata_t user_meta, // from main control + in pna_main_output_metadata_t ostd) +{ + apply { + pkt.emit(hdr.ethernet); + pkt.emit(hdr.ipv4); + } +} + +// BEGIN:Package_Instantiation_Example +PNA_NIC( + MainParserImpl(), + PreControlImpl(), + MainControlImpl(), + MainDeparserImpl() + // Hoping to make this optional parameter later, but not supported + // by p4c yet. + //, PreParserImpl() + ) main; +// END:Package_Instantiation_Example diff --git a/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey-first.p4 b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey-first.p4 new file mode 100644 index 0000000000..16747467d6 --- /dev/null +++ b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey-first.p4 @@ -0,0 +1,91 @@ +#include +#include + +typedef bit<48> EthernetAddress; +header ethernet_t { + EthernetAddress dstAddr; + EthernetAddress srcAddr; + bit<16> etherType; +} + +header ipv4_t { + bit<4> version; + bit<4> ihl; + bit<8> diffserv; + bit<16> totalLen; + bit<16> identification; + bit<3> flags; + bit<13> fragOffset; + bit<8> ttl; + bit<8> protocol; + bit<16> hdrChecksum; + bit<32> srcAddr; + bit<32> dstAddr; +} + +struct empty_metadata_t { +} + +typedef bit<48> ByteCounter_t; +typedef bit<32> PacketCounter_t; +typedef bit<80> PacketByteCounter_t; +const bit<32> NUM_PORTS = 32w4; +struct main_metadata_t { +} + +struct headers_t { + ethernet_t ethernet; + ipv4_t ipv4; +} + +control PreControlImpl(in headers_t hdr, inout main_metadata_t meta, in pna_pre_input_metadata_t istd, inout pna_pre_output_metadata_t ostd) { + apply { + } +} + +parser MainParserImpl(packet_in pkt, out headers_t hdr, inout main_metadata_t main_meta, in pna_main_parser_input_metadata_t istd) { + state start { + pkt.extract(hdr.ethernet); + transition select(hdr.ethernet.etherType) { + 16w0x800: parse_ipv4; + default: accept; + } + } + state parse_ipv4 { + pkt.extract(hdr.ipv4); + transition accept; + } +} + +control MainControlImpl(inout headers_t hdr, inout main_metadata_t user_meta, in pna_main_input_metadata_t istd, inout pna_main_output_metadata_t ostd) { + action next_hop(PortId_t vport) { + send_to_port(vport); + } + action default_route_drop() { + drop_packet(); + } + table ipv4_da_lpm { + key = { + hdr.ipv4.dstAddr & 32w0xf: exact @name("hdr.ipv4.dstAddr & 0xf"); + } + actions = { + next_hop(); + default_route_drop(); + } + const default_action = default_route_drop(); + } + apply { + if (hdr.ipv4.isValid()) { + ipv4_da_lpm.apply(); + } + } +} + +control MainDeparserImpl(packet_out pkt, in headers_t hdr, in main_metadata_t user_meta, in pna_main_output_metadata_t ostd) { + apply { + pkt.emit(hdr.ethernet); + pkt.emit(hdr.ipv4); + } +} + +PNA_NIC(MainParserImpl(), PreControlImpl(), MainControlImpl(), MainDeparserImpl()) main; diff --git a/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey-frontend.p4 b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey-frontend.p4 new file mode 100644 index 0000000000..493d57eaa4 --- /dev/null +++ b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey-frontend.p4 @@ -0,0 +1,87 @@ +#include +#include + +typedef bit<48> EthernetAddress; +header ethernet_t { + EthernetAddress dstAddr; + EthernetAddress srcAddr; + bit<16> etherType; +} + +header ipv4_t { + bit<4> version; + bit<4> ihl; + bit<8> diffserv; + bit<16> totalLen; + bit<16> identification; + bit<3> flags; + bit<13> fragOffset; + bit<8> ttl; + bit<8> protocol; + bit<16> hdrChecksum; + bit<32> srcAddr; + bit<32> dstAddr; +} + +struct empty_metadata_t { +} + +struct main_metadata_t { +} + +struct headers_t { + ethernet_t ethernet; + ipv4_t ipv4; +} + +control PreControlImpl(in headers_t hdr, inout main_metadata_t meta, in pna_pre_input_metadata_t istd, inout pna_pre_output_metadata_t ostd) { + apply { + } +} + +parser MainParserImpl(packet_in pkt, out headers_t hdr, inout main_metadata_t main_meta, in pna_main_parser_input_metadata_t istd) { + state start { + pkt.extract(hdr.ethernet); + transition select(hdr.ethernet.etherType) { + 16w0x800: parse_ipv4; + default: accept; + } + } + state parse_ipv4 { + pkt.extract(hdr.ipv4); + transition accept; + } +} + +control MainControlImpl(inout headers_t hdr, inout main_metadata_t user_meta, in pna_main_input_metadata_t istd, inout pna_main_output_metadata_t ostd) { + @name("MainControlImpl.next_hop") action next_hop(@name("vport") PortId_t vport) { + send_to_port(vport); + } + @name("MainControlImpl.default_route_drop") action default_route_drop() { + drop_packet(); + } + @name("MainControlImpl.ipv4_da_lpm") table ipv4_da_lpm_0 { + key = { + hdr.ipv4.dstAddr & 32w0xf: exact @name("hdr.ipv4.dstAddr & 0xf"); + } + actions = { + next_hop(); + default_route_drop(); + } + const default_action = default_route_drop(); + } + apply { + if (hdr.ipv4.isValid()) { + ipv4_da_lpm_0.apply(); + } + } +} + +control MainDeparserImpl(packet_out pkt, in headers_t hdr, in main_metadata_t user_meta, in pna_main_output_metadata_t ostd) { + apply { + pkt.emit(hdr.ethernet); + pkt.emit(hdr.ipv4); + } +} + +PNA_NIC(MainParserImpl(), PreControlImpl(), MainControlImpl(), MainDeparserImpl()) main; diff --git a/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey-midend.p4 b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey-midend.p4 new file mode 100644 index 0000000000..1181ba15dc --- /dev/null +++ b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey-midend.p4 @@ -0,0 +1,106 @@ +#include +#include + +header ethernet_t { + bit<48> dstAddr; + bit<48> srcAddr; + bit<16> etherType; +} + +header ipv4_t { + bit<4> version; + bit<4> ihl; + bit<8> diffserv; + bit<16> totalLen; + bit<16> identification; + bit<3> flags; + bit<13> fragOffset; + bit<8> ttl; + bit<8> protocol; + bit<16> hdrChecksum; + bit<32> srcAddr; + bit<32> dstAddr; +} + +struct empty_metadata_t { +} + +struct main_metadata_t { +} + +struct headers_t { + ethernet_t ethernet; + ipv4_t ipv4; +} + +control PreControlImpl(in headers_t hdr, inout main_metadata_t meta, in pna_pre_input_metadata_t istd, inout pna_pre_output_metadata_t ostd) { + apply { + } +} + +parser MainParserImpl(packet_in pkt, out headers_t hdr, inout main_metadata_t main_meta, in pna_main_parser_input_metadata_t istd) { + state start { + pkt.extract(hdr.ethernet); + transition select(hdr.ethernet.etherType) { + 16w0x800: parse_ipv4; + default: accept; + } + } + state parse_ipv4 { + pkt.extract(hdr.ipv4); + transition accept; + } +} + +control MainControlImpl(inout headers_t hdr, inout main_metadata_t user_meta, in pna_main_input_metadata_t istd, inout pna_main_output_metadata_t ostd) { + bit<32> key_0; + @name("MainControlImpl.next_hop") action next_hop(@name("vport") bit<32> vport) { + send_to_port(vport); + } + @name("MainControlImpl.default_route_drop") action default_route_drop() { + drop_packet(); + } + @name("MainControlImpl.ipv4_da_lpm") table ipv4_da_lpm_0 { + key = { + key_0: exact @name("hdr.ipv4.dstAddr & 0xf"); + } + actions = { + next_hop(); + default_route_drop(); + } + const default_action = default_route_drop(); + } + @hidden action pnaexamplebAndintableKey141() { + key_0 = hdr.ipv4.dstAddr & 32w0xf; + } + @hidden table tbl_pnaexamplebAndintableKey141 { + actions = { + pnaexamplebAndintableKey141(); + } + const default_action = pnaexamplebAndintableKey141(); + } + apply { + if (hdr.ipv4.isValid()) { + tbl_pnaexamplebAndintableKey141.apply(); + ipv4_da_lpm_0.apply(); + } + } +} + +control MainDeparserImpl(packet_out pkt, in headers_t hdr, in main_metadata_t user_meta, in pna_main_output_metadata_t ostd) { + @hidden action pnaexamplebAndintableKey164() { + pkt.emit(hdr.ethernet); + pkt.emit(hdr.ipv4); + } + @hidden table tbl_pnaexamplebAndintableKey164 { + actions = { + pnaexamplebAndintableKey164(); + } + const default_action = pnaexamplebAndintableKey164(); + } + apply { + tbl_pnaexamplebAndintableKey164.apply(); + } +} + +PNA_NIC(MainParserImpl(), PreControlImpl(), MainControlImpl(), MainDeparserImpl()) main; diff --git a/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey.p4 b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey.p4 new file mode 100644 index 0000000000..eca56d5c21 --- /dev/null +++ b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey.p4 @@ -0,0 +1,91 @@ +#include +#include + +typedef bit<48> EthernetAddress; +header ethernet_t { + EthernetAddress dstAddr; + EthernetAddress srcAddr; + bit<16> etherType; +} + +header ipv4_t { + bit<4> version; + bit<4> ihl; + bit<8> diffserv; + bit<16> totalLen; + bit<16> identification; + bit<3> flags; + bit<13> fragOffset; + bit<8> ttl; + bit<8> protocol; + bit<16> hdrChecksum; + bit<32> srcAddr; + bit<32> dstAddr; +} + +struct empty_metadata_t { +} + +typedef bit<48> ByteCounter_t; +typedef bit<32> PacketCounter_t; +typedef bit<80> PacketByteCounter_t; +const bit<32> NUM_PORTS = 4; +struct main_metadata_t { +} + +struct headers_t { + ethernet_t ethernet; + ipv4_t ipv4; +} + +control PreControlImpl(in headers_t hdr, inout main_metadata_t meta, in pna_pre_input_metadata_t istd, inout pna_pre_output_metadata_t ostd) { + apply { + } +} + +parser MainParserImpl(packet_in pkt, out headers_t hdr, inout main_metadata_t main_meta, in pna_main_parser_input_metadata_t istd) { + state start { + pkt.extract(hdr.ethernet); + transition select(hdr.ethernet.etherType) { + 0x800: parse_ipv4; + default: accept; + } + } + state parse_ipv4 { + pkt.extract(hdr.ipv4); + transition accept; + } +} + +control MainControlImpl(inout headers_t hdr, inout main_metadata_t user_meta, in pna_main_input_metadata_t istd, inout pna_main_output_metadata_t ostd) { + action next_hop(PortId_t vport) { + send_to_port(vport); + } + action default_route_drop() { + drop_packet(); + } + table ipv4_da_lpm { + key = { + hdr.ipv4.dstAddr & 0xf: exact; + } + actions = { + next_hop; + default_route_drop; + } + const default_action = default_route_drop; + } + apply { + if (hdr.ipv4.isValid()) { + ipv4_da_lpm.apply(); + } + } +} + +control MainDeparserImpl(packet_out pkt, in headers_t hdr, in main_metadata_t user_meta, in pna_main_output_metadata_t ostd) { + apply { + pkt.emit(hdr.ethernet); + pkt.emit(hdr.ipv4); + } +} + +PNA_NIC(MainParserImpl(), PreControlImpl(), MainControlImpl(), MainDeparserImpl()) main; diff --git a/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey.p4-error b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey.p4-error new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey.p4-stderr b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey.p4-stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey.p4.bfrt.json b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey.p4.bfrt.json new file mode 100644 index 0000000000..1b55d06b6e --- /dev/null +++ b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey.p4.bfrt.json @@ -0,0 +1,61 @@ +{ + "schema_version" : "1.0.0", + "tables" : [ + { + "name" : "pipe.MainControlImpl.ipv4_da_lpm", + "id" : 40097106, + "table_type" : "MatchAction_Direct", + "size" : 1024, + "annotations" : [], + "depends_on" : [], + "has_const_default_action" : true, + "key" : [ + { + "id" : 1, + "name" : "hdr.ipv4.dstAddr & 0xf", + "repeated" : false, + "annotations" : [], + "mandatory" : false, + "match_type" : "Exact", + "type" : { + "type" : "bytes", + "width" : 32 + } + } + ], + "action_specs" : [ + { + "id" : 25584005, + "name" : "MainControlImpl.next_hop", + "action_scope" : "TableAndDefault", + "annotations" : [], + "data" : [ + { + "id" : 1, + "name" : "vport", + "repeated" : false, + "mandatory" : true, + "read_only" : false, + "annotations" : [], + "type" : { + "type" : "bytes", + "width" : 32 + } + } + ] + }, + { + "id" : 19071441, + "name" : "MainControlImpl.default_route_drop", + "action_scope" : "TableAndDefault", + "annotations" : [], + "data" : [] + } + ], + "data" : [], + "supported_operations" : [], + "attributes" : ["EntryScope"] + } + ], + "learn_filters" : [] +} \ No newline at end of file diff --git a/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey.p4.spec b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey.p4.spec new file mode 100644 index 0000000000..f26c52f45f --- /dev/null +++ b/testdata/p4_16_samples_outputs/pna-example-bAnd-in-tableKey.p4.spec @@ -0,0 +1,75 @@ + +struct ethernet_t { + bit<48> dstAddr + bit<48> srcAddr + bit<16> etherType +} + +struct ipv4_t { + bit<8> version_ihl + bit<8> diffserv + bit<16> totalLen + bit<16> identification + bit<16> flags_fragOffset + bit<8> ttl + bit<8> protocol + bit<16> hdrChecksum + bit<32> srcAddr + bit<32> dstAddr +} + +struct next_hop_arg_t { + bit<32> vport +} + +struct main_metadata_t { + bit<32> pna_main_input_metadata_input_port + bit<32> pna_main_output_metadata_output_port + bit<32> MainControlT_key +} +metadata instanceof main_metadata_t + +header ethernet instanceof ethernet_t +header ipv4 instanceof ipv4_t + +regarray direction size 0x100 initval 0 + +action next_hop args instanceof next_hop_arg_t { + mov m.pna_main_output_metadata_output_port t.vport + return +} + +action default_route_drop args none { + drop + return +} + +table ipv4_da_lpm { + key { + m.MainControlT_key exact + } + actions { + next_hop + default_route_drop + } + default_action default_route_drop args none const + size 0x10000 +} + + +apply { + rx m.pna_main_input_metadata_input_port + extract h.ethernet + jmpeq MAINPARSERIMPL_PARSE_IPV4 h.ethernet.etherType 0x800 + jmp MAINPARSERIMPL_ACCEPT + MAINPARSERIMPL_PARSE_IPV4 : extract h.ipv4 + MAINPARSERIMPL_ACCEPT : jmpnv LABEL_END h.ipv4 + mov m.MainControlT_key h.ipv4.dstAddr + and m.MainControlT_key 0xF + table ipv4_da_lpm + LABEL_END : emit h.ethernet + emit h.ipv4 + tx m.pna_main_output_metadata_output_port +} + +