blob: 5e126cccd9daf85200543fe85be004d5d083c537 [file] [log] [blame]
Yi Tseng0b809722017-11-03 10:23:26 -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
Carmelo Cascone356ab8b2019-09-25 01:02:53 -070017package org.onosproject.pipelines.fabric.impl.behaviour.pipeliner;
Yi Tseng0b809722017-11-03 10:23:26 -070018
Daniele Moro5a2de712019-09-24 14:34:07 -070019import com.google.common.collect.Lists;
Carmelo Casconeb5324e72018-11-25 02:26:32 -080020import org.junit.Before;
Yi Tseng0b809722017-11-03 10:23:26 -070021import org.junit.Test;
22import org.onlab.packet.Ethernet;
23import org.onlab.packet.MacAddress;
24import org.onlab.packet.VlanId;
25import org.onlab.util.ImmutableByteSequence;
26import org.onosproject.net.PortNumber;
27import org.onosproject.net.flow.DefaultFlowRule;
28import org.onosproject.net.flow.DefaultTrafficSelector;
29import org.onosproject.net.flow.DefaultTrafficTreatment;
30import org.onosproject.net.flow.FlowRule;
31import org.onosproject.net.flow.TableId;
32import org.onosproject.net.flow.TrafficSelector;
33import org.onosproject.net.flow.TrafficTreatment;
34import org.onosproject.net.flow.criteria.Criteria;
Daniele Moro7c3a0022019-07-12 13:38:34 -070035import org.onosproject.net.flow.criteria.PiCriterion;
Yi Tseng0b809722017-11-03 10:23:26 -070036import org.onosproject.net.flowobjective.DefaultFilteringObjective;
37import org.onosproject.net.flowobjective.FilteringObjective;
38import org.onosproject.net.flowobjective.ObjectiveError;
Yi Tseng0b809722017-11-03 10:23:26 -070039import org.onosproject.net.pi.runtime.PiAction;
40import org.onosproject.net.pi.runtime.PiActionParam;
Carmelo Cascone2102bfb2020-12-04 16:54:24 -080041import org.onosproject.pipelines.fabric.FabricConstants;
Yi Tseng0b809722017-11-03 10:23:26 -070042
Daniele Moro5a2de712019-09-24 14:34:07 -070043import java.util.Collection;
44import java.util.List;
45
Yi Tseng0b809722017-11-03 10:23:26 -070046import static org.junit.Assert.assertEquals;
Wailok Shumfb7e7872021-06-18 17:30:08 +080047import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.DEFAULT_PW_TRANSPORT_VLAN;
48import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.DEFAULT_VLAN;
pierventre4d29d3c2021-08-27 17:20:00 +020049import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.EDGE_PORT;
Wailok Shumfb7e7872021-06-18 17:30:08 +080050import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.ETH_TYPE_EXACT_MASK;
51import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.FWD_IPV4_ROUTING;
52import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.FWD_IPV6_ROUTING;
53import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.FWD_MPLS;
pierventre4d29d3c2021-08-27 17:20:00 +020054import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.INFRA_PORT;
Wailok Shumfb7e7872021-06-18 17:30:08 +080055import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.ONE;
pierventre4d29d3c2021-08-27 17:20:00 +020056import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.PAIR_PORT;
Wailok Shumfb7e7872021-06-18 17:30:08 +080057import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.PORT_TYPE_EDGE;
58import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.PORT_TYPE_INFRA;
59import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.ZERO;
Yi Tseng0b809722017-11-03 10:23:26 -070060
61/**
62 * Test cases for fabric.p4 pipeline filtering control block.
63 */
Carmelo Cascone2388cc12021-05-26 19:30:30 +020064public class FilteringObjectiveTranslatorTest extends BaseObjectiveTranslatorTest {
Yi Tseng0b809722017-11-03 10:23:26 -070065
Carmelo Casconeb5324e72018-11-25 02:26:32 -080066 private FilteringObjectiveTranslator translator;
67
68 @Before
69 public void setup() {
70 super.doSetup();
71 translator = new FilteringObjectiveTranslator(DEVICE_ID, capabilitiesHashed);
72 }
73
Yi Tseng0b809722017-11-03 10:23:26 -070074 /**
75 * Creates one rule for ingress_port_vlan table and 3 rules for
Carmelo Cascone356ab8b2019-09-25 01:02:53 -070076 * fwd_classifier table (IPv4, IPv6 and MPLS unicast) when the condition is
77 * VLAN + MAC.
Yi Tseng0b809722017-11-03 10:23:26 -070078 */
79 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -080080 public void testRouterMacAndVlanFilter() throws FabricPipelinerException {
pierventre4d29d3c2021-08-27 17:20:00 +020081 FilteringObjective filteringObjective = buildFilteringObjective(ROUTER_MAC, EDGE_PORT);
Carmelo Casconeb5324e72018-11-25 02:26:32 -080082 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
Daniele Moro5a2de712019-09-24 14:34:07 -070083 Collection<FlowRule> expectedFlowRules = Lists.newArrayList();
Yi Tseng0b809722017-11-03 10:23:26 -070084 // in port vlan flow rule
Daniele Moro5a2de712019-09-24 14:34:07 -070085 expectedFlowRules.add(buildExpectedVlanInPortRule(
Carmelo Cascone356ab8b2019-09-25 01:02:53 -070086 PORT_1,
87 VlanId.NONE,
88 VlanId.NONE,
89 VLAN_100,
Wailok Shumfb7e7872021-06-18 17:30:08 +080090 PORT_TYPE_EDGE,
Daniele Moro5a2de712019-09-24 14:34:07 -070091 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN));
Yi Tseng0b809722017-11-03 10:23:26 -070092
93 // forwarding classifier ipv4
Daniele Moro5a2de712019-09-24 14:34:07 -070094 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
Carmelo Cascone356ab8b2019-09-25 01:02:53 -070095 PORT_1,
96 ROUTER_MAC,
97 null,
98 Ethernet.TYPE_IPV4,
Wailok Shumfb7e7872021-06-18 17:30:08 +080099 FWD_IPV4_ROUTING));
Yi Tseng0b809722017-11-03 10:23:26 -0700100
101 // forwarding classifier ipv6
Daniele Moro5a2de712019-09-24 14:34:07 -0700102 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700103 PORT_1,
104 ROUTER_MAC,
105 null,
106 Ethernet.TYPE_IPV6,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800107 FWD_IPV6_ROUTING));
Yi Tseng0b809722017-11-03 10:23:26 -0700108
109 // forwarding classifier mpls
Daniele Moro5a2de712019-09-24 14:34:07 -0700110 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700111 PORT_1,
112 ROUTER_MAC,
113 null,
114 Ethernet.MPLS_UNICAST,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800115 FWD_MPLS));
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800116
Daniele Moro5a2de712019-09-24 14:34:07 -0700117// ObjectiveTranslation.Builder expectedTranslationBuilder = ObjectiveTranslation.builder()
118// .addFlowRule(inportFlowRuleExpected);
119// for (FlowRule flowRule : classifierV4FlowRuleExpected) {
120// expectedTranslationBuilder.addFlowRule(flowRule);
121// }
122// for (FlowRule flowRule : classifierV6FlowRuleExpected) {
123// expectedTranslationBuilder.addFlowRule(flowRule);
124// }
125// for (FlowRule flowRule : classifierMplsFlowRuleExpected) {
126// expectedTranslationBuilder.addFlowRule(flowRule);
127// }
128 ObjectiveTranslation expectedTranslation = buildExpectedTranslation(expectedFlowRules);
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800129
130 assertEquals(expectedTranslation, actualTranslation);
Yi Tseng0b809722017-11-03 10:23:26 -0700131 }
132
133 /**
134 * Creates one rule for ingress_port_vlan table and one rule for
135 * fwd_classifier table (IPv4 multicast) when the condition is ipv4
136 * multicast mac address.
137 */
138 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800139 public void testIpv4MulticastFwdClass() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700140 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
141 .pushVlan()
142 .setVlanId(VLAN_100)
pierventre4d29d3c2021-08-27 17:20:00 +0200143 .writeMetadata(EDGE_PORT, 0xffffffffffffffffL)
Yi Tseng0b809722017-11-03 10:23:26 -0700144 .build();
145 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
146 .permit()
147 .withPriority(PRIORITY)
148 .withKey(Criteria.matchInPort(PORT_1))
Charles Chan384aea22018-08-23 22:08:02 -0700149 .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV4_MULTICAST, MacAddress.IPV4_MULTICAST_MASK))
Yi Tseng0b809722017-11-03 10:23:26 -0700150 .addCondition(Criteria.matchVlanId(VlanId.NONE))
151 .withMeta(treatment)
152 .fromApp(APP_ID)
153 .makePermanent()
154 .add();
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800155 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
Daniele Moro5a2de712019-09-24 14:34:07 -0700156 List<FlowRule> expectedFlowRules = Lists.newArrayList();
Yi Tseng0b809722017-11-03 10:23:26 -0700157 // in port vlan flow rule
Daniele Moro5a2de712019-09-24 14:34:07 -0700158 expectedFlowRules.add(buildExpectedVlanInPortRule(
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700159 PORT_1,
160 VlanId.NONE,
161 VlanId.NONE,
162 VLAN_100,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800163 PORT_TYPE_EDGE,
Daniele Moro5a2de712019-09-24 14:34:07 -0700164 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN));
Yi Tseng0b809722017-11-03 10:23:26 -0700165
166 // forwarding classifier
Daniele Moro5a2de712019-09-24 14:34:07 -0700167 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700168 PORT_1,
169 MacAddress.IPV4_MULTICAST,
170 MacAddress.IPV4_MULTICAST_MASK,
171 Ethernet.TYPE_IPV4,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800172 FWD_IPV4_ROUTING));
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800173
Daniele Moro5a2de712019-09-24 14:34:07 -0700174 ObjectiveTranslation expectedTranslation = buildExpectedTranslation(expectedFlowRules);
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800175
176 assertEquals(expectedTranslation, actualTranslation);
Yi Tseng0b809722017-11-03 10:23:26 -0700177 }
178
179 /**
180 * Creates one rule for ingress_port_vlan table and one rule for
181 * fwd_classifier table (IPv6 multicast) when the condition is ipv6
182 * multicast mac address.
183 */
184 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800185 public void testIpv6MulticastFwdClass() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700186 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
187 .pushVlan()
188 .setVlanId(VLAN_100)
pierventre4d29d3c2021-08-27 17:20:00 +0200189 .writeMetadata(EDGE_PORT, 0xffffffffffffffffL)
Yi Tseng0b809722017-11-03 10:23:26 -0700190 .build();
191 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
192 .permit()
193 .withPriority(PRIORITY)
194 .withKey(Criteria.matchInPort(PORT_1))
Charles Chan384aea22018-08-23 22:08:02 -0700195 .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV6_MULTICAST, MacAddress.IPV6_MULTICAST_MASK))
Yi Tseng0b809722017-11-03 10:23:26 -0700196 .addCondition(Criteria.matchVlanId(VlanId.NONE))
197 .withMeta(treatment)
198 .fromApp(APP_ID)
199 .makePermanent()
200 .add();
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800201 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
Daniele Moro5a2de712019-09-24 14:34:07 -0700202 Collection<FlowRule> flowRules = Lists.newArrayList();
Yi Tseng0b809722017-11-03 10:23:26 -0700203 // in port vlan flow rule
Daniele Moro5a2de712019-09-24 14:34:07 -0700204 flowRules.add(buildExpectedVlanInPortRule(
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700205 PORT_1,
206 VlanId.NONE,
207 VlanId.NONE,
208 VLAN_100,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800209 PORT_TYPE_EDGE,
Daniele Moro5a2de712019-09-24 14:34:07 -0700210 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN));
Yi Tseng0b809722017-11-03 10:23:26 -0700211
Daniele Moro5a2de712019-09-24 14:34:07 -0700212 flowRules.addAll(buildExpectedFwdClassifierRule(
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700213 PORT_1,
214 MacAddress.IPV6_MULTICAST,
215 MacAddress.IPV6_MULTICAST_MASK,
216 Ethernet.TYPE_IPV6,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800217 FWD_IPV6_ROUTING));
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800218
Daniele Moro5a2de712019-09-24 14:34:07 -0700219 ObjectiveTranslation expectedTranslation = buildExpectedTranslation(flowRules);
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800220
221 assertEquals(expectedTranslation, actualTranslation);
Yi Tseng0b809722017-11-03 10:23:26 -0700222 }
223
224 /**
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700225 * Creates only one rule for ingress_port_vlan table if there is no
226 * condition of destination mac address. The packet will be handled by
227 * bridging table by default.
Yi Tseng0b809722017-11-03 10:23:26 -0700228 */
229 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800230 public void testFwdBridging() throws Exception {
pierventre4d29d3c2021-08-27 17:20:00 +0200231 FilteringObjective filteringObjective = buildFilteringObjective(null, EDGE_PORT);
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800232 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
Yi Tseng0b809722017-11-03 10:23:26 -0700233
234 // in port vlan flow rule
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700235 FlowRule flowRuleExpected = buildExpectedVlanInPortRule(
236 PORT_1,
237 VlanId.NONE,
238 VlanId.NONE,
239 VLAN_100,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800240 PORT_TYPE_EDGE,
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700241 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
Yi Tseng0b809722017-11-03 10:23:26 -0700242
243 // No rules in forwarding classifier, will do default action: set fwd type to bridging
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800244
245 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
246 .addFlowRule(flowRuleExpected)
247 .build();
248
249 assertEquals(expectedTranslation, actualTranslation);
Yi Tseng0b809722017-11-03 10:23:26 -0700250 }
251
252 /**
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800253 * Test DENY objective.
Yi Tseng0b809722017-11-03 10:23:26 -0700254 */
255 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800256 public void testDenyObjective() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700257 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
258 .deny()
259 .withKey(Criteria.matchInPort(PORT_1))
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800260 .addCondition(Criteria.matchVlanId(VlanId.NONE))
Yi Tseng0b809722017-11-03 10:23:26 -0700261 .fromApp(APP_ID)
262 .makePermanent()
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800263 .withPriority(PRIORITY)
Yi Tseng0b809722017-11-03 10:23:26 -0700264 .add();
265
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800266 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
Yi Tseng0b809722017-11-03 10:23:26 -0700267
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800268 TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
269 .matchInPort(PORT_1)
Daniele Moro7c3a0022019-07-12 13:38:34 -0700270 .matchPi(buildPiCriterionVlan(null, null));
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800271 PiAction piAction = PiAction.builder()
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700272 .withId(FabricConstants.FABRIC_INGRESS_FILTERING_DENY)
273 .build();
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800274 FlowRule expectedFlowRule = DefaultFlowRule.builder()
275 .withPriority(PRIORITY)
276 .withSelector(selector.build())
277 .withTreatment(DefaultTrafficTreatment.builder()
278 .piTableAction(piAction).build())
279 .fromApp(APP_ID)
280 .forDevice(DEVICE_ID)
281 .makePermanent()
282 .forTable(FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN)
283 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700284
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800285 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
286 .addFlowRule(expectedFlowRule)
287 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700288
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800289 assertEquals(expectedTranslation, actualTranslation);
290
Yi Tseng0b809722017-11-03 10:23:26 -0700291 }
292
293 /**
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700294 * Test double VLAN pop filtering objective Creates one rule for
295 * ingress_port_vlan table and 3 rules for fwd_classifier table (IPv4, IPv6
296 * and MPLS unicast) when the condition is MAC + VLAN + INNER_VLAN.
Daniele Morof51d0c12019-07-30 10:43:10 -0700297 */
298 @Test
299 public void testPopVlan() throws FabricPipelinerException {
300 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
301 .withKey(Criteria.matchInPort(PORT_1))
302 .addCondition(Criteria.matchEthDst(ROUTER_MAC))
303 .addCondition(Criteria.matchVlanId(VLAN_100))
304 .addCondition(Criteria.matchInnerVlanId(VLAN_200))
305 .withPriority(PRIORITY)
306 .fromApp(APP_ID)
307 .withMeta(DefaultTrafficTreatment.builder()
pierventre4d29d3c2021-08-27 17:20:00 +0200308 .popVlan()
309 .writeMetadata(EDGE_PORT, 0xffffffffffffffffL)
310 .build())
Daniele Morof51d0c12019-07-30 10:43:10 -0700311 .permit()
312 .add();
313 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
Daniele Moro5a2de712019-09-24 14:34:07 -0700314 Collection<FlowRule> expectedFlowRules = Lists.newArrayList();
Daniele Morof51d0c12019-07-30 10:43:10 -0700315 // Ingress port vlan rule
Daniele Moro5a2de712019-09-24 14:34:07 -0700316 expectedFlowRules.add(buildExpectedVlanInPortRule(
Wailok Shumfb7e7872021-06-18 17:30:08 +0800317 PORT_1, VLAN_100, VLAN_200, VlanId.NONE, PORT_TYPE_EDGE,
Daniele Moro5a2de712019-09-24 14:34:07 -0700318 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN));
Daniele Morof51d0c12019-07-30 10:43:10 -0700319 // Forwarding classifier rules (ipv6, ipv4, mpls)
Daniele Moro5a2de712019-09-24 14:34:07 -0700320 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700321 PORT_1, ROUTER_MAC, null, Ethernet.TYPE_IPV4,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800322 FWD_IPV4_ROUTING));
Daniele Moro5a2de712019-09-24 14:34:07 -0700323 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700324 PORT_1, ROUTER_MAC, null, Ethernet.TYPE_IPV6,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800325 FWD_IPV6_ROUTING));
Daniele Moro5a2de712019-09-24 14:34:07 -0700326 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700327 PORT_1, ROUTER_MAC, null, Ethernet.MPLS_UNICAST,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800328 FWD_MPLS));
Daniele Moro5a2de712019-09-24 14:34:07 -0700329 ObjectiveTranslation expectedTranslation = buildExpectedTranslation(expectedFlowRules);
Daniele Morof51d0c12019-07-30 10:43:10 -0700330
331 assertEquals(expectedTranslation, actualTranslation);
332 }
333
334 /**
Yi Tseng0b809722017-11-03 10:23:26 -0700335 * Incorrect filtering key or filtering conditions test.
336 */
337 @Test
338 public void badParamTest() {
339 // Filtering objective should contains filtering key
340 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
341 .permit()
342 .addCondition(Criteria.matchVlanId(VLAN_100))
343 .fromApp(APP_ID)
344 .makePermanent()
345 .add();
346
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800347 ObjectiveTranslation result1 = translator.translate(filteringObjective);
348 assertError(ObjectiveError.BADPARAMS, result1);
Yi Tseng0b809722017-11-03 10:23:26 -0700349
350 // Filtering objective should use in_port as key
351 filteringObjective = DefaultFilteringObjective.builder()
352 .permit()
353 .withKey(Criteria.matchEthDst(ROUTER_MAC))
354 .addCondition(Criteria.matchVlanId(VLAN_100))
355 .withMeta(DefaultTrafficTreatment.emptyTreatment())
356 .fromApp(APP_ID)
357 .makePermanent()
358 .add();
359
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800360 ObjectiveTranslation result2 = translator.translate(filteringObjective);
361 assertError(ObjectiveError.BADPARAMS, result2);
Yi Tseng0b809722017-11-03 10:23:26 -0700362 }
363
pierventre167d4482021-01-08 17:35:47 +0100364 /**
365 * Test port update scenarios for filtering objective. Creates only one rule for
366 * ingress_port_vlan table.
367 */
368 @Test
Wailok Shumfb7e7872021-06-18 17:30:08 +0800369 public void testIsPortUpdate() throws FabricPipelinerException {
pierventre167d4482021-01-08 17:35:47 +0100370 // Tagged port scenario
371 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
372 .withKey(Criteria.matchInPort(PORT_1))
373 .addCondition(Criteria.matchEthDst(ROUTER_MAC))
374 .addCondition(Criteria.matchVlanId(VLAN_100))
375 .withPriority(PRIORITY)
376 .fromApp(APP_ID)
377 .withMeta(DefaultTrafficTreatment.builder()
pierventre4d29d3c2021-08-27 17:20:00 +0200378 .writeMetadata(10, 0xffffffffffffffffL)
pierventre167d4482021-01-08 17:35:47 +0100379 .build())
380 .permit()
381 .add();
382 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
383 Collection<FlowRule> expectedFlowRules = Lists.newArrayList();
384 // Ingress port vlan rule
385 expectedFlowRules.add(buildExpectedVlanInPortRule(
Wailok Shumfb7e7872021-06-18 17:30:08 +0800386 PORT_1, VLAN_100, null, VlanId.NONE, PORT_TYPE_EDGE,
pierventre167d4482021-01-08 17:35:47 +0100387 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN));
388 ObjectiveTranslation expectedTranslation = buildExpectedTranslation(expectedFlowRules);
389 assertEquals(expectedTranslation, actualTranslation);
390
391 // Untagged port scenario
392 filteringObjective = DefaultFilteringObjective.builder()
393 .withKey(Criteria.matchInPort(PORT_1))
394 .addCondition(Criteria.matchEthDst(ROUTER_MAC))
395 .addCondition(Criteria.matchVlanId(VlanId.NONE))
396 .withPriority(PRIORITY)
397 .fromApp(APP_ID)
398 .withMeta(DefaultTrafficTreatment.builder()
399 .pushVlan()
400 .setVlanId(VLAN_200)
pierventre4d29d3c2021-08-27 17:20:00 +0200401 .writeMetadata(10, 0xffffffffffffffffL)
pierventre167d4482021-01-08 17:35:47 +0100402 .build())
403 .permit()
404 .add();
405 actualTranslation = translator.translate(filteringObjective);
406 expectedFlowRules = Lists.newArrayList();
407 // Ingress port vlan rule
408 expectedFlowRules.add(buildExpectedVlanInPortRule(
Wailok Shumfb7e7872021-06-18 17:30:08 +0800409 PORT_1, VlanId.NONE, null, VLAN_200, PORT_TYPE_EDGE,
pierventre167d4482021-01-08 17:35:47 +0100410 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN));
411 expectedTranslation = buildExpectedTranslation(expectedFlowRules);
412 assertEquals(expectedTranslation, actualTranslation);
413 }
414
Wailok Shum4f51bde2021-06-11 22:48:41 +0800415 /**
416 * Test no more ports scenario for filtering objective.
417 */
418 @Test
419 public void testNoMorePorts() throws FabricPipelinerException {
420 // Tagged port scenario
421 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
422 .withKey(Criteria.matchInPort(PORT_1))
423 .addCondition(Criteria.matchEthDst(ROUTER_MAC))
424 .addCondition(Criteria.matchVlanId(VLAN_100))
425 .withPriority(PRIORITY)
426 .fromApp(APP_ID)
pierventre4d29d3c2021-08-27 17:20:00 +0200427 .withMeta(DefaultTrafficTreatment.builder()
428 .writeMetadata(EDGE_PORT, 0xffffffffffffffffL)
429 .wipeDeferred()
430 .build())
Wailok Shum4f51bde2021-06-11 22:48:41 +0800431 .permit()
432 .add();
433 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
434 Collection<FlowRule> expectedFlowRules = Lists.newArrayList();
435 // Ingress port vlan rule
436 expectedFlowRules.add(buildExpectedVlanInPortRule(
Wailok Shumfb7e7872021-06-18 17:30:08 +0800437 PORT_1, VLAN_100, null, VlanId.NONE, PORT_TYPE_EDGE,
Wailok Shum4f51bde2021-06-11 22:48:41 +0800438 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN));
439 // forwarding classifier ipv4
440 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
441 PORT_1,
442 ROUTER_MAC,
443 null,
444 Ethernet.TYPE_IPV4,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800445 FWD_IPV4_ROUTING));
Wailok Shum4f51bde2021-06-11 22:48:41 +0800446 // forwarding classifier ipv6
447 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
448 PORT_1,
449 ROUTER_MAC,
450 null,
451 Ethernet.TYPE_IPV6,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800452 FWD_IPV6_ROUTING));
Wailok Shum4f51bde2021-06-11 22:48:41 +0800453 // forwarding classifier mpls
454 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
455 PORT_1,
456 ROUTER_MAC,
457 null,
458 Ethernet.MPLS_UNICAST,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800459 FWD_MPLS));
Wailok Shum4f51bde2021-06-11 22:48:41 +0800460
461 ObjectiveTranslation expectedTranslation = buildExpectedTranslation(expectedFlowRules);
462 assertEquals(expectedTranslation, actualTranslation);
463 }
464
Wailok Shumfb7e7872021-06-18 17:30:08 +0800465 /**
466 * Test is infra port scenarios for filtering objective.
467 */
468 @Test
469 public void testIsInfraPort() throws FabricPipelinerException {
470 // PW transport vlan
471 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
472 .withKey(Criteria.matchInPort(PORT_1))
473 .addCondition(Criteria.matchEthDst(ROUTER_MAC))
474 .addCondition(Criteria.matchVlanId(VlanId.vlanId((short) DEFAULT_PW_TRANSPORT_VLAN)))
475 .withPriority(PRIORITY)
pierventre4d29d3c2021-08-27 17:20:00 +0200476 .withMeta(DefaultTrafficTreatment.builder()
477 .writeMetadata(INFRA_PORT, 0xffffffffffffffffL)
478 .build())
Wailok Shumfb7e7872021-06-18 17:30:08 +0800479 .fromApp(APP_ID)
480 .permit()
481 .add();
482 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
483
484 Collection<FlowRule> expectedFlowRules = Lists.newArrayList();
485 expectedFlowRules.add(buildExpectedVlanInPortRule(
486 PORT_1, VlanId.vlanId((short) DEFAULT_PW_TRANSPORT_VLAN), null, VlanId.NONE,
487 PORT_TYPE_INFRA, FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN));
488 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
489 PORT_1,
490 ROUTER_MAC,
491 null,
492 Ethernet.TYPE_IPV4,
493 FWD_IPV4_ROUTING));
494 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
495 PORT_1,
496 ROUTER_MAC,
497 null,
498 Ethernet.TYPE_IPV6,
499 FWD_IPV6_ROUTING));
500 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
501 PORT_1,
502 ROUTER_MAC,
503 null,
504 Ethernet.MPLS_UNICAST,
505 FWD_MPLS));
506
507 ObjectiveTranslation expectedTranslation = buildExpectedTranslation(expectedFlowRules);
508 assertEquals(expectedTranslation, actualTranslation);
509
510 // Untagged port scenario
511 filteringObjective = DefaultFilteringObjective.builder()
512 .withKey(Criteria.matchInPort(PORT_1))
513 .addCondition(Criteria.matchEthDst(ROUTER_MAC))
514 .addCondition(Criteria.matchVlanId(VlanId.NONE))
515 .withPriority(PRIORITY)
516 .fromApp(APP_ID)
517 .withMeta(DefaultTrafficTreatment.builder()
518 .pushVlan()
519 .setVlanId(VlanId.vlanId((short) DEFAULT_VLAN))
pierventre4d29d3c2021-08-27 17:20:00 +0200520 .writeMetadata(INFRA_PORT, 0xffffffffffffffffL)
Wailok Shumfb7e7872021-06-18 17:30:08 +0800521 .build())
522 .permit()
523 .add();
524 actualTranslation = translator.translate(filteringObjective);
525 expectedFlowRules = Lists.newArrayList();
526 expectedFlowRules.add(buildExpectedVlanInPortRule(
527 PORT_1, null, null, VlanId.vlanId((short) DEFAULT_VLAN),
528 PORT_TYPE_INFRA, FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN));
529 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
530 PORT_1,
531 ROUTER_MAC,
532 null,
533 Ethernet.TYPE_IPV4,
534 FWD_IPV4_ROUTING));
535 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
536 PORT_1,
537 ROUTER_MAC,
538 null,
539 Ethernet.TYPE_IPV6,
540 FWD_IPV6_ROUTING));
541 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
542 PORT_1,
543 ROUTER_MAC,
544 null,
545 Ethernet.MPLS_UNICAST,
546 FWD_MPLS));
547
548 expectedTranslation = buildExpectedTranslation(expectedFlowRules);
549 assertEquals(expectedTranslation, actualTranslation);
550 }
551
pierventre4d29d3c2021-08-27 17:20:00 +0200552 /**
553 * Test is pair port scenarios for filtering objective.
554 */
555 @Test
556 public void testIsPairPort() throws FabricPipelinerException {
557 // Only pair port flag
558 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
559 .withKey(Criteria.matchInPort(PORT_1))
560 .addCondition(Criteria.matchEthDst(ROUTER_MAC))
561 .addCondition(Criteria.matchVlanId(VLAN_100))
562 .withPriority(PRIORITY)
563 .withMeta(DefaultTrafficTreatment.builder()
564 .writeMetadata(PAIR_PORT, 0xffffffffffffffffL)
565 .build())
566 .fromApp(APP_ID)
567 .permit()
568 .add();
569 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
570
571 Collection<FlowRule> expectedFlowRules = Lists.newArrayList();
572 expectedFlowRules.add(buildExpectedVlanInPortRule(
573 PORT_1, VLAN_100, null, VlanId.NONE,
574 PORT_TYPE_INFRA, FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN));
575 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
576 PORT_1,
577 ROUTER_MAC,
578 null,
579 Ethernet.TYPE_IPV4,
580 FWD_IPV4_ROUTING));
581 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
582 PORT_1,
583 ROUTER_MAC,
584 null,
585 Ethernet.TYPE_IPV6,
586 FWD_IPV6_ROUTING));
587 expectedFlowRules.addAll(buildExpectedFwdClassifierRule(
588 PORT_1,
589 ROUTER_MAC,
590 null,
591 Ethernet.MPLS_UNICAST,
592 FWD_MPLS));
593
594 ObjectiveTranslation expectedTranslation = buildExpectedTranslation(expectedFlowRules);
595 assertEquals(expectedTranslation, actualTranslation);
596
597 // Pair port and config update flags
598 filteringObjective = DefaultFilteringObjective.builder()
599 .withKey(Criteria.matchInPort(PORT_1))
600 .addCondition(Criteria.matchEthDst(ROUTER_MAC))
601 .addCondition(Criteria.matchVlanId(VLAN_100))
602 .withPriority(PRIORITY)
603 .fromApp(APP_ID)
604 .withMeta(DefaultTrafficTreatment.builder()
605 .writeMetadata(6, 0xffffffffffffffffL)
606 .build())
607 .permit()
608 .add();
609
610 actualTranslation = translator.translate(filteringObjective);
611 expectedFlowRules = Lists.newArrayList();
612 // Ingress port vlan rule
613 expectedFlowRules.add(buildExpectedVlanInPortRule(
614 PORT_1, VLAN_100, null, VlanId.NONE, PORT_TYPE_INFRA,
615 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN));
616 expectedTranslation = buildExpectedTranslation(expectedFlowRules);
617 assertEquals(expectedTranslation, actualTranslation);
618 }
619
Yi Tseng0b809722017-11-03 10:23:26 -0700620 /* Utilities */
621
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800622 private void assertError(ObjectiveError error, ObjectiveTranslation actualTranslation) {
623 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.ofError(error);
624 assertEquals(expectedTranslation, actualTranslation);
625 }
626
pierventre4d29d3c2021-08-27 17:20:00 +0200627 private FilteringObjective buildFilteringObjective(MacAddress dstMac, long portType) {
Yi Tseng0b809722017-11-03 10:23:26 -0700628 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
629 .pushVlan()
630 .setVlanId(VLAN_100)
pierventre4d29d3c2021-08-27 17:20:00 +0200631 .writeMetadata(portType, 0xffffffffffffffffL)
Yi Tseng0b809722017-11-03 10:23:26 -0700632 .build();
633 DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder()
634 .permit()
635 .withPriority(PRIORITY)
636 .withKey(Criteria.matchInPort(PORT_1));
637 if (dstMac != null) {
638 builder.addCondition(Criteria.matchEthDst(dstMac));
639 }
640
641 builder.addCondition(Criteria.matchVlanId(VlanId.NONE))
642 .withMeta(treatment)
643 .fromApp(APP_ID)
644 .makePermanent();
645 return builder.add();
646 }
647
Daniele Moro7c3a0022019-07-12 13:38:34 -0700648 private FlowRule buildExpectedVlanInPortRule(PortNumber inPort,
649 VlanId vlanId,
650 VlanId innerVlanId,
Yi Tseng0b809722017-11-03 10:23:26 -0700651 VlanId internalVlan,
Wailok Shumfb7e7872021-06-18 17:30:08 +0800652 byte portType,
Yi Tseng0b809722017-11-03 10:23:26 -0700653 TableId tableId) {
654
655 TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
656 .matchInPort(inPort);
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800657 PiAction piAction;
Daniele Moro7c3a0022019-07-12 13:38:34 -0700658 selector.matchPi(buildPiCriterionVlan(vlanId, innerVlanId));
659 if (!vlanValid(vlanId)) {
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800660 piAction = PiAction.builder()
661 .withId(FabricConstants.FABRIC_INGRESS_FILTERING_PERMIT_WITH_INTERNAL_VLAN)
Wailok Shumfb7e7872021-06-18 17:30:08 +0800662 .withParameter(new PiActionParam(FabricConstants.VLAN_ID, internalVlan.toShort()))
663 .withParameter(new PiActionParam(FabricConstants.PORT_TYPE, portType))
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800664 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700665 } else {
Yi Tseng0b809722017-11-03 10:23:26 -0700666 selector.matchVlanId(vlanId);
Daniele Morof51d0c12019-07-30 10:43:10 -0700667 if (vlanValid(innerVlanId)) {
668 selector.matchInnerVlanId(innerVlanId);
669 }
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800670 piAction = PiAction.builder()
671 .withId(FabricConstants.FABRIC_INGRESS_FILTERING_PERMIT)
Wailok Shumfb7e7872021-06-18 17:30:08 +0800672 .withParameter(new PiActionParam(FabricConstants.PORT_TYPE, portType))
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800673 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700674 }
675
676 return DefaultFlowRule.builder()
677 .withPriority(PRIORITY)
678 .withSelector(selector.build())
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800679 .withTreatment(DefaultTrafficTreatment.builder()
680 .piTableAction(piAction).build())
Yi Tseng0b809722017-11-03 10:23:26 -0700681 .fromApp(APP_ID)
682 .forDevice(DEVICE_ID)
683 .makePermanent()
684 .forTable(tableId)
685 .build();
686 }
687
Daniele Moro7c3a0022019-07-12 13:38:34 -0700688 private boolean vlanValid(VlanId vlanId) {
689 return (vlanId != null && !vlanId.equals(VlanId.NONE));
690 }
691
692 private PiCriterion buildPiCriterionVlan(VlanId vlanId,
693 VlanId innerVlanId) {
694 PiCriterion.Builder piCriterionBuilder = PiCriterion.builder()
695 .matchExact(FabricConstants.HDR_VLAN_IS_VALID,
696 vlanValid(vlanId) ? ONE : ZERO);
697 return piCriterionBuilder.build();
698 }
699
Daniele Moro5a2de712019-09-24 14:34:07 -0700700 private Collection<FlowRule> buildExpectedFwdClassifierRule(PortNumber inPort,
701 MacAddress dstMac,
702 MacAddress dstMacMask,
703 short ethType,
704 byte fwdClass) {
Yi Tseng43ee7e82018-04-12 16:37:34 +0800705 PiActionParam classParam = new PiActionParam(FabricConstants.FWD_TYPE,
Yi Tseng0b809722017-11-03 10:23:26 -0700706 ImmutableByteSequence.copyFrom(fwdClass));
707 PiAction fwdClassifierAction = PiAction.builder()
Yi Tseng43ee7e82018-04-12 16:37:34 +0800708 .withId(FabricConstants.FABRIC_INGRESS_FILTERING_SET_FORWARDING_TYPE)
Yi Tseng0b809722017-11-03 10:23:26 -0700709 .withParameter(classParam)
710 .build();
711 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
712 .piTableAction(fwdClassifierAction)
713 .build();
714
Daniele Moro5a2de712019-09-24 14:34:07 -0700715 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder()
716 .matchInPort(inPort);
717 if (dstMacMask != null) {
718 sbuilder.matchEthDstMasked(dstMac, dstMacMask);
719 } else {
720 sbuilder.matchEthDstMasked(dstMac, MacAddress.EXACT_MASK);
721 }
722 // Special case for MPLS UNICAST forwarding, need to build 2 rules for MPLS+IPv4 and MPLS+IPv6
723 if (ethType == Ethernet.MPLS_UNICAST) {
724 return buildExpectedFwdClassifierRulesMpls(fwdClassifierAction, treatment, sbuilder);
725 }
726 sbuilder.matchPi(PiCriterion.builder()
727 .matchExact(FabricConstants.HDR_IP_ETH_TYPE, ethType)
728 .build());
729 TrafficSelector selector = sbuilder.build();
730 return List.of(DefaultFlowRule.builder()
731 .withPriority(PRIORITY)
732 .withSelector(selector)
733 .withTreatment(treatment)
734 .fromApp(APP_ID)
735 .forDevice(DEVICE_ID)
736 .makePermanent()
737 .forTable(FabricConstants.FABRIC_INGRESS_FILTERING_FWD_CLASSIFIER)
738 .build());
739 }
740
741 private Collection<FlowRule> buildExpectedFwdClassifierRulesMpls(PiAction fwdClassifierAction,
742 TrafficTreatment treatment,
743 TrafficSelector.Builder selectorBuilder) {
744
745 Collection<FlowRule> flowRules = Lists.newArrayList();
746 TrafficSelector selectorIpv4 = selectorBuilder
747 .add(PiCriterion.builder()
Wailok Shumfb7e7872021-06-18 17:30:08 +0800748 .matchTernary(FabricConstants.HDR_ETH_TYPE, Ethernet.MPLS_UNICAST, ETH_TYPE_EXACT_MASK)
Daniele Moro5a2de712019-09-24 14:34:07 -0700749 .matchExact(FabricConstants.HDR_IP_ETH_TYPE, Ethernet.TYPE_IPV4)
750 .build())
Yi Tseng0b809722017-11-03 10:23:26 -0700751 .build();
Daniele Moro5a2de712019-09-24 14:34:07 -0700752 TrafficSelector selectorIpv6 = selectorBuilder
753 .add(PiCriterion.builder()
Wailok Shumfb7e7872021-06-18 17:30:08 +0800754 .matchTernary(FabricConstants.HDR_ETH_TYPE, Ethernet.MPLS_UNICAST, ETH_TYPE_EXACT_MASK)
Daniele Moro5a2de712019-09-24 14:34:07 -0700755 .matchExact(FabricConstants.HDR_IP_ETH_TYPE, Ethernet.TYPE_IPV6)
756 .build())
757 .build();
758 flowRules.add(DefaultFlowRule.builder()
759 .withPriority(PRIORITY + 1)
760 .withSelector(selectorIpv4)
761 .withTreatment(treatment)
762 .fromApp(APP_ID)
763 .forDevice(DEVICE_ID)
764 .makePermanent()
765 .forTable(FabricConstants.FABRIC_INGRESS_FILTERING_FWD_CLASSIFIER)
766 .build());
767 flowRules.add(DefaultFlowRule.builder()
768 .withPriority(PRIORITY + 1)
769 .withSelector(selectorIpv6)
770 .withTreatment(treatment)
771 .fromApp(APP_ID)
772 .forDevice(DEVICE_ID)
773 .makePermanent()
774 .forTable(FabricConstants.FABRIC_INGRESS_FILTERING_FWD_CLASSIFIER)
775 .build());
776 return flowRules;
777 }
778
779 private ObjectiveTranslation buildExpectedTranslation(Collection<FlowRule> flowRules)
780 throws FabricPipelinerException {
781 ObjectiveTranslation.Builder expectedTranslationBuilder = ObjectiveTranslation.builder();
782 for (FlowRule flowRule : flowRules) {
783 expectedTranslationBuilder.addFlowRule(flowRule);
784 }
785 return expectedTranslationBuilder.build();
Yi Tseng0b809722017-11-03 10:23:26 -0700786 }
787}