blob: 7d551dd498b8a931bbc5a69c7912e37aa78f69bd [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 action_selector(HashAlgorithm.crc16, 32w64, 32w16) ecmp_selector;
Yi Tseng3a5731e2018-01-22 11:38:58 -080028 direct_counter(CounterType.packets_and_bytes) simple_counter;
29 direct_counter(CounterType.packets_and_bytes) hashed_counter;
Yi Tsengbe342052017-11-03 10:21:23 -070030
Yi Tsengbe342052017-11-03 10:21:23 -070031 action output(port_num_t port_num) {
32 standard_metadata.egress_spec = port_num;
Yi Tsengbe342052017-11-03 10:21:23 -070033 }
34
35 action set_vlan_output(vlan_id_t new_vlan_id, port_num_t port_num){
36 hdr.vlan_tag.vlan_id = new_vlan_id;
37
38 // don't remove the vlan from egress since we set the vlan to it.
39 fabric_metadata.pop_vlan_at_egress = false;
40 output(port_num);
41 }
42
43 action rewrite_smac(mac_addr_t smac) {
44 hdr.ethernet.src_addr = smac;
45 }
46
47 action rewrite_dmac(mac_addr_t dmac) {
48 hdr.ethernet.dst_addr = dmac;
49 }
50
51 action l3_routing(port_num_t port_num, mac_addr_t smac, mac_addr_t dmac) {
52 rewrite_smac(smac);
53 rewrite_dmac(dmac);
54 output(port_num);
55 }
56
Yi Tseng1b154bd2017-11-20 17:48:19 -080057 action push_mpls (mpls_label_t label, bit<3> tc) {
Yi Tseng1d842672017-11-28 16:06:52 -080058 // Suppose that the maximum number of label is one.
Yi Tseng1b154bd2017-11-20 17:48:19 -080059 hdr.mpls.setValid();
Yi Tsengbd46d052018-01-22 17:18:16 -080060 hdr.vlan_tag.ether_type = ETHERTYPE_MPLS;
Yi Tseng1b154bd2017-11-20 17:48:19 -080061 hdr.mpls.label = label;
62 hdr.mpls.tc = tc;
Yi Tseng1d842672017-11-28 16:06:52 -080063 hdr.mpls.bos = 1w1; // BOS = TRUE
Yi Tseng1b154bd2017-11-20 17:48:19 -080064 hdr.mpls.ttl = DEFAULT_MPLS_TTL;
65 }
66
67 action mpls_routing_v4 (port_num_t port_num, mac_addr_t smac, mac_addr_t dmac,
68 mpls_label_t label) {
69 l3_routing(port_num, smac, dmac);
Yi Tseng1d842672017-11-28 16:06:52 -080070
71 // TODO: set tc according to diffserv from ipv4
72 push_mpls(label, 3w0);
Yi Tseng1b154bd2017-11-20 17:48:19 -080073 }
74
75 action mpls_routing_v6 (port_num_t port_num, mac_addr_t smac, mac_addr_t dmac,
76 mpls_label_t label) {
77 l3_routing(port_num, smac, dmac);
Yi Tseng1d842672017-11-28 16:06:52 -080078
79 // TODO: set tc according to traffic_class from ipv4
80 push_mpls(label, 3w0);
Yi Tseng1b154bd2017-11-20 17:48:19 -080081 }
82
Yi Tsengbe342052017-11-03 10:21:23 -070083 table simple {
84 key = {
85 fabric_metadata.next_id: exact;
86 }
87
88 actions = {
89 output;
90 set_vlan_output;
91 l3_routing;
Yi Tseng3a5731e2018-01-22 11:38:58 -080092 mpls_routing_v4;
Yi Tsengbe342052017-11-03 10:21:23 -070093 }
Yi Tseng3a5731e2018-01-22 11:38:58 -080094 counters = simple_counter;
Yi Tsengbe342052017-11-03 10:21:23 -070095 }
96
97 table hashed {
98 key = {
99 fabric_metadata.next_id: exact;
Yi Tseng3d3956d2018-01-31 17:28:05 -0800100 hdr.ipv4.dst_addr: selector;
101 hdr.ipv4.src_addr: selector;
Yi Tseng1d842672017-11-28 16:06:52 -0800102 fabric_metadata.ip_proto: selector;
Yi Tsengbe342052017-11-03 10:21:23 -0700103 fabric_metadata.l4_src_port: selector;
104 fabric_metadata.l4_dst_port: selector;
105 }
106
107 actions = {
108 l3_routing;
Yi Tseng1b154bd2017-11-20 17:48:19 -0800109 mpls_routing_v4;
110 mpls_routing_v6;
Yi Tsengbe342052017-11-03 10:21:23 -0700111 }
112
113 implementation = ecmp_selector;
Yi Tseng3a5731e2018-01-22 11:38:58 -0800114 counters = hashed_counter;
Yi Tsengbe342052017-11-03 10:21:23 -0700115 }
116
Carmelo Casconea1061402018-02-03 17:39:59 -0800117#ifdef WITH_MULTICAST
Yi Tsengbe342052017-11-03 10:21:23 -0700118 /*
119 * Work in progress
120 */
Carmelo Casconea1061402018-02-03 17:39:59 -0800121 action set_mcast_group(group_id_t gid, mac_addr_t smac) {
122 standard_metadata.mcast_grp = gid;
123 rewrite_smac(smac);
124 }
125
126 direct_counter(CounterType.packets_and_bytes) multicast_counter;
127
128 table multicast {
Yi Tsengbe342052017-11-03 10:21:23 -0700129 key = {
130 fabric_metadata.next_id: exact;
131 }
132 actions = {
133 set_mcast_group;
134 }
Carmelo Casconea1061402018-02-03 17:39:59 -0800135 counters = multicast_counter;
Yi Tsengbe342052017-11-03 10:21:23 -0700136 }
Carmelo Casconea1061402018-02-03 17:39:59 -0800137#endif // WITH_MULTICAST
Yi Tsengbe342052017-11-03 10:21:23 -0700138
139 apply {
Yi Tseng1d842672017-11-28 16:06:52 -0800140 if (simple.apply().hit) {
141 if (!hdr.mpls.isValid()) {
142 if(hdr.ipv4.isValid()) {
143 hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
144 }
Carmelo Casconeed88f2b2018-01-26 17:36:34 -0800145#ifdef WITH_IPV6
Yi Tseng1d842672017-11-28 16:06:52 -0800146 else if (hdr.ipv6.isValid()) {
147 hdr.ipv6.hop_limit = hdr.ipv6.hop_limit - 1;
148 }
Carmelo Casconeed88f2b2018-01-26 17:36:34 -0800149#endif // WITH_IPV6
Yi Tseng1d842672017-11-28 16:06:52 -0800150 }
151 }
Yi Tsengf55eaa82017-11-29 15:51:28 -0800152 hashed.apply();
Carmelo Casconea1061402018-02-03 17:39:59 -0800153#ifdef WITH_MULTICAST
154 multicast.apply();
155#endif // WITH_MULTICAST
Yi Tsengbe342052017-11-03 10:21:23 -0700156 }
157}
158
159control EgressNextControl (
160 inout parsed_headers_t hdr,
161 inout fabric_metadata_t fabric_metadata,
162 inout standard_metadata_t standard_metadata){
163
164 apply {
165 // pop internal vlan if the meta is set
166 if (fabric_metadata.pop_vlan_at_egress) {
Yi Tsengbd46d052018-01-22 17:18:16 -0800167 hdr.ethernet.ether_type = hdr.vlan_tag.ether_type;
Yi Tsengbe342052017-11-03 10:21:23 -0700168 hdr.vlan_tag.setInvalid();
169 }
170 }
171}