blob: a96b522de054958568542f105ae0244e0643aa0f [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;
Wailok Shumfb7e7872021-06-18 17:30:08 +080038 fabric_metadata.port_type = PORT_TYPE_UNKNOWN;
Yi Tseng47eac892018-07-11 02:17:04 +080039 ingress_port_vlan_counter.count();
Yi Tseng1d842672017-11-28 16:06:52 -080040 }
Yi Tsengbe342052017-11-03 10:21:23 -070041
Wailok Shumfb7e7872021-06-18 17:30:08 +080042 action permit(port_type_t port_type) {
Carmelo Casconeb5324e72018-11-25 02:26:32 -080043 // Allow packet as is.
Wailok Shumfb7e7872021-06-18 17:30:08 +080044 fabric_metadata.port_type = port_type;
Yi Tseng47eac892018-07-11 02:17:04 +080045 ingress_port_vlan_counter.count();
Yi Tsengbe342052017-11-03 10:21:23 -070046 }
47
Wailok Shumfb7e7872021-06-18 17:30:08 +080048 action permit_with_internal_vlan(vlan_id_t vlan_id, port_type_t port_type) {
Carmelo Casconeb5324e72018-11-25 02:26:32 -080049 fabric_metadata.vlan_id = vlan_id;
Wailok Shumfb7e7872021-06-18 17:30:08 +080050 permit(port_type);
Carmelo Cascone8a715f82018-08-20 23:16:27 -070051 }
52
Daniele Morob3d199b2019-11-01 14:01:46 -070053 // FIXME: remove the use of ternary match on inner VLAN.
Daniele Moro7c3a0022019-07-12 13:38:34 -070054 // Use multi-table approach to remove ternary matching
Yi Tsengbe342052017-11-03 10:21:23 -070055 table ingress_port_vlan {
56 key = {
Daniele Moro7c3a0022019-07-12 13:38:34 -070057 standard_metadata.ingress_port : exact @name("ig_port");
58 hdr.vlan_tag.isValid() : exact @name("vlan_is_valid");
59 hdr.vlan_tag.vlan_id : ternary @name("vlan_id");
Daniele Morob3d199b2019-11-01 14:01:46 -070060#ifdef WITH_DOUBLE_VLAN_TERMINATION
Daniele Moro7c3a0022019-07-12 13:38:34 -070061 hdr.inner_vlan_tag.vlan_id : ternary @name("inner_vlan_id");
Daniele Morob3d199b2019-11-01 14:01:46 -070062#endif // WITH_DOUBLE_VLAN_TERMINATION
Yi Tsengbe342052017-11-03 10:21:23 -070063 }
Yi Tsengbe342052017-11-03 10:21:23 -070064 actions = {
Carmelo Casconeb5324e72018-11-25 02:26:32 -080065 deny();
66 permit();
67 permit_with_internal_vlan();
Yi Tsengbe342052017-11-03 10:21:23 -070068 }
Carmelo Casconeb5324e72018-11-25 02:26:32 -080069 const default_action = deny();
Yi Tseng3a5731e2018-01-22 11:38:58 -080070 counters = ingress_port_vlan_counter;
Carmelo Cascone70e816b2019-03-19 16:15:47 -070071 size = PORT_VLAN_TABLE_SIZE;
Yi Tsengbe342052017-11-03 10:21:23 -070072 }
73
Yi Tseng47eac892018-07-11 02:17:04 +080074 /*
75 * Forwarding Classifier.
Carmelo Casconeb5324e72018-11-25 02:26:32 -080076 *
77 * Set which type of forwarding behavior to execute in the next control block.
Yi Tseng47eac892018-07-11 02:17:04 +080078 * There are six types of tables in Forwarding control block:
79 * - Bridging: default forwarding type
80 * - MPLS: destination mac address is the router mac and ethernet type is
Carmelo Casconeb5324e72018-11-25 02:26:32 -080081 * MPLS(0x8847)
Yi Tseng47eac892018-07-11 02:17:04 +080082 * - IP Multicast: destination mac address is multicast address and ethernet
Carmelo Casconeb5324e72018-11-25 02:26:32 -080083 * type is IP(0x0800 or 0x86dd)
Yi Tseng47eac892018-07-11 02:17:04 +080084 * - IP Unicast: destination mac address is router mac and ethernet type is
Carmelo Casconeb5324e72018-11-25 02:26:32 -080085 * IP(0x0800 or 0x86dd)
Yi Tseng47eac892018-07-11 02:17:04 +080086 */
87 direct_counter(CounterType.packets_and_bytes) fwd_classifier_counter;
88
89 action set_forwarding_type(fwd_type_t fwd_type) {
90 fabric_metadata.fwd_type = fwd_type;
91 fwd_classifier_counter.count();
92 }
93
Yi Tsengbe342052017-11-03 10:21:23 -070094 table fwd_classifier {
95 key = {
Daniele Moro7c3a0022019-07-12 13:38:34 -070096 standard_metadata.ingress_port : exact @name("ig_port");
97 hdr.ethernet.dst_addr : ternary @name("eth_dst");
Daniele Moro5a2de712019-09-24 14:34:07 -070098 hdr.eth_type.value : ternary @name("eth_type");
99 fabric_metadata.ip_eth_type : exact @name("ip_eth_type");
Yi Tsengbe342052017-11-03 10:21:23 -0700100 }
Yi Tsengbe342052017-11-03 10:21:23 -0700101 actions = {
102 set_forwarding_type;
103 }
Yi Tsengbe342052017-11-03 10:21:23 -0700104 const default_action = set_forwarding_type(FWD_BRIDGING);
Yi Tseng3a5731e2018-01-22 11:38:58 -0800105 counters = fwd_classifier_counter;
Carmelo Cascone70e816b2019-03-19 16:15:47 -0700106 size = FWD_CLASSIFIER_TABLE_SIZE;
Yi Tsengbe342052017-11-03 10:21:23 -0700107 }
108
109 apply {
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800110 // Initialize lookup metadata. Packets without a VLAN header will be
111 // treated as belonging to a default VLAN ID (see parser).
112 if (hdr.vlan_tag.isValid()) {
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800113 fabric_metadata.vlan_id = hdr.vlan_tag.vlan_id;
114 fabric_metadata.vlan_pri = hdr.vlan_tag.pri;
115 fabric_metadata.vlan_cfi = hdr.vlan_tag.cfi;
Carmelo Cascone8a715f82018-08-20 23:16:27 -0700116 }
Daniele Moro7c3a0022019-07-12 13:38:34 -0700117 #ifdef WITH_DOUBLE_VLAN_TERMINATION
118 if (hdr.inner_vlan_tag.isValid()) {
119 fabric_metadata.inner_vlan_id = hdr.inner_vlan_tag.vlan_id;
120 fabric_metadata.inner_vlan_pri = hdr.inner_vlan_tag.pri;
121 fabric_metadata.inner_vlan_cfi = hdr.inner_vlan_tag.cfi;
122 }
123 #endif // WITH_DOUBLE_VLAN_TERMINATION
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800124 if (!hdr.mpls.isValid()) {
125 // Packets with a valid MPLS header will have
126 // fabric_metadata.mpls_ttl set to the packet's MPLS ttl value (see
127 // parser). In any case, if we are forwarding via MPLS, ttl will be
128 // decremented in egress.
129 fabric_metadata.mpls_ttl = DEFAULT_MPLS_TTL + 1;
130 }
131
132 ingress_port_vlan.apply();
133 fwd_classifier.apply();
Yi Tsengbe342052017-11-03 10:21:23 -0700134 }
135}