muke56
August 12, 2022, 6:34pm
1
Hello folks … I am hitting what seems like a basic issue with p4c compiler.
I have a switch statement with a fall-through case, like so
100 control aaa {
101 apply {
102 ...
103 meta.xxx = hdr.yyy;
104 switch (table1.apply().action_run) {
105 actionA: // fall-through
106 actionB: {
107 table2.apply();
108 }
109 }
110 table3.apply();
111 }
112 }
the json generated skips table 1, table 2 and directly jumps to table3
{
"name" : "tbl_aaa103",
"source_info" : {
"filename" : "aaa.p4",
"line" : 103,
"column" : 10,
"source_fragment" : "= hdr.yyy; ..."
},
...
"base_default_next" : "table3",
"next_tables" : {
"aaa103" : "table3"
},
whereas if I change the code to this
100 control aaa {
101 apply {
102 ...
103 meta.xxx = hdr.yyy;
104 switch (table1.apply().action_run) {
106 actionB: {
107 table2.apply();
108 }
109 }
110 table3.apply();
111 }
112 }
then the json generated has this
{
"name" : "tbl_aaa103",
"source_info" : {
"filename" : "aaa.p4",
"line" : 103,
"column" : 10,
"source_fragment" : "= hdr.yyy; ..."
},
...
"base_default_next" : "table1",
"next_tables" : {
"aaa103" : "table1"
},
I am invoking p4c from the p4lang/p4c:latest docker image.
Am I doing something wrong ?
I would recommend publishing complete P4 source files for the cases that you believe may be generating incorrect code, e.g. in a public code repository like Github or Gitlab, and provide a link to it here.
Could it perhaps be that your table1 and table2’s actions do not do anything, and the compiler might be eliminating them as an optimization that preserves the same packet processing behavior?
muke56
August 15, 2022, 11:13pm
3
Thanks for getting back Andy. No I don’t see how the compiler could have optimized this out … especially since just the 1 change of removing the fallback action A fixes it.
The source code is from the public Sonic Dash repo. This is the line that causes the issue
#ifdef STATEFUL_P4
ConntrackIn.apply(1);
#endif /* STATEFUL_P4 */
#ifdef PNA_CONNTRACK
ConntrackIn.apply(hdr, meta);
#endif // PNA_CONNTRACK
meta.lkup_dst_ip_addr = meta.dst_ip_addr;
meta.is_lkup_dst_ip_v6 = meta.is_dst_ip_v6;
switch (routing.apply().action_run) {
route_vnet_direct:
route_vnet: {
ca_to_pa.apply();
vnet.apply();
vxlan_encap(hdr,
meta.encap_data.underlay_dmac,
meta.encap_data.underlay_smac,
meta.encap_data.underlay_dip,
From the source code route_vnet is the actionA (fall-through)
and route_vnet_direct is actionB.
By any chance have you found a smaller P4 program that exhibits a similar looks-wrong behavior in its output? If so, it would be great if you could publish that, as it can help more quickly isolate the cause of the problem.
Any chance you could file a bug with the open-source compiler here:
muke56
August 17, 2022, 5:23pm
6
Yes I hit the issue with this simple p4 test program.
muke56
August 17, 2022, 5:29pm
7
Sure thanks. I filed the issue.
opened 05:28PM - 17 Aug 22 UTC
closed 11:32PM - 18 Aug 22 UTC
bug
fixed
I am hitting what seems like a basic issue with a fall-through action in a P4 sw… itch statement.
I have a switch statement with a fall-through case, like so with the fall-through action at line number 105.
```
100 control aaa {
101 apply {
102 ...
103 meta.xxx = hdr.yyy;
104 switch (table1.apply().action_run) {
105 actionA: // fall-through
106 actionB: {
107 table2.apply();
108 }
109 }
110 table3.apply();
111 }
112 }
```
the json generated skips table 1, table 2 and directly jumps to table3
```
{
"name" : "tbl_aaa103",
"source_info" : {
"filename" : "aaa.p4",
"line" : 103,
"column" : 10,
"source_fragment" : "= hdr.yyy; ..."
},
...
"base_default_next" : "table3",
"next_tables" : {
"aaa103" : "table3"
},
```
whereas if I change the code to remove just the fall-through action without any other changes
```
100 control aaa {
101 apply {
102 ...
103 meta.xxx = hdr.yyy;
104 switch (table1.apply().action_run) {
106 actionB: {
107 table2.apply();
108 }
109 }
110 table3.apply();
111 }
112 }
```
now the generated json properly points to table1 as the next stage.
```
{
"name" : "tbl_aaa103",
"source_info" : {
"filename" : "aaa.p4",
"line" : 103,
"column" : 10,
"source_fragment" : "= hdr.yyy; ..."
},
...
"base_default_next" : "table1",
"next_tables" : {
"aaa103" : "table1"
},
```
I am invoking p4c from the p4lang/p4c:latest docker image.