Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -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 | |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 17 | package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner; |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 18 | |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 19 | import com.google.common.collect.Lists; |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 20 | import org.junit.Before; |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 21 | import org.junit.Test; |
| 22 | import org.onlab.packet.Ethernet; |
| 23 | import org.onlab.packet.MacAddress; |
| 24 | import org.onlab.packet.VlanId; |
| 25 | import org.onlab.util.ImmutableByteSequence; |
| 26 | import org.onosproject.net.PortNumber; |
| 27 | import org.onosproject.net.flow.DefaultFlowRule; |
| 28 | import org.onosproject.net.flow.DefaultTrafficSelector; |
| 29 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
| 30 | import org.onosproject.net.flow.FlowRule; |
| 31 | import org.onosproject.net.flow.TableId; |
| 32 | import org.onosproject.net.flow.TrafficSelector; |
| 33 | import org.onosproject.net.flow.TrafficTreatment; |
| 34 | import org.onosproject.net.flow.criteria.Criteria; |
Daniele Moro | 7c3a002 | 2019-07-12 13:38:34 -0700 | [diff] [blame] | 35 | import org.onosproject.net.flow.criteria.PiCriterion; |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 36 | import org.onosproject.net.flowobjective.DefaultFilteringObjective; |
| 37 | import org.onosproject.net.flowobjective.FilteringObjective; |
| 38 | import org.onosproject.net.flowobjective.ObjectiveError; |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 39 | import org.onosproject.net.pi.runtime.PiAction; |
| 40 | import org.onosproject.net.pi.runtime.PiActionParam; |
Carmelo Cascone | 2102bfb | 2020-12-04 16:54:24 -0800 | [diff] [blame] | 41 | import org.onosproject.pipelines.fabric.FabricConstants; |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 42 | |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 43 | import java.util.Collection; |
| 44 | import java.util.List; |
| 45 | |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 46 | import static org.junit.Assert.assertEquals; |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 47 | import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.DEFAULT_PW_TRANSPORT_VLAN; |
| 48 | import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.DEFAULT_VLAN; |
| 49 | import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.ETH_TYPE_EXACT_MASK; |
| 50 | import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.FWD_IPV4_ROUTING; |
| 51 | import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.FWD_IPV6_ROUTING; |
| 52 | import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.FWD_MPLS; |
| 53 | import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.ONE; |
| 54 | import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.PORT_TYPE_EDGE; |
| 55 | import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.PORT_TYPE_INFRA; |
| 56 | import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.ZERO; |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 57 | |
| 58 | /** |
| 59 | * Test cases for fabric.p4 pipeline filtering control block. |
| 60 | */ |
Carmelo Cascone | 2388cc1 | 2021-05-26 19:30:30 +0200 | [diff] [blame] | 61 | public class FilteringObjectiveTranslatorTest extends BaseObjectiveTranslatorTest { |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 62 | |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 63 | private FilteringObjectiveTranslator translator; |
| 64 | |
| 65 | @Before |
| 66 | public void setup() { |
| 67 | super.doSetup(); |
| 68 | translator = new FilteringObjectiveTranslator(DEVICE_ID, capabilitiesHashed); |
| 69 | } |
| 70 | |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 71 | /** |
| 72 | * Creates one rule for ingress_port_vlan table and 3 rules for |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 73 | * fwd_classifier table (IPv4, IPv6 and MPLS unicast) when the condition is |
| 74 | * VLAN + MAC. |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 75 | */ |
| 76 | @Test |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 77 | public void testRouterMacAndVlanFilter() throws FabricPipelinerException { |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 78 | FilteringObjective filteringObjective = buildFilteringObjective(ROUTER_MAC); |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 79 | ObjectiveTranslation actualTranslation = translator.translate(filteringObjective); |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 80 | Collection<FlowRule> expectedFlowRules = Lists.newArrayList(); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 81 | // in port vlan flow rule |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 82 | expectedFlowRules.add(buildExpectedVlanInPortRule( |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 83 | PORT_1, |
| 84 | VlanId.NONE, |
| 85 | VlanId.NONE, |
| 86 | VLAN_100, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 87 | PORT_TYPE_EDGE, |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 88 | FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN)); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 89 | |
| 90 | // forwarding classifier ipv4 |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 91 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 92 | PORT_1, |
| 93 | ROUTER_MAC, |
| 94 | null, |
| 95 | Ethernet.TYPE_IPV4, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 96 | FWD_IPV4_ROUTING)); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 97 | |
| 98 | // forwarding classifier ipv6 |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 99 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 100 | PORT_1, |
| 101 | ROUTER_MAC, |
| 102 | null, |
| 103 | Ethernet.TYPE_IPV6, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 104 | FWD_IPV6_ROUTING)); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 105 | |
| 106 | // forwarding classifier mpls |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 107 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 108 | PORT_1, |
| 109 | ROUTER_MAC, |
| 110 | null, |
| 111 | Ethernet.MPLS_UNICAST, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 112 | FWD_MPLS)); |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 113 | |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 114 | // ObjectiveTranslation.Builder expectedTranslationBuilder = ObjectiveTranslation.builder() |
| 115 | // .addFlowRule(inportFlowRuleExpected); |
| 116 | // for (FlowRule flowRule : classifierV4FlowRuleExpected) { |
| 117 | // expectedTranslationBuilder.addFlowRule(flowRule); |
| 118 | // } |
| 119 | // for (FlowRule flowRule : classifierV6FlowRuleExpected) { |
| 120 | // expectedTranslationBuilder.addFlowRule(flowRule); |
| 121 | // } |
| 122 | // for (FlowRule flowRule : classifierMplsFlowRuleExpected) { |
| 123 | // expectedTranslationBuilder.addFlowRule(flowRule); |
| 124 | // } |
| 125 | ObjectiveTranslation expectedTranslation = buildExpectedTranslation(expectedFlowRules); |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 126 | |
| 127 | assertEquals(expectedTranslation, actualTranslation); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 128 | } |
| 129 | |
| 130 | /** |
| 131 | * Creates one rule for ingress_port_vlan table and one rule for |
| 132 | * fwd_classifier table (IPv4 multicast) when the condition is ipv4 |
| 133 | * multicast mac address. |
| 134 | */ |
| 135 | @Test |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 136 | public void testIpv4MulticastFwdClass() throws FabricPipelinerException { |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 137 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
| 138 | .pushVlan() |
| 139 | .setVlanId(VLAN_100) |
| 140 | .build(); |
| 141 | FilteringObjective filteringObjective = DefaultFilteringObjective.builder() |
| 142 | .permit() |
| 143 | .withPriority(PRIORITY) |
| 144 | .withKey(Criteria.matchInPort(PORT_1)) |
Charles Chan | 384aea2 | 2018-08-23 22:08:02 -0700 | [diff] [blame] | 145 | .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV4_MULTICAST, MacAddress.IPV4_MULTICAST_MASK)) |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 146 | .addCondition(Criteria.matchVlanId(VlanId.NONE)) |
| 147 | .withMeta(treatment) |
| 148 | .fromApp(APP_ID) |
| 149 | .makePermanent() |
| 150 | .add(); |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 151 | ObjectiveTranslation actualTranslation = translator.translate(filteringObjective); |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 152 | List<FlowRule> expectedFlowRules = Lists.newArrayList(); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 153 | // in port vlan flow rule |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 154 | expectedFlowRules.add(buildExpectedVlanInPortRule( |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 155 | PORT_1, |
| 156 | VlanId.NONE, |
| 157 | VlanId.NONE, |
| 158 | VLAN_100, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 159 | PORT_TYPE_EDGE, |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 160 | FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN)); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 161 | |
| 162 | // forwarding classifier |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 163 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 164 | PORT_1, |
| 165 | MacAddress.IPV4_MULTICAST, |
| 166 | MacAddress.IPV4_MULTICAST_MASK, |
| 167 | Ethernet.TYPE_IPV4, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 168 | FWD_IPV4_ROUTING)); |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 169 | |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 170 | ObjectiveTranslation expectedTranslation = buildExpectedTranslation(expectedFlowRules); |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 171 | |
| 172 | assertEquals(expectedTranslation, actualTranslation); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 173 | } |
| 174 | |
| 175 | /** |
| 176 | * Creates one rule for ingress_port_vlan table and one rule for |
| 177 | * fwd_classifier table (IPv6 multicast) when the condition is ipv6 |
| 178 | * multicast mac address. |
| 179 | */ |
| 180 | @Test |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 181 | public void testIpv6MulticastFwdClass() throws FabricPipelinerException { |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 182 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
| 183 | .pushVlan() |
| 184 | .setVlanId(VLAN_100) |
| 185 | .build(); |
| 186 | FilteringObjective filteringObjective = DefaultFilteringObjective.builder() |
| 187 | .permit() |
| 188 | .withPriority(PRIORITY) |
| 189 | .withKey(Criteria.matchInPort(PORT_1)) |
Charles Chan | 384aea2 | 2018-08-23 22:08:02 -0700 | [diff] [blame] | 190 | .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV6_MULTICAST, MacAddress.IPV6_MULTICAST_MASK)) |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 191 | .addCondition(Criteria.matchVlanId(VlanId.NONE)) |
| 192 | .withMeta(treatment) |
| 193 | .fromApp(APP_ID) |
| 194 | .makePermanent() |
| 195 | .add(); |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 196 | ObjectiveTranslation actualTranslation = translator.translate(filteringObjective); |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 197 | Collection<FlowRule> flowRules = Lists.newArrayList(); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 198 | // in port vlan flow rule |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 199 | flowRules.add(buildExpectedVlanInPortRule( |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 200 | PORT_1, |
| 201 | VlanId.NONE, |
| 202 | VlanId.NONE, |
| 203 | VLAN_100, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 204 | PORT_TYPE_EDGE, |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 205 | FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN)); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 206 | |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 207 | flowRules.addAll(buildExpectedFwdClassifierRule( |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 208 | PORT_1, |
| 209 | MacAddress.IPV6_MULTICAST, |
| 210 | MacAddress.IPV6_MULTICAST_MASK, |
| 211 | Ethernet.TYPE_IPV6, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 212 | FWD_IPV6_ROUTING)); |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 213 | |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 214 | ObjectiveTranslation expectedTranslation = buildExpectedTranslation(flowRules); |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 215 | |
| 216 | assertEquals(expectedTranslation, actualTranslation); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 217 | } |
| 218 | |
| 219 | /** |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 220 | * Creates only one rule for ingress_port_vlan table if there is no |
| 221 | * condition of destination mac address. The packet will be handled by |
| 222 | * bridging table by default. |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 223 | */ |
| 224 | @Test |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 225 | public void testFwdBridging() throws Exception { |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 226 | FilteringObjective filteringObjective = buildFilteringObjective(null); |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 227 | ObjectiveTranslation actualTranslation = translator.translate(filteringObjective); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 228 | |
| 229 | // in port vlan flow rule |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 230 | FlowRule flowRuleExpected = buildExpectedVlanInPortRule( |
| 231 | PORT_1, |
| 232 | VlanId.NONE, |
| 233 | VlanId.NONE, |
| 234 | VLAN_100, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 235 | PORT_TYPE_EDGE, |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 236 | FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 237 | |
| 238 | // No rules in forwarding classifier, will do default action: set fwd type to bridging |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 239 | |
| 240 | ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder() |
| 241 | .addFlowRule(flowRuleExpected) |
| 242 | .build(); |
| 243 | |
| 244 | assertEquals(expectedTranslation, actualTranslation); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 245 | } |
| 246 | |
| 247 | /** |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 248 | * Test DENY objective. |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 249 | */ |
| 250 | @Test |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 251 | public void testDenyObjective() throws FabricPipelinerException { |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 252 | FilteringObjective filteringObjective = DefaultFilteringObjective.builder() |
| 253 | .deny() |
| 254 | .withKey(Criteria.matchInPort(PORT_1)) |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 255 | .addCondition(Criteria.matchVlanId(VlanId.NONE)) |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 256 | .fromApp(APP_ID) |
| 257 | .makePermanent() |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 258 | .withPriority(PRIORITY) |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 259 | .add(); |
| 260 | |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 261 | ObjectiveTranslation actualTranslation = translator.translate(filteringObjective); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 262 | |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 263 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder() |
| 264 | .matchInPort(PORT_1) |
Daniele Moro | 7c3a002 | 2019-07-12 13:38:34 -0700 | [diff] [blame] | 265 | .matchPi(buildPiCriterionVlan(null, null)); |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 266 | PiAction piAction = PiAction.builder() |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 267 | .withId(FabricConstants.FABRIC_INGRESS_FILTERING_DENY) |
| 268 | .build(); |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 269 | FlowRule expectedFlowRule = DefaultFlowRule.builder() |
| 270 | .withPriority(PRIORITY) |
| 271 | .withSelector(selector.build()) |
| 272 | .withTreatment(DefaultTrafficTreatment.builder() |
| 273 | .piTableAction(piAction).build()) |
| 274 | .fromApp(APP_ID) |
| 275 | .forDevice(DEVICE_ID) |
| 276 | .makePermanent() |
| 277 | .forTable(FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN) |
| 278 | .build(); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 279 | |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 280 | ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder() |
| 281 | .addFlowRule(expectedFlowRule) |
| 282 | .build(); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 283 | |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 284 | assertEquals(expectedTranslation, actualTranslation); |
| 285 | |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 286 | } |
| 287 | |
| 288 | /** |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 289 | * Test double VLAN pop filtering objective Creates one rule for |
| 290 | * ingress_port_vlan table and 3 rules for fwd_classifier table (IPv4, IPv6 |
| 291 | * and MPLS unicast) when the condition is MAC + VLAN + INNER_VLAN. |
Daniele Moro | f51d0c1 | 2019-07-30 10:43:10 -0700 | [diff] [blame] | 292 | */ |
| 293 | @Test |
| 294 | public void testPopVlan() throws FabricPipelinerException { |
| 295 | FilteringObjective filteringObjective = DefaultFilteringObjective.builder() |
| 296 | .withKey(Criteria.matchInPort(PORT_1)) |
| 297 | .addCondition(Criteria.matchEthDst(ROUTER_MAC)) |
| 298 | .addCondition(Criteria.matchVlanId(VLAN_100)) |
| 299 | .addCondition(Criteria.matchInnerVlanId(VLAN_200)) |
| 300 | .withPriority(PRIORITY) |
| 301 | .fromApp(APP_ID) |
| 302 | .withMeta(DefaultTrafficTreatment.builder() |
| 303 | .popVlan() |
| 304 | .build()) |
| 305 | .permit() |
| 306 | .add(); |
| 307 | ObjectiveTranslation actualTranslation = translator.translate(filteringObjective); |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 308 | Collection<FlowRule> expectedFlowRules = Lists.newArrayList(); |
Daniele Moro | f51d0c1 | 2019-07-30 10:43:10 -0700 | [diff] [blame] | 309 | // Ingress port vlan rule |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 310 | expectedFlowRules.add(buildExpectedVlanInPortRule( |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 311 | PORT_1, VLAN_100, VLAN_200, VlanId.NONE, PORT_TYPE_EDGE, |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 312 | FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN)); |
Daniele Moro | f51d0c1 | 2019-07-30 10:43:10 -0700 | [diff] [blame] | 313 | // Forwarding classifier rules (ipv6, ipv4, mpls) |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 314 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 315 | PORT_1, ROUTER_MAC, null, Ethernet.TYPE_IPV4, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 316 | FWD_IPV4_ROUTING)); |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 317 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 318 | PORT_1, ROUTER_MAC, null, Ethernet.TYPE_IPV6, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 319 | FWD_IPV6_ROUTING)); |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 320 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
Carmelo Cascone | 356ab8b | 2019-09-25 01:02:53 -0700 | [diff] [blame] | 321 | PORT_1, ROUTER_MAC, null, Ethernet.MPLS_UNICAST, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 322 | FWD_MPLS)); |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 323 | ObjectiveTranslation expectedTranslation = buildExpectedTranslation(expectedFlowRules); |
Daniele Moro | f51d0c1 | 2019-07-30 10:43:10 -0700 | [diff] [blame] | 324 | |
| 325 | assertEquals(expectedTranslation, actualTranslation); |
| 326 | } |
| 327 | |
| 328 | /** |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 329 | * Incorrect filtering key or filtering conditions test. |
| 330 | */ |
| 331 | @Test |
| 332 | public void badParamTest() { |
| 333 | // Filtering objective should contains filtering key |
| 334 | FilteringObjective filteringObjective = DefaultFilteringObjective.builder() |
| 335 | .permit() |
| 336 | .addCondition(Criteria.matchVlanId(VLAN_100)) |
| 337 | .fromApp(APP_ID) |
| 338 | .makePermanent() |
| 339 | .add(); |
| 340 | |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 341 | ObjectiveTranslation result1 = translator.translate(filteringObjective); |
| 342 | assertError(ObjectiveError.BADPARAMS, result1); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 343 | |
| 344 | // Filtering objective should use in_port as key |
| 345 | filteringObjective = DefaultFilteringObjective.builder() |
| 346 | .permit() |
| 347 | .withKey(Criteria.matchEthDst(ROUTER_MAC)) |
| 348 | .addCondition(Criteria.matchVlanId(VLAN_100)) |
| 349 | .withMeta(DefaultTrafficTreatment.emptyTreatment()) |
| 350 | .fromApp(APP_ID) |
| 351 | .makePermanent() |
| 352 | .add(); |
| 353 | |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 354 | ObjectiveTranslation result2 = translator.translate(filteringObjective); |
| 355 | assertError(ObjectiveError.BADPARAMS, result2); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 356 | } |
| 357 | |
pierventre | 167d448 | 2021-01-08 17:35:47 +0100 | [diff] [blame] | 358 | /** |
| 359 | * Test port update scenarios for filtering objective. Creates only one rule for |
| 360 | * ingress_port_vlan table. |
| 361 | */ |
| 362 | @Test |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 363 | public void testIsPortUpdate() throws FabricPipelinerException { |
pierventre | 167d448 | 2021-01-08 17:35:47 +0100 | [diff] [blame] | 364 | // Tagged port scenario |
| 365 | FilteringObjective filteringObjective = DefaultFilteringObjective.builder() |
| 366 | .withKey(Criteria.matchInPort(PORT_1)) |
| 367 | .addCondition(Criteria.matchEthDst(ROUTER_MAC)) |
| 368 | .addCondition(Criteria.matchVlanId(VLAN_100)) |
| 369 | .withPriority(PRIORITY) |
| 370 | .fromApp(APP_ID) |
| 371 | .withMeta(DefaultTrafficTreatment.builder() |
| 372 | .writeMetadata(2, 0xffffffffffffffffL) |
| 373 | .build()) |
| 374 | .permit() |
| 375 | .add(); |
| 376 | ObjectiveTranslation actualTranslation = translator.translate(filteringObjective); |
| 377 | Collection<FlowRule> expectedFlowRules = Lists.newArrayList(); |
| 378 | // Ingress port vlan rule |
| 379 | expectedFlowRules.add(buildExpectedVlanInPortRule( |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 380 | PORT_1, VLAN_100, null, VlanId.NONE, PORT_TYPE_EDGE, |
pierventre | 167d448 | 2021-01-08 17:35:47 +0100 | [diff] [blame] | 381 | FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN)); |
| 382 | ObjectiveTranslation expectedTranslation = buildExpectedTranslation(expectedFlowRules); |
| 383 | assertEquals(expectedTranslation, actualTranslation); |
| 384 | |
| 385 | // Untagged port scenario |
| 386 | filteringObjective = DefaultFilteringObjective.builder() |
| 387 | .withKey(Criteria.matchInPort(PORT_1)) |
| 388 | .addCondition(Criteria.matchEthDst(ROUTER_MAC)) |
| 389 | .addCondition(Criteria.matchVlanId(VlanId.NONE)) |
| 390 | .withPriority(PRIORITY) |
| 391 | .fromApp(APP_ID) |
| 392 | .withMeta(DefaultTrafficTreatment.builder() |
| 393 | .pushVlan() |
| 394 | .setVlanId(VLAN_200) |
| 395 | .writeMetadata(2, 0xffffffffffffffffL) |
| 396 | .build()) |
| 397 | .permit() |
| 398 | .add(); |
| 399 | actualTranslation = translator.translate(filteringObjective); |
| 400 | expectedFlowRules = Lists.newArrayList(); |
| 401 | // Ingress port vlan rule |
| 402 | expectedFlowRules.add(buildExpectedVlanInPortRule( |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 403 | PORT_1, VlanId.NONE, null, VLAN_200, PORT_TYPE_EDGE, |
pierventre | 167d448 | 2021-01-08 17:35:47 +0100 | [diff] [blame] | 404 | FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN)); |
| 405 | expectedTranslation = buildExpectedTranslation(expectedFlowRules); |
| 406 | assertEquals(expectedTranslation, actualTranslation); |
| 407 | } |
| 408 | |
Wailok Shum | 4f51bde | 2021-06-11 22:48:41 +0800 | [diff] [blame] | 409 | /** |
| 410 | * Test no more ports scenario for filtering objective. |
| 411 | */ |
| 412 | @Test |
| 413 | public void testNoMorePorts() throws FabricPipelinerException { |
| 414 | // Tagged port scenario |
| 415 | FilteringObjective filteringObjective = DefaultFilteringObjective.builder() |
| 416 | .withKey(Criteria.matchInPort(PORT_1)) |
| 417 | .addCondition(Criteria.matchEthDst(ROUTER_MAC)) |
| 418 | .addCondition(Criteria.matchVlanId(VLAN_100)) |
| 419 | .withPriority(PRIORITY) |
| 420 | .fromApp(APP_ID) |
| 421 | .withMeta(DefaultTrafficTreatment.builder().wipeDeferred().build()) |
| 422 | .permit() |
| 423 | .add(); |
| 424 | ObjectiveTranslation actualTranslation = translator.translate(filteringObjective); |
| 425 | Collection<FlowRule> expectedFlowRules = Lists.newArrayList(); |
| 426 | // Ingress port vlan rule |
| 427 | expectedFlowRules.add(buildExpectedVlanInPortRule( |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 428 | PORT_1, VLAN_100, null, VlanId.NONE, PORT_TYPE_EDGE, |
Wailok Shum | 4f51bde | 2021-06-11 22:48:41 +0800 | [diff] [blame] | 429 | FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN)); |
| 430 | // forwarding classifier ipv4 |
| 431 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
| 432 | PORT_1, |
| 433 | ROUTER_MAC, |
| 434 | null, |
| 435 | Ethernet.TYPE_IPV4, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 436 | FWD_IPV4_ROUTING)); |
Wailok Shum | 4f51bde | 2021-06-11 22:48:41 +0800 | [diff] [blame] | 437 | // forwarding classifier ipv6 |
| 438 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
| 439 | PORT_1, |
| 440 | ROUTER_MAC, |
| 441 | null, |
| 442 | Ethernet.TYPE_IPV6, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 443 | FWD_IPV6_ROUTING)); |
Wailok Shum | 4f51bde | 2021-06-11 22:48:41 +0800 | [diff] [blame] | 444 | // forwarding classifier mpls |
| 445 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
| 446 | PORT_1, |
| 447 | ROUTER_MAC, |
| 448 | null, |
| 449 | Ethernet.MPLS_UNICAST, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 450 | FWD_MPLS)); |
Wailok Shum | 4f51bde | 2021-06-11 22:48:41 +0800 | [diff] [blame] | 451 | |
| 452 | ObjectiveTranslation expectedTranslation = buildExpectedTranslation(expectedFlowRules); |
| 453 | assertEquals(expectedTranslation, actualTranslation); |
| 454 | } |
| 455 | |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 456 | /** |
| 457 | * Test is infra port scenarios for filtering objective. |
| 458 | */ |
| 459 | @Test |
| 460 | public void testIsInfraPort() throws FabricPipelinerException { |
| 461 | // PW transport vlan |
| 462 | FilteringObjective filteringObjective = DefaultFilteringObjective.builder() |
| 463 | .withKey(Criteria.matchInPort(PORT_1)) |
| 464 | .addCondition(Criteria.matchEthDst(ROUTER_MAC)) |
| 465 | .addCondition(Criteria.matchVlanId(VlanId.vlanId((short) DEFAULT_PW_TRANSPORT_VLAN))) |
| 466 | .withPriority(PRIORITY) |
| 467 | .fromApp(APP_ID) |
| 468 | .permit() |
| 469 | .add(); |
| 470 | ObjectiveTranslation actualTranslation = translator.translate(filteringObjective); |
| 471 | |
| 472 | Collection<FlowRule> expectedFlowRules = Lists.newArrayList(); |
| 473 | expectedFlowRules.add(buildExpectedVlanInPortRule( |
| 474 | PORT_1, VlanId.vlanId((short) DEFAULT_PW_TRANSPORT_VLAN), null, VlanId.NONE, |
| 475 | PORT_TYPE_INFRA, FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN)); |
| 476 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
| 477 | PORT_1, |
| 478 | ROUTER_MAC, |
| 479 | null, |
| 480 | Ethernet.TYPE_IPV4, |
| 481 | FWD_IPV4_ROUTING)); |
| 482 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
| 483 | PORT_1, |
| 484 | ROUTER_MAC, |
| 485 | null, |
| 486 | Ethernet.TYPE_IPV6, |
| 487 | FWD_IPV6_ROUTING)); |
| 488 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
| 489 | PORT_1, |
| 490 | ROUTER_MAC, |
| 491 | null, |
| 492 | Ethernet.MPLS_UNICAST, |
| 493 | FWD_MPLS)); |
| 494 | |
| 495 | ObjectiveTranslation expectedTranslation = buildExpectedTranslation(expectedFlowRules); |
| 496 | assertEquals(expectedTranslation, actualTranslation); |
| 497 | |
| 498 | // Untagged port scenario |
| 499 | filteringObjective = DefaultFilteringObjective.builder() |
| 500 | .withKey(Criteria.matchInPort(PORT_1)) |
| 501 | .addCondition(Criteria.matchEthDst(ROUTER_MAC)) |
| 502 | .addCondition(Criteria.matchVlanId(VlanId.NONE)) |
| 503 | .withPriority(PRIORITY) |
| 504 | .fromApp(APP_ID) |
| 505 | .withMeta(DefaultTrafficTreatment.builder() |
| 506 | .pushVlan() |
| 507 | .setVlanId(VlanId.vlanId((short) DEFAULT_VLAN)) |
| 508 | .build()) |
| 509 | .permit() |
| 510 | .add(); |
| 511 | actualTranslation = translator.translate(filteringObjective); |
| 512 | expectedFlowRules = Lists.newArrayList(); |
| 513 | expectedFlowRules.add(buildExpectedVlanInPortRule( |
| 514 | PORT_1, null, null, VlanId.vlanId((short) DEFAULT_VLAN), |
| 515 | PORT_TYPE_INFRA, FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN)); |
| 516 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
| 517 | PORT_1, |
| 518 | ROUTER_MAC, |
| 519 | null, |
| 520 | Ethernet.TYPE_IPV4, |
| 521 | FWD_IPV4_ROUTING)); |
| 522 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
| 523 | PORT_1, |
| 524 | ROUTER_MAC, |
| 525 | null, |
| 526 | Ethernet.TYPE_IPV6, |
| 527 | FWD_IPV6_ROUTING)); |
| 528 | expectedFlowRules.addAll(buildExpectedFwdClassifierRule( |
| 529 | PORT_1, |
| 530 | ROUTER_MAC, |
| 531 | null, |
| 532 | Ethernet.MPLS_UNICAST, |
| 533 | FWD_MPLS)); |
| 534 | |
| 535 | expectedTranslation = buildExpectedTranslation(expectedFlowRules); |
| 536 | assertEquals(expectedTranslation, actualTranslation); |
| 537 | } |
| 538 | |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 539 | /* Utilities */ |
| 540 | |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 541 | private void assertError(ObjectiveError error, ObjectiveTranslation actualTranslation) { |
| 542 | ObjectiveTranslation expectedTranslation = ObjectiveTranslation.ofError(error); |
| 543 | assertEquals(expectedTranslation, actualTranslation); |
| 544 | } |
| 545 | |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 546 | private FilteringObjective buildFilteringObjective(MacAddress dstMac) { |
| 547 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
| 548 | .pushVlan() |
| 549 | .setVlanId(VLAN_100) |
| 550 | .build(); |
| 551 | DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder() |
| 552 | .permit() |
| 553 | .withPriority(PRIORITY) |
| 554 | .withKey(Criteria.matchInPort(PORT_1)); |
| 555 | if (dstMac != null) { |
| 556 | builder.addCondition(Criteria.matchEthDst(dstMac)); |
| 557 | } |
| 558 | |
| 559 | builder.addCondition(Criteria.matchVlanId(VlanId.NONE)) |
| 560 | .withMeta(treatment) |
| 561 | .fromApp(APP_ID) |
| 562 | .makePermanent(); |
| 563 | return builder.add(); |
| 564 | } |
| 565 | |
Daniele Moro | 7c3a002 | 2019-07-12 13:38:34 -0700 | [diff] [blame] | 566 | private FlowRule buildExpectedVlanInPortRule(PortNumber inPort, |
| 567 | VlanId vlanId, |
| 568 | VlanId innerVlanId, |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 569 | VlanId internalVlan, |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 570 | byte portType, |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 571 | TableId tableId) { |
| 572 | |
| 573 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder() |
| 574 | .matchInPort(inPort); |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 575 | PiAction piAction; |
Daniele Moro | 7c3a002 | 2019-07-12 13:38:34 -0700 | [diff] [blame] | 576 | selector.matchPi(buildPiCriterionVlan(vlanId, innerVlanId)); |
| 577 | if (!vlanValid(vlanId)) { |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 578 | piAction = PiAction.builder() |
| 579 | .withId(FabricConstants.FABRIC_INGRESS_FILTERING_PERMIT_WITH_INTERNAL_VLAN) |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 580 | .withParameter(new PiActionParam(FabricConstants.VLAN_ID, internalVlan.toShort())) |
| 581 | .withParameter(new PiActionParam(FabricConstants.PORT_TYPE, portType)) |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 582 | .build(); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 583 | } else { |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 584 | selector.matchVlanId(vlanId); |
Daniele Moro | f51d0c1 | 2019-07-30 10:43:10 -0700 | [diff] [blame] | 585 | if (vlanValid(innerVlanId)) { |
| 586 | selector.matchInnerVlanId(innerVlanId); |
| 587 | } |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 588 | piAction = PiAction.builder() |
| 589 | .withId(FabricConstants.FABRIC_INGRESS_FILTERING_PERMIT) |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 590 | .withParameter(new PiActionParam(FabricConstants.PORT_TYPE, portType)) |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 591 | .build(); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 592 | } |
| 593 | |
| 594 | return DefaultFlowRule.builder() |
| 595 | .withPriority(PRIORITY) |
| 596 | .withSelector(selector.build()) |
Carmelo Cascone | b5324e7 | 2018-11-25 02:26:32 -0800 | [diff] [blame] | 597 | .withTreatment(DefaultTrafficTreatment.builder() |
| 598 | .piTableAction(piAction).build()) |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 599 | .fromApp(APP_ID) |
| 600 | .forDevice(DEVICE_ID) |
| 601 | .makePermanent() |
| 602 | .forTable(tableId) |
| 603 | .build(); |
| 604 | } |
| 605 | |
Daniele Moro | 7c3a002 | 2019-07-12 13:38:34 -0700 | [diff] [blame] | 606 | private boolean vlanValid(VlanId vlanId) { |
| 607 | return (vlanId != null && !vlanId.equals(VlanId.NONE)); |
| 608 | } |
| 609 | |
| 610 | private PiCriterion buildPiCriterionVlan(VlanId vlanId, |
| 611 | VlanId innerVlanId) { |
| 612 | PiCriterion.Builder piCriterionBuilder = PiCriterion.builder() |
| 613 | .matchExact(FabricConstants.HDR_VLAN_IS_VALID, |
| 614 | vlanValid(vlanId) ? ONE : ZERO); |
| 615 | return piCriterionBuilder.build(); |
| 616 | } |
| 617 | |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 618 | private Collection<FlowRule> buildExpectedFwdClassifierRule(PortNumber inPort, |
| 619 | MacAddress dstMac, |
| 620 | MacAddress dstMacMask, |
| 621 | short ethType, |
| 622 | byte fwdClass) { |
Yi Tseng | 43ee7e8 | 2018-04-12 16:37:34 +0800 | [diff] [blame] | 623 | PiActionParam classParam = new PiActionParam(FabricConstants.FWD_TYPE, |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 624 | ImmutableByteSequence.copyFrom(fwdClass)); |
| 625 | PiAction fwdClassifierAction = PiAction.builder() |
Yi Tseng | 43ee7e8 | 2018-04-12 16:37:34 +0800 | [diff] [blame] | 626 | .withId(FabricConstants.FABRIC_INGRESS_FILTERING_SET_FORWARDING_TYPE) |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 627 | .withParameter(classParam) |
| 628 | .build(); |
| 629 | TrafficTreatment treatment = DefaultTrafficTreatment.builder() |
| 630 | .piTableAction(fwdClassifierAction) |
| 631 | .build(); |
| 632 | |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 633 | TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder() |
| 634 | .matchInPort(inPort); |
| 635 | if (dstMacMask != null) { |
| 636 | sbuilder.matchEthDstMasked(dstMac, dstMacMask); |
| 637 | } else { |
| 638 | sbuilder.matchEthDstMasked(dstMac, MacAddress.EXACT_MASK); |
| 639 | } |
| 640 | // Special case for MPLS UNICAST forwarding, need to build 2 rules for MPLS+IPv4 and MPLS+IPv6 |
| 641 | if (ethType == Ethernet.MPLS_UNICAST) { |
| 642 | return buildExpectedFwdClassifierRulesMpls(fwdClassifierAction, treatment, sbuilder); |
| 643 | } |
| 644 | sbuilder.matchPi(PiCriterion.builder() |
| 645 | .matchExact(FabricConstants.HDR_IP_ETH_TYPE, ethType) |
| 646 | .build()); |
| 647 | TrafficSelector selector = sbuilder.build(); |
| 648 | return List.of(DefaultFlowRule.builder() |
| 649 | .withPriority(PRIORITY) |
| 650 | .withSelector(selector) |
| 651 | .withTreatment(treatment) |
| 652 | .fromApp(APP_ID) |
| 653 | .forDevice(DEVICE_ID) |
| 654 | .makePermanent() |
| 655 | .forTable(FabricConstants.FABRIC_INGRESS_FILTERING_FWD_CLASSIFIER) |
| 656 | .build()); |
| 657 | } |
| 658 | |
| 659 | private Collection<FlowRule> buildExpectedFwdClassifierRulesMpls(PiAction fwdClassifierAction, |
| 660 | TrafficTreatment treatment, |
| 661 | TrafficSelector.Builder selectorBuilder) { |
| 662 | |
| 663 | Collection<FlowRule> flowRules = Lists.newArrayList(); |
| 664 | TrafficSelector selectorIpv4 = selectorBuilder |
| 665 | .add(PiCriterion.builder() |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 666 | .matchTernary(FabricConstants.HDR_ETH_TYPE, Ethernet.MPLS_UNICAST, ETH_TYPE_EXACT_MASK) |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 667 | .matchExact(FabricConstants.HDR_IP_ETH_TYPE, Ethernet.TYPE_IPV4) |
| 668 | .build()) |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 669 | .build(); |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 670 | TrafficSelector selectorIpv6 = selectorBuilder |
| 671 | .add(PiCriterion.builder() |
Wailok Shum | fb7e787 | 2021-06-18 17:30:08 +0800 | [diff] [blame] | 672 | .matchTernary(FabricConstants.HDR_ETH_TYPE, Ethernet.MPLS_UNICAST, ETH_TYPE_EXACT_MASK) |
Daniele Moro | 5a2de71 | 2019-09-24 14:34:07 -0700 | [diff] [blame] | 673 | .matchExact(FabricConstants.HDR_IP_ETH_TYPE, Ethernet.TYPE_IPV6) |
| 674 | .build()) |
| 675 | .build(); |
| 676 | flowRules.add(DefaultFlowRule.builder() |
| 677 | .withPriority(PRIORITY + 1) |
| 678 | .withSelector(selectorIpv4) |
| 679 | .withTreatment(treatment) |
| 680 | .fromApp(APP_ID) |
| 681 | .forDevice(DEVICE_ID) |
| 682 | .makePermanent() |
| 683 | .forTable(FabricConstants.FABRIC_INGRESS_FILTERING_FWD_CLASSIFIER) |
| 684 | .build()); |
| 685 | flowRules.add(DefaultFlowRule.builder() |
| 686 | .withPriority(PRIORITY + 1) |
| 687 | .withSelector(selectorIpv6) |
| 688 | .withTreatment(treatment) |
| 689 | .fromApp(APP_ID) |
| 690 | .forDevice(DEVICE_ID) |
| 691 | .makePermanent() |
| 692 | .forTable(FabricConstants.FABRIC_INGRESS_FILTERING_FWD_CLASSIFIER) |
| 693 | .build()); |
| 694 | return flowRules; |
| 695 | } |
| 696 | |
| 697 | private ObjectiveTranslation buildExpectedTranslation(Collection<FlowRule> flowRules) |
| 698 | throws FabricPipelinerException { |
| 699 | ObjectiveTranslation.Builder expectedTranslationBuilder = ObjectiveTranslation.builder(); |
| 700 | for (FlowRule flowRule : flowRules) { |
| 701 | expectedTranslationBuilder.addFlowRule(flowRule); |
| 702 | } |
| 703 | return expectedTranslationBuilder.build(); |
Yi Tseng | 0b80972 | 2017-11-03 10:23:26 -0700 | [diff] [blame] | 704 | } |
| 705 | } |