-
Notifications
You must be signed in to change notification settings - Fork 157
/
Copy pathaction-selector.p4
184 lines (167 loc) · 4.4 KB
/
action-selector.p4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include <core.p4>
#include <v1model.p4>
typedef bit<48> EthernetAddress;
typedef bit<32> IPv4Address;
header ethernet_t {
bit<48> dstAddr;
bit<48> srcAddr;
bit<16> etherType;
}
// IPv4 header _with_ options
header ipv4_t {
bit<4> version;
bit<4> ihl;
bit<8> diffserv;
bit<16> totalLen;
bit<16> identification;
bit<3> flags;
bit<13> fragOffset;
bit<8> ttl;
bit<8> protocol;
bit<16> hdrChecksum;
IPv4Address srcAddr;
IPv4Address dstAddr;
varbit<320> options;
}
header tcp_t {
bit<16> srcPort;
bit<16> dstPort;
bit<32> seqNo;
bit<32> ackNo;
bit<4> dataOffset;
bit<3> res;
bit<3> ecn;
bit<6> ctrl;
bit<16> window;
bit<16> checksum;
bit<16> urgentPtr;
}
header IPv4_up_to_ihl_only_h {
bit<4> version;
bit<4> ihl;
}
struct headers {
ethernet_t ethernet;
ipv4_t ipv4;
tcp_t tcp;
}
struct mystruct1_t {
bit<4> a;
bit<4> b;
}
struct metadata {
mystruct1_t mystruct1;
bit<16> hash1;
}
// Declare user-defined errors that may be signaled during parsing
error {
IPv4HeaderTooShort,
IPv4IncorrectVersion,
IPv4ChecksumError
}
parser parserI(packet_in pkt,
out headers hdr,
inout metadata meta,
inout standard_metadata_t stdmeta)
{
state start {
pkt.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType) {
0x0800: parse_ipv4;
default: accept;
}
}
state parse_ipv4 {
// The 4-bit IHL field of the IPv4 base header is the number
// of 32-bit words in the entire IPv4 header. It is an error
// for it to be less than 5. There are only IPv4 options
// present if the value is at least 6. The length of the IPv4
// options alone, without the 20-byte base header, is thus ((4
// * ihl) - 20) bytes, or 8 times that many bits.
pkt.extract(hdr.ipv4,
(bit<32>)
(8 *
(4 * (bit<9>) (pkt.lookahead<IPv4_up_to_ihl_only_h >().ihl)
- 20)));
verify(hdr.ipv4.version == 4w4, error.IPv4IncorrectVersion);
verify(hdr.ipv4.ihl >= 4w5, error.IPv4HeaderTooShort);
transition select (hdr.ipv4.protocol) {
6: parse_tcp;
default: accept;
}
}
state parse_tcp {
pkt.extract(hdr.tcp);
transition accept;
}
}
control cIngress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t stdmeta)
{
action foo1(IPv4Address dstAddr) {
hdr.ipv4.dstAddr = dstAddr;
}
action foo2(IPv4Address srcAddr) {
hdr.ipv4.srcAddr = srcAddr;
}
table t2 {
actions = {
foo1;
foo2;
}
key = {
hdr.tcp.srcPort : exact;
meta.hash1 : selector;
}
size = 16;
@mode("fair") implementation =
action_selector(HashAlgorithm.identity, 16, 4);
}
apply {
//hash(meta.hash1, HashAlgorithm.crc16, (bit<16>) 0,
// { hdr.ipv4.srcAddr,
// hdr.ipv4.dstAddr,
// hdr.ipv4.protocol,
// hdr.tcp.srcPort,
// hdr.tcp.dstPort },
// (bit<32>) 65536);
// The following assignment isn't really a good hash function
// for calculating meta.hash1. I wrote it this way simply to
// make it easy to control and predict what its value will be
// when sending in test packets.
meta.hash1 = hdr.ipv4.dstAddr[15:0];
t2.apply();
}
}
control cEgress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t stdmeta)
{
apply { }
}
control vc(inout headers hdr,
inout metadata meta)
{
apply { }
}
control uc(inout headers hdr,
inout metadata meta)
{
apply { }
}
control DeparserI(packet_out packet,
in headers hdr)
{
apply {
packet.emit(hdr.ethernet);
packet.emit(hdr.ipv4);
packet.emit(hdr.tcp);
}
}
V1Switch<headers, metadata>(parserI(),
vc(),
cIngress(),
cEgress(),
uc(),
DeparserI()) main;