Skip to content

Commit

Permalink
Make stricter PSA tests that verify packet_path and instance fields i… (
Browse files Browse the repository at this point in the history
p4lang#2509)

* Make stricter PSA tests that verify packet_path and instance fields in egress

* Change action containing if statements to sub-control for better portability
Sub-controls with if statements should be fairly universally
supported, due to front/mid end of compiler inlining the sub-control
into controls that apply it.  actions with if statements are less
widely supported across targets.

* Minor comment change to correct copyright, and force Travis rebuild

* Make the sub-control return value always initialized
  • Loading branch information
jafingerhut authored Aug 20, 2020
1 parent e4af568 commit e142a64
Show file tree
Hide file tree
Showing 15 changed files with 991 additions and 27 deletions.
173 changes: 173 additions & 0 deletions testdata/p4_16_samples/psa-multicast-basic-2-bmv2.p4
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/*
Copyright 2020 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 <core.p4>
#include "psa.p4"


typedef bit<48> EthernetAddress;

header ethernet_t {
EthernetAddress dstAddr;
EthernetAddress srcAddr;
bit<16> etherType;
}

header output_data_t {
bit<32> word0;
bit<32> word1;
bit<32> word2;
bit<32> word3;
}

struct empty_metadata_t {
}

struct metadata_t {
}

struct headers_t {
ethernet_t ethernet;
output_data_t output_data;
}

control packet_path_to_int (in PSA_PacketPath_t packet_path,
out bit<32> ret)
{
apply {
// Unconditionally assign a value of 8 to ret, because if all
// assignments to ret are conditional, p4c gives warnings
// about ret possibly being uninitialized.
ret = 8;
if (packet_path == PSA_PacketPath_t.NORMAL) {
ret = 1;
} else if (packet_path == PSA_PacketPath_t.NORMAL_UNICAST) {
ret = 2;
} else if (packet_path == PSA_PacketPath_t.NORMAL_MULTICAST) {
ret = 3;
} else if (packet_path == PSA_PacketPath_t.CLONE_I2E) {
ret = 4;
} else if (packet_path == PSA_PacketPath_t.CLONE_E2E) {
ret = 5;
} else if (packet_path == PSA_PacketPath_t.RESUBMIT) {
ret = 6;
} else if (packet_path == PSA_PacketPath_t.RECIRCULATE) {
ret = 7;
}
// ret should still be 8 if packet_path is not any of those
// enum values, which according to the P4_16 specification,
// could happen if packet_path were uninitialized.
}
}

parser IngressParserImpl(packet_in pkt,
out headers_t hdr,
inout metadata_t user_meta,
in psa_ingress_parser_input_metadata_t istd,
in empty_metadata_t resubmit_meta,
in empty_metadata_t recirculate_meta)
{
state start {
pkt.extract(hdr.ethernet);
pkt.extract(hdr.output_data);
transition accept;
}
}

control cIngress(inout headers_t hdr,
inout metadata_t user_meta,
in psa_ingress_input_metadata_t istd,
inout psa_ingress_output_metadata_t ostd)
{
apply {
multicast(ostd,
(MulticastGroup_t) (MulticastGroupUint_t) hdr.ethernet.dstAddr);
}
}

parser EgressParserImpl(packet_in pkt,
out headers_t hdr,
inout metadata_t user_meta,
in psa_egress_parser_input_metadata_t istd,
in empty_metadata_t normal_meta,
in empty_metadata_t clone_i2e_meta,
in empty_metadata_t clone_e2e_meta)
{
state start {
pkt.extract(hdr.ethernet);
pkt.extract(hdr.output_data);
transition accept;
}
}

control cEgress(inout headers_t hdr,
inout metadata_t user_meta,
in psa_egress_input_metadata_t istd,
inout psa_egress_output_metadata_t ostd)
{
apply {
hdr.output_data.word0 = (bit<32>) istd.egress_port;
hdr.output_data.word1 = (bit<32>) ((EgressInstanceUint_t) istd.instance);
packet_path_to_int.apply(istd.packet_path, hdr.output_data.word2);
}
}

control CommonDeparserImpl(packet_out packet,
inout headers_t hdr)
{
apply {
packet.emit(hdr.ethernet);
packet.emit(hdr.output_data);
}
}

control IngressDeparserImpl(packet_out buffer,
out empty_metadata_t clone_i2e_meta,
out empty_metadata_t resubmit_meta,
out empty_metadata_t normal_meta,
inout headers_t hdr,
in metadata_t meta,
in psa_ingress_output_metadata_t istd)
{
CommonDeparserImpl() cp;
apply {
cp.apply(buffer, hdr);
}
}

control EgressDeparserImpl(packet_out buffer,
out empty_metadata_t clone_e2e_meta,
out empty_metadata_t recirculate_meta,
inout headers_t hdr,
in metadata_t meta,
in psa_egress_output_metadata_t istd,
in psa_egress_deparser_input_metadata_t edstd)
{
CommonDeparserImpl() cp;
apply {
cp.apply(buffer, hdr);
}
}

IngressPipeline(IngressParserImpl(),
cIngress(),
IngressDeparserImpl()) ip;

EgressPipeline(EgressParserImpl(),
cEgress(),
EgressDeparserImpl()) ep;

PSA_Switch(ip, PacketReplicationEngine(), ep, BufferingQueueingEngine()) main;
30 changes: 30 additions & 0 deletions testdata/p4_16_samples/psa-multicast-basic-2-bmv2.stf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
mc_mgrp_create 1
mc_node_create 257 6 8
mc_node_create 258 7 8
mc_node_associate 1 0
mc_node_associate 1 1


mc_mgrp_create 2
mc_node_create 259 9
mc_node_create 260 10
mc_node_create 261 11
mc_node_associate 2 2
mc_node_associate 2 3
mc_node_associate 2 4


#input packet
packet 2 000000000001 000000000000 ffff deadbeef deadbeef deadbeef deadbeef
# expect ports
expect 6 000000000001 000000000000 ffff 00000006 00000101 00000003 deadbeef $
expect 7 000000000001 000000000000 ffff 00000007 00000102 00000003 deadbeef $
expect 8 000000000001 000000000000 ffff 00000008 00000101 00000003 deadbeef $
expect 8 000000000001 000000000000 ffff 00000008 00000102 00000003 deadbeef $

#input packet
packet 2 000000000002 000000000000 ffff deadbeef deadbeef deadbeef deadbeef
# expect ports
expect 9 000000000002 000000000000 ffff 00000009 00000103 00000003 deadbeef $
expect 10 000000000002 000000000000 ffff 0000000a 00000104 00000003 deadbeef $
expect 11 000000000002 000000000000 ffff 0000000b 00000105 00000003 deadbeef $
48 changes: 46 additions & 2 deletions testdata/p4_16_samples/psa-unicast-or-drop-bmv2.p4
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ header ethernet_t {
bit<16> etherType;
}

header output_data_t {
bit<32> word0;
bit<32> word1;
bit<32> word2;
bit<32> word3;
}

struct empty_metadata_t {
}

Expand All @@ -34,6 +41,36 @@ struct metadata_t {

struct headers_t {
ethernet_t ethernet;
output_data_t output_data;
}

control packet_path_to_int (in PSA_PacketPath_t packet_path,
out bit<32> ret)
{
apply {
// Unconditionally assign a value of 8 to ret, because if all
// assignments to ret are conditional, p4c gives warnings
// about ret possibly being uninitialized.
ret = 8;
if (packet_path == PSA_PacketPath_t.NORMAL) {
ret = 1;
} else if (packet_path == PSA_PacketPath_t.NORMAL_UNICAST) {
ret = 2;
} else if (packet_path == PSA_PacketPath_t.NORMAL_MULTICAST) {
ret = 3;
} else if (packet_path == PSA_PacketPath_t.CLONE_I2E) {
ret = 4;
} else if (packet_path == PSA_PacketPath_t.CLONE_E2E) {
ret = 5;
} else if (packet_path == PSA_PacketPath_t.RESUBMIT) {
ret = 6;
} else if (packet_path == PSA_PacketPath_t.RECIRCULATE) {
ret = 7;
}
// ret should still be 8 if packet_path is not any of those
// enum values, which according to the P4_16 specification,
// could happen if packet_path were uninitialized.
}
}

parser IngressParserImpl(packet_in pkt,
Expand All @@ -45,6 +82,7 @@ parser IngressParserImpl(packet_in pkt,
{
state start {
pkt.extract(hdr.ethernet);
pkt.extract(hdr.output_data);
transition accept;
}
}
Expand All @@ -71,7 +109,7 @@ control cIngress(inout headers_t hdr,
}
}

parser EgressParserImpl(packet_in buffer,
parser EgressParserImpl(packet_in pkt,
out headers_t hdr,
inout metadata_t user_meta,
in psa_egress_parser_input_metadata_t istd,
Expand All @@ -80,6 +118,8 @@ parser EgressParserImpl(packet_in buffer,
in empty_metadata_t clone_e2e_meta)
{
state start {
pkt.extract(hdr.ethernet);
pkt.extract(hdr.output_data);
transition accept;
}
}
Expand All @@ -89,14 +129,18 @@ control cEgress(inout headers_t hdr,
in psa_egress_input_metadata_t istd,
inout psa_egress_output_metadata_t ostd)
{
apply { }
apply {
hdr.output_data.word0 = (bit<32>) istd.egress_port;
packet_path_to_int.apply(istd.packet_path, hdr.output_data.word2);
}
}

control CommonDeparserImpl(packet_out packet,
inout headers_t hdr)
{
apply {
packet.emit(hdr.ethernet);
packet.emit(hdr.output_data);
}
}

Expand Down
14 changes: 7 additions & 7 deletions testdata/p4_16_samples/psa-unicast-or-drop-bmv2.stf
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
packet 4 000000000001 000000000000 ffff
expect 1 000000000001 000000000000 ffff $
packet 4 000000000001 000000000000 ffff deadbeef deadbeef deadbeef deadbeef
expect 1 000000000001 000000000000 ffff 00000001 deadbeef 00000002 deadbeef $

packet 4 000000000002 000000000000 ffff
expect 2 000000000002 000000000000 ffff $
packet 4 000000000002 000000000000 ffff deadbeef deadbeef deadbeef deadbeef
expect 2 000000000002 000000000000 ffff 00000002 deadbeef 00000002 deadbeef $

packet 4 000000000003 000000000000 ffff
expect 3 000000000003 000000000000 ffff $
packet 4 000000000003 000000000000 ffff deadbeef deadbeef deadbeef deadbeef
expect 3 000000000003 000000000000 ffff 00000003 deadbeef 00000002 deadbeef $

# This packet should be dropped. We send it into port 0, because if
# there are no packets sent into nor expected on port 0, then the test
# infrastructure does not check any of the packets that come out port
# 0, or whether the right number come out port 0.
packet 0 000000000000 000000000000 ffff
packet 0 000000000000 000000000000 ffff deadbeef deadbeef deadbeef deadbeef
Loading

0 comments on commit e142a64

Please sign in to comment.