Skip to content

Commit 5d2f81a

Browse files
author
mbudiu-vmw
committed
Added 3 @atomic tests and fix for bug losing @atomic block
1 parent b13c93b commit 5d2f81a

19 files changed

+1865
-1
lines changed

midend/actionSynthesis.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ const IR::Node* DoSynthesizeActions::preorder(IR::BlockStatement* statement) {
170170
// Since we have only one 'changes' per P4Control, this may
171171
// be conservatively creating a new block when it hasn't changed.
172172
// But the result should be correct.
173-
auto result = new IR::BlockStatement(Util::SourceInfo(), IR::Annotations::empty, left);
173+
auto result = new IR::BlockStatement(Util::SourceInfo(), statement->annotations, left);
174174
return result;
175175
}
176176
return statement;
+233
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
#include <core.p4>
2+
#include <v1model.p4>
3+
4+
struct ingress_metadata_t {
5+
bit<32> flow_ipg;
6+
bit<13> flowlet_map_index;
7+
bit<16> flowlet_id;
8+
bit<32> flowlet_lasttime;
9+
bit<14> ecmp_offset;
10+
bit<32> nhop_ipv4;
11+
}
12+
13+
struct intrinsic_metadata_t {
14+
bit<48> ingress_global_timestamp;
15+
bit<32> lf_field_list;
16+
bit<16> mcast_grp;
17+
bit<16> egress_rid;
18+
}
19+
20+
header ethernet_t {
21+
bit<48> dstAddr;
22+
bit<48> srcAddr;
23+
bit<16> etherType;
24+
}
25+
26+
header ipv4_t {
27+
bit<4> version;
28+
bit<4> ihl;
29+
bit<8> diffserv;
30+
bit<16> totalLen;
31+
bit<16> identification;
32+
bit<3> flags;
33+
bit<13> fragOffset;
34+
bit<8> ttl;
35+
bit<8> protocol;
36+
bit<16> hdrChecksum;
37+
bit<32> srcAddr;
38+
bit<32> dstAddr;
39+
}
40+
41+
header tcp_t {
42+
bit<16> srcPort;
43+
bit<16> dstPort;
44+
bit<32> seqNo;
45+
bit<32> ackNo;
46+
bit<4> dataOffset;
47+
bit<3> res;
48+
bit<3> ecn;
49+
bit<6> ctrl;
50+
bit<16> window;
51+
bit<16> checksum;
52+
bit<16> urgentPtr;
53+
}
54+
55+
struct metadata {
56+
@name("ingress_metadata")
57+
ingress_metadata_t ingress_metadata;
58+
@name("intrinsic_metadata")
59+
intrinsic_metadata_t intrinsic_metadata;
60+
}
61+
62+
struct headers {
63+
@name("ethernet")
64+
ethernet_t ethernet;
65+
@name("ipv4")
66+
ipv4_t ipv4;
67+
@name("tcp")
68+
tcp_t tcp;
69+
}
70+
71+
parser ParserImpl(packet_in packet, out headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
72+
@name("parse_ethernet") state parse_ethernet {
73+
packet.extract(hdr.ethernet);
74+
transition select(hdr.ethernet.etherType) {
75+
16w0x800: parse_ipv4;
76+
default: accept;
77+
}
78+
}
79+
@name("parse_ipv4") state parse_ipv4 {
80+
packet.extract(hdr.ipv4);
81+
transition select(hdr.ipv4.protocol) {
82+
8w6: parse_tcp;
83+
default: accept;
84+
}
85+
}
86+
@name("parse_tcp") state parse_tcp {
87+
packet.extract(hdr.tcp);
88+
transition accept;
89+
}
90+
@name("start") state start {
91+
transition parse_ethernet;
92+
}
93+
}
94+
95+
control egress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
96+
@name("rewrite_mac") action rewrite_mac(bit<48> smac) {
97+
hdr.ethernet.srcAddr = smac;
98+
}
99+
@name("_drop") action _drop() {
100+
mark_to_drop();
101+
}
102+
@name("send_frame") table send_frame() {
103+
actions = {
104+
rewrite_mac;
105+
_drop;
106+
NoAction;
107+
}
108+
key = {
109+
standard_metadata.egress_port: exact;
110+
}
111+
size = 256;
112+
default_action = NoAction();
113+
}
114+
apply {
115+
send_frame.apply();
116+
}
117+
}
118+
119+
control ingress(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
120+
@name("flowlet_id") register<bit<16>>(32w8192) flowlet_id;
121+
@name("flowlet_lasttime") register<bit<32>>(32w8192) flowlet_lasttime;
122+
@name("_drop") action _drop() {
123+
mark_to_drop();
124+
}
125+
@name("set_ecmp_select") action set_ecmp_select(bit<8> ecmp_base, bit<8> ecmp_count) {
126+
hash(meta.ingress_metadata.ecmp_offset, HashAlgorithm.crc16, (bit<10>)ecmp_base, { hdr.ipv4.srcAddr, hdr.ipv4.dstAddr, hdr.ipv4.protocol, hdr.tcp.srcPort, hdr.tcp.dstPort, meta.ingress_metadata.flowlet_id }, (bit<20>)ecmp_count);
127+
}
128+
@name("set_nhop") action set_nhop(bit<32> nhop_ipv4, bit<9> port) {
129+
meta.ingress_metadata.nhop_ipv4 = nhop_ipv4;
130+
standard_metadata.egress_spec = port;
131+
hdr.ipv4.ttl = hdr.ipv4.ttl + 8w255;
132+
}
133+
@name("lookup_flowlet_map") action lookup_flowlet_map() {
134+
hash(meta.ingress_metadata.flowlet_map_index, HashAlgorithm.crc16, (bit<13>)0, { hdr.ipv4.srcAddr, hdr.ipv4.dstAddr, hdr.ipv4.protocol, hdr.tcp.srcPort, hdr.tcp.dstPort }, (bit<26>)13);
135+
flowlet_id.read(meta.ingress_metadata.flowlet_id, (bit<32>)meta.ingress_metadata.flowlet_map_index);
136+
meta.ingress_metadata.flow_ipg = meta.intrinsic_metadata.ingress_global_timestamp;
137+
flowlet_lasttime.read(meta.ingress_metadata.flowlet_lasttime, (bit<32>)meta.ingress_metadata.flowlet_map_index);
138+
meta.ingress_metadata.flow_ipg = meta.ingress_metadata.flow_ipg - meta.ingress_metadata.flowlet_lasttime;
139+
flowlet_lasttime.write((bit<32>)meta.ingress_metadata.flowlet_map_index, (bit<32>)meta.intrinsic_metadata.ingress_global_timestamp);
140+
}
141+
@name("set_dmac") action set_dmac(bit<48> dmac) {
142+
hdr.ethernet.dstAddr = dmac;
143+
}
144+
@name("update_flowlet_id") action update_flowlet_id() {
145+
meta.ingress_metadata.flowlet_id = meta.ingress_metadata.flowlet_id + 16w1;
146+
flowlet_id.write((bit<32>)meta.ingress_metadata.flowlet_map_index, (bit<16>)meta.ingress_metadata.flowlet_id);
147+
}
148+
@name("ecmp_group") table ecmp_group() {
149+
actions = {
150+
_drop;
151+
set_ecmp_select;
152+
NoAction;
153+
}
154+
key = {
155+
hdr.ipv4.dstAddr: lpm;
156+
}
157+
size = 1024;
158+
default_action = NoAction();
159+
}
160+
@name("ecmp_nhop") table ecmp_nhop() {
161+
actions = {
162+
_drop;
163+
set_nhop;
164+
NoAction;
165+
}
166+
key = {
167+
meta.ingress_metadata.ecmp_offset: exact;
168+
}
169+
size = 16384;
170+
default_action = NoAction();
171+
}
172+
@name("flowlet") table flowlet() {
173+
actions = {
174+
lookup_flowlet_map;
175+
NoAction;
176+
}
177+
default_action = NoAction();
178+
}
179+
@name("forward") table forward() {
180+
actions = {
181+
set_dmac;
182+
_drop;
183+
NoAction;
184+
}
185+
key = {
186+
meta.ingress_metadata.nhop_ipv4: exact;
187+
}
188+
size = 512;
189+
default_action = NoAction();
190+
}
191+
@name("new_flowlet") table new_flowlet() {
192+
actions = {
193+
update_flowlet_id;
194+
NoAction;
195+
}
196+
default_action = NoAction();
197+
}
198+
apply {
199+
@atomic {
200+
flowlet.apply();
201+
if (meta.ingress_metadata.flow_ipg > 32w50000)
202+
new_flowlet.apply();
203+
}
204+
ecmp_group.apply();
205+
ecmp_nhop.apply();
206+
forward.apply();
207+
}
208+
}
209+
210+
control DeparserImpl(packet_out packet, in headers hdr) {
211+
apply {
212+
packet.emit(hdr.ethernet);
213+
packet.emit(hdr.ipv4);
214+
packet.emit(hdr.tcp);
215+
}
216+
}
217+
218+
control verifyChecksum(in headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
219+
Checksum16() ipv4_checksum;
220+
apply {
221+
if (hdr.ipv4.hdrChecksum == ipv4_checksum.get({ hdr.ipv4.version, hdr.ipv4.ihl, hdr.ipv4.diffserv, hdr.ipv4.totalLen, hdr.ipv4.identification, hdr.ipv4.flags, hdr.ipv4.fragOffset, hdr.ipv4.ttl, hdr.ipv4.protocol, hdr.ipv4.srcAddr, hdr.ipv4.dstAddr }))
222+
mark_to_drop();
223+
}
224+
}
225+
226+
control computeChecksum(inout headers hdr, inout metadata meta, inout standard_metadata_t standard_metadata) {
227+
Checksum16() ipv4_checksum;
228+
apply {
229+
hdr.ipv4.hdrChecksum = ipv4_checksum.get({ hdr.ipv4.version, hdr.ipv4.ihl, hdr.ipv4.diffserv, hdr.ipv4.totalLen, hdr.ipv4.identification, hdr.ipv4.flags, hdr.ipv4.fragOffset, hdr.ipv4.ttl, hdr.ipv4.protocol, hdr.ipv4.srcAddr, hdr.ipv4.dstAddr });
230+
}
231+
}
232+
233+
V1Switch(ParserImpl(), verifyChecksum(), ingress(), egress(), computeChecksum(), DeparserImpl()) main;

