blob: a8fae49907b26ff9c67802a0f9202ef1477720ae [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 Morodd0568b2019-11-01 14:01:46 -070051 // FIXME: remove the use of ternary match on inner VLAN.
Daniele Moro7c3a0022019-07-12 13:38:34 -070052 // 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");
Daniele Morodd0568b2019-11-01 14:01:46 -070058#ifdef WITH_DOUBLE_VLAN_TERMINATION
Daniele Moro7c3a0022019-07-12 13:38:34 -070059 hdr.inner_vlan_tag.vlan_id : ternary @name("inner_vlan_id");
Daniele Morodd0568b2019-11-01 14:01:46 -070060#endif // WITH_DOUBLE_VLAN_TERMINATION
Yi Tsengbe342052017-11-03 10:21:23 -070061 }
Yi Tsengbe342052017-11-03 10:21:23 -070062 actions = {
Carmelo Casconeb5324e72018-11-25 02:26:32 -080063 deny();
64 permit();
65 permit_with_internal_vlan();
Yi Tsengbe342052017-11-03 10:21:23 -070066 }
Carmelo Casconeb5324e72018-11-25 02:26:32 -080067 const default_action = deny();
Yi Tseng3a5731e2018-01-22 11:38:58 -080068 counters = ingress_port_vlan_counter;
Carmelo Cascone70e816b2019-03-19 16:15:47 -070069 size = PORT_VLAN_TABLE_SIZE;
Yi Tsengbe342052017-11-03 10:21:23 -070070 }
71
Yi Tseng47eac892018-07-11 02:17:04 +080072 /*
73 * Forwarding Classifier.
Carmelo Casconeb5324e72018-11-25 02:26:32 -080074 *
75 * Set which type of forwarding behavior to execute in the next control block.
Yi Tseng47eac892018-07-11 02:17:04 +080076 * There are six types of tables in Forwarding control block:
77 * - Bridging: default forwarding type
78 * - MPLS: destination mac address is the router mac and ethernet type is
Carmelo Casconeb5324e72018-11-25 02:26:32 -080079 * MPLS(0x8847)
Yi Tseng47eac892018-07-11 02:17:04 +080080 * - IP Multicast: destination mac address is multicast address and ethernet
Carmelo Casconeb5324e72018-11-25 02:26:32 -080081 * type is IP(0x0800 or 0x86dd)
Yi Tseng47eac892018-07-11 02:17:04 +080082 * - IP Unicast: destination mac address is router mac and ethernet type is
Carmelo Casconeb5324e72018-11-25 02:26:32 -080083 * IP(0x0800 or 0x86dd)
Yi Tseng47eac892018-07-11 02:17:04 +080084 */
85 direct_counter(CounterType.packets_and_bytes) fwd_classifier_counter;
86
87 action set_forwarding_type(fwd_type_t fwd_type) {
88 fabric_metadata.fwd_type = fwd_type;
89 fwd_classifier_counter.count();
90 }
91
Yi Tsengbe342052017-11-03 10:21:23 -070092 table fwd_classifier {
93 key = {
Daniele Moro7c3a0022019-07-12 13:38:34 -070094 standard_metadata.ingress_port : exact @name("ig_port");
95 hdr.ethernet.dst_addr : ternary @name("eth_dst");
Daniele Moro693d76f2019-09-24 14:34:07 -070096 hdr.eth_type.value : ternary @name("eth_type");
97 fabric_metadata.ip_eth_type : exact @name("ip_eth_type");
Yi Tsengbe342052017-11-03 10:21:23 -070098 }
Yi Tsengbe342052017-11-03 10:21:23 -070099 actions = {
100 set_forwarding_type;
101 }
Yi Tsengbe342052017-11-03 10:21:23 -0700102 const default_action = set_forwarding_type(FWD_BRIDGING);
Yi Tseng3a5731e2018-01-22 11:38:58 -0800103 counters = fwd_classifier_counter;
Carmelo Cascone70e816b2019-03-19 16:15:47 -0700104 size = FWD_CLASSIFIER_TABLE_SIZE;
Yi Tsengbe342052017-11-03 10:21:23 -0700105 }
106
107 apply {
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800108 // Initialize lookup metadata. Packets without a VLAN header will be
109 // treated as belonging to a default VLAN ID (see parser).
110 if (hdr.vlan_tag.isValid()) {
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800111 fabric_metadata.vlan_id = hdr.vlan_tag.vlan_id;
112 fabric_metadata.vlan_pri = hdr.vlan_tag.pri;
113 fabric_metadata.vlan_cfi = hdr.vlan_tag.cfi;
Carmelo Cascone8a715f82018-08-20 23:16:27 -0700114 }
Daniele Moro7c3a0022019-07-12 13:38:34 -0700115 #ifdef WITH_DOUBLE_VLAN_TERMINATION
116 if (hdr.inner_vlan_tag.isValid()) {
117 fabric_metadata.inner_vlan_id = hdr.inner_vlan_tag.vlan_id;
118 fabric_metadata.inner_vlan_pri = hdr.inner_vlan_tag.pri;
119 fabric_metadata.inner_vlan_cfi = hdr.inner_vlan_tag.cfi;
120 }
121 #endif // WITH_DOUBLE_VLAN_TERMINATION
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800122 if (!hdr.mpls.isValid()) {
123 // Packets with a valid MPLS header will have
124 // fabric_metadata.mpls_ttl set to the packet's MPLS ttl value (see
125 // parser). In any case, if we are forwarding via MPLS, ttl will be
126 // decremented in egress.
127 fabric_metadata.mpls_ttl = DEFAULT_MPLS_TTL + 1;
128 }
129
130 ingress_port_vlan.apply();
131 fwd_classifier.apply();
Yi Tsengbe342052017-11-03 10:21:23 -0700132 }
133}