blob: dbb2bd4405ad051405387ae89aac82d7328b87ff [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 /**
268 * Incorrect filtering key or filtering conditions test.
269 */
270 @Test
271 public void badParamTest() {
272 // Filtering objective should contains filtering key
273 FilteringObjective filteringObjective = DefaultFilteringObjective.builder()
274 .permit()
275 .addCondition(Criteria.matchVlanId(VLAN_100))
276 .fromApp(APP_ID)
277 .makePermanent()
278 .add();
279
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800280 ObjectiveTranslation result1 = translator.translate(filteringObjective);
281 assertError(ObjectiveError.BADPARAMS, result1);
Yi Tseng0b809722017-11-03 10:23:26 -0700282
283 // Filtering objective should use in_port as key
284 filteringObjective = DefaultFilteringObjective.builder()
285 .permit()
286 .withKey(Criteria.matchEthDst(ROUTER_MAC))
287 .addCondition(Criteria.matchVlanId(VLAN_100))
288 .withMeta(DefaultTrafficTreatment.emptyTreatment())
289 .fromApp(APP_ID)
290 .makePermanent()
291 .add();
292
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800293 ObjectiveTranslation result2 = translator.translate(filteringObjective);
294 assertError(ObjectiveError.BADPARAMS, result2);
Yi Tseng0b809722017-11-03 10:23:26 -0700295 }
296
Daniele Moro7c3a0022019-07-12 13:38:34 -0700297 /**
298 * Test the mapping between EtherType and conditions.
299 */
300 @Test
301 public void testMappingEthType() {
302 PiCriterion expectedMappingDefault = PiCriterion.builder()
303 .matchExact(FabricConstants.HDR_IS_MPLS, ZERO)
304 .matchExact(FabricConstants.HDR_IS_IPV4, ZERO)
305 .matchExact(FabricConstants.HDR_IS_IPV6, ZERO)
306 .build();
307 PiCriterion expectedMappingIpv6 = PiCriterion.builder()
308 .matchExact(FabricConstants.HDR_IS_MPLS, ZERO)
309 .matchExact(FabricConstants.HDR_IS_IPV4, ZERO)
310 .matchExact(FabricConstants.HDR_IS_IPV6, ONE)
311 .build();
312 PiCriterion expectedMappingIpv4 = PiCriterion.builder()
313 .matchExact(FabricConstants.HDR_IS_MPLS, ZERO)
314 .matchExact(FabricConstants.HDR_IS_IPV4, ONE)
315 .matchExact(FabricConstants.HDR_IS_IPV6, ZERO)
316 .build();
317 PiCriterion expectedMappingMpls = PiCriterion.builder()
318 .matchExact(FabricConstants.HDR_IS_MPLS, ONE)
319 .matchExact(FabricConstants.HDR_IS_IPV4, ZERO)
320 .matchExact(FabricConstants.HDR_IS_IPV6, ZERO)
321 .build();
322
323
324 PiCriterion actualMappingIpv6 = FilteringObjectiveTranslator.mapEthTypeFwdClassifier(Ethernet.TYPE_IPV6);
325 assertEquals(expectedMappingIpv6, actualMappingIpv6);
326
327 PiCriterion actualMappingIpv4 = FilteringObjectiveTranslator.mapEthTypeFwdClassifier(Ethernet.TYPE_IPV4);
328 assertEquals(expectedMappingIpv4, actualMappingIpv4);
329
330 PiCriterion actualMappingMpls = FilteringObjectiveTranslator.mapEthTypeFwdClassifier(Ethernet.MPLS_UNICAST);
331 assertEquals(expectedMappingMpls, actualMappingMpls);
332
333 PiCriterion actualMapping = FilteringObjectiveTranslator.mapEthTypeFwdClassifier(Ethernet.TYPE_ARP);
334 assertEquals(expectedMappingDefault, actualMapping);
335
336
337 }
338
Yi Tseng0b809722017-11-03 10:23:26 -0700339 /* Utilities */
340
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800341 private void assertError(ObjectiveError error, ObjectiveTranslation actualTranslation) {
342 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.ofError(error);
343 assertEquals(expectedTranslation, actualTranslation);
344 }
345
Yi Tseng0b809722017-11-03 10:23:26 -0700346 private FilteringObjective buildFilteringObjective(MacAddress dstMac) {
347 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
348 .pushVlan()
349 .setVlanId(VLAN_100)
350 .build();
351 DefaultFilteringObjective.Builder builder = DefaultFilteringObjective.builder()
352 .permit()
353 .withPriority(PRIORITY)
354 .withKey(Criteria.matchInPort(PORT_1));
355 if (dstMac != null) {
356 builder.addCondition(Criteria.matchEthDst(dstMac));
357 }
358
359 builder.addCondition(Criteria.matchVlanId(VlanId.NONE))
360 .withMeta(treatment)
361 .fromApp(APP_ID)
362 .makePermanent();
363 return builder.add();
364 }
365
Daniele Moro7c3a0022019-07-12 13:38:34 -0700366 private FlowRule buildExpectedVlanInPortRule(PortNumber inPort,
367 VlanId vlanId,
368 VlanId innerVlanId,
Yi Tseng0b809722017-11-03 10:23:26 -0700369 VlanId internalVlan,
370 TableId tableId) {
371
372 TrafficSelector.Builder selector = DefaultTrafficSelector.builder()
373 .matchInPort(inPort);
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800374 PiAction piAction;
Daniele Moro7c3a0022019-07-12 13:38:34 -0700375 selector.matchPi(buildPiCriterionVlan(vlanId, innerVlanId));
376 if (!vlanValid(vlanId)) {
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800377 piAction = PiAction.builder()
378 .withId(FabricConstants.FABRIC_INGRESS_FILTERING_PERMIT_WITH_INTERNAL_VLAN)
379 .withParameter(new PiActionParam(
380 FabricConstants.VLAN_ID, internalVlan.toShort()))
381 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700382 } else {
Yi Tseng0b809722017-11-03 10:23:26 -0700383 selector.matchVlanId(vlanId);
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800384 piAction = PiAction.builder()
385 .withId(FabricConstants.FABRIC_INGRESS_FILTERING_PERMIT)
386 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700387 }
388
389 return DefaultFlowRule.builder()
390 .withPriority(PRIORITY)
391 .withSelector(selector.build())
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800392 .withTreatment(DefaultTrafficTreatment.builder()
393 .piTableAction(piAction).build())
Yi Tseng0b809722017-11-03 10:23:26 -0700394 .fromApp(APP_ID)
395 .forDevice(DEVICE_ID)
396 .makePermanent()
397 .forTable(tableId)
398 .build();
399 }
400
Daniele Moro7c3a0022019-07-12 13:38:34 -0700401 private boolean vlanValid(VlanId vlanId) {
402 return (vlanId != null && !vlanId.equals(VlanId.NONE));
403 }
404
405 private PiCriterion buildPiCriterionVlan(VlanId vlanId,
406 VlanId innerVlanId) {
407 PiCriterion.Builder piCriterionBuilder = PiCriterion.builder()
408 .matchExact(FabricConstants.HDR_VLAN_IS_VALID,
409 vlanValid(vlanId) ? ONE : ZERO);
410 return piCriterionBuilder.build();
411 }
412
Yi Tseng0b809722017-11-03 10:23:26 -0700413 private FlowRule buildExpectedFwdClassifierRule(PortNumber inPort,
414 MacAddress dstMac,
Charles Chan384aea22018-08-23 22:08:02 -0700415 MacAddress dstMacMask,
Yi Tseng0b809722017-11-03 10:23:26 -0700416 short ethType,
417 byte fwdClass) {
Charles Chan384aea22018-08-23 22:08:02 -0700418 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder()
Yi Tseng0b809722017-11-03 10:23:26 -0700419 .matchInPort(inPort)
Daniele Moro7c3a0022019-07-12 13:38:34 -0700420 .matchPi(FilteringObjectiveTranslator.mapEthTypeFwdClassifier(ethType));
Charles Chan384aea22018-08-23 22:08:02 -0700421 if (dstMacMask != null) {
422 sbuilder.matchEthDstMasked(dstMac, dstMacMask);
423 } else {
424 sbuilder.matchEthDstMasked(dstMac, MacAddress.EXACT_MASK);
425 }
426 TrafficSelector selector = sbuilder.build();
427
Yi Tseng43ee7e82018-04-12 16:37:34 +0800428 PiActionParam classParam = new PiActionParam(FabricConstants.FWD_TYPE,
Yi Tseng0b809722017-11-03 10:23:26 -0700429 ImmutableByteSequence.copyFrom(fwdClass));
430 PiAction fwdClassifierAction = PiAction.builder()
Yi Tseng43ee7e82018-04-12 16:37:34 +0800431 .withId(FabricConstants.FABRIC_INGRESS_FILTERING_SET_FORWARDING_TYPE)
Yi Tseng0b809722017-11-03 10:23:26 -0700432 .withParameter(classParam)
433 .build();
434 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
435 .piTableAction(fwdClassifierAction)
436 .build();
437
438 return DefaultFlowRule.builder()
439 .withPriority(PRIORITY)
440 .withSelector(selector)
441 .withTreatment(treatment)
442 .fromApp(APP_ID)
443 .forDevice(DEVICE_ID)
444 .makePermanent()
Yi Tseng43ee7e82018-04-12 16:37:34 +0800445 .forTable(FabricConstants.FABRIC_INGRESS_FILTERING_FWD_CLASSIFIER)
Yi Tseng0b809722017-11-03 10:23:26 -0700446 .build();
447 }
448}