testdata/p4_16_samples/rcp.p4

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
Copyright 2016 VMware, Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Example Rate-Control Protocol implementation using @atomic blocks
18+
19+
#include <core.p4>
20+
21+
extern Register<T> {
22+
Register(bit<32> size);
23+
void read(in bit<32> index, out T value);
24+
void write(in bit<32> index, in T value);
25+
}
26+
27+
control proto<P, M>(inout P packet, in M meta);
28+
package top<P, M>(proto<P, M> _p);
29+
30+
///////////////////////
31+
32+
header H {
33+
bit<32> rtt;
34+
}
35+
36+
struct Metadata {
37+
bit<32> pkt_len;
38+
}
39+
40+
const bit<32> MAX_ALLOWABLE_RTT = 2500;
41+
42+
control ingress(inout H pkt_hdr, in Metadata metadata) {
43+
Register<bit<32>>(1) input_traffic_bytes;
44+
Register<bit<32>>(1) sum_rtt_Tr;
45+
Register<bit<32>>(1) num_pkts_with_rtt;
46+
47+
apply {
48+
@atomic{
49+
bit<32> input_traffic_bytes_tmp;
50+
input_traffic_bytes.read(0, input_traffic_bytes_tmp);
51+
input_traffic_bytes_tmp = input_traffic_bytes_tmp + metadata.pkt_len;
52+
input_traffic_bytes.write(input_traffic_bytes_tmp, 0);
53+
if (pkt_hdr.rtt < MAX_ALLOWABLE_RTT) {
54+
bit<32> sum_rtt_Tr_tmp;
55+
sum_rtt_Tr.read(0, sum_rtt_Tr_tmp);
56+
sum_rtt_Tr_tmp = sum_rtt_Tr_tmp + pkt_hdr.rtt;
57+
sum_rtt_Tr.write(sum_rtt_Tr_tmp, 0);
58+
59+
bit<32> num_pkts_with_rtt_tmp;
60+
num_pkts_with_rtt.read(0, num_pkts_with_rtt_tmp);
61+
num_pkts_with_rtt_tmp = num_pkts_with_rtt_tmp + 1;
62+
num_pkts_with_rtt.write(num_pkts_with_rtt_tmp, 0);
63+
}
64+
}
65+
}
66+
}
67+
68+
69+
top(ingress()) main;

