Yi Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 1 | /* |
| 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 Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 21 | |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 22 | control Filtering (inout parsed_headers_t hdr, |
| 23 | inout fabric_metadata_t fabric_metadata, |
| 24 | inout standard_metadata_t standard_metadata) { |
Yi Tseng | 47eac89 | 2018-07-11 02:17:04 +0800 | [diff] [blame] | 25 | |
| 26 | /* |
| 27 | * Ingress Port VLAN Table. |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 28 | * |
| 29 | * Filter packets based on ingress port and VLAN tag. |
Yi Tseng | 47eac89 | 2018-07-11 02:17:04 +0800 | [diff] [blame] | 30 | */ |
Yi Tseng | 3a5731e | 2018-01-22 11:38:58 -0800 | [diff] [blame] | 31 | direct_counter(CounterType.packets_and_bytes) ingress_port_vlan_counter; |
Yi Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 32 | |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 33 | 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 Tseng | 47eac89 | 2018-07-11 02:17:04 +0800 | [diff] [blame] | 38 | ingress_port_vlan_counter.count(); |
Yi Tseng | 1d84267 | 2017-11-28 16:06:52 -0800 | [diff] [blame] | 39 | } |
Yi Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 40 | |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 41 | action permit() { |
| 42 | // Allow packet as is. |
Yi Tseng | 47eac89 | 2018-07-11 02:17:04 +0800 | [diff] [blame] | 43 | ingress_port_vlan_counter.count(); |
Yi Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 44 | } |
| 45 | |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 46 | action permit_with_internal_vlan(vlan_id_t vlan_id) { |
| 47 | fabric_metadata.vlan_id = vlan_id; |
Daniele Moro | 7c3a002 | 2019-07-12 13:38:34 -0700 | [diff] [blame] | 48 | permit(); |
Carmelo Cascone | 8a715f8 | 2018-08-20 23:16:27 -0700 | [diff] [blame] | 49 | } |
| 50 | |
Daniele Moro | dd0568b | 2019-11-01 14:01:46 -0700 | [diff] [blame] | 51 | // FIXME: remove the use of ternary match on inner VLAN. |
Daniele Moro | 7c3a002 | 2019-07-12 13:38:34 -0700 | [diff] [blame] | 52 | // Use multi-table approach to remove ternary matching |
Yi Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 53 | table ingress_port_vlan { |
| 54 | key = { |
Daniele Moro | 7c3a002 | 2019-07-12 13:38:34 -0700 | [diff] [blame] | 55 | 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 Moro | dd0568b | 2019-11-01 14:01:46 -0700 | [diff] [blame] | 58 | #ifdef WITH_DOUBLE_VLAN_TERMINATION |
Daniele Moro | 7c3a002 | 2019-07-12 13:38:34 -0700 | [diff] [blame] | 59 | hdr.inner_vlan_tag.vlan_id : ternary @name("inner_vlan_id"); |
Daniele Moro | dd0568b | 2019-11-01 14:01:46 -0700 | [diff] [blame] | 60 | #endif // WITH_DOUBLE_VLAN_TERMINATION |
Yi Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 61 | } |
Yi Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 62 | actions = { |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 63 | deny(); |
| 64 | permit(); |
| 65 | permit_with_internal_vlan(); |
Yi Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 66 | } |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 67 | const default_action = deny(); |
Yi Tseng | 3a5731e | 2018-01-22 11:38:58 -0800 | [diff] [blame] | 68 | counters = ingress_port_vlan_counter; |
Carmelo Cascone | 70e816b | 2019-03-19 16:15:47 -0700 | [diff] [blame] | 69 | size = PORT_VLAN_TABLE_SIZE; |
Yi Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 70 | } |
| 71 | |
Yi Tseng | 47eac89 | 2018-07-11 02:17:04 +0800 | [diff] [blame] | 72 | /* |
| 73 | * Forwarding Classifier. |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 74 | * |
| 75 | * Set which type of forwarding behavior to execute in the next control block. |
Yi Tseng | 47eac89 | 2018-07-11 02:17:04 +0800 | [diff] [blame] | 76 | * 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 Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 79 | * MPLS(0x8847) |
Yi Tseng | 47eac89 | 2018-07-11 02:17:04 +0800 | [diff] [blame] | 80 | * - IP Multicast: destination mac address is multicast address and ethernet |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 81 | * type is IP(0x0800 or 0x86dd) |
Yi Tseng | 47eac89 | 2018-07-11 02:17:04 +0800 | [diff] [blame] | 82 | * - IP Unicast: destination mac address is router mac and ethernet type is |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 83 | * IP(0x0800 or 0x86dd) |
Yi Tseng | 47eac89 | 2018-07-11 02:17:04 +0800 | [diff] [blame] | 84 | */ |
| 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 Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 92 | table fwd_classifier { |
| 93 | key = { |
Daniele Moro | 7c3a002 | 2019-07-12 13:38:34 -0700 | [diff] [blame] | 94 | standard_metadata.ingress_port : exact @name("ig_port"); |
| 95 | hdr.ethernet.dst_addr : ternary @name("eth_dst"); |
Daniele Moro | 693d76f | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 96 | hdr.eth_type.value : ternary @name("eth_type"); |
| 97 | fabric_metadata.ip_eth_type : exact @name("ip_eth_type"); |
Yi Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 98 | } |
Yi Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 99 | actions = { |
| 100 | set_forwarding_type; |
| 101 | } |
Yi Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 102 | const default_action = set_forwarding_type(FWD_BRIDGING); |
Yi Tseng | 3a5731e | 2018-01-22 11:38:58 -0800 | [diff] [blame] | 103 | counters = fwd_classifier_counter; |
Carmelo Cascone | 70e816b | 2019-03-19 16:15:47 -0700 | [diff] [blame] | 104 | size = FWD_CLASSIFIER_TABLE_SIZE; |
Yi Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 105 | } |
| 106 | |
| 107 | apply { |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 108 | // 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 Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 111 | 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 Cascone | 8a715f8 | 2018-08-20 23:16:27 -0700 | [diff] [blame] | 114 | } |
Daniele Moro | 7c3a002 | 2019-07-12 13:38:34 -0700 | [diff] [blame] | 115 | #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 Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 122 | 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 Tseng | be34205 | 2017-11-03 10:21:23 -0700 | [diff] [blame] | 132 | } |
| 133 | } |