Skip to content
27 changes: 20 additions & 7 deletions p4-16/psa/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,33 @@ clean:
P4C=p4test
#P4C=p4test --Wdisable=uninitialized_out_param

# TBD: The lines commented out below are PSA example programs that
# have not yet been updated for the proposed new way of handling
# recirculate, resubmit, clone, and normal (aka bridged metadata)
# preserved metadata.

# Most of those commented out programs would look much like
# psa-example-drop-all.p4 in the changes required, since they do not
# preserve any metadata for those cases.

# psa-example-parser-error-handling.p4 does need some updates, most
# likely ones that look nearly identical to
# psa-example-parser-error-handling.p4

check:
${P4C} examples/psa-example-drop-all.p4
${P4C} examples/psa-example-hello-world.p4
${P4C} examples/psa-example-bridged-metadata.p4
${P4C} examples/psa-example-clone-to-port.p4
${P4C} examples/psa-example-counters.p4
${P4C} examples/psa-example-digest.p4
${P4C} examples/psa-example-incremental-checksum.p4
${P4C} examples/psa-example-incremental-checksum2.p4
${P4C} examples/psa-example-parser-checksum.p4
${P4C} examples/psa-example-parser-error-handling.p4
#${P4C} examples/psa-example-counters.p4
#${P4C} examples/psa-example-digest.p4
#${P4C} examples/psa-example-incremental-checksum.p4
#${P4C} examples/psa-example-incremental-checksum2.p4
#${P4C} examples/psa-example-parser-checksum.p4
#${P4C} examples/psa-example-parser-error-handling.p4
${P4C} examples/psa-example-parser-error-handling2.p4
${P4C} examples/psa-example-recirculate.p4
${P4C} examples/psa-example-register2.p4
#${P4C} examples/psa-example-register2.p4
${P4C} examples/psa-example-resubmit.p4

# check-others:
Expand Down
279 changes: 147 additions & 132 deletions p4-16/psa/examples/psa-example-bridged-metadata.p4
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,6 @@ struct headers {
ipv4_t ipv4;
}

error {
UnknownCloneI2EFormatId
}