testdata/p4_16_samples/rcp1.p4

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
Copyright 2016 VMware, Inc.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// Example Rate-Control Protocol implementation using @atomic blocks
18+
// and custom extern blocks
19+
20+
#include <core.p4>
21+
22+
extern ConditionalAccumulator<T> {
23+
ConditionalAccumulator(bit<32> size);
24+
void read(out T value);
25+
void write(in T value, in bool condition);
26+
}
27+
28+
enum CounterType {
29+
packets,
30+
bytes,
31+
packets_and_bytes
32+
}
33+
34+
extern Counter<T> {
35+
Counter(CounterType type);
36+
void count();
37+
}
38+
39+
control proto<P, M>(inout P packet, in M meta);
40+
package top<P, M>(proto<P, M> _p);
41+
42+
///////////////////////
43+
44+
header H {
45+
bit<32> rtt;
46+
}
47+
48+
struct Metadata {
49+
bit<32> pkt_len;
50+
}
51+
52+
const bit<32> MAX_ALLOWABLE_RTT = 2500;
53+
54+
control ingress(inout H pkt_hdr, in Metadata metadata) {
55+
Counter<bit<32>>(CounterType.packets_and_bytes) input_traffic_bytes;
56+
ConditionalAccumulator<bit<32>>(1) sum_rtt_Tr;
57+
ConditionalAccumulator<bit<32>>(1) num_pkts_with_rtt;
58+
59+
apply {
60+
@atomic {
61+
input_traffic_bytes.count();
62+
sum_rtt_Tr.write(pkt_hdr.rtt, pkt_hdr.rtt < MAX_ALLOWABLE_RTT);
63+
num_pkts_with_rtt.write(1, pkt_hdr.rtt < MAX_ALLOWABLE_RTT);
64+
}
65+
}
66+
}
67+
68+
69+
top(ingress()) main;

0 commit comments

Comments
 (0)