From ef756eea60e99938d04e6a78f2633391009999b4 Mon Sep 17 00:00:00 2001 From: Komal Jain Date: Fri, 19 Jan 2024 14:37:19 +0530 Subject: [PATCH] Convert deparser header to 'inout' and address casting for functions with control block parameters (#4338) * Convert deparser header to 'inout'. Function with control block parameters generate correct cast * Remove commented code. * Fix failing issue --- backends/tc/ebpfCodeGen.cpp | 12 +- p4include/tc/pna.p4 | 2 +- .../p4tc_samples/default_action_example.p4 | 2 +- .../p4tc_samples/default_hit_const_example.p4 | 2 +- .../default_hit_const_repeat_errors.p4 | 2 +- ...hit_default_hit_const_annotation_errors.p4 | 2 +- .../p4tc_samples/default_hit_repeat_errors.p4 | 2 +- testdata/p4tc_samples/drop_packet_example.p4 | 2 +- .../p4tc_samples/global_action_example_01.p4 | 2 +- .../p4tc_samples/global_action_example_02.p4 | 2 +- testdata/p4tc_samples/ipip.p4 | 156 +++++++ testdata/p4tc_samples/matchtype.p4 | 2 +- .../p4tc_samples/mix_matchtype_example.p4 | 2 +- .../multiple_annotation_same_action_errors.p4 | 2 +- .../multiple_annotation_same_table_errors.p4 | 2 +- .../multiple_tables_example_01.p4 | 2 +- .../multiple_tables_example_02.p4 | 2 +- .../p4tc_samples/name_annotation_example.p4 | 2 +- testdata/p4tc_samples/no_table_example.p4 | 2 +- testdata/p4tc_samples/noaction_example_01.p4 | 2 +- testdata/p4tc_samples/noaction_example_02.p4 | 2 +- .../p4tc_samples/nummask_annotation_errors.p4 | 2 +- .../nummask_annotation_example.p4 | 2 +- testdata/p4tc_samples/send_to_port_example.p4 | 2 +- .../p4tc_samples/set_entry_timer_example.p4 | 2 +- testdata/p4tc_samples/simple_exact_example.p4 | 2 +- testdata/p4tc_samples/simple_lpm_example.p4 | 2 +- .../p4tc_samples/simple_ternary_example.p4 | 2 +- testdata/p4tc_samples/size_param_example.p4 | 2 +- ...tableonly_default_hit_annotation_errors.p4 | 2 +- ...nly_default_hit_const_annotation_errors.p4 | 2 +- ...tableonly_defaultonly_annotation_errors.p4 | 2 +- .../p4tc_samples/tc_type_annotation_errors.p4 | 2 +- .../tc_type_annotation_example.p4 | 2 +- testdata/p4tc_samples/test_ipv6_example.p4 | 2 +- testdata/p4tc_samples_outputs/ipip.json | 84 ++++ testdata/p4tc_samples_outputs/ipip.p4-stderr | 0 testdata/p4tc_samples_outputs/ipip.template | 30 ++ .../ipip_control_blocks.c | 442 ++++++++++++++++++ testdata/p4tc_samples_outputs/ipip_parser.c | 185 ++++++++ testdata/p4tc_samples_outputs/ipip_parser.h | 52 +++ 41 files changed, 993 insertions(+), 34 deletions(-) create mode 100644 testdata/p4tc_samples/ipip.p4 create mode 100644 testdata/p4tc_samples_outputs/ipip.json create mode 100644 testdata/p4tc_samples_outputs/ipip.p4-stderr create mode 100755 testdata/p4tc_samples_outputs/ipip.template create mode 100644 testdata/p4tc_samples_outputs/ipip_control_blocks.c create mode 100644 testdata/p4tc_samples_outputs/ipip_parser.c create mode 100644 testdata/p4tc_samples_outputs/ipip_parser.h diff --git a/backends/tc/ebpfCodeGen.cpp b/backends/tc/ebpfCodeGen.cpp index 62be4d1eb2..61531bf8bc 100644 --- a/backends/tc/ebpfCodeGen.cpp +++ b/backends/tc/ebpfCodeGen.cpp @@ -986,7 +986,17 @@ void IngressDeparserPNA::emitPreDeparser(EBPF::CodeBuilder *builder) { void IngressDeparserPNA::emit(EBPF::CodeBuilder *builder) { codeGen->setBuilder(builder); - for (auto a : controlBlock->container->controlLocals) emitDeclaration(builder, a); + for (auto a : controlBlock->container->controlLocals) { + if (a->is()) { + auto vd = a->to(); + if (vd->type->toString() == headers->type->toString() || + vd->type->toString() == user_metadata->type->toString()) { + codeGen->isPointerVariable(a->name.name); + codeGen->useAsPointerVariable(vd->name); + } + } + emitDeclaration(builder, a); + } emitDeparserExternCalls(builder); builder->newline(); diff --git a/p4include/tc/pna.p4 b/p4include/tc/pna.p4 index c1b76668bf..a193800511 100644 --- a/p4include/tc/pna.p4 +++ b/p4include/tc/pna.p4 @@ -864,7 +864,7 @@ control MainControlT( control MainDeparserT( packet_out pkt, - in MH main_hdr, + inout MH main_hdr, in MM main_user_meta, in pna_main_output_metadata_t ostd); diff --git a/testdata/p4tc_samples/default_action_example.p4 b/testdata/p4tc_samples/default_action_example.p4 index 052a19d05c..2ed490e7d7 100644 --- a/testdata/p4tc_samples/default_action_example.p4 +++ b/testdata/p4tc_samples/default_action_example.p4 @@ -115,7 +115,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/default_hit_const_example.p4 b/testdata/p4tc_samples/default_hit_const_example.p4 index 95ee2dcab5..123c36a2aa 100644 --- a/testdata/p4tc_samples/default_hit_const_example.p4 +++ b/testdata/p4tc_samples/default_hit_const_example.p4 @@ -156,7 +156,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in metadata_t meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/default_hit_const_repeat_errors.p4 b/testdata/p4tc_samples/default_hit_const_repeat_errors.p4 index 1da3839049..c61d6bd03d 100644 --- a/testdata/p4tc_samples/default_hit_const_repeat_errors.p4 +++ b/testdata/p4tc_samples/default_hit_const_repeat_errors.p4 @@ -157,7 +157,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in metadata_t meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/default_hit_default_hit_const_annotation_errors.p4 b/testdata/p4tc_samples/default_hit_default_hit_const_annotation_errors.p4 index de6e9f3a3d..6437c8daec 100644 --- a/testdata/p4tc_samples/default_hit_default_hit_const_annotation_errors.p4 +++ b/testdata/p4tc_samples/default_hit_default_hit_const_annotation_errors.p4 @@ -157,7 +157,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in metadata_t meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/default_hit_repeat_errors.p4 b/testdata/p4tc_samples/default_hit_repeat_errors.p4 index fd3eeffe02..29ba84eae4 100644 --- a/testdata/p4tc_samples/default_hit_repeat_errors.p4 +++ b/testdata/p4tc_samples/default_hit_repeat_errors.p4 @@ -157,7 +157,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in metadata_t meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/drop_packet_example.p4 b/testdata/p4tc_samples/drop_packet_example.p4 index 84a0b80ada..28eba430bc 100644 --- a/testdata/p4tc_samples/drop_packet_example.p4 +++ b/testdata/p4tc_samples/drop_packet_example.p4 @@ -98,7 +98,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/global_action_example_01.p4 b/testdata/p4tc_samples/global_action_example_01.p4 index ca9c28a4bc..5785c24b29 100644 --- a/testdata/p4tc_samples/global_action_example_01.p4 +++ b/testdata/p4tc_samples/global_action_example_01.p4 @@ -126,7 +126,7 @@ control ingress( control Ingress_Deparser( packet_out pkt, - in my_ingress_headers_t hdr, + inout my_ingress_headers_t hdr, in my_ingress_metadata_t meta, in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/global_action_example_02.p4 b/testdata/p4tc_samples/global_action_example_02.p4 index b956132a38..719982e4b4 100644 --- a/testdata/p4tc_samples/global_action_example_02.p4 +++ b/testdata/p4tc_samples/global_action_example_02.p4 @@ -125,7 +125,7 @@ control ingress( control Ingress_Deparser( packet_out pkt, - in my_ingress_headers_t hdr, + inout my_ingress_headers_t hdr, in my_ingress_metadata_t meta, in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/ipip.p4 b/testdata/p4tc_samples/ipip.p4 new file mode 100644 index 0000000000..ce7beb943e --- /dev/null +++ b/testdata/p4tc_samples/ipip.p4 @@ -0,0 +1,156 @@ +#include +#include + +struct metadata_t { + bit<32> src; + bit<32> dst; + bool push; +} + +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 headers_t { + ethernet_t ethernet; + ipv4_t outer; + ipv4_t inner; +} + +#define ETHERTYPE_IPV4 0x0800 +#define IPPROTO_IPV4 0x4 + +/*********************** P A R S E R **************************/ +parser Parser( + packet_in pkt, + out headers_t hdr, + inout metadata_t meta, + in pna_main_parser_input_metadata_t istd) +{ + state start { + transition parse_ethernet; + } + + state parse_ethernet { + pkt.extract(hdr.ethernet); + transition select(hdr.ethernet.etherType) { + ETHERTYPE_IPV4: parse_ipv4; + default: reject; + } + } + + state parse_ipv4 { + pkt.extract(hdr.outer); + transition select(hdr.outer.protocol) { + IPPROTO_IPV4: parse_ipv4_inner; + default: accept; + } + } + + state parse_ipv4_inner { + pkt.extract(hdr.inner); + transition accept; + } +} + +void ipip_push(inout headers_t hdr, in metadata_t meta) +{ + hdr.inner = hdr.outer; + hdr.outer.srcAddr = meta.src; + hdr.outer.dstAddr = meta.dst; + hdr.outer.ttl = 64; + hdr.outer.protocol = 4; /* IPIP */ + /* Assume MTU can accomodate +20 bytes */ + hdr.outer.totalLen = hdr.outer.totalLen + 20; + hdr.outer.hdrChecksum = 0; +} + +/***************** M A T C H - A C T I O N *********************/ +control Main( + inout headers_t hdr, + inout metadata_t meta, + in pna_main_input_metadata_t istd, + inout pna_main_output_metadata_t ostd +) +{ + action set_ipip(@tc_type("ipv4") bit<32> src, @tc_type("ipv4") bit<32> dst, @tc_type("dev") PortId_t port) { + meta.src = src; + meta.dst = dst; + meta.push = true; + send_to_port(port); + } + + action set_nh(@tc_type("macaddr") bit<48> dmac, @tc_type("dev") PortId_t port) { + hdr.ethernet.dstAddr = dmac; + send_to_port(port); + } + + action drop() { + drop_packet(); + } + + table fwd_table { + key = { + istd.input_port : exact @tc_type("dev") @name("port"); + } + actions = { + set_ipip; + set_nh; + drop; + } + default_action = drop; + } + + apply { + if (hdr.outer.isValid()) { /* applies to both ipip and plain ip */ + fwd_table.apply(); /* lookup based on incoming netdev */ + if (hdr.inner.isValid()) { /* incoming packet ipip */ + /* Pop the ipip header by invalidating outer header */ + hdr.outer.setInvalid(); + } + } + } +} + +/********************* D E P A R S E R ************************/ +control Deparser( + packet_out pkt, + inout headers_t hdr, + in metadata_t meta, + in pna_main_output_metadata_t ostd) +{ + + apply { + pkt.emit(hdr.ethernet); + if (meta.push && hdr.outer.isValid()) { + /* Push the ipip header */ + ipip_push(hdr, meta); + } + pkt.emit(hdr.outer); + pkt.emit(hdr.inner); + } +} + +/************ F I N A L P A C K A G E ******************************/ +PNA_NIC( + Parser(), + Main(), + Deparser() +) main; diff --git a/testdata/p4tc_samples/matchtype.p4 b/testdata/p4tc_samples/matchtype.p4 index 54bfd7e77d..dab6b35f00 100644 --- a/testdata/p4tc_samples/matchtype.p4 +++ b/testdata/p4tc_samples/matchtype.p4 @@ -137,7 +137,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/mix_matchtype_example.p4 b/testdata/p4tc_samples/mix_matchtype_example.p4 index e4de50a979..d816e72eaf 100644 --- a/testdata/p4tc_samples/mix_matchtype_example.p4 +++ b/testdata/p4tc_samples/mix_matchtype_example.p4 @@ -138,7 +138,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/multiple_annotation_same_action_errors.p4 b/testdata/p4tc_samples/multiple_annotation_same_action_errors.p4 index aba5a3f827..d4c87b6d53 100644 --- a/testdata/p4tc_samples/multiple_annotation_same_action_errors.p4 +++ b/testdata/p4tc_samples/multiple_annotation_same_action_errors.p4 @@ -157,7 +157,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in metadata_t meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/multiple_annotation_same_table_errors.p4 b/testdata/p4tc_samples/multiple_annotation_same_table_errors.p4 index 53f5c3a453..673152123b 100644 --- a/testdata/p4tc_samples/multiple_annotation_same_table_errors.p4 +++ b/testdata/p4tc_samples/multiple_annotation_same_table_errors.p4 @@ -157,7 +157,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in metadata_t meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/multiple_tables_example_01.p4 b/testdata/p4tc_samples/multiple_tables_example_01.p4 index 05dd769976..dced7039bc 100644 --- a/testdata/p4tc_samples/multiple_tables_example_01.p4 +++ b/testdata/p4tc_samples/multiple_tables_example_01.p4 @@ -250,7 +250,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/multiple_tables_example_02.p4 b/testdata/p4tc_samples/multiple_tables_example_02.p4 index c71abf3752..d1b1d5205a 100644 --- a/testdata/p4tc_samples/multiple_tables_example_02.p4 +++ b/testdata/p4tc_samples/multiple_tables_example_02.p4 @@ -251,7 +251,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/name_annotation_example.p4 b/testdata/p4tc_samples/name_annotation_example.p4 index 6c49cbf18f..4fade1cc6a 100644 --- a/testdata/p4tc_samples/name_annotation_example.p4 +++ b/testdata/p4tc_samples/name_annotation_example.p4 @@ -114,7 +114,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/no_table_example.p4 b/testdata/p4tc_samples/no_table_example.p4 index b0a330b808..19201d70b2 100644 --- a/testdata/p4tc_samples/no_table_example.p4 +++ b/testdata/p4tc_samples/no_table_example.p4 @@ -92,7 +92,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/noaction_example_01.p4 b/testdata/p4tc_samples/noaction_example_01.p4 index 6842520067..396a9c404f 100644 --- a/testdata/p4tc_samples/noaction_example_01.p4 +++ b/testdata/p4tc_samples/noaction_example_01.p4 @@ -119,7 +119,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/noaction_example_02.p4 b/testdata/p4tc_samples/noaction_example_02.p4 index 1ddc923641..3fdf756a25 100644 --- a/testdata/p4tc_samples/noaction_example_02.p4 +++ b/testdata/p4tc_samples/noaction_example_02.p4 @@ -109,7 +109,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/nummask_annotation_errors.p4 b/testdata/p4tc_samples/nummask_annotation_errors.p4 index 067cd52bf4..ad41646285 100644 --- a/testdata/p4tc_samples/nummask_annotation_errors.p4 +++ b/testdata/p4tc_samples/nummask_annotation_errors.p4 @@ -158,7 +158,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in metadata_t meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/nummask_annotation_example.p4 b/testdata/p4tc_samples/nummask_annotation_example.p4 index 05a143830f..c0db402327 100644 --- a/testdata/p4tc_samples/nummask_annotation_example.p4 +++ b/testdata/p4tc_samples/nummask_annotation_example.p4 @@ -158,7 +158,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in metadata_t meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/send_to_port_example.p4 b/testdata/p4tc_samples/send_to_port_example.p4 index badae7237e..d0c5159906 100644 --- a/testdata/p4tc_samples/send_to_port_example.p4 +++ b/testdata/p4tc_samples/send_to_port_example.p4 @@ -100,7 +100,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/set_entry_timer_example.p4 b/testdata/p4tc_samples/set_entry_timer_example.p4 index c0c5fb0721..4a28dfdb92 100644 --- a/testdata/p4tc_samples/set_entry_timer_example.p4 +++ b/testdata/p4tc_samples/set_entry_timer_example.p4 @@ -117,7 +117,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/simple_exact_example.p4 b/testdata/p4tc_samples/simple_exact_example.p4 index a4b30c9876..e2853b99e8 100644 --- a/testdata/p4tc_samples/simple_exact_example.p4 +++ b/testdata/p4tc_samples/simple_exact_example.p4 @@ -107,7 +107,7 @@ control ingress( control Ingress_Deparser( packet_out pkt, - in my_ingress_headers_t hdr, + inout my_ingress_headers_t hdr, in my_ingress_metadata_t meta, in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/simple_lpm_example.p4 b/testdata/p4tc_samples/simple_lpm_example.p4 index 01cf0c1832..b4400d330c 100644 --- a/testdata/p4tc_samples/simple_lpm_example.p4 +++ b/testdata/p4tc_samples/simple_lpm_example.p4 @@ -107,7 +107,7 @@ control ingress( control Ingress_Deparser( packet_out pkt, - in my_ingress_headers_t hdr, + inout my_ingress_headers_t hdr, in my_ingress_metadata_t meta, in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/simple_ternary_example.p4 b/testdata/p4tc_samples/simple_ternary_example.p4 index 74a25524d5..2f384a1577 100644 --- a/testdata/p4tc_samples/simple_ternary_example.p4 +++ b/testdata/p4tc_samples/simple_ternary_example.p4 @@ -108,7 +108,7 @@ control ingress( control Ingress_Deparser( packet_out pkt, - in my_ingress_headers_t hdr, + inout my_ingress_headers_t hdr, in my_ingress_metadata_t meta, in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/size_param_example.p4 b/testdata/p4tc_samples/size_param_example.p4 index cc9f5e205e..6c8203a1e5 100644 --- a/testdata/p4tc_samples/size_param_example.p4 +++ b/testdata/p4tc_samples/size_param_example.p4 @@ -118,7 +118,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/tableonly_default_hit_annotation_errors.p4 b/testdata/p4tc_samples/tableonly_default_hit_annotation_errors.p4 index fc741a45b4..a09c710329 100644 --- a/testdata/p4tc_samples/tableonly_default_hit_annotation_errors.p4 +++ b/testdata/p4tc_samples/tableonly_default_hit_annotation_errors.p4 @@ -157,7 +157,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in metadata_t meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/tableonly_default_hit_const_annotation_errors.p4 b/testdata/p4tc_samples/tableonly_default_hit_const_annotation_errors.p4 index 7693cd153c..d571c5c56e 100644 --- a/testdata/p4tc_samples/tableonly_default_hit_const_annotation_errors.p4 +++ b/testdata/p4tc_samples/tableonly_default_hit_const_annotation_errors.p4 @@ -157,7 +157,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in metadata_t meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/tableonly_defaultonly_annotation_errors.p4 b/testdata/p4tc_samples/tableonly_defaultonly_annotation_errors.p4 index c54a609c83..55a09a7fd2 100644 --- a/testdata/p4tc_samples/tableonly_defaultonly_annotation_errors.p4 +++ b/testdata/p4tc_samples/tableonly_defaultonly_annotation_errors.p4 @@ -249,7 +249,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/tc_type_annotation_errors.p4 b/testdata/p4tc_samples/tc_type_annotation_errors.p4 index 0dfa6fd833..b241454be1 100644 --- a/testdata/p4tc_samples/tc_type_annotation_errors.p4 +++ b/testdata/p4tc_samples/tc_type_annotation_errors.p4 @@ -157,7 +157,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in metadata_t meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/tc_type_annotation_example.p4 b/testdata/p4tc_samples/tc_type_annotation_example.p4 index 711a7bf8d2..c6dd6edc81 100644 --- a/testdata/p4tc_samples/tc_type_annotation_example.p4 +++ b/testdata/p4tc_samples/tc_type_annotation_example.p4 @@ -109,7 +109,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples/test_ipv6_example.p4 b/testdata/p4tc_samples/test_ipv6_example.p4 index 72d441cfac..cc99367e99 100644 --- a/testdata/p4tc_samples/test_ipv6_example.p4 +++ b/testdata/p4tc_samples/test_ipv6_example.p4 @@ -105,7 +105,7 @@ control MainControlImpl( control MainDeparserImpl( packet_out pkt, - in headers_t hdr, // from main control + inout headers_t hdr, // from main control in main_metadata_t user_meta, // from main control in pna_main_output_metadata_t ostd) { diff --git a/testdata/p4tc_samples_outputs/ipip.json b/testdata/p4tc_samples_outputs/ipip.json new file mode 100644 index 0000000000..0865f511f2 --- /dev/null +++ b/testdata/p4tc_samples_outputs/ipip.json @@ -0,0 +1,84 @@ +{ + "schema_version" : "1.0.0", + "pipeline_name" : "ipip", + "id" : 1, + "tables" : [ + { + "name" : "Main/fwd_table", + "id" : 1, + "tentries" : 2048, + "nummask" : 8, + "keysize" : 32, + "keyfields" : [ + { + "id" : 1, + "name" : "port", + "type" : "dev", + "match_type" : "exact", + "bitwidth" : 32 + } + ], + "actions" : [ + { + "id" : 1, + "name" : "Main/set_ipip", + "action_scope" : "TableAndDefault", + "annotations" : [], + "params" : [ + { + "id" : 1, + "name" : "src", + "type" : "ipv4", + "bitwidth" : 32 + }, + { + "id" : 2, + "name" : "dst", + "type" : "ipv4", + "bitwidth" : 32 + }, + { + "id" : 3, + "name" : "port", + "type" : "dev", + "bitwidth" : 32 + } + ], + "default_hit_action" : false, + "default_miss_action" : false + }, + { + "id" : 2, + "name" : "Main/set_nh", + "action_scope" : "TableAndDefault", + "annotations" : [], + "params" : [ + { + "id" : 1, + "name" : "dmac", + "type" : "macaddr", + "bitwidth" : 48 + }, + { + "id" : 2, + "name" : "port", + "type" : "dev", + "bitwidth" : 32 + } + ], + "default_hit_action" : false, + "default_miss_action" : false + }, + { + "id" : 3, + "name" : "Main/drop", + "action_scope" : "TableAndDefault", + "annotations" : [], + "params" : [], + "default_hit_action" : false, + "default_miss_action" : true + } + ] + } + ] +} \ No newline at end of file diff --git a/testdata/p4tc_samples_outputs/ipip.p4-stderr b/testdata/p4tc_samples_outputs/ipip.p4-stderr new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testdata/p4tc_samples_outputs/ipip.template b/testdata/p4tc_samples_outputs/ipip.template new file mode 100755 index 0000000000..8a314cd23b --- /dev/null +++ b/testdata/p4tc_samples_outputs/ipip.template @@ -0,0 +1,30 @@ +#!/bin/bash -x + +set -e + +TC="tc" +$TC p4template create pipeline/ipip pipeid 1 numtables 1 + +$TC p4template create action/ipip/Main/set_ipip actid 1 \ + param src type ipv4 \ + param dst type ipv4 \ + param port type dev +$TC p4template update action/ipip/Main/set_ipip state active + +$TC p4template create action/ipip/Main/set_nh actid 2 \ + param dmac type macaddr \ + param port type dev +$TC p4template update action/ipip/Main/set_nh state active + +$TC p4template create action/ipip/Main/drop actid 3 +$TC p4template update action/ipip/Main/drop state active + +$TC p4template create table/ipip/Main/fwd_table \ + tblid 1 \ + type exact \ + keysz 32 nummasks 8 tentries 2048 \ + table_acts act name ipip/Main/set_ipip \ + act name ipip/Main/set_nh \ + act name ipip/Main/drop +$TC p4template update table/ipip/Main/fwd_table default_miss_action action ipip/Main/drop +$TC p4template update pipeline/ipip state ready \ No newline at end of file diff --git a/testdata/p4tc_samples_outputs/ipip_control_blocks.c b/testdata/p4tc_samples_outputs/ipip_control_blocks.c new file mode 100644 index 0000000000..32a275ecf3 --- /dev/null +++ b/testdata/p4tc_samples_outputs/ipip_control_blocks.c @@ -0,0 +1,442 @@ +#include "ipip_parser.h" +struct internal_metadata { + __u16 pkt_ether_type; +} __attribute__((aligned(4))); + +struct __attribute__((__packed__)) Main_fwd_table_key { + u32 keysz; + u32 maskid; + u32 field0; /* istd.input_port */ +} __attribute__((aligned(4))); +#define MAIN_FWD_TABLE_ACT_MAIN_SET_IPIP 1 +#define MAIN_FWD_TABLE_ACT_MAIN_SET_NH 2 +#define MAIN_FWD_TABLE_ACT_MAIN_DROP 3 +struct __attribute__((__packed__)) Main_fwd_table_value { + unsigned int action; + union { + struct { + } _NoAction; + struct __attribute__((__packed__)) { + u32 src; + u32 dst; + u32 port; + } Main_set_ipip; + struct __attribute__((__packed__)) { + u64 dmac; + u32 port; + } Main_set_nh; + struct { + } Main_drop; + } u; +}; + +REGISTER_START() +REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) +BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) +REGISTER_END() + +SEC("xdp/xdp-ingress") +int xdp_func(struct xdp_md *skb) { + void *data_end = (void *)(long)skb->data_end; + struct ethhdr *eth = (struct ethhdr *)(long)skb->data; + if ((void *)((struct ethhdr *) eth + 1) > data_end) { + return XDP_ABORTED; + } + if (eth->h_proto == bpf_htons(0x0800) || eth->h_proto == bpf_htons(0x86DD)) { + return XDP_PASS; + } + + struct internal_metadata *meta; + int ret = bpf_xdp_adjust_meta(skb, -(int)sizeof(*meta)); + if (ret < 0) { + return XDP_ABORTED; + } + meta = (struct internal_metadata *)(unsigned long)skb->data_meta; + eth = (void *)(long)skb->data; + data_end = (void *)(long)skb->data_end; + if ((void *) ((struct internal_metadata *) meta + 1) > (void *)(long)skb->data) + return XDP_ABORTED; + if ((void *)((struct ethhdr *) eth + 1) > data_end) { + return XDP_ABORTED; + } + meta->pkt_ether_type = eth->h_proto; + eth->h_proto = bpf_htons(0x0800); + + return XDP_PASS; +} +static __always_inline int process(struct __sk_buff *skb, struct headers_t *hdr, struct pna_global_metadata *compiler_meta__) +{ + struct hdr_md *hdrMd; + + unsigned ebpf_packetOffsetInBits_save = 0; + ParserError_t ebpf_errorCode = NoError; + void* pkt = ((void*)(long)skb->data); + void* ebpf_packetEnd = ((void*)(long)skb->data_end); + u32 ebpf_zero = 0; + u32 ebpf_one = 1; + unsigned char ebpf_byte; + u32 pkt_len = skb->len; + + struct metadata_t *meta; + hdrMd = BPF_MAP_LOOKUP_ELEM(hdr_md_cpumap, &ebpf_zero); + if (!hdrMd) + return TC_ACT_SHOT; + unsigned ebpf_packetOffsetInBits = hdrMd->ebpf_packetOffsetInBits; + hdr = &(hdrMd->cpumap_hdr); + meta = &(hdrMd->cpumap_usermeta); +{ + u8 hit; + { +if (/* hdr->outer.isValid() */ + hdr->outer.ebpf_valid) { +/* fwd_table_0.apply() */ + { + /* construct key */ + struct p4tc_table_entry_act_bpf_params__local params = { + .pipeid = 1, + .tblid = 1 + }; + struct Main_fwd_table_key key = {}; + key.keysz = 32; + key.field0 = skb->ifindex; + struct p4tc_table_entry_act_bpf *act_bpf; + /* value */ + struct Main_fwd_table_value *value = NULL; + /* perform lookup */ + act_bpf = bpf_p4tc_tbl_read(skb, ¶ms, &key, sizeof(key)); + value = (struct Main_fwd_table_value *)act_bpf; + if (value == NULL) { + /* miss; find default action */ + hit = 0; + } else { + hit = 1; + } + if (value != NULL) { + /* run action */ + switch (value->action) { + case MAIN_FWD_TABLE_ACT_MAIN_SET_IPIP: + { + meta->src = value->u.Main_set_ipip.src; + meta->dst = value->u.Main_set_ipip.dst; + meta->push = true; + /* send_to_port(value->u.Main_set_ipip.port) */ + compiler_meta__->drop = false; + send_to_port(value->u.Main_set_ipip.port); + } + break; + case MAIN_FWD_TABLE_ACT_MAIN_SET_NH: + { + hdr->ethernet.dstAddr = value->u.Main_set_nh.dmac; + /* send_to_port(value->u.Main_set_nh.port) */ + compiler_meta__->drop = false; + send_to_port(value->u.Main_set_nh.port); + } + break; + case MAIN_FWD_TABLE_ACT_MAIN_DROP: + { +/* drop_packet() */ + drop_packet(); + } + break; + default: + return TC_ACT_SHOT; + } + } else { +/* drop_packet() */ + drop_packet(); + } + } +; + if (/* hdr->inner.isValid() */ + hdr->inner.ebpf_valid) { +/* hdr->outer.setInvalid() */ + hdr->outer.ebpf_valid = false; } + + } + } + } + { + struct headers_t *hdr_1; + struct metadata_t *meta_1; +{ +; + if (meta->push && /* hdr->outer.isValid() */ + hdr->outer.ebpf_valid) { + hdr_1 = hdr; + meta_1 = meta; + hdr_1->inner = hdr_1->outer; + hdr_1->outer.srcAddr = meta_1->src; + hdr_1->outer.dstAddr = meta_1->dst; + hdr_1->outer.ttl = 64; + hdr_1->outer.protocol = 4; + hdr_1->outer.totalLen = (hdr_1->outer.totalLen + 20); + hdr_1->outer.hdrChecksum = 0; + hdr = hdr_1; + } + ; + ; + } + + if (compiler_meta__->drop) { + return TC_ACT_SHOT; + } + int outHeaderLength = 0; + if (hdr->ethernet.ebpf_valid) { + outHeaderLength += 112; + } +; if (hdr->outer.ebpf_valid) { + outHeaderLength += 160; + } +; if (hdr->inner.ebpf_valid) { + outHeaderLength += 160; + } +; + int outHeaderOffset = BYTES(outHeaderLength) - BYTES(ebpf_packetOffsetInBits); + if (outHeaderOffset != 0) { + int returnCode = 0; + returnCode = bpf_skb_adjust_room(skb, outHeaderOffset, 1, 0); + if (returnCode) { + return TC_ACT_SHOT; + } + } + pkt = ((void*)(long)skb->data); + ebpf_packetEnd = ((void*)(long)skb->data_end); + ebpf_packetOffsetInBits = 0; + if (hdr->ethernet.ebpf_valid) { + if (ebpf_packetEnd < pkt + BYTES(ebpf_packetOffsetInBits + 112)) { + return TC_ACT_SHOT; + } + + hdr->ethernet.dstAddr = htonll(hdr->ethernet.dstAddr << 16); + ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[2]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[3]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[4]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 4, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.dstAddr))[5]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); + ebpf_packetOffsetInBits += 48; + + hdr->ethernet.srcAddr = htonll(hdr->ethernet.srcAddr << 16); + ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[2]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[3]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[4]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 4, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.srcAddr))[5]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 5, (ebpf_byte)); + ebpf_packetOffsetInBits += 48; + + hdr->ethernet.etherType = bpf_htons(hdr->ethernet.etherType); + ebpf_byte = ((char*)(&hdr->ethernet.etherType))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->ethernet.etherType))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + } +; if (hdr->outer.ebpf_valid) { + if (ebpf_packetEnd < pkt + BYTES(ebpf_packetOffsetInBits + 160)) { + return TC_ACT_SHOT; + } + + ebpf_byte = ((char*)(&hdr->outer.version))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 4, 4, (ebpf_byte >> 0)); + ebpf_packetOffsetInBits += 4; + + ebpf_byte = ((char*)(&hdr->outer.ihl))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 4, 0, (ebpf_byte >> 0)); + ebpf_packetOffsetInBits += 4; + + ebpf_byte = ((char*)(&hdr->outer.diffserv))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_packetOffsetInBits += 8; + + hdr->outer.totalLen = bpf_htons(hdr->outer.totalLen); + ebpf_byte = ((char*)(&hdr->outer.totalLen))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.totalLen))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + hdr->outer.identification = bpf_htons(hdr->outer.identification); + ebpf_byte = ((char*)(&hdr->outer.identification))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.identification))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + ebpf_byte = ((char*)(&hdr->outer.flags))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 3, 5, (ebpf_byte >> 0)); + ebpf_packetOffsetInBits += 3; + + hdr->outer.fragOffset = bpf_htons(hdr->outer.fragOffset << 3); + ebpf_byte = ((char*)(&hdr->outer.fragOffset))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 5, 0, (ebpf_byte >> 3)); + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0 + 1, 3, 5, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.fragOffset))[1]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 1, 5, 0, (ebpf_byte >> 3)); + ebpf_packetOffsetInBits += 13; + + ebpf_byte = ((char*)(&hdr->outer.ttl))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_packetOffsetInBits += 8; + + ebpf_byte = ((char*)(&hdr->outer.protocol))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_packetOffsetInBits += 8; + + hdr->outer.hdrChecksum = bpf_htons(hdr->outer.hdrChecksum); + ebpf_byte = ((char*)(&hdr->outer.hdrChecksum))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.hdrChecksum))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + hdr->outer.srcAddr = htonl(hdr->outer.srcAddr); + ebpf_byte = ((char*)(&hdr->outer.srcAddr))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.srcAddr))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.srcAddr))[2]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.srcAddr))[3]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte)); + ebpf_packetOffsetInBits += 32; + + hdr->outer.dstAddr = htonl(hdr->outer.dstAddr); + ebpf_byte = ((char*)(&hdr->outer.dstAddr))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.dstAddr))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.dstAddr))[2]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->outer.dstAddr))[3]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte)); + ebpf_packetOffsetInBits += 32; + + } +; if (hdr->inner.ebpf_valid) { + if (ebpf_packetEnd < pkt + BYTES(ebpf_packetOffsetInBits + 160)) { + return TC_ACT_SHOT; + } + + ebpf_byte = ((char*)(&hdr->inner.version))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 4, 4, (ebpf_byte >> 0)); + ebpf_packetOffsetInBits += 4; + + ebpf_byte = ((char*)(&hdr->inner.ihl))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 4, 0, (ebpf_byte >> 0)); + ebpf_packetOffsetInBits += 4; + + ebpf_byte = ((char*)(&hdr->inner.diffserv))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_packetOffsetInBits += 8; + + hdr->inner.totalLen = bpf_htons(hdr->inner.totalLen); + ebpf_byte = ((char*)(&hdr->inner.totalLen))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.totalLen))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + hdr->inner.identification = bpf_htons(hdr->inner.identification); + ebpf_byte = ((char*)(&hdr->inner.identification))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.identification))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + ebpf_byte = ((char*)(&hdr->inner.flags))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 3, 5, (ebpf_byte >> 0)); + ebpf_packetOffsetInBits += 3; + + hdr->inner.fragOffset = bpf_htons(hdr->inner.fragOffset << 3); + ebpf_byte = ((char*)(&hdr->inner.fragOffset))[0]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0, 5, 0, (ebpf_byte >> 3)); + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 0 + 1, 3, 5, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.fragOffset))[1]; + write_partial(pkt + BYTES(ebpf_packetOffsetInBits) + 1, 5, 0, (ebpf_byte >> 3)); + ebpf_packetOffsetInBits += 13; + + ebpf_byte = ((char*)(&hdr->inner.ttl))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_packetOffsetInBits += 8; + + ebpf_byte = ((char*)(&hdr->inner.protocol))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_packetOffsetInBits += 8; + + hdr->inner.hdrChecksum = bpf_htons(hdr->inner.hdrChecksum); + ebpf_byte = ((char*)(&hdr->inner.hdrChecksum))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.hdrChecksum))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_packetOffsetInBits += 16; + + hdr->inner.srcAddr = htonl(hdr->inner.srcAddr); + ebpf_byte = ((char*)(&hdr->inner.srcAddr))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.srcAddr))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.srcAddr))[2]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.srcAddr))[3]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte)); + ebpf_packetOffsetInBits += 32; + + hdr->inner.dstAddr = htonl(hdr->inner.dstAddr); + ebpf_byte = ((char*)(&hdr->inner.dstAddr))[0]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 0, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.dstAddr))[1]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 1, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.dstAddr))[2]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 2, (ebpf_byte)); + ebpf_byte = ((char*)(&hdr->inner.dstAddr))[3]; + write_byte(pkt, BYTES(ebpf_packetOffsetInBits) + 3, (ebpf_byte)); + ebpf_packetOffsetInBits += 32; + + } +; + } + return -1; +} +SEC("classifier/tc-ingress") +int tc_ingress_func(struct __sk_buff *skb) { + struct pna_global_metadata *compiler_meta__ = (struct pna_global_metadata *) skb->cb; + if (compiler_meta__->pass_to_kernel == true) return TC_ACT_OK; + if (!compiler_meta__->recirculated) { + compiler_meta__->mark = 153; + struct internal_metadata *md = (struct internal_metadata *)(unsigned long)skb->data_meta; + if ((void *) ((struct internal_metadata *) md + 1) <= (void *)(long)skb->data) { + __u16 *ether_type = (__u16 *) ((void *) (long)skb->data + 12); + if ((void *) ((__u16 *) ether_type + 1) > (void *) (long) skb->data_end) { + return TC_ACT_SHOT; + } + *ether_type = md->pkt_ether_type; + } + } + struct hdr_md *hdrMd; + struct headers_t *hdr; + int ret = -1; + ret = process(skb, (struct headers_t *) hdr, compiler_meta__); + if (ret != -1) { + return ret; + } + if (!compiler_meta__->drop && compiler_meta__->egress_port == 0) { + compiler_meta__->pass_to_kernel = true; + return bpf_redirect(skb->ifindex, BPF_F_INGRESS); + } + return bpf_redirect(compiler_meta__->egress_port, 0); +} +char _license[] SEC("license") = "GPL"; diff --git a/testdata/p4tc_samples_outputs/ipip_parser.c b/testdata/p4tc_samples_outputs/ipip_parser.c new file mode 100644 index 0000000000..4a73d9a287 --- /dev/null +++ b/testdata/p4tc_samples_outputs/ipip_parser.c @@ -0,0 +1,185 @@ +#include "ipip_parser.h" + +REGISTER_START() +REGISTER_TABLE(hdr_md_cpumap, BPF_MAP_TYPE_PERCPU_ARRAY, u32, struct hdr_md, 2) +BPF_ANNOTATE_KV_PAIR(hdr_md_cpumap, u32, struct hdr_md) +REGISTER_END() + +static __always_inline int run_parser(struct __sk_buff *skb, struct headers_t *hdr, struct pna_global_metadata *compiler_meta__) +{ + struct hdr_md *hdrMd; + + unsigned ebpf_packetOffsetInBits_save = 0; + ParserError_t ebpf_errorCode = NoError; + void* pkt = ((void*)(long)skb->data); + void* ebpf_packetEnd = ((void*)(long)skb->data_end); + u32 ebpf_zero = 0; + u32 ebpf_one = 1; + unsigned char ebpf_byte; + u32 pkt_len = skb->len; + + struct metadata_t *meta; + + hdrMd = BPF_MAP_LOOKUP_ELEM(hdr_md_cpumap, &ebpf_zero); + if (!hdrMd) + return TC_ACT_SHOT; + __builtin_memset(hdrMd, 0, sizeof(struct hdr_md)); + + unsigned ebpf_packetOffsetInBits = 0; + hdr = &(hdrMd->cpumap_hdr); + meta = &(hdrMd->cpumap_usermeta); + { + goto start; + parse_ipv4: { +/* extract(hdr->outer) */ + if (ebpf_packetEnd < pkt + BYTES(ebpf_packetOffsetInBits + 160 + 0)) { + ebpf_errorCode = PacketTooShort; + goto reject; + } + + hdr->outer.version = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)) >> 4) & EBPF_MASK(u8, 4)); + ebpf_packetOffsetInBits += 4; + + hdr->outer.ihl = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u8, 4)); + ebpf_packetOffsetInBits += 4; + + hdr->outer.diffserv = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 8; + + hdr->outer.totalLen = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + hdr->outer.identification = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + hdr->outer.flags = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)) >> 5) & EBPF_MASK(u8, 3)); + ebpf_packetOffsetInBits += 3; + + hdr->outer.fragOffset = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u16, 13)); + ebpf_packetOffsetInBits += 13; + + hdr->outer.ttl = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 8; + + hdr->outer.protocol = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 8; + + hdr->outer.hdrChecksum = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + hdr->outer.srcAddr = (u32)((load_word(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 32; + + hdr->outer.dstAddr = (u32)((load_word(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 32; + + hdr->outer.ebpf_valid = 1; + +; + u8 select_0; + select_0 = hdr->outer.protocol; + if (select_0 == 0x4)goto parse_ipv4_inner; + if ((select_0 & 0x0) == (0x0 & 0x0))goto accept; + else goto reject; + } + parse_ipv4_inner: { +/* extract(hdr->inner) */ + if (ebpf_packetEnd < pkt + BYTES(ebpf_packetOffsetInBits + 160 + 0)) { + ebpf_errorCode = PacketTooShort; + goto reject; + } + + hdr->inner.version = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)) >> 4) & EBPF_MASK(u8, 4)); + ebpf_packetOffsetInBits += 4; + + hdr->inner.ihl = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u8, 4)); + ebpf_packetOffsetInBits += 4; + + hdr->inner.diffserv = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 8; + + hdr->inner.totalLen = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + hdr->inner.identification = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + hdr->inner.flags = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)) >> 5) & EBPF_MASK(u8, 3)); + ebpf_packetOffsetInBits += 3; + + hdr->inner.fragOffset = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits))) & EBPF_MASK(u16, 13)); + ebpf_packetOffsetInBits += 13; + + hdr->inner.ttl = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 8; + + hdr->inner.protocol = (u8)((load_byte(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 8; + + hdr->inner.hdrChecksum = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + hdr->inner.srcAddr = (u32)((load_word(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 32; + + hdr->inner.dstAddr = (u32)((load_word(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 32; + + hdr->inner.ebpf_valid = 1; + +; + goto accept; + } + start: { +/* extract(hdr->ethernet) */ + if (ebpf_packetEnd < pkt + BYTES(ebpf_packetOffsetInBits + 112 + 0)) { + ebpf_errorCode = PacketTooShort; + goto reject; + } + + hdr->ethernet.dstAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + ebpf_packetOffsetInBits += 48; + + hdr->ethernet.srcAddr = (u64)((load_dword(pkt, BYTES(ebpf_packetOffsetInBits)) >> 16) & EBPF_MASK(u64, 48)); + ebpf_packetOffsetInBits += 48; + + hdr->ethernet.etherType = (u16)((load_half(pkt, BYTES(ebpf_packetOffsetInBits)))); + ebpf_packetOffsetInBits += 16; + + hdr->ethernet.ebpf_valid = 1; + +; + u16 select_1; + select_1 = hdr->ethernet.etherType; + if (select_1 == 0x800)goto parse_ipv4; + if ((select_1 & 0x0) == (0x0 & 0x0))goto reject; + else goto reject; + } + + reject: { + if (ebpf_errorCode == 0) { + return TC_ACT_SHOT; + } + goto accept; + } + + } + + accept: + hdrMd->ebpf_packetOffsetInBits = ebpf_packetOffsetInBits; + return -1; +} + +SEC("classifier/tc-parse") +int tc_parse_func(struct __sk_buff *skb) { + struct pna_global_metadata *compiler_meta__ = (struct pna_global_metadata *) skb->cb; + struct hdr_md *hdrMd; + struct headers_t *hdr; + int ret = -1; + ret = run_parser(skb, (struct headers_t *) hdr, compiler_meta__); + if (ret != -1) { + return ret; + } + return TC_ACT_PIPE; + } +char _license[] SEC("license") = "GPL"; diff --git a/testdata/p4tc_samples_outputs/ipip_parser.h b/testdata/p4tc_samples_outputs/ipip_parser.h new file mode 100644 index 0000000000..1c352a0d0c --- /dev/null +++ b/testdata/p4tc_samples_outputs/ipip_parser.h @@ -0,0 +1,52 @@ +#include "ebpf_kernel.h" + +#include +#include +#include "pna.h" + +#define EBPF_MASK(t, w) ((((t)(1)) << (w)) - (t)1) +#define BYTES(w) ((w) / 8) +#define write_partial(a, w, s, v) do { *((u8*)a) = ((*((u8*)a)) & ~(EBPF_MASK(u8, w) << s)) | (v << s) ; } while (0) +#define write_byte(base, offset, v) do { *(u8*)((base) + (offset)) = (v); } while (0) +#define bpf_trace_message(fmt, ...) + + +struct metadata_t { + u32 src; /* bit<32> */ + u32 dst; /* bit<32> */ + u8 push; /* bool */ +}; +struct ethernet_t { + u64 dstAddr; /* bit<48> */ + u64 srcAddr; /* bit<48> */ + u16 etherType; /* bit<16> */ + u8 ebpf_valid; +}; +struct ipv4_t { + u8 version; /* bit<4> */ + u8 ihl; /* bit<4> */ + u8 diffserv; /* bit<8> */ + u16 totalLen; /* bit<16> */ + u16 identification; /* bit<16> */ + u8 flags; /* bit<3> */ + u16 fragOffset; /* bit<13> */ + u8 ttl; /* bit<8> */ + u8 protocol; /* bit<8> */ + u16 hdrChecksum; /* bit<16> */ + u32 srcAddr; /* bit<32> */ + u32 dstAddr; /* bit<32> */ + u8 ebpf_valid; +}; +struct headers_t { + struct ethernet_t ethernet; /* ethernet_t */ + struct ipv4_t outer; /* ipv4_t */ + struct ipv4_t inner; /* ipv4_t */ +}; + +struct hdr_md { + struct headers_t cpumap_hdr; + struct metadata_t cpumap_usermeta; + unsigned ebpf_packetOffsetInBits; + __u8 __hook; +}; +