-
Notifications
You must be signed in to change notification settings - Fork 80
How to do resubmit in PSA?
A P4 program may decide to undo a parsing decision and re-parse the incoming packet with a different parser. This can be achieved with the resubmit
operation. The original packet is resubmitted to the ingress parser, with a few extra bytes of metadata added to beginning of the packet. The metadata is typically referred to as the resubmit metadata
. The resubmit metadata is often used as a communication channel between the two separate passes on the packet. The P4 program can use the resubmit metadata to communicate the parsing decision from the first pass on the packet to the second re-parse pass on the packet. During the parsing of resubmitted packet, the ingress parser needs to extract the resubmit metadata first, then extracts and re-parses the original packet based on the content in the resubmit metadata.
The PSA architecture exposes a simpler interface to resubmit operation. The resubmit metadata is exposed to the ingress parser as an in
metadata. It is up to the architecture, not the user, to provide the implementation for extracting the resubmit metadata. On the other hand, it is up to the user to provide the layout of the resubmit metadata. User can specify the layout of the resubmit metadata by defining the type of the resubmit metadata parameter to the ingress parser. Typically, the resubmit metadata type is specified as a struct
containing a header
type as a member field. For instances,
header resubmit_layout_0 {
bit<8> data;
}
struct resubmit_metadata_t {
resubmit_layout_0 rl0;
}
If the user needs to specify more than one resubmit metadata layout, the user may use a header union type with a tag kind
to identify the header in the header union.
header resubmit_layout_0 {
bit<8> data;
}
header resubmit_layout_1 {
bit<8> data_0;
bit<8> data_1;
}
header_union resubmit_layouts {
resubmit_layout_0 rl0;
resubmit_layout_1 rl1;
}
struct resubmit_metadata_t {
bit<8> kind;
resubmit_layouts rls;
}
The PSA ingress parser uses the packet_path
standard_metadata to identify the resubmit packet. The packet_path
metadata is typically read in the first state of the ingress parser to branch into subsequent parse states for different types of packets (resubmit, clone, normal). The following example shows how to support both resubmit and normal packet in the ingress parser.
state start {
transition select(istd.packet_path) {
PSA_PacketPath_t.RESUBMIT: parse_resubmit_packet;
PSA_PacketPath_t.NORMAL: parse_normal_packet;
}
}
The user-defined parse_resubmit_packet
state parses the resubmit metadata. If there is only one possible layout for the resubmit metadata, i.e., the resubmit metadata is defined as a struct
with a header
member, then the parsing can be simply a copy from in resubmit_metadata
parameter to user-defined metadata. A more complex case is when there are multiple possible layouts for the resubmit metadata. For instance, the user may define the type of the resubmit metadata as a struct
with a header_union
member. In this case, the parse_resubmit_packet
state must select on a user-provided tag to parse the header union.
state parse_resubmit_packet {
transition select(resub_meta.selector) {
8w0: parse_resubmit_0;
8w1: parse_resubmit_1;
}
}
state parse_resubmit_0 {
user_meta.h_a = resubmit_meta.u.a;
transition parse_packet_as_type_a;
}
state parse_resubmit_1 {
user_meta.h_b = resubmit_meta.u.b;
transition parse_packet_as_type_b;
}
During the ingress processing, the P4 program can enable the resubmit operation on a packet by setting the ostd.resubmit
flag to true. The resubmit operation can be disabled by setting the same flag to false. If there are multiple assignments to the same ostd.resubmit
flag, the last assignment takes precedence.
On the ingress deparser side, The PSA architecture provides a helper extern function psa_resubmit()
to predicate the assignment to the out resub_meta
parameter. If the function returns true, then the P4 program will enable resubmit operation on the current packet. Otherwise, the resubmit operation will be disabled. If the resubmit metadata struct has a header
as member, the P4 program can assign value from any metadata at the end ingress processing to the header. If the resubmit metadata struct has a kind
tag field and a header union
member, the P4 program needs to assign a value to the tag field, as well as value to one of the headers inside the header union.
// if only header in resubmit metadata
if (psa_resubmit(istd)) {
resubmit_meta.a = meta.h.a;
}
// if tag and header union in resubmit metadata
if (psa_resubmit(istd, 0)) {
resubmit_meta.kind = 8w0;
resubmit_meta.a = meta.h.a;
} else if (psa_resubmit(istd, 1)) {
resubmit_meta.kind = 8w1;
resubmit_meta.b = meta.h.b;
}