You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The spec specifies that calling setInvalid() on any header inside a header union should invalidate all headers in that union:
u.hi.setInvalid(): if the valid bit for any member header of u is true then sets it to false, which implies that it is unspecified what value reading any member header of u will return.
However, Testgen doesn't expect all the headers to be invalidated, only the one on which setInvalid() is called.
Example source code:
#include <v1model.p4>
header opt_t {
bit<8> opt;
}
header ethernet_t {
bit<48> dst_addr;
bit<48> src_addr;
bit<16> eth_type;
}
header H {
bit<8> a;
bit<8> a1;
bit<8> b;
}
header_union U {
ethernet_t e;
H h;
}
struct Headers {
opt_t opt;
U u;
}
struct Meta {}
parser p(packet_in pkt, out Headers h, inout Meta meta, inout standard_metadata_t stdmeta) {
state start {
pkt.extract(h.opt);
transition select(h.opt.opt) {
0x0: parse_e;
0x1: parse_h;
default: accept;
}
}
state parse_e {
pkt.extract(h.u.e);
transition accept;
}
state parse_h {
pkt.extract(h.u.h);
transition accept;
}
}
control vrfy(inout Headers h, inout Meta meta) {
apply { }
}
control ingress(inout Headers h, inout Meta m, inout standard_metadata_t s) {
apply {
h.u.e.setInvalid();
}
}
control egress(inout Headers h, inout Meta m, inout standard_metadata_t s) {
apply { }
}
control update(inout Headers h, inout Meta m) {
apply { }
}
control deparser(packet_out pkt, in Headers h) {
apply {
pkt.emit(h);
}
}
V1Switch(p(), vrfy(), ingress(), egress(), update(), deparser()) main;
Yeah... we have always punted this specification detail. Support for header unions and varbits is brittle. Let me see whether there is an easy way to implement it
Actually, the reason this might be modeled incorrectly is that BMv2 also has the same behavior. The test, as written, passes. If I add code to set other headers invalid I am seeing mismatches.
@antoninbas Does BMv2 model this behavior? It looks like remove_header doesn't account for unions either?
@antoninbas The best way to handle this as of now would be for the backend to generate a remove_header call for every header that constitutes the union.
Agreed with Antonin's assessment. The bug is in the combination of the behavior of the p4c BMv2 back end, combined with BMv2. Modifications to either (or both) of them could correct the issue.
The spec specifies that calling
setInvalid()
on any header inside a header union should invalidate all headers in that union:However, Testgen doesn't expect all the headers to be invalidated, only the one on which
setInvalid()
is called.Example source code:
Command:
Output (main_3.stf):
This emit should be invalid:
The text was updated successfully, but these errors were encountered: