blob: 2920a15db14f5cf1905f1b959470a565c6b9aa67 [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#ifndef __PARSER__
18#define __PARSER__
19
20#include "define.p4"
21
22parser FabricParser (
23packet_in packet,
24out parsed_headers_t hdr,
25inout fabric_metadata_t fabric_metadata,
26inout standard_metadata_t standard_metadata) {
Yi Tseng1d842672017-11-28 16:06:52 -080027
Carmelo Cascone04888222018-03-19 22:18:12 -070028 bit<6> last_ipv4_dscp = 0;
29
Yi Tsengbe342052017-11-03 10:21:23 -070030 state start {
31 transition select(standard_metadata.ingress_port) {
32 CPU_PORT: parse_packet_out;
33 default: parse_ethernet;
34 }
35 }
36
37 state parse_packet_out {
38 packet.extract(hdr.packet_out);
39 transition parse_ethernet;
40 }
41
42 state parse_ethernet {
43 packet.extract(hdr.ethernet);
Yi Tseng1d842672017-11-28 16:06:52 -080044 fabric_metadata.original_ether_type = hdr.ethernet.ether_type;
Yi Tsengbe342052017-11-03 10:21:23 -070045 transition select(hdr.ethernet.ether_type){
Yi Tsengbe342052017-11-03 10:21:23 -070046 ETHERTYPE_VLAN: parse_vlan_tag;
47 ETHERTYPE_MPLS: parse_mpls;
48 ETHERTYPE_ARP: parse_arp;
49 ETHERTYPE_IPV4: parse_ipv4;
Carmelo Casconeed88f2b2018-01-26 17:36:34 -080050#ifdef WITH_IPV6
Yi Tsengbe342052017-11-03 10:21:23 -070051 ETHERTYPE_IPV6: parse_ipv6;
Carmelo Casconeed88f2b2018-01-26 17:36:34 -080052#endif // WITH_IPV6
Yi Tsengbe342052017-11-03 10:21:23 -070053 default: accept;
54 }
55 }
56
57 state parse_vlan_tag {
58 packet.extract(hdr.vlan_tag);
59 transition select(hdr.vlan_tag.ether_type){
Yi Tsengbe342052017-11-03 10:21:23 -070060 ETHERTYPE_ARP: parse_arp;
61 ETHERTYPE_IPV4: parse_ipv4;
Carmelo Casconeed88f2b2018-01-26 17:36:34 -080062#ifdef WITH_IPV6
Yi Tsengbe342052017-11-03 10:21:23 -070063 ETHERTYPE_IPV6: parse_ipv6;
Carmelo Casconeed88f2b2018-01-26 17:36:34 -080064#endif // WITH_IPV6
Yi Tsengbd46d052018-01-22 17:18:16 -080065 ETHERTYPE_MPLS: parse_mpls;
Yi Tsengbe342052017-11-03 10:21:23 -070066 default: accept;
67 }
68 }
69
70 state parse_mpls {
71 packet.extract(hdr.mpls);
Yi Tsengc6844f52017-12-19 11:58:25 -080072 // There is only one MPLS label for this fabric.
73 // Assume header after MPLS header is IP/IPv6
74 // Lookup first 4 bits for version
Yi Tseng3d3956d2018-01-31 17:28:05 -080075 transition select(packet.lookahead<bit<IP_VER_LENGTH>>()) {
Yi Tsengbe342052017-11-03 10:21:23 -070076 //The packet should be either IPv4 or IPv6.
77 IP_VERSION_4: parse_ipv4;
Carmelo Casconeed88f2b2018-01-26 17:36:34 -080078#ifdef WITH_IPV6
Yi Tsengbe342052017-11-03 10:21:23 -070079 IP_VERSION_6: parse_ipv6;
Carmelo Casconeed88f2b2018-01-26 17:36:34 -080080#endif // WITH_IPV6
Yi Tsengbe342052017-11-03 10:21:23 -070081 default: parse_ethernet;
82 }
83 }
84
85 state parse_ipv4 {
86 packet.extract(hdr.ipv4);
Carmelo Cascone04888222018-03-19 22:18:12 -070087 last_ipv4_dscp = hdr.ipv4.dscp;
Yi Tsengbe342052017-11-03 10:21:23 -070088 fabric_metadata.ip_proto = hdr.ipv4.protocol;
89 //Need header verification?
90 transition select(hdr.ipv4.protocol) {
91 PROTO_TCP: parse_tcp;
92 PROTO_UDP: parse_udp;
93 PROTO_ICMP: parse_icmp;
94 default: accept;
95 }
96 }
97
Carmelo Casconeed88f2b2018-01-26 17:36:34 -080098#ifdef WITH_IPV6
Yi Tsengbe342052017-11-03 10:21:23 -070099 state parse_ipv6 {
100 packet.extract(hdr.ipv6);
101 fabric_metadata.ip_proto = hdr.ipv6.next_hdr;
102 transition select(hdr.ipv6.next_hdr) {
103 PROTO_TCP: parse_tcp;
104 PROTO_UDP: parse_udp;
105 PROTO_ICMPV6: parse_icmp;
106 default: accept;
107 }
108 }
Carmelo Casconeed88f2b2018-01-26 17:36:34 -0800109#endif // WITH_IPV6
Yi Tsengbe342052017-11-03 10:21:23 -0700110
111 state parse_arp {
112 packet.extract(hdr.arp);
113 transition accept;
114 }
115
116 state parse_tcp {
117 packet.extract(hdr.tcp);
118 fabric_metadata.l4_src_port = hdr.tcp.src_port;
119 fabric_metadata.l4_dst_port = hdr.tcp.dst_port;
120 transition accept;
121 }
122
123 state parse_udp {
124 packet.extract(hdr.udp);
125 fabric_metadata.l4_src_port = hdr.udp.src_port;
126 fabric_metadata.l4_dst_port = hdr.udp.dst_port;
Carmelo Casconeb81f4be2018-01-16 23:24:01 -0800127 transition select(hdr.udp.dst_port) {
Carmelo Cascone04888222018-03-19 22:18:12 -0700128#ifdef WITH_SPGW
Carmelo Casconeb81f4be2018-01-16 23:24:01 -0800129 UDP_PORT_GTPU: parse_gtpu;
Carmelo Casconeb81f4be2018-01-16 23:24:01 -0800130#endif // WITH_SPGW
Carmelo Cascone04888222018-03-19 22:18:12 -0700131#ifdef WITH_INT_TRANSIT
132 default: parse_int;
133#else
134 default: accept;
135#endif // WITH_INT_TRANSIT
136 }
Yi Tsengbe342052017-11-03 10:21:23 -0700137 }
138
139 state parse_icmp {
140 packet.extract(hdr.icmp);
141 transition accept;
142 }
Carmelo Casconeb81f4be2018-01-16 23:24:01 -0800143
144#ifdef WITH_SPGW
145 state parse_gtpu {
146 packet.extract(hdr.gtpu);
147 transition parse_ipv4_inner;
148 }
149
150 state parse_ipv4_inner {
Carmelo Casconeb757dbc2018-01-25 17:53:17 -0800151 packet.extract(hdr.gtpu_ipv4);
Carmelo Cascone04888222018-03-19 22:18:12 -0700152 last_ipv4_dscp = hdr.gtpu_ipv4.dscp;
Carmelo Casconeb757dbc2018-01-25 17:53:17 -0800153 transition select(hdr.gtpu_ipv4.protocol) {
Carmelo Casconeb81f4be2018-01-16 23:24:01 -0800154 PROTO_TCP: parse_tcp;
155 PROTO_UDP: parse_udp_inner;
156 PROTO_ICMP: parse_icmp;
157 default: accept;
158 }
159 }
160
161 state parse_udp_inner {
Carmelo Casconeb757dbc2018-01-25 17:53:17 -0800162 packet.extract(hdr.gtpu_udp);
163 fabric_metadata.l4_src_port = hdr.gtpu_udp.src_port;
164 fabric_metadata.l4_dst_port = hdr.gtpu_udp.dst_port;
Carmelo Cascone04888222018-03-19 22:18:12 -0700165#ifdef WITH_INT_TRANSIT
166 transition parse_int;
167#else
Carmelo Casconeb81f4be2018-01-16 23:24:01 -0800168 transition accept;
Carmelo Cascone04888222018-03-19 22:18:12 -0700169#endif // WITH_INT_TRANSIT
Carmelo Casconeb81f4be2018-01-16 23:24:01 -0800170 }
171#endif // WITH_SPGW
Carmelo Cascone04888222018-03-19 22:18:12 -0700172
173#ifdef WITH_INT_TRANSIT
174 state parse_int {
175 transition select(last_ipv4_dscp) {
176 DSCP_INT &&& DSCP_INT: parse_intl4_shim;
177 default: accept;
178 }
179 }
180
181 state parse_intl4_shim {
182 packet.extract(hdr.intl4_shim);
183 transition parse_int_header;
184 }
185
186 state parse_int_header {
187 packet.extract(hdr.int_header);
188 fabric_metadata.int_metadata.ins_cnt_tmp = hdr.int_header.ins_cnt;
189 transition accept;
190 }
191#endif // WITH_INT_TRANSIT
Yi Tsengbe342052017-11-03 10:21:23 -0700192}
193
194control FabricDeparser(packet_out packet, in parsed_headers_t hdr) {
Yi Tseng3d3956d2018-01-31 17:28:05 -0800195 apply {
Yi Tsengbe342052017-11-03 10:21:23 -0700196 packet.emit(hdr.packet_in);
197 packet.emit(hdr.ethernet);
198 packet.emit(hdr.vlan_tag);
Yi Tsengbe342052017-11-03 10:21:23 -0700199 packet.emit(hdr.mpls);
200 packet.emit(hdr.arp);
Carmelo Casconeb81f4be2018-01-16 23:24:01 -0800201#ifdef WITH_SPGW
202 packet.emit(hdr.gtpu_ipv4);
203 packet.emit(hdr.gtpu_udp);
204 packet.emit(hdr.gtpu);
205#endif // WITH_SPGW
Yi Tsengbe342052017-11-03 10:21:23 -0700206 packet.emit(hdr.ipv4);
Carmelo Casconeed88f2b2018-01-26 17:36:34 -0800207#ifdef WITH_IPV6
Yi Tsengbe342052017-11-03 10:21:23 -0700208 packet.emit(hdr.ipv6);
Carmelo Casconeed88f2b2018-01-26 17:36:34 -0800209#endif // WITH_IPV6
Yi Tsengbe342052017-11-03 10:21:23 -0700210 packet.emit(hdr.tcp);
211 packet.emit(hdr.udp);
Yi Tsengf73a5532017-11-17 15:58:57 -0800212 packet.emit(hdr.icmp);
Carmelo Cascone04888222018-03-19 22:18:12 -0700213#ifdef WITH_INT_TRANSIT
214 packet.emit(hdr.intl4_shim);
215 packet.emit(hdr.int_header);
216 packet.emit(hdr.int_switch_id);
217 packet.emit(hdr.int_port_ids);
218 packet.emit(hdr.int_hop_latency);
219 packet.emit(hdr.int_q_occupancy);
220 packet.emit(hdr.int_ingress_tstamp);
221 packet.emit(hdr.int_egress_tstamp);
222 packet.emit(hdr.int_q_congestion);
223 packet.emit(hdr.int_egress_port_tx_util);
224#endif // WITH_INT_TRANSIT
Yi Tsengbe342052017-11-03 10:21:23 -0700225 }
226}
227
228#endif