blob: e15b11740f0f4bda61ad5a9ac34284c4b69fd4e6 [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
17package org.onosproject.pipelines.fabric.pipeliner;
18
Carmelo Casconeb5324e72018-11-25 02:26:32 -080019import org.junit.Before;
Yi Tseng0b809722017-11-03 10:23:26 -070020import org.junit.Test;
21import org.onlab.packet.Ethernet;
22import org.onlab.packet.MacAddress;
23import org.onlab.packet.VlanId;
24import org.onlab.util.ImmutableByteSequence;
25import org.onosproject.net.PortNumber;
26import org.onosproject.net.flow.DefaultFlowRule;
27import org.onosproject.net.flow.DefaultTrafficSelector;
28import org.onosproject.net.flow.DefaultTrafficTreatment;
29import org.onosproject.net.flow.FlowRule;
30import org.onosproject.net.flow.TableId;
31import org.onosproject.net.flow.TrafficSelector;
32import org.onosproject.net.flow.TrafficTreatment;
33import org.onosproject.net.flow.criteria.Criteria;
Daniele Moro7c3a0022019-07-12 13:38:34 -070034import org.onosproject.net.flow.criteria.PiCriterion;
Yi Tseng0b809722017-11-03 10:23:26 -070035import org.onosproject.net.flowobjective.DefaultFilteringObjective;
36import org.onosproject.net.flowobjective.FilteringObjective;
37import org.onosproject.net.flowobjective.ObjectiveError;
Yi Tseng0b809722017-11-03 10:23:26 -070038import org.onosproject.net.pi.runtime.PiAction;
39import org.onosproject.net.pi.runtime.PiActionParam;
40import org.onosproject.pipelines.fabric.FabricConstants;
41
Yi Tseng0b809722017-11-03 10:23:26 -070042import static org.junit.Assert.assertEquals;
Yi Tseng0b809722017-11-03 10:23:26 -070043
44/**
45 * Test cases for fabric.p4 pipeline filtering control block.
46 */
47public class FabricFilteringPipelinerTest extends FabricPipelinerTest {
48
Daniele Moro7c3a0022019-07-12 13:38:34 -070049 public static final byte[] ONE = {1};
50 public static final byte[] ZERO = {0};
Carmelo Casconeb5324e72018-11-25 02:26:32 -080051 private FilteringObjectiveTranslator translator;
52
53 @Before
54 public void setup() {
55 super.doSetup();
56 translator = new FilteringObjectiveTranslator(DEVICE_ID, capabilitiesHashed);
57 }
58
Yi Tseng0b809722017-11-03 10:23:26 -070059 /**
60 * Creates one rule for ingress_port_vlan table and 3 rules for
61 * fwd_classifier table (IPv4, IPv6 and MPLS unicast) when
62 * the condition is VLAN + MAC.
63 */
64 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -080065 public void testRouterMacAndVlanFilter() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -070066 FilteringObjective filteringObjective = buildFilteringObjective(ROUTER_MAC);
Carmelo Casconeb5324e72018-11-25 02:26:32 -080067 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
Yi Tseng0b809722017-11-03 10:23:26 -070068
69 // in port vlan flow rule
Carmelo Casconeb5324e72018-11-25 02:26:32 -080070 FlowRule inportFlowRuleExpected =
Yi Tseng43ee7e82018-04-12 16:37:34 +080071 buildExpectedVlanInPortRule(PORT_1,
72 VlanId.NONE,
Daniele Moro7c3a0022019-07-12 13:38:34 -070073 VlanId.NONE,
Yi Tseng43ee7e82018-04-12 16:37:34 +080074 VLAN_100,
75 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
Yi Tseng0b809722017-11-03 10:23:26 -070076
77 // forwarding classifier ipv4
Carmelo Casconeb5324e72018-11-25 02:26:32 -080078 FlowRule classifierV4FlowRuleExpected = buildExpectedFwdClassifierRule(PORT_1,
Yi Tseng0b809722017-11-03 10:23:26 -070079 ROUTER_MAC,
Charles Chan384aea22018-08-23 22:08:02 -070080 null,
Yi Tseng0b809722017-11-03 10:23:26 -070081 Ethernet.TYPE_IPV4,
Carmelo Casconeb5324e72018-11-25 02:26:32 -080082 FilteringObjectiveTranslator.FWD_IPV4_ROUTING);
Yi Tseng0b809722017-11-03 10:23:26 -070083
84 // forwarding classifier ipv6
Carmelo Casconeb5324e72018-11-25 02:26:32 -080085 FlowRule classifierV6FlowRuleExpected = buildExpectedFwdClassifierRule(PORT_1,
Yi Tseng0b809722017-11-03 10:23:26 -070086 ROUTER_MAC,
Charles Chan384aea22018-08-23 22:08:02 -070087 null,
Yi Tseng0b809722017-11-03 10:23:26 -070088 Ethernet.TYPE_IPV6,
Carmelo Casconeb5324e72018-11-25 02:26:32 -080089 FilteringObjectiveTranslator.FWD_IPV6_ROUTING);
Yi Tseng0b809722017-11-03 10:23:26 -070090
91 // forwarding classifier mpls
Carmelo Casconeb5324e72018-11-25 02:26:32 -080092 FlowRule classifierMplsFlowRuleExpected = buildExpectedFwdClassifierRule(PORT_1,
Yi Tseng0b809722017-11-03 10:23:26 -070093 ROUTER_MAC,
Charles Chan384aea22018-08-23 22:08:02 -070094 null,
Yi Tseng0b809722017-11-03 10:23:26 -070095 Ethernet.MPLS_UNICAST,
Carmelo Casconeb5324e72018-11-25 02:26:32 -080096 FilteringObjectiveTranslator.FWD_MPLS);
97
98 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
99 .addFlowRule(inportFlowRuleExpected)
100 .addFlowRule(classifierV4FlowRuleExpected)
101 .addFlowRule(classifierV6FlowRuleExpected)
102 .addFlowRule(classifierMplsFlowRuleExpected)
103 .build();
104
105 assertEquals(expectedTranslation, actualTranslation);
Yi Tseng0b809722017-11-03 10:23:26 -0700106 }
107
108 /**
109 * Creates one rule for ingress_port_vlan table and one rule for
110 * fwd_classifier table (IPv4 multicast) when the condition is ipv4
111 * multicast mac address.
112 */
113 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800114 public void testIpv4MulticastFwdClass() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700115 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
116 .pushVlan()
117 .setVlanId(VLAN_100)
118 .build();
119 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
120 .permit()
121 .withPriority(PRIORITY)
122 .withKey(Criteria.matchInPort(PORT_1))
Charles Chan384aea22018-08-23 22:08:02 -0700123 .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV4_MULTICAST, MacAddress.IPV4_MULTICAST_MASK))
Yi Tseng0b809722017-11-03 10:23:26 -0700124 .addCondition(Criteria.matchVlanId(VlanId.NONE))
125 .withMeta(treatment)
126 .fromApp(APP_ID)
127 .makePermanent()
128 .add();
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800129 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
Yi Tseng0b809722017-11-03 10:23:26 -0700130
131 // in port vlan flow rule
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800132 FlowRule inportFlowRuleExpected =
Yi Tseng43ee7e82018-04-12 16:37:34 +0800133 buildExpectedVlanInPortRule(PORT_1,
134 VlanId.NONE,
Daniele Moro7c3a0022019-07-12 13:38:34 -0700135 VlanId.NONE,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800136 VLAN_100,
137 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
Yi Tseng0b809722017-11-03 10:23:26 -0700138
139 // forwarding classifier
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800140 FlowRule classifierFlowRuleExpected = buildExpectedFwdClassifierRule(PORT_1,
Yi Tseng0b809722017-11-03 10:23:26 -0700141 MacAddress.IPV4_MULTICAST,
Charles Chan384aea22018-08-23 22:08:02 -0700142 MacAddress.IPV4_MULTICAST_MASK,
Yi Tseng0b809722017-11-03 10:23:26 -0700143 Ethernet.TYPE_IPV4,
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800144 FilteringObjectiveTranslator.FWD_IPV4_ROUTING);
145
146 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
147 .addFlowRule(inportFlowRuleExpected)
148 .addFlowRule(classifierFlowRuleExpected)
149 .build();
150
151 assertEquals(expectedTranslation, actualTranslation);
Yi Tseng0b809722017-11-03 10:23:26 -0700152 }
153
154 /**
155 * Creates one rule for ingress_port_vlan table and one rule for
156 * fwd_classifier table (IPv6 multicast) when the condition is ipv6
157 * multicast mac address.
158 */
159 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800160 public void testIpv6MulticastFwdClass() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700161 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
162 .pushVlan()
163 .setVlanId(VLAN_100)
164 .build();
165 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
166 .permit()
167 .withPriority(PRIORITY)
168 .withKey(Criteria.matchInPort(PORT_1))
Charles Chan384aea22018-08-23 22:08:02 -0700169 .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV6_MULTICAST, MacAddress.IPV6_MULTICAST_MASK))
Yi Tseng0b809722017-11-03 10:23:26 -0700170 .addCondition(Criteria.matchVlanId(VlanId.NONE))
171 .withMeta(treatment)
172 .fromApp(APP_ID)
173 .makePermanent()
174 .add();
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800175 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
Yi Tseng0b809722017-11-03 10:23:26 -0700176
177 // in port vlan flow rule
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800178 FlowRule inportFlowRuleExpected =
Yi Tseng43ee7e82018-04-12 16:37:34 +0800179 buildExpectedVlanInPortRule(PORT_1,
180 VlanId.NONE,
Daniele Moro7c3a0022019-07-12 13:38:34 -0700181 VlanId.NONE,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800182 VLAN_100,
183 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
Yi Tseng0b809722017-11-03 10:23:26 -0700184
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800185 FlowRule classifierFlowRuleExpected = buildExpectedFwdClassifierRule(PORT_1,
Yi Tseng0b809722017-11-03 10:23:26 -0700186 MacAddress.IPV6_MULTICAST,
Charles Chan384aea22018-08-23 22:08:02 -0700187 MacAddress.IPV6_MULTICAST_MASK,
Yi Tseng0b809722017-11-03 10:23:26 -0700188 Ethernet.TYPE_IPV6,
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800189 FilteringObjectiveTranslator.FWD_IPV6_ROUTING);
190
191 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
192 .addFlowRule(inportFlowRuleExpected)
193 .addFlowRule(classifierFlowRuleExpected)
194 .build();
195
196 assertEquals(expectedTranslation, actualTranslation);
Yi Tseng0b809722017-11-03 10:23:26 -0700197 }
198
199 /**
200 * Creates only one rule for ingress_port_vlan table if there is no condition
201 * of destination mac address.
202 * The packet will be handled by bridging table by default.
203 */
204 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800205 public void testFwdBridging() throws Exception {
Yi Tseng0b809722017-11-03 10:23:26 -0700206 FilteringObjective filteringObjective = buildFilteringObjective(null);
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800207 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
Yi Tseng0b809722017-11-03 10:23:26 -0700208
209 // in port vlan flow rule
Yi Tseng43ee7e82018-04-12 16:37:34 +0800210 FlowRule flowRuleExpected =
211 buildExpectedVlanInPortRule(PORT_1,
212 VlanId.NONE,
Daniele Moro7c3a0022019-07-12 13:38:34 -0700213 VlanId.NONE,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800214 VLAN_100,
215 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
Yi Tseng0b809722017-11-03 10:23:26 -0700216
217 // No rules in forwarding classifier, will do default action: set fwd type to bridging
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800218
219 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
220 .addFlowRule(flowRuleExpected)
221 .build();
222
223 assertEquals(expectedTranslation, actualTranslation);
Yi Tseng0b809722017-11-03 10:23:26 -0700224 }
225
226 /**
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800227 * Test DENY objective.
Yi Tseng0b809722017-11-03 10:23:26 -0700228 */
229 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800230 public void testDenyObjective() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700231 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
232 .deny()
233 .withKey(Criteria.matchInPort(PORT_1))
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800234 .addCondition(Criteria.matchVlanId(VlanId.NONE))
Yi Tseng0b809722017-11-03 10:23:26 -0700235 .fromApp(APP_ID)
236 .makePermanent()
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800237 .withPriority(PRIORITY)
Yi Tseng0b809722017-11-03 10:23:26 -0700238 .add();
239
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800240 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
Yi Tseng0b809722017-11-03 10:23:26 -0700241
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800242 TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
243 .matchInPort(PORT_1)
Daniele Moro7c3a0022019-07-12 13:38:34 -0700244 .matchPi(buildPiCriterionVlan(null, null));
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800245 PiAction piAction = PiAction.builder()
246 .withId(FabricConstants.FABRIC_INGRESS_FILTERING_DENY)
247 .build();
248 FlowRule expectedFlowRule = DefaultFlowRule.builder()
249 .withPriority(PRIORITY)
250 .withSelector(selector.build())
251 .withTreatment(DefaultTrafficTreatment.builder()
252 .piTableAction(piAction).build())
253 .fromApp(APP_ID)
254 .forDevice(DEVICE_ID)
255 .makePermanent()
256 .forTable(FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN)
257 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700258
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800259 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
260 .addFlowRule(expectedFlowRule)
261 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700262
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800263 assertEquals(expectedTranslation, actualTranslation);
264
Yi Tseng0b809722017-11-03 10:23:26 -0700265 }
266
267 /**
Daniele Morof51d0c12019-07-30 10:43:10 -0700268 * Test double VLAN pop filtering objective
269 * Creates one rule for ingress_port_vlan table and 3 rules for
270 * fwd_classifier table (IPv4, IPv6 and MPLS unicast) when
271 * the condition is MAC + VLAN + INNER_VLAN.
272 */
273 @Test
274 public void testPopVlan() throws FabricPipelinerException {
275 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
276 .withKey(Criteria.matchInPort(PORT_1))
277 .addCondition(Criteria.matchEthDst(ROUTER_MAC))
278 .addCondition(Criteria.matchVlanId(VLAN_100))
279 .addCondition(Criteria.matchInnerVlanId(VLAN_200))
280 .withPriority(PRIORITY)
281 .fromApp(APP_ID)
282 .withMeta(DefaultTrafficTreatment.builder()
283 .popVlan()
284 .build())
285 .permit()
286 .add();
287 ObjectiveTranslation actualTranslation = translator.translate(filteringObjective);
288
289 // Ingress port vlan rule
290 FlowRule inportFlowRuleExpected = buildExpectedVlanInPortRule(
291 PORT_1, VLAN_100, VLAN_200, VlanId.NONE,
292 FabricConstants.FABRIC_INGRESS_FILTERING_INGRESS_PORT_VLAN);
293 // Forwarding classifier rules (ipv6, ipv4, mpls)
294 FlowRule classifierV4FlowRuleExpected = buildExpectedFwdClassifierRule(
295 PORT_1, ROUTER_MAC, null, Ethernet.TYPE_IPV4,
296 FilteringObjectiveTranslator.FWD_IPV4_ROUTING);
297 FlowRule classifierV6FlowRuleExpected = buildExpectedFwdClassifierRule(
298 PORT_1, ROUTER_MAC, null, Ethernet.TYPE_IPV6,
299 FilteringObjectiveTranslator.FWD_IPV6_ROUTING);
300 FlowRule classifierMplsFlowRuleExpected = buildExpectedFwdClassifierRule(
301 PORT_1, ROUTER_MAC, null, Ethernet.MPLS_UNICAST,
302 FilteringObjectiveTranslator.FWD_MPLS);
303 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
304 .addFlowRule(inportFlowRuleExpected)
305 .addFlowRule(classifierV4FlowRuleExpected)
306 .addFlowRule(classifierV6FlowRuleExpected)
307 .addFlowRule(classifierMplsFlowRuleExpected)
308 .build();
309
310 assertEquals(expectedTranslation, actualTranslation);
311 }
312
313 /**
Yi Tseng0b809722017-11-03 10:23:26 -0700314 * Incorrect filtering key or filtering conditions test.
315 */
316 @Test
317 public void badParamTest() {
318 // Filtering objective should contains filtering key
319 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
320 .permit()
321 .addCondition(Criteria.matchVlanId(VLAN_100))
322 .fromApp(APP_ID)
323 .makePermanent()
324 .add();
325
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800326 ObjectiveTranslation result1 = translator.translate(filteringObjective);
327 assertError(ObjectiveError.BADPARAMS, result1);
Yi Tseng0b809722017-11-03 10:23:26 -0700328
329 // Filtering objective should use in_port as key
330 filteringObjective = DefaultFilteringObjective.builder()
331 .permit()
332 .withKey(Criteria.matchEthDst(ROUTER_MAC))
333 .addCondition(Criteria.matchVlanId(VLAN_100))
334 .withMeta(DefaultTrafficTreatment.emptyTreatment())
335 .fromApp(APP_ID)
336 .makePermanent()
337 .add();
338
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800339 ObjectiveTranslation result2 = translator.translate(filteringObjective);
340 assertError(ObjectiveError.BADPARAMS, result2);
Yi Tseng0b809722017-11-03 10:23:26 -0700341 }
342
Daniele Moro7c3a0022019-07-12 13:38:34 -0700343 /**
344 * Test the mapping between EtherType and conditions.
345 */
346 @Test
347 public void testMappingEthType() {
348 PiCriterion expectedMappingDefault = PiCriterion.builder()
349 .matchExact(FabricConstants.HDR_IS_MPLS, ZERO)
350 .matchExact(FabricConstants.HDR_IS_IPV4, ZERO)
351 .matchExact(FabricConstants.HDR_IS_IPV6, ZERO)
352 .build();
353 PiCriterion expectedMappingIpv6 = PiCriterion.builder()
354 .matchExact(FabricConstants.HDR_IS_MPLS, ZERO)
355 .matchExact(FabricConstants.HDR_IS_IPV4, ZERO)
356 .matchExact(FabricConstants.HDR_IS_IPV6, ONE)
357 .build();
358 PiCriterion expectedMappingIpv4 = PiCriterion.builder()
359 .matchExact(FabricConstants.HDR_IS_MPLS, ZERO)
360 .matchExact(FabricConstants.HDR_IS_IPV4, ONE)
361 .matchExact(FabricConstants.HDR_IS_IPV6, ZERO)
362 .build();
363 PiCriterion expectedMappingMpls = PiCriterion.builder()
364 .matchExact(FabricConstants.HDR_IS_MPLS, ONE)
365 .matchExact(FabricConstants.HDR_IS_IPV4, ZERO)
366 .matchExact(FabricConstants.HDR_IS_IPV6, ZERO)
367 .build();
368
369
370 PiCriterion actualMappingIpv6 = FilteringObjectiveTranslator.mapEthTypeFwdClassifier(Ethernet.TYPE_IPV6);
371 assertEquals(expectedMappingIpv6, actualMappingIpv6);
372
373 PiCriterion actualMappingIpv4 = FilteringObjectiveTranslator.mapEthTypeFwdClassifier(Ethernet.TYPE_IPV4);
374 assertEquals(expectedMappingIpv4, actualMappingIpv4);
375
376 PiCriterion actualMappingMpls = FilteringObjectiveTranslator.mapEthTypeFwdClassifier(Ethernet.MPLS_UNICAST);
377 assertEquals(expectedMappingMpls, actualMappingMpls);
378
379 PiCriterion actualMapping = FilteringObjectiveTranslator.mapEthTypeFwdClassifier(Ethernet.TYPE_ARP);
380 assertEquals(expectedMappingDefault, actualMapping);
381
382
383 }
384
Yi Tseng0b809722017-11-03 10:23:26 -0700385 /* Utilities */
386
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800387 private void assertError(ObjectiveError error, ObjectiveTranslation actualTranslation) {
388 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.ofError(error);
389 assertEquals(expectedTranslation, actualTranslation);
390 }
391
Yi Tseng0b809722017-11-03 10:23:26 -0700392 private FilteringObjective buildFilteringObjective(MacAddress dstMac) {
393 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
394 .pushVlan()
395 .setVlanId(VLAN_100)
396 .build();
397 DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder()
398 .permit()
399 .withPriority(PRIORITY)
400 .withKey(Criteria.matchInPort(PORT_1));
401 if (dstMac != null) {
402 builder.addCondition(Criteria.matchEthDst(dstMac));
403 }
404
405 builder.addCondition(Criteria.matchVlanId(VlanId.NONE))
406 .withMeta(treatment)
407 .fromApp(APP_ID)
408 .makePermanent();
409 return builder.add();
410 }
411
Daniele Moro7c3a0022019-07-12 13:38:34 -0700412 private FlowRule buildExpectedVlanInPortRule(PortNumber inPort,
413 VlanId vlanId,
414 VlanId innerVlanId,
Yi Tseng0b809722017-11-03 10:23:26 -0700415 VlanId internalVlan,
416 TableId tableId) {
417
418 TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
419 .matchInPort(inPort);
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800420 PiAction piAction;
Daniele Moro7c3a0022019-07-12 13:38:34 -0700421 selector.matchPi(buildPiCriterionVlan(vlanId, innerVlanId));
422 if (!vlanValid(vlanId)) {
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800423 piAction = PiAction.builder()
424 .withId(FabricConstants.FABRIC_INGRESS_FILTERING_PERMIT_WITH_INTERNAL_VLAN)
425 .withParameter(new PiActionParam(
426 FabricConstants.VLAN_ID, internalVlan.toShort()))
427 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700428 } else {
Yi Tseng0b809722017-11-03 10:23:26 -0700429 selector.matchVlanId(vlanId);
Daniele Morof51d0c12019-07-30 10:43:10 -0700430 if (vlanValid(innerVlanId)) {
431 selector.matchInnerVlanId(innerVlanId);
432 }
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800433 piAction = PiAction.builder()
434 .withId(FabricConstants.FABRIC_INGRESS_FILTERING_PERMIT)
435 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700436 }
437
438 return DefaultFlowRule.builder()
439 .withPriority(PRIORITY)
440 .withSelector(selector.build())
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800441 .withTreatment(DefaultTrafficTreatment.builder()
442 .piTableAction(piAction).build())
Yi Tseng0b809722017-11-03 10:23:26 -0700443 .fromApp(APP_ID)
444 .forDevice(DEVICE_ID)
445 .makePermanent()
446 .forTable(tableId)
447 .build();
448 }
449
Daniele Moro7c3a0022019-07-12 13:38:34 -0700450 private boolean vlanValid(VlanId vlanId) {
451 return (vlanId != null && !vlanId.equals(VlanId.NONE));
452 }
453
454 private PiCriterion buildPiCriterionVlan(VlanId vlanId,
455 VlanId innerVlanId) {
456 PiCriterion.Builder piCriterionBuilder = PiCriterion.builder()
457 .matchExact(FabricConstants.HDR_VLAN_IS_VALID,
458 vlanValid(vlanId) ? ONE : ZERO);
459 return piCriterionBuilder.build();
460 }
461
Yi Tseng0b809722017-11-03 10:23:26 -0700462 private FlowRule buildExpectedFwdClassifierRule(PortNumber inPort,
463 MacAddress dstMac,
Charles Chan384aea22018-08-23 22:08:02 -0700464 MacAddress dstMacMask,
Yi Tseng0b809722017-11-03 10:23:26 -0700465 short ethType,
466 byte fwdClass) {
Charles Chan384aea22018-08-23 22:08:02 -0700467 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder()
Yi Tseng0b809722017-11-03 10:23:26 -0700468 .matchInPort(inPort)
Daniele Moro7c3a0022019-07-12 13:38:34 -0700469 .matchPi(FilteringObjectiveTranslator.mapEthTypeFwdClassifier(ethType));
Charles Chan384aea22018-08-23 22:08:02 -0700470 if (dstMacMask != null) {
471 sbuilder.matchEthDstMasked(dstMac, dstMacMask);
472 } else {
473 sbuilder.matchEthDstMasked(dstMac, MacAddress.EXACT_MASK);
474 }
475 TrafficSelector selector = sbuilder.build();
476
Yi Tseng43ee7e82018-04-12 16:37:34 +0800477 PiActionParam classParam = new PiActionParam(FabricConstants.FWD_TYPE,
Yi Tseng0b809722017-11-03 10:23:26 -0700478 ImmutableByteSequence.copyFrom(fwdClass));
479 PiAction fwdClassifierAction = PiAction.builder()
Yi Tseng43ee7e82018-04-12 16:37:34 +0800480 .withId(FabricConstants.FABRIC_INGRESS_FILTERING_SET_FORWARDING_TYPE)
Yi Tseng0b809722017-11-03 10:23:26 -0700481 .withParameter(classParam)
482 .build();
483 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
484 .piTableAction(fwdClassifierAction)
485 .build();
486
487 return DefaultFlowRule.builder()
488 .withPriority(PRIORITY)
489 .withSelector(selector)
490 .withTreatment(treatment)
491 .fromApp(APP_ID)
492 .forDevice(DEVICE_ID)
493 .makePermanent()
Yi Tseng43ee7e82018-04-12 16:37:34 +0800494 .forTable(FabricConstants.FABRIC_INGRESS_FILTERING_FWD_CLASSIFIER)
Yi Tseng0b809722017-11-03 10:23:26 -0700495 .build();
496 }
497}