[ONOS-7128] Initial commit of fabric.p4
Change-Id: I5224c411a1eccdbee84b1fc0b1824c5fa922f689
diff --git a/pipelines/fabric/src/main/resources/include/parser.p4 b/pipelines/fabric/src/main/resources/include/parser.p4
new file mode 100644
index 0000000..0e13cfd
--- /dev/null
+++ b/pipelines/fabric/src/main/resources/include/parser.p4
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __PARSER__
+#define __PARSER__
+
+#include "define.p4"
+
+parser FabricParser (
+packet_in packet,
+out parsed_headers_t hdr,
+inout fabric_metadata_t fabric_metadata,
+inout standard_metadata_t standard_metadata) {
+ state start {
+ transition select(standard_metadata.ingress_port) {
+ CPU_PORT: parse_packet_out;
+ default: parse_ethernet;
+ }
+ }
+
+ state parse_packet_out {
+ packet.extract(hdr.packet_out);
+ transition parse_ethernet;
+ }
+
+ state parse_ethernet {
+ packet.extract(hdr.ethernet);
+ transition select(hdr.ethernet.ether_type){
+ ETHERTYPE_QINQ_NON_STD: parse_vlan_tag;
+ ETHERTYPE_QINQ: parse_vlan_tag;
+ ETHERTYPE_VLAN: parse_vlan_tag;
+ ETHERTYPE_MPLS: parse_mpls;
+ ETHERTYPE_ARP: parse_arp;
+ ETHERTYPE_IPV4: parse_ipv4;
+ ETHERTYPE_IPV6: parse_ipv6;
+ default: accept;
+ }
+ }
+
+ state parse_vlan_tag {
+ packet.extract(hdr.vlan_tag);
+ transition select(hdr.vlan_tag.ether_type){
+ ETHERTYPE_VLAN: parse_inner_vlan_tag;
+ ETHERTYPE_ARP: parse_arp;
+ ETHERTYPE_IPV4: parse_ipv4;
+ ETHERTYPE_IPV6: parse_ipv6;
+ default: accept;
+ }
+ }
+
+ state parse_inner_vlan_tag {
+ packet.extract(hdr.inner_vlan_tag);
+ transition select(hdr.vlan_tag.ether_type){
+ ETHERTYPE_ARP: parse_arp;
+ ETHERTYPE_IPV4: parse_ipv4;
+ ETHERTYPE_IPV6: parse_ipv6;
+ default: accept;
+ }
+ }
+
+ state parse_mpls {
+ packet.extract(hdr.mpls);
+
+ //There is only one MPLS label for this fabric.
+ transition select(packet.lookahead<ipv4_t>().version) {
+ //The packet should be either IPv4 or IPv6.
+ IP_VERSION_4: parse_ipv4;
+ IP_VERSION_6: parse_ipv6;
+ default: parse_ethernet;
+ }
+ }
+
+ state parse_ipv4 {
+ packet.extract(hdr.ipv4);
+ fabric_metadata.ip_proto = hdr.ipv4.protocol;
+ //Need header verification?
+ transition select(hdr.ipv4.protocol) {
+ PROTO_TCP: parse_tcp;
+ PROTO_UDP: parse_udp;
+ PROTO_ICMP: parse_icmp;
+ default: accept;
+ }
+ }
+
+ state parse_ipv6 {
+ packet.extract(hdr.ipv6);
+ fabric_metadata.ip_proto = hdr.ipv6.next_hdr;
+ transition select(hdr.ipv6.next_hdr) {
+ PROTO_TCP: parse_tcp;
+ PROTO_UDP: parse_udp;
+ PROTO_ICMPV6: parse_icmp;
+ default: accept;
+ }
+ }
+
+ state parse_arp {
+ packet.extract(hdr.arp);
+ transition accept;
+ }
+
+ state parse_tcp {
+ packet.extract(hdr.tcp);
+ fabric_metadata.l4_src_port = hdr.tcp.src_port;
+ fabric_metadata.l4_dst_port = hdr.tcp.dst_port;
+ transition accept;
+ }
+
+ state parse_udp {
+ packet.extract(hdr.udp);
+ fabric_metadata.l4_src_port = hdr.udp.src_port;
+ fabric_metadata.l4_dst_port = hdr.udp.dst_port;
+ transition accept;
+ }
+
+ state parse_icmp {
+ packet.extract(hdr.icmp);
+ transition accept;
+ }
+}
+
+control FabricDeparser(packet_out packet, in parsed_headers_t hdr) {
+ apply{
+ packet.emit(hdr.packet_in);
+ packet.emit(hdr.ethernet);
+ packet.emit(hdr.vlan_tag);
+ packet.emit(hdr.inner_vlan_tag);
+ packet.emit(hdr.mpls);
+ packet.emit(hdr.arp);
+ packet.emit(hdr.ipv4);
+ packet.emit(hdr.ipv6);
+ packet.emit(hdr.tcp);
+ packet.emit(hdr.udp);
+ }
+}
+
+#endif