blob: 69e622bf4753bb34b0f699033e2c254920bd5523 [file] [log] [blame]
Yi Tsengbe342052017-11-03 10:21:23 -07001/*
2 * Copyright 2017-present Open Networking Foundation
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#include <core.p4>
18#include <v1model.p4>
19
20#include "../header.p4"
21#include "../action.p4"
22
23control Next (
24 inout parsed_headers_t hdr,
25 inout fabric_metadata_t fabric_metadata,
26 inout standard_metadata_t standard_metadata) {
Yi Tsengbe342052017-11-03 10:21:23 -070027
Yi Tseng47eac892018-07-11 02:17:04 +080028 /*
29 * General actions.
30 */
Yi Tseng20f9e7b2018-05-24 23:27:39 +080031 action pop_vlan() {
32 hdr.ethernet.ether_type = hdr.vlan_tag.ether_type;
33 hdr.vlan_tag.setInvalid();
34 }
35
Yi Tsengbe342052017-11-03 10:21:23 -070036 action rewrite_smac(mac_addr_t smac) {
37 hdr.ethernet.src_addr = smac;
38 }
39
40 action rewrite_dmac(mac_addr_t dmac) {
41 hdr.ethernet.dst_addr = dmac;
42 }
43
Yi Tseng1b154bd2017-11-20 17:48:19 -080044 action push_mpls (mpls_label_t label, bit<3> tc) {
Yi Tseng1d842672017-11-28 16:06:52 -080045 // Suppose that the maximum number of label is one.
Yi Tseng1b154bd2017-11-20 17:48:19 -080046 hdr.mpls.setValid();
Yi Tsengbd46d052018-01-22 17:18:16 -080047 hdr.vlan_tag.ether_type = ETHERTYPE_MPLS;
Yi Tseng1b154bd2017-11-20 17:48:19 -080048 hdr.mpls.label = label;
49 hdr.mpls.tc = tc;
Yi Tseng1d842672017-11-28 16:06:52 -080050 hdr.mpls.bos = 1w1; // BOS = TRUE
Yi Tseng1b154bd2017-11-20 17:48:19 -080051 hdr.mpls.ttl = DEFAULT_MPLS_TTL;
52 }
53
Yi Tseng47eac892018-07-11 02:17:04 +080054 /*
55 * VLAN Metadata Table.
56 * Modify VLAN Id according to metadata from NextObjective(next id).
57 */
58 direct_counter(CounterType.packets_and_bytes) vlan_meta_counter;
Yi Tseng1d842672017-11-28 16:06:52 -080059
Yi Tseng47eac892018-07-11 02:17:04 +080060 action set_vlan(vlan_id_t new_vlan_id) {
61 hdr.vlan_tag.vlan_id = new_vlan_id;
62 vlan_meta_counter.count();
Yi Tseng1b154bd2017-11-20 17:48:19 -080063 }
64
Yi Tseng20f9e7b2018-05-24 23:27:39 +080065 table vlan_meta {
66 key = {
67 fabric_metadata.next_id: exact;
68 }
69
70 actions = {
71 set_vlan;
Yi Tseng47eac892018-07-11 02:17:04 +080072 @defaultonly nop;
Yi Tseng20f9e7b2018-05-24 23:27:39 +080073 }
74 default_action = nop;
75 counters = vlan_meta_counter;
76 }
77
Yi Tseng47eac892018-07-11 02:17:04 +080078 /*
79 * Simple Table.
80 * Do a single egress action based on next id.
81 */
82 direct_counter(CounterType.packets_and_bytes) simple_counter;
83
84 action output_simple(port_num_t port_num) {
85 standard_metadata.egress_spec = port_num;
86 simple_counter.count();
87 }
88
89 action set_vlan_output(vlan_id_t new_vlan_id, port_num_t port_num){
90 hdr.vlan_tag.vlan_id = new_vlan_id;
91 output_simple(port_num);
92 }
93
94 action l3_routing_simple(port_num_t port_num, mac_addr_t smac, mac_addr_t dmac) {
95 rewrite_smac(smac);
96 rewrite_dmac(dmac);
97 output_simple(port_num);
98 }
99
100 action mpls_routing_v4_simple(port_num_t port_num, mac_addr_t smac, mac_addr_t dmac,
101 mpls_label_t label) {
102 l3_routing_simple(port_num, smac, dmac);
103
104 // TODO: set tc according to diffserv from ipv4
105 push_mpls(label, 3w0);
106 }
107
108 action mpls_routing_v6_simple (port_num_t port_num, mac_addr_t smac, mac_addr_t dmac,
109 mpls_label_t label) {
110 l3_routing_simple(port_num, smac, dmac);
111
112 // TODO: set tc according to traffic_class from ipv4
113 push_mpls(label, 3w0);
114 }
115
116 action l3_routing_vlan(port_num_t port_num, mac_addr_t smac, mac_addr_t dmac, vlan_id_t new_vlan_id) {
117 rewrite_smac(smac);
118 rewrite_dmac(dmac);
119 set_vlan_output(new_vlan_id, port_num);
120 }
121
Yi Tsengbe342052017-11-03 10:21:23 -0700122 table simple {
123 key = {
124 fabric_metadata.next_id: exact;
125 }
126
127 actions = {
Yi Tseng47eac892018-07-11 02:17:04 +0800128 output_simple;
Yi Tsengbe342052017-11-03 10:21:23 -0700129 set_vlan_output;
Yi Tseng47eac892018-07-11 02:17:04 +0800130 l3_routing_simple;
131 mpls_routing_v4_simple;
132 mpls_routing_v6_simple;
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800133 l3_routing_vlan;
Yi Tsengbe342052017-11-03 10:21:23 -0700134 }
Yi Tseng3a5731e2018-01-22 11:38:58 -0800135 counters = simple_counter;
Yi Tsengbe342052017-11-03 10:21:23 -0700136 }
137
Yi Tseng47eac892018-07-11 02:17:04 +0800138 /*
139 * Hashed table.
140 * Execute an action profile group based on next id.
141 * One action profile group may contains multple egress decision.
142 * The execution picks one action profile group memebr by using 5-tuple
143 * hashing.
144 */
145 action_selector(HashAlgorithm.crc16, 32w64, 32w16) ecmp_selector;
146 direct_counter(CounterType.packets_and_bytes) hashed_counter;
147
148 action output_hashed(port_num_t port_num) {
149 standard_metadata.egress_spec = port_num;
150 hashed_counter.count();
151 }
152
153 action l3_routing_hashed(port_num_t port_num, mac_addr_t smac, mac_addr_t dmac) {
154 rewrite_smac(smac);
155 rewrite_dmac(dmac);
156 output_hashed(port_num);
157 }
158
159 action mpls_routing_v4_hashed (port_num_t port_num, mac_addr_t smac, mac_addr_t dmac,
160 mpls_label_t label) {
161 l3_routing_hashed(port_num, smac, dmac);
162
163 // TODO: set tc according to diffserv from ipv4
164 push_mpls(label, 3w0);
165 }
166
167 action mpls_routing_v6_hashed (port_num_t port_num, mac_addr_t smac, mac_addr_t dmac,
168 mpls_label_t label) {
169 l3_routing_hashed(port_num, smac, dmac);
170
171 // TODO: set tc according to traffic_class from ipv4
172 push_mpls(label, 3w0);
173 }
174
Yi Tsengbe342052017-11-03 10:21:23 -0700175 table hashed {
176 key = {
177 fabric_metadata.next_id: exact;
Yi Tseng3d3956d2018-01-31 17:28:05 -0800178 hdr.ipv4.dst_addr: selector;
179 hdr.ipv4.src_addr: selector;
Yi Tseng1d842672017-11-28 16:06:52 -0800180 fabric_metadata.ip_proto: selector;
Yi Tsengbe342052017-11-03 10:21:23 -0700181 fabric_metadata.l4_src_port: selector;
182 fabric_metadata.l4_dst_port: selector;
183 }
184
185 actions = {
Yi Tseng47eac892018-07-11 02:17:04 +0800186 l3_routing_hashed;
187 mpls_routing_v4_hashed;
188 mpls_routing_v6_hashed;
Yi Tsengbe342052017-11-03 10:21:23 -0700189 }
190
191 implementation = ecmp_selector;
Yi Tseng3a5731e2018-01-22 11:38:58 -0800192 counters = hashed_counter;
Yi Tsengbe342052017-11-03 10:21:23 -0700193 }
194
195 /*
Yi Tseng47eac892018-07-11 02:17:04 +0800196 * Multicast Table.
197 * Setup multicast group id for packet replication engine (PRE).
Yi Tsengbe342052017-11-03 10:21:23 -0700198 */
Yi Tseng47eac892018-07-11 02:17:04 +0800199 direct_counter(CounterType.packets_and_bytes) multicast_counter;
200
Esin Karaman971fb7f2017-12-28 13:44:52 +0000201 action set_mcast_group(group_id_t gid) {
Carmelo Casconea1061402018-02-03 17:39:59 -0800202 standard_metadata.mcast_grp = gid;
Carmelo Cascone1e8843f2018-07-19 19:01:12 +0200203 fabric_metadata.is_multicast = _TRUE;
Yi Tseng47eac892018-07-11 02:17:04 +0800204 multicast_counter.count();
Carmelo Casconea1061402018-02-03 17:39:59 -0800205 }
206
Carmelo Casconea1061402018-02-03 17:39:59 -0800207 table multicast {
Yi Tsengbe342052017-11-03 10:21:23 -0700208 key = {
209 fabric_metadata.next_id: exact;
210 }
211 actions = {
212 set_mcast_group;
213 }
Carmelo Casconea1061402018-02-03 17:39:59 -0800214 counters = multicast_counter;
Yi Tsengbe342052017-11-03 10:21:23 -0700215 }
216
217 apply {
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800218 vlan_meta.apply();
Carmelo Casconea5400af2018-07-17 22:11:54 +0200219 if (!simple.apply().hit) {
220 if (!hashed.apply().hit) {
221 if (!multicast.apply().hit) {
222 // Next ID doesn't match any table.
223 return;
Yi Tseng1d842672017-11-28 16:06:52 -0800224 }
Yi Tseng1d842672017-11-28 16:06:52 -0800225 }
226 }
Carmelo Casconea5400af2018-07-17 22:11:54 +0200227 // Decrement TTL
228 if (!hdr.mpls.isValid()) {
229 if(hdr.ipv4.isValid()) {
230 hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
231 }
232#ifdef WITH_IPV6
233 else if (hdr.ipv6.isValid()) {
234 hdr.ipv6.hop_limit = hdr.ipv6.hop_limit - 1;
235 }
236#endif // WITH_IPV6
237 }
Yi Tsengbe342052017-11-03 10:21:23 -0700238 }
239}
240
241control EgressNextControl (
242 inout parsed_headers_t hdr,
243 inout fabric_metadata_t fabric_metadata,
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800244 inout standard_metadata_t standard_metadata) {
245
Yi Tseng47eac892018-07-11 02:17:04 +0800246 /*
247 * Egress VLAN Table.
248 * Pops VLAN tag according to interface(Port and VLAN) configuration.
249 */
250 direct_counter(CounterType.packets_and_bytes) egress_vlan_counter;
251
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800252 action pop_vlan() {
253 hdr.ethernet.ether_type = hdr.vlan_tag.ether_type;
254 hdr.vlan_tag.setInvalid();
Yi Tseng47eac892018-07-11 02:17:04 +0800255 egress_vlan_counter.count();
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800256 }
257
258 table egress_vlan {
259 key = {
260 hdr.vlan_tag.vlan_id: exact;
261 standard_metadata.egress_port: exact;
262 }
263 actions = {
264 pop_vlan;
Yi Tseng47eac892018-07-11 02:17:04 +0800265 @defaultonly nop;
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800266 }
267 default_action = nop;
Yi Tseng47eac892018-07-11 02:17:04 +0800268 counters = egress_vlan_counter;
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800269 }
Yi Tsengbe342052017-11-03 10:21:23 -0700270
271 apply {
Carmelo Cascone1e8843f2018-07-19 19:01:12 +0200272 if (fabric_metadata.is_multicast == _TRUE
Carmelo Casconea5400af2018-07-17 22:11:54 +0200273 && standard_metadata.ingress_port == standard_metadata.egress_port) {
274 drop_now();
275 }
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800276 egress_vlan.apply();
Yi Tsengbe342052017-11-03 10:21:23 -0700277 }
278}