blob: a3213e9b0e5e733c83d6139b2b4322681ac6d234 [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"
Yi Tsengbe342052017-11-03 10:21:23 -070021
Carmelo Casconeb5324e72018-11-25 02:26:32 -080022control Filtering (inout parsed_headers_t hdr,
23 inout fabric_metadata_t fabric_metadata,
24 inout standard_metadata_t standard_metadata) {
Yi Tseng47eac892018-07-11 02:17:04 +080025
26 /*
27 * Ingress Port VLAN Table.
Carmelo Casconeb5324e72018-11-25 02:26:32 -080028 *
29 * Filter packets based on ingress port and VLAN tag.
Yi Tseng47eac892018-07-11 02:17:04 +080030 */
Yi Tseng3a5731e2018-01-22 11:38:58 -080031 direct_counter(CounterType.packets_and_bytes) ingress_port_vlan_counter;
Yi Tsengbe342052017-11-03 10:21:23 -070032
Carmelo Casconeb5324e72018-11-25 02:26:32 -080033 action deny() {
34 // Packet from unconfigured port. Skip forwarding and next block.
35 // Do ACL table in case we want to punt to cpu.
36 fabric_metadata.skip_forwarding = _TRUE;
37 fabric_metadata.skip_next = _TRUE;
Yi Tseng47eac892018-07-11 02:17:04 +080038 ingress_port_vlan_counter.count();
Yi Tseng1d842672017-11-28 16:06:52 -080039 }
Yi Tsengbe342052017-11-03 10:21:23 -070040
Carmelo Casconeb5324e72018-11-25 02:26:32 -080041 action permit() {
42 // Allow packet as is.
Yi Tseng47eac892018-07-11 02:17:04 +080043 ingress_port_vlan_counter.count();
Yi Tsengbe342052017-11-03 10:21:23 -070044 }
45
Carmelo Casconeb5324e72018-11-25 02:26:32 -080046 action permit_with_internal_vlan(vlan_id_t vlan_id) {
47 fabric_metadata.vlan_id = vlan_id;
Daniele Moro7c3a0022019-07-12 13:38:34 -070048 permit();
Carmelo Cascone8a715f82018-08-20 23:16:27 -070049 }
50
Daniele Moro7c3a0022019-07-12 13:38:34 -070051 // FIXME: remove the use of ternary match on valid inner VLAN.
52 // Use multi-table approach to remove ternary matching
Yi Tsengbe342052017-11-03 10:21:23 -070053 table ingress_port_vlan {
54 key = {
Daniele Moro7c3a0022019-07-12 13:38:34 -070055 standard_metadata.ingress_port : exact @name("ig_port");
56 hdr.vlan_tag.isValid() : exact @name("vlan_is_valid");
57 hdr.vlan_tag.vlan_id : ternary @name("vlan_id");
58 hdr.inner_vlan_tag.vlan_id : ternary @name("inner_vlan_id");
Yi Tsengbe342052017-11-03 10:21:23 -070059 }
Yi Tsengbe342052017-11-03 10:21:23 -070060 actions = {
Carmelo Casconeb5324e72018-11-25 02:26:32 -080061 deny();
62 permit();
63 permit_with_internal_vlan();
Yi Tsengbe342052017-11-03 10:21:23 -070064 }
Carmelo Casconeb5324e72018-11-25 02:26:32 -080065 const default_action = deny();
Yi Tseng3a5731e2018-01-22 11:38:58 -080066 counters = ingress_port_vlan_counter;
Carmelo Cascone70e816b2019-03-19 16:15:47 -070067 size = PORT_VLAN_TABLE_SIZE;
Yi Tsengbe342052017-11-03 10:21:23 -070068 }
69
Yi Tseng47eac892018-07-11 02:17:04 +080070 /*
71 * Forwarding Classifier.
Carmelo Casconeb5324e72018-11-25 02:26:32 -080072 *
73 * Set which type of forwarding behavior to execute in the next control block.
Yi Tseng47eac892018-07-11 02:17:04 +080074 * There are six types of tables in Forwarding control block:
75 * - Bridging: default forwarding type
76 * - MPLS: destination mac address is the router mac and ethernet type is
Carmelo Casconeb5324e72018-11-25 02:26:32 -080077 * MPLS(0x8847)
Yi Tseng47eac892018-07-11 02:17:04 +080078 * - IP Multicast: destination mac address is multicast address and ethernet
Carmelo Casconeb5324e72018-11-25 02:26:32 -080079 * type is IP(0x0800 or 0x86dd)
Yi Tseng47eac892018-07-11 02:17:04 +080080 * - IP Unicast: destination mac address is router mac and ethernet type is
Carmelo Casconeb5324e72018-11-25 02:26:32 -080081 * IP(0x0800 or 0x86dd)
Yi Tseng47eac892018-07-11 02:17:04 +080082 */
83 direct_counter(CounterType.packets_and_bytes) fwd_classifier_counter;
84
85 action set_forwarding_type(fwd_type_t fwd_type) {
86 fabric_metadata.fwd_type = fwd_type;
87 fwd_classifier_counter.count();
88 }
89
Yi Tsengbe342052017-11-03 10:21:23 -070090 table fwd_classifier {
91 key = {
Daniele Moro7c3a0022019-07-12 13:38:34 -070092 standard_metadata.ingress_port : exact @name("ig_port");
93 hdr.ethernet.dst_addr : ternary @name("eth_dst");
94 fabric_metadata.is_ipv4 : exact @name("is_ipv4");
95 fabric_metadata.is_ipv6 : exact @name("is_ipv6");
96 fabric_metadata.is_mpls : exact @name("is_mpls");
Yi Tsengbe342052017-11-03 10:21:23 -070097 }
Yi Tsengbe342052017-11-03 10:21:23 -070098 actions = {
99 set_forwarding_type;
100 }
Yi Tsengbe342052017-11-03 10:21:23 -0700101 const default_action = set_forwarding_type(FWD_BRIDGING);
Yi Tseng3a5731e2018-01-22 11:38:58 -0800102 counters = fwd_classifier_counter;
Carmelo Cascone70e816b2019-03-19 16:15:47 -0700103 size = FWD_CLASSIFIER_TABLE_SIZE;
Yi Tsengbe342052017-11-03 10:21:23 -0700104 }
105
106 apply {
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800107 // Initialize lookup metadata. Packets without a VLAN header will be
108 // treated as belonging to a default VLAN ID (see parser).
109 if (hdr.vlan_tag.isValid()) {
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800110 fabric_metadata.vlan_id = hdr.vlan_tag.vlan_id;
111 fabric_metadata.vlan_pri = hdr.vlan_tag.pri;
112 fabric_metadata.vlan_cfi = hdr.vlan_tag.cfi;
Carmelo Cascone8a715f82018-08-20 23:16:27 -0700113 }
Daniele Moro7c3a0022019-07-12 13:38:34 -0700114 #ifdef WITH_DOUBLE_VLAN_TERMINATION
115 if (hdr.inner_vlan_tag.isValid()) {
116 fabric_metadata.inner_vlan_id = hdr.inner_vlan_tag.vlan_id;
117 fabric_metadata.inner_vlan_pri = hdr.inner_vlan_tag.pri;
118 fabric_metadata.inner_vlan_cfi = hdr.inner_vlan_tag.cfi;
119 }
120 #endif // WITH_DOUBLE_VLAN_TERMINATION
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800121 if (!hdr.mpls.isValid()) {
122 // Packets with a valid MPLS header will have
123 // fabric_metadata.mpls_ttl set to the packet's MPLS ttl value (see
124 // parser). In any case, if we are forwarding via MPLS, ttl will be
125 // decremented in egress.
126 fabric_metadata.mpls_ttl = DEFAULT_MPLS_TTL + 1;
127 }
128
Daniele Moro7c3a0022019-07-12 13:38:34 -0700129 // Set last_eth_type checking the validity of the L2.5 headers
130 if (hdr.mpls.isValid()) {
131 fabric_metadata.last_eth_type = ETHERTYPE_MPLS;
132 } else {
133 if (hdr.vlan_tag.isValid()) {
134#if defined(WITH_XCONNECT) || defined(WITH_BNG) || defined(WITH_DOUBLE_VLAN_TERMINATION)
135 if(hdr.inner_vlan_tag.isValid()) {
136 fabric_metadata.last_eth_type = hdr.inner_vlan_tag.eth_type;
137 } else
138#endif // WITH_XCONNECT || WITH_BNG || WITH_DOUBLE_VLAN_TERMINATION
139 fabric_metadata.last_eth_type = hdr.vlan_tag.eth_type;
140 } else {
141 fabric_metadata.last_eth_type = hdr.ethernet.eth_type;
142 }
143 }
144
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800145 ingress_port_vlan.apply();
146 fwd_classifier.apply();
Yi Tsengbe342052017-11-03 10:21:23 -0700147 }
148}