parser CommonParser(packet_in buffer,
out headers parsed_hdr,
Expand All @@ -169,32 +166,10 @@ parser IngressParserImpl(
packet_in buffer,
out headers parsed_hdr,
inout metadata meta,
in psa_ingress_parser_input_metadata_t istd,
in resubmit_metadata_t resubmit_meta,
in recirculate_metadata_t recirculate_meta)
in psa_ingress_parser_input_metadata_t istd)
{
CommonParser() p;

state start {
transition select (istd.packet_path) {
PSA_PacketPath_t.RESUBMIT: copy_resubmit_meta;
PSA_PacketPath_t.RECIRCULATE: copy_recirculate_meta;
// No metadata to copy for packets received from port,
// whether a front panel port or the port from the CPU.
default: packet_in_parsing;
}
}
state copy_resubmit_meta {
meta.my_meta4 = resubmit_meta.my_meta4;
transition packet_in_parsing;
}
state copy_recirculate_meta {
meta.my_meta2 = recirculate_meta.my_meta2;
meta.my_meta3 = recirculate_meta.my_meta3;
transition packet_in_parsing;
}

state packet_in_parsing {
p.apply(buffer, parsed_hdr, meta);
transition accept;
}
Expand All @@ -204,57 +179,10 @@ parser EgressParserImpl(
packet_in buffer,
out headers parsed_hdr,
inout metadata meta,
in psa_egress_parser_input_metadata_t istd,
in metadata normal_meta,
in clone_i2e_metadata_t clone_i2e_meta,
in clone_e2e_metadata_t clone_e2e_meta)
in psa_egress_parser_input_metadata_t istd)
{
CommonParser() p;

state start {
transition select (istd.packet_path) {
PSA_PacketPath_t.CLONE_I2E: copy_clone_i2e_meta;
PSA_PacketPath_t.CLONE_E2E: copy_clone_e2e_meta;
default: copy_normal_meta;
}
}
state copy_clone_i2e_meta {
transition select (clone_i2e_meta.format_id) {
0: copy_clone_i2e_meta_format_0;
1: copy_clone_i2e_meta_format_1;
2: copy_clone_i2e_meta_format_2;
default: clone_i2e_unknown_format_id;
}
}
state copy_clone_i2e_meta_format_0 {
meta.my_meta2 = clone_i2e_meta.my_meta2;
meta.my_meta5 = clone_i2e_meta.my_meta5;
transition packet_in_parsing;
}
state copy_clone_i2e_meta_format_1 {
meta.my_meta6 = clone_i2e_meta.my_meta6;
transition packet_in_parsing;
}
state copy_clone_i2e_meta_format_2 {
meta.my_meta5 = clone_i2e_meta.my_meta5;
meta.my_meta1 = clone_i2e_meta.my_meta1;
meta.my_meta3 = clone_i2e_meta.my_meta3;
transition packet_in_parsing;
}
state clone_i2e_unknown_format_id {
verify(false, error.UnknownCloneI2EFormatId);
}
state copy_clone_e2e_meta {
meta.my_meta2 = clone_e2e_meta.my_meta2;
meta.my_meta5 = clone_e2e_meta.my_meta5;
transition packet_in_parsing;
}
state copy_normal_meta {
meta = normal_meta;
transition packet_in_parsing;
}

state packet_in_parsing {
p.apply(buffer, parsed_hdr, meta);
transition accept;
}
Expand Down Expand Up @@ -289,89 +217,176 @@ control CommonDeparserImpl(packet_out packet, inout headers hdr) {

control IngressDeparserImpl(
packet_out packet,
out clone_i2e_metadata_t clone_i2e_meta,
out resubmit_metadata_t resubmit_meta,
out metadata normal_meta,
inout headers hdr,
in metadata meta,
in psa_ingress_output_metadata_t istd)
{
CommonDeparserImpl() common_deparser;
apply {
// Assignments to the out parameter clone_i2e_meta must be
// guarded by this if condition:
if (psa_clone_i2e(istd)) {
clone_i2e_meta.format_id = meta.clone_i2e_meta_format_id;
if (meta.clone_i2e_meta_format_id == 0) {
clone_i2e_meta.my_meta2 = meta.my_meta2;
clone_i2e_meta.my_meta5 = meta.my_meta5;
} else if (meta.clone_i2e_meta_format_id == 1) {
clone_i2e_meta.my_meta6 = meta.my_meta6;
} else if (meta.clone_i2e_meta_format_id == 2) {
clone_i2e_meta.my_meta5 = meta.my_meta5;
clone_i2e_meta.my_meta1 = meta.my_meta1;
clone_i2e_meta.my_meta3 = meta.my_meta3;
}
}

// Assignments to the out parameter resubmit_meta must be
// guarded by this if condition:
if (psa_resubmit(istd)) {
resubmit_meta.my_meta4 = meta.my_meta4;
}

// Assignments to the out parameter normal_meta must be
// guarded by this if condition:
if (psa_normal(istd)) {
normal_meta = meta;
}

common_deparser.apply(packet, hdr);
}
}

control EgressDeparserImpl(
packet_out packet,
out clone_e2e_metadata_t clone_e2e_meta,
out recirculate_metadata_t recirculate_meta,
inout headers hdr,
in metadata meta,
in psa_egress_output_metadata_t istd,
in psa_egress_deparser_input_metadata_t edstd)
in psa_egress_output_metadata_t istd)
{
CommonDeparserImpl() common_deparser;
apply {
// Assignments to the out parameter clone_e2e_meta must be
// guarded by this if condition:
if (psa_clone_e2e(istd)) {
// Metadata to be carried along with CLONE_E2E packets.
clone_e2e_meta.my_meta2 = meta.my_meta2;
clone_e2e_meta.my_meta5 = meta.my_meta5;
}
common_deparser.apply(packet, hdr);
}
}

control NormalPackerImpl(
in headers hdr, // TBD: Should this be here?
in metadata meta,
out metadata normal_meta)
{
apply {
normal_meta = meta;
}
}

control NormalUnpackerImpl(
in metadata normal_meta,
inout metadata meta)
{
apply {
meta = normal_meta;
}
}

// Assignments to the out parameter recirculate_meta must be
// guarded by this if condition:
if (psa_recirculate(istd, edstd)) {
recirculate_meta.my_meta2 = meta.my_meta2;
recirculate_meta.my_meta3 = meta.my_meta3;
control ResubmitPackerImpl(
in headers hdr, // TBD: Should this be here?
in metadata meta,
out resubmit_metadata_t resubmit_meta)
{
apply {
resubmit_meta.my_meta4 = meta.my_meta4;
}
}

control ResubmitUnpackerImpl(
in resubmit_metadata_t resubmit_meta,
inout metadata meta)
{
apply {
meta.my_meta4 = resubmit_meta.my_meta4;
}
}

control RecirculatePackerImpl(
in headers hdr, // TBD: Should this be here?
in metadata meta,
out recirculate_metadata_t recirculate_meta)
{
apply {
recirculate_meta.my_meta2 = meta.my_meta2;
recirculate_meta.my_meta3 = meta.my_meta3;
}
}

control RecirculateUnpackerImpl(
in recirculate_metadata_t recirculate_meta,
inout metadata meta)
{
apply {
meta.my_meta2 = recirculate_meta.my_meta2;
meta.my_meta3 = recirculate_meta.my_meta3;
}
}

control CloneI2EPackerImpl(
in headers hdr, // TBD: Should this be here?
in metadata meta,
out clone_i2e_metadata_t clone_i2e_meta)
{
apply {
clone_i2e_meta.format_id = meta.clone_i2e_meta_format_id;
if (meta.clone_i2e_meta_format_id == 0) {
clone_i2e_meta.my_meta2 = meta.my_meta2;
clone_i2e_meta.my_meta5 = meta.my_meta5;
} else if (meta.clone_i2e_meta_format_id == 1) {
clone_i2e_meta.my_meta6 = meta.my_meta6;
} else if (meta.clone_i2e_meta_format_id == 2) {
clone_i2e_meta.my_meta5 = meta.my_meta5;
clone_i2e_meta.my_meta1 = meta.my_meta1;
clone_i2e_meta.my_meta3 = meta.my_meta3;
}
}
}

// There is no metadata that can be included with normal
// packets going to the a physical port of the device. TBD
// whether there should be a way to do so for packets sent to
// the CPU port.
control CloneI2EUnpackerImpl(
in clone_i2e_metadata_t clone_i2e_meta,
inout metadata meta)
{
apply {
// TBD: An actual switch statement would be nicer here. Or,
// if there is some new proposed syntax to implement a tagged
// union, then whatever that syntax is. I am only using
// if-then-elseif daisy chain here to demonstrate the desired
// logic of execution, in a way that is current valid P4_16
// syntax that p4c can compile without errors.
if (clone_i2e_meta.format_id == 0) {
meta.my_meta2 = clone_i2e_meta.my_meta2;
meta.my_meta5 = clone_i2e_meta.my_meta5;
} else if (clone_i2e_meta.format_id == 1) {
meta.my_meta6 = clone_i2e_meta.my_meta6;
} else if (clone_i2e_meta.format_id == 2) {
meta.my_meta5 = clone_i2e_meta.my_meta5;
meta.my_meta1 = clone_i2e_meta.my_meta1;
meta.my_meta3 = clone_i2e_meta.my_meta3;
}
// TBD: Add another 'else' branch if you want to handle the
// possibility of clone_i2e_meta.format_id not having any of
// the expected values. A tagged union should avoid that
// possibility altogether.
}
}

common_deparser.apply(packet, hdr);
control CloneE2EPackerImpl(
in headers hdr, // TBD: Should this be here?
in metadata meta,
out clone_e2e_metadata_t clone_e2e_meta)
{
apply {
clone_e2e_meta.my_meta2 = meta.my_meta2;
clone_e2e_meta.my_meta5 = meta.my_meta5;
}
}

control CloneE2EUnpackerImpl(
in clone_e2e_metadata_t clone_e2e_meta,
inout metadata meta)
{
apply {
meta.my_meta2 = clone_e2e_meta.my_meta2;
meta.my_meta5 = clone_e2e_meta.my_meta5;
}
}

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

EgressPipeline(EgressParserImpl(),
egress(),
EgressDeparserImpl()) ep;
IngressPipeline(
IngressParserImpl(),
ingress(),
IngressDeparserImpl(),
EmptyNewPacketMetadataInitializer(),
ResubmitUnpackerImpl(),
RecirculateUnpackerImpl(),
NormalPackerImpl(),
ResubmitPackerImpl(),
CloneI2EPackerImpl()) ip;

EgressPipeline(
EgressParserImpl(),
egress(),
EgressDeparserImpl(),
NormalUnpackerImpl(),
CloneI2EUnpackerImpl(),
CloneE2EUnpackerImpl(),
RecirculatePackerImpl(),
CloneE2EPackerImpl()) ep;

PSA_Switch(ip, PacketReplicationEngine(), ep, BufferingQueueingEngine()) main;
Loading