blob: dfae0df4a50578dbde3800216574990a7bd83e69 [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 Moro01ca2ab2019-06-25 11:48:48 -070019import com.google.common.collect.ImmutableList;
Carmelo Casconeb5324e72018-11-25 02:26:32 -080020import org.junit.Before;
Yi Tseng0b809722017-11-03 10:23:26 -070021import org.junit.Ignore;
22import org.junit.Test;
23import org.onlab.packet.Ethernet;
24import org.onlab.packet.IPv4;
Charles Chan384aea22018-08-23 22:08:02 -070025import org.onlab.packet.MacAddress;
Yi Tseng0b809722017-11-03 10:23:26 -070026import org.onlab.packet.TpPort;
27import org.onlab.packet.UDP;
Daniele Moro01ca2ab2019-06-25 11:48:48 -070028import org.onosproject.net.PortNumber;
Yi Tseng0b809722017-11-03 10:23:26 -070029import org.onosproject.net.flow.DefaultFlowRule;
30import org.onosproject.net.flow.DefaultTrafficSelector;
31import org.onosproject.net.flow.DefaultTrafficTreatment;
32import org.onosproject.net.flow.FlowRule;
33import org.onosproject.net.flow.TrafficSelector;
34import org.onosproject.net.flow.TrafficTreatment;
Charles Chan384aea22018-08-23 22:08:02 -070035import org.onosproject.net.flow.criteria.Criterion;
36import org.onosproject.net.flow.criteria.EthCriterion;
Wailok Shumfb7e7872021-06-18 17:30:08 +080037import org.onosproject.net.flow.criteria.PiCriterion;
Yi Tseng0b809722017-11-03 10:23:26 -070038import org.onosproject.net.flowobjective.DefaultForwardingObjective;
39import org.onosproject.net.flowobjective.ForwardingObjective;
Daniele Moro01ca2ab2019-06-25 11:48:48 -070040import org.onosproject.net.group.DefaultGroupBucket;
41import org.onosproject.net.group.DefaultGroupDescription;
42import org.onosproject.net.group.DefaultGroupKey;
43import org.onosproject.net.group.GroupBucket;
44import org.onosproject.net.group.GroupBuckets;
Yi Tseng0b809722017-11-03 10:23:26 -070045import org.onosproject.net.group.GroupDescription;
Daniele Moro01ca2ab2019-06-25 11:48:48 -070046import org.onosproject.net.group.GroupKey;
Yi Tseng0b809722017-11-03 10:23:26 -070047import org.onosproject.net.pi.model.PiTableId;
48import org.onosproject.net.pi.runtime.PiAction;
49import org.onosproject.net.pi.runtime.PiActionParam;
Carmelo Cascone2102bfb2020-12-04 16:54:24 -080050import org.onosproject.pipelines.fabric.FabricConstants;
Yi Tseng0b809722017-11-03 10:23:26 -070051
52import java.util.List;
53
54import static org.junit.Assert.assertEquals;
55import static org.junit.Assert.assertTrue;
Wailok Shumfb7e7872021-06-18 17:30:08 +080056import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.PORT_TYPE_EDGE;
57import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.PORT_TYPE_INFRA;
58import static org.onosproject.pipelines.fabric.impl.behaviour.Constants.PORT_TYPE_MASK;
Yi Tseng0b809722017-11-03 10:23:26 -070059
60/**
61 * Test cases for fabric.p4 pipeline forwarding control block.
62 */
Carmelo Cascone2388cc12021-05-26 19:30:30 +020063public class ForwardingObjectiveTranslatorTest extends BaseObjectiveTranslatorTest {
Yi Tseng0b809722017-11-03 10:23:26 -070064
Carmelo Casconeb5324e72018-11-25 02:26:32 -080065 private ForwardingObjectiveTranslator translator;
66
67 @Before
68 public void setup() {
69 super.doSetup();
70 translator = new ForwardingObjectiveTranslator(DEVICE_ID, capabilitiesHashed);
71 }
72
Yi Tseng0b809722017-11-03 10:23:26 -070073 /**
74 * Test versatile flag of forwarding objective with ARP match.
75 */
76 @Test
77 public void testAclArp() {
78 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Yi Tseng0b809722017-11-03 10:23:26 -070079 .punt()
80 .build();
81 // ARP
82 TrafficSelector selector = DefaultTrafficSelector.builder()
83 .matchEthType(Ethernet.TYPE_ARP)
84 .build();
85 ForwardingObjective fwd = DefaultForwardingObjective.builder()
86 .withSelector(selector)
87 .withPriority(PRIORITY)
88 .fromApp(APP_ID)
89 .makePermanent()
90 .withFlag(ForwardingObjective.Flag.VERSATILE)
91 .withTreatment(treatment)
92 .add();
93
Carmelo Casconeb5324e72018-11-25 02:26:32 -080094 ObjectiveTranslation result = translator.translate(fwd);
Yi Tseng0b809722017-11-03 10:23:26 -070095
96 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
97 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
98 assertEquals(1, flowRulesInstalled.size());
Daniele Moro01ca2ab2019-06-25 11:48:48 -070099 assertEquals(1, groupsInstalled.size());
Yi Tseng0b809722017-11-03 10:23:26 -0700100
101 FlowRule actualFlowRule = flowRulesInstalled.get(0);
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800102 PiAction piAction = PiAction.builder()
Daniele Moro01ca2ab2019-06-25 11:48:48 -0700103 .withId(FabricConstants.FABRIC_INGRESS_ACL_SET_CLONE_SESSION_ID)
104 .withParameter(new PiActionParam(
105 FabricConstants.CLONE_ID,
106 ForwardingObjectiveTranslator.CLONE_TO_CPU_ID))
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800107 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700108 FlowRule expectedFlowRule = DefaultFlowRule.builder()
109 .forDevice(DEVICE_ID)
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800110 .forTable(FabricConstants.FABRIC_INGRESS_ACL_ACL)
Yi Tseng0b809722017-11-03 10:23:26 -0700111 .withPriority(PRIORITY)
112 .makePermanent()
113 .withSelector(selector)
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800114 .withTreatment(DefaultTrafficTreatment.builder()
115 .piTableAction(piAction).build())
Yi Tseng0b809722017-11-03 10:23:26 -0700116 .fromApp(APP_ID)
117 .build();
118
Daniele Moro01ca2ab2019-06-25 11:48:48 -0700119 GroupDescription actualCloneGroup = groupsInstalled.get(0);
120 TrafficTreatment cloneGroupTreatment = DefaultTrafficTreatment.builder()
121 .setOutput(PortNumber.CONTROLLER)
122 .build();
123
124 List<GroupBucket> cloneBuckets = ImmutableList.of(
125 DefaultGroupBucket.createCloneGroupBucket(cloneGroupTreatment));
126
127 GroupBuckets cloneGroupBuckets = new GroupBuckets(cloneBuckets);
128 GroupKey cloneGroupKey = new DefaultGroupKey(
129 FabricPipeliner.KRYO.serialize(ForwardingObjectiveTranslator.CLONE_TO_CPU_ID));
130 GroupDescription expectedCloneGroup = new DefaultGroupDescription(
131 DEVICE_ID,
132 GroupDescription.Type.CLONE,
133 cloneGroupBuckets,
134 cloneGroupKey,
135 ForwardingObjectiveTranslator.CLONE_TO_CPU_ID,
136 APP_ID
137 );
138
Yi Tseng0b809722017-11-03 10:23:26 -0700139 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
Daniele Moro01ca2ab2019-06-25 11:48:48 -0700140 assertTrue(expectedCloneGroup.equals(actualCloneGroup));
Yi Tseng0b809722017-11-03 10:23:26 -0700141 }
142
143 /**
144 * Test versatile flag of forwarding objective with DHCP match.
145 */
146 @Test
147 public void testAclDhcp() {
148 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
149 .wipeDeferred()
150 .punt()
151 .build();
152 // DHCP
153 TrafficSelector selector = DefaultTrafficSelector.builder()
154 .matchEthType(Ethernet.TYPE_IPV4)
155 .matchIPProtocol(IPv4.PROTOCOL_UDP)
156 .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT))
157 .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
158 .build();
159 ForwardingObjective fwd = DefaultForwardingObjective.builder()
160 .withSelector(selector)
161 .withPriority(PRIORITY)
162 .fromApp(APP_ID)
163 .makePermanent()
164 .withFlag(ForwardingObjective.Flag.VERSATILE)
165 .withTreatment(treatment)
166 .add();
167
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800168 ObjectiveTranslation result = translator.translate(fwd);
Yi Tseng0b809722017-11-03 10:23:26 -0700169
170 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
171 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
172 assertEquals(1, flowRulesInstalled.size());
173 assertTrue(groupsInstalled.isEmpty());
174
175 FlowRule actualFlowRule = flowRulesInstalled.get(0);
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800176 PiAction piAction = PiAction.builder()
177 .withId(FabricConstants.FABRIC_INGRESS_ACL_PUNT_TO_CPU)
178 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700179 FlowRule expectedFlowRule = DefaultFlowRule.builder()
180 .forDevice(DEVICE_ID)
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800181 .forTable(FabricConstants.FABRIC_INGRESS_ACL_ACL)
Yi Tseng0b809722017-11-03 10:23:26 -0700182 .withPriority(PRIORITY)
183 .makePermanent()
184 .withSelector(selector)
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800185 .withTreatment(DefaultTrafficTreatment.builder()
186 .piTableAction(piAction).build())
Yi Tseng0b809722017-11-03 10:23:26 -0700187 .fromApp(APP_ID)
188 .build();
189
190 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
191 }
Wailok Shumfb7e7872021-06-18 17:30:08 +0800192
193 /**
194 * Test versatile flag of forwarding objective with next step.
195 */
196 @Test
197 public void testAclNext() {
198 // ACL 8-tuples
199 TrafficSelector selector = DefaultTrafficSelector.builder()
200 .matchEthType(Ethernet.TYPE_IPV4)
201 .matchIPDst(IPV4_UNICAST_ADDR)
202 .build();
203 ForwardingObjective fwd = DefaultForwardingObjective.builder()
204 .withSelector(selector)
205 .withPriority(PRIORITY)
206 .fromApp(APP_ID)
207 .makePermanent()
208 .withFlag(ForwardingObjective.Flag.VERSATILE)
209 .nextStep(NEXT_ID_1)
210 .add();
211
212 ObjectiveTranslation result = translator.translate(fwd);
213
214 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
215 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
216 assertEquals(1, flowRulesInstalled.size());
217 assertTrue(groupsInstalled.isEmpty());
218
219 FlowRule actualFlowRule = flowRulesInstalled.get(0);
220 PiAction piAction = PiAction.builder()
221 .withId(FabricConstants.FABRIC_INGRESS_ACL_SET_NEXT_ID_ACL)
222 .withParameter(new PiActionParam(FabricConstants.NEXT_ID, NEXT_ID_1))
223 .build();
224 FlowRule expectedFlowRule = DefaultFlowRule.builder()
225 .forDevice(DEVICE_ID)
226 .forTable(FabricConstants.FABRIC_INGRESS_ACL_ACL)
227 .withPriority(PRIORITY)
228 .makePermanent()
229 .withSelector(selector)
230 .withTreatment(DefaultTrafficTreatment.builder()
231 .piTableAction(piAction).build())
232 .fromApp(APP_ID)
233 .build();
234
235 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
236 }
237
238 /**
239 * Test versatile flag of forwarding objective with next step and port type.
240 */
241 @Test
242 public void testAclNextWithPortType() {
243 // ACL 8-tuples
244 TrafficSelector selector = DefaultTrafficSelector.builder()
245 .matchEthType(Ethernet.TYPE_IPV4)
246 .matchIPDst(IPV4_UNICAST_ADDR)
247 .build();
248 TrafficSelector metaSelector = DefaultTrafficSelector.builder()
249 .matchMetadata(PORT_TYPE_EDGE)
250 .build();
251 ForwardingObjective fwd = DefaultForwardingObjective.builder()
252 .withSelector(selector)
253 .withPriority(PRIORITY)
254 .fromApp(APP_ID)
255 .makePermanent()
256 .withFlag(ForwardingObjective.Flag.VERSATILE)
257 .nextStep(NEXT_ID_1)
258 .withMeta(metaSelector)
259 .add();
260
261 ObjectiveTranslation result = translator.translate(fwd);
262
263 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
264 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
265 assertEquals(1, flowRulesInstalled.size());
266 assertTrue(groupsInstalled.isEmpty());
267
268 FlowRule actualFlowRule = flowRulesInstalled.get(0);
269 PiAction piAction = PiAction.builder()
270 .withId(FabricConstants.FABRIC_INGRESS_ACL_SET_NEXT_ID_ACL)
271 .withParameter(new PiActionParam(FabricConstants.NEXT_ID, NEXT_ID_1))
272 .build();
273 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
274 .matchEthType(Ethernet.TYPE_IPV4)
275 .matchIPDst(IPV4_UNICAST_ADDR)
276 .matchPi(PiCriterion.builder()
277 .matchTernary(FabricConstants.HDR_PORT_TYPE, PORT_TYPE_EDGE, PORT_TYPE_MASK)
278 .build())
279 .build();
280 FlowRule expectedFlowRule = DefaultFlowRule.builder()
281 .forDevice(DEVICE_ID)
282 .forTable(FabricConstants.FABRIC_INGRESS_ACL_ACL)
283 .withPriority(PRIORITY)
284 .makePermanent()
285 .withSelector(expectedSelector)
286 .withTreatment(DefaultTrafficTreatment.builder()
287 .piTableAction(piAction).build())
288 .fromApp(APP_ID)
289 .build();
290
291 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
292
293 metaSelector = DefaultTrafficSelector.builder()
294 .matchMetadata(PORT_TYPE_INFRA)
295 .build();
296 fwd = DefaultForwardingObjective.builder()
297 .withSelector(selector)
298 .withPriority(PRIORITY)
299 .fromApp(APP_ID)
300 .makePermanent()
301 .withFlag(ForwardingObjective.Flag.VERSATILE)
302 .nextStep(NEXT_ID_1)
303 .withMeta(metaSelector)
304 .add();
305
306 result = translator.translate(fwd);
307
308 flowRulesInstalled = (List<FlowRule>) result.flowRules();
309 groupsInstalled = (List<GroupDescription>) result.groups();
310 assertEquals(1, flowRulesInstalled.size());
311 assertTrue(groupsInstalled.isEmpty());
312
313 actualFlowRule = flowRulesInstalled.get(0);
314 expectedSelector = DefaultTrafficSelector.builder()
315 .matchEthType(Ethernet.TYPE_IPV4)
316 .matchIPDst(IPV4_UNICAST_ADDR)
317 .matchPi(PiCriterion.builder()
318 .matchTernary(FabricConstants.HDR_PORT_TYPE, PORT_TYPE_INFRA, PORT_TYPE_MASK)
319 .build())
320 .build();
321 expectedFlowRule = DefaultFlowRule.builder()
322 .forDevice(DEVICE_ID)
323 .forTable(FabricConstants.FABRIC_INGRESS_ACL_ACL)
324 .withPriority(PRIORITY)
325 .makePermanent()
326 .withSelector(expectedSelector)
327 .withTreatment(DefaultTrafficTreatment.builder()
328 .piTableAction(piAction).build())
329 .fromApp(APP_ID)
330 .build();
331
332 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
333 }
334
335 /**
Wailok Shum4f51bde2021-06-11 22:48:41 +0800336 * Test versatile flag of forwarding objective with acl drop.
337 */
338 @Test
339 public void testAclDrop() {
340 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
341 .wipeDeferred()
342 .build();
343 // ACL 8-tuples like
344 TrafficSelector selector = DefaultTrafficSelector.builder()
345 .matchIPDst(IPV4_UNICAST_ADDR)
346 .build();
347 ForwardingObjective fwd = DefaultForwardingObjective.builder()
348 .withSelector(selector)
349 .withPriority(PRIORITY)
350 .fromApp(APP_ID)
351 .makePermanent()
352 .withFlag(ForwardingObjective.Flag.VERSATILE)
353 .withTreatment(treatment)
354 .add();
355
356 ObjectiveTranslation result = translator.translate(fwd);
357
358 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
359 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
360 assertEquals(1, flowRulesInstalled.size());
361 assertTrue(groupsInstalled.isEmpty());
362
363 FlowRule actualFlowRule = flowRulesInstalled.get(0);
364 PiAction piAction = PiAction.builder()
365 .withId(FabricConstants.FABRIC_INGRESS_ACL_DROP)
366 .build();
367 FlowRule expectedFlowRule = DefaultFlowRule.builder()
368 .forDevice(DEVICE_ID)
369 .forTable(FabricConstants.FABRIC_INGRESS_ACL_ACL)
370 .withPriority(PRIORITY)
371 .makePermanent()
372 .withSelector(selector)
373 .withTreatment(DefaultTrafficTreatment.builder()
374 .piTableAction(piAction).build())
375 .fromApp(APP_ID)
376 .build();
377
378 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
379 }
380
381 /**
382 * Test versatile flag of forwarding objective with acl nop.
383 */
384 @Test
385 public void testAclNop() {
386 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
387 .build();
388 // ACL 8-tuples like
389 TrafficSelector selector = DefaultTrafficSelector.builder()
390 .matchIPDst(IPV4_UNICAST_ADDR)
391 .build();
392 ForwardingObjective fwd = DefaultForwardingObjective.builder()
393 .withSelector(selector)
394 .withPriority(PRIORITY)
395 .fromApp(APP_ID)
396 .makePermanent()
397 .withFlag(ForwardingObjective.Flag.VERSATILE)
398 .withTreatment(treatment)
399 .add();
400
401 ObjectiveTranslation result = translator.translate(fwd);
402
403 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
404 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
405 assertEquals(1, flowRulesInstalled.size());
406 assertTrue(groupsInstalled.isEmpty());
407
408 FlowRule actualFlowRule = flowRulesInstalled.get(0);
409 PiAction piAction = PiAction.builder()
410 .withId(FabricConstants.FABRIC_INGRESS_ACL_NOP_ACL)
411 .build();
412 FlowRule expectedFlowRule = DefaultFlowRule.builder()
413 .forDevice(DEVICE_ID)
414 .forTable(FabricConstants.FABRIC_INGRESS_ACL_ACL)
415 .withPriority(PRIORITY)
416 .makePermanent()
417 .withSelector(selector)
418 .withTreatment(DefaultTrafficTreatment.builder()
419 .piTableAction(piAction).build())
420 .fromApp(APP_ID)
421 .build();
422
423 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
424 }
Yi Tseng0b809722017-11-03 10:23:26 -0700425
426 /**
427 * Test programming L2 unicast rule to bridging table.
428 */
429 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800430 public void testL2Unicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700431 TrafficSelector selector = DefaultTrafficSelector.builder()
432 .matchVlanId(VLAN_100)
433 .matchEthDst(HOST_MAC)
434 .build();
Yi Tseng43ee7e82018-04-12 16:37:34 +0800435 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_BRIDGING,
Charles Chan384aea22018-08-23 22:08:02 -0700436 buildExpectedSelector(selector), selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700437 }
438
439 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800440 public void testL2Broadcast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700441 TrafficSelector selector = DefaultTrafficSelector.builder()
442 .matchVlanId(VLAN_100)
443 .build();
Yi Tseng43ee7e82018-04-12 16:37:34 +0800444 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_BRIDGING,
445 selector, selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700446 }
447
448 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800449 public void testIPv4Unicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700450 TrafficSelector selector = DefaultTrafficSelector.builder()
451 .matchEthType(Ethernet.TYPE_IPV4)
452 .matchIPDst(IPV4_UNICAST_ADDR)
453 .build();
454 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
455 .matchIPDst(IPV4_UNICAST_ADDR)
456 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700457 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800458 expectedSelector, selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700459 }
460
461 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800462 public void testIPv4UnicastWithNoNextId() throws FabricPipelinerException {
Yi Tsengdf3eec52018-02-15 14:56:02 -0800463 TrafficSelector selector = DefaultTrafficSelector.builder()
464 .matchEthType(Ethernet.TYPE_IPV4)
465 .matchIPDst(IPV4_UNICAST_ADDR)
466 .build();
467 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
468 .matchIPDst(IPV4_UNICAST_ADDR)
469 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700470 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800471 expectedSelector, selector, null);
Yi Tsengdf3eec52018-02-15 14:56:02 -0800472 }
473
474 @Test
Yi Tseng0b809722017-11-03 10:23:26 -0700475 @Ignore
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800476 public void testIPv4Multicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700477 TrafficSelector selector = DefaultTrafficSelector.builder()
478 .matchEthType(Ethernet.TYPE_IPV4)
479 .matchVlanId(VLAN_100)
480 .matchIPDst(IPV4_MCAST_ADDR)
481 .build();
482 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
483 .matchIPDst(IPV4_MCAST_ADDR)
484 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700485 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800486 expectedSelector, selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700487 }
488
489 @Test
490 @Ignore
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800491 public void testIPv6Unicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700492 TrafficSelector selector = DefaultTrafficSelector.builder()
493 .matchEthType(Ethernet.TYPE_IPV6)
494 .matchIPDst(IPV6_UNICAST_ADDR)
495 .build();
496 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
497 .matchIPDst(IPV6_UNICAST_ADDR)
498 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700499 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V6,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800500 expectedSelector, selector, NEXT_ID_1);
501
Yi Tseng0b809722017-11-03 10:23:26 -0700502 }
503
504 @Test
505 @Ignore
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800506 public void testIPv6Multicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700507 TrafficSelector selector = DefaultTrafficSelector.builder()
508 .matchEthType(Ethernet.TYPE_IPV6)
509 .matchVlanId(VLAN_100)
510 .matchIPDst(IPV6_MCAST_ADDR)
511 .build();
512 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
513 .matchIPDst(IPV6_MCAST_ADDR)
514 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700515 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V6,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800516 expectedSelector, selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700517 }
518
519 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800520 public void testMpls() throws FabricPipelinerException {
Yi Tseng1b154bd2017-11-20 17:48:19 -0800521 TrafficSelector selector = DefaultTrafficSelector.builder()
522 .matchEthType(Ethernet.MPLS_UNICAST)
523 .matchMplsLabel(MPLS_10)
524 .matchMplsBos(true)
525 .build();
526 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
527 .matchMplsLabel(MPLS_10)
528 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700529
Charles Chanea89a1c2018-08-13 13:14:18 -0700530 PiActionParam nextIdParam = new PiActionParam(FabricConstants.NEXT_ID, NEXT_ID_1);
Yi Tseng1b154bd2017-11-20 17:48:19 -0800531 PiAction setNextIdAction = PiAction.builder()
Yi Tseng43ee7e82018-04-12 16:37:34 +0800532 .withId(FabricConstants.FABRIC_INGRESS_FORWARDING_POP_MPLS_AND_NEXT)
Yi Tseng1b154bd2017-11-20 17:48:19 -0800533 .withParameter(nextIdParam)
534 .build();
535 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
536 .piTableAction(setNextIdAction)
537 .build();
Yi Tseng43ee7e82018-04-12 16:37:34 +0800538 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_MPLS,
539 expectedSelector, selector, NEXT_ID_1, treatment);
Yi Tseng0b809722017-11-03 10:23:26 -0700540 }
541
542 private void testSpecificForward(PiTableId expectedTableId, TrafficSelector expectedSelector,
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800543 TrafficSelector selector, Integer nextId) throws FabricPipelinerException {
Yi Tsengdf3eec52018-02-15 14:56:02 -0800544 TrafficTreatment setNextIdTreatment;
545 if (nextId == null) {
546 // Ref: RoutingRulePopulator.java->revokeIpRuleForRouter
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800547
548 setNextIdTreatment = DefaultTrafficTreatment.builder().
549 piTableAction(PiAction.builder()
550 .withId(FabricConstants.FABRIC_INGRESS_FORWARDING_NOP_ROUTING_V4)
551 .build())
552 .build();
Yi Tsengdf3eec52018-02-15 14:56:02 -0800553 } else {
Charles Chanea89a1c2018-08-13 13:14:18 -0700554 PiActionParam nextIdParam = new PiActionParam(FabricConstants.NEXT_ID, nextId);
Yi Tseng47eac892018-07-11 02:17:04 +0800555 PiAction.Builder setNextIdAction = PiAction.builder()
556 .withParameter(nextIdParam);
557
558 if (expectedTableId.equals(FabricConstants.FABRIC_INGRESS_FORWARDING_BRIDGING)) {
559 setNextIdAction.withId(FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_BRIDGING);
Charles Chan384aea22018-08-23 22:08:02 -0700560 } else if (expectedTableId.equals(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4)) {
561 setNextIdAction.withId(FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_ROUTING_V4);
562 } else if (expectedTableId.equals(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V6)) {
563 setNextIdAction.withId(FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_ROUTING_V6);
Yi Tseng47eac892018-07-11 02:17:04 +0800564 }
565
Yi Tsengdf3eec52018-02-15 14:56:02 -0800566 setNextIdTreatment = DefaultTrafficTreatment.builder()
Yi Tseng47eac892018-07-11 02:17:04 +0800567 .piTableAction(setNextIdAction.build())
Yi Tsengdf3eec52018-02-15 14:56:02 -0800568 .build();
569 }
Yi Tseng1b154bd2017-11-20 17:48:19 -0800570
571 testSpecificForward(expectedTableId, expectedSelector, selector, nextId, setNextIdTreatment);
572
573 }
574
575 private void testSpecificForward(PiTableId expectedTableId, TrafficSelector expectedSelector,
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800576 TrafficSelector selector, Integer nextId, TrafficTreatment treatment)
577 throws FabricPipelinerException {
Yi Tsengdf3eec52018-02-15 14:56:02 -0800578 ForwardingObjective.Builder fwd = DefaultForwardingObjective.builder()
Yi Tseng0b809722017-11-03 10:23:26 -0700579 .withSelector(selector)
580 .withPriority(PRIORITY)
581 .fromApp(APP_ID)
582 .makePermanent()
Yi Tsengdf3eec52018-02-15 14:56:02 -0800583 .withTreatment(treatment)
584 .withFlag(ForwardingObjective.Flag.SPECIFIC);
Yi Tseng0b809722017-11-03 10:23:26 -0700585
Yi Tsengdf3eec52018-02-15 14:56:02 -0800586 if (nextId != null) {
587 fwd.nextStep(nextId);
588 }
589
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800590 ObjectiveTranslation actualTranslation = translator.translate(fwd.add());
Yi Tseng0b809722017-11-03 10:23:26 -0700591
592 FlowRule expectedFlowRule = DefaultFlowRule.builder()
593 .forDevice(DEVICE_ID)
594 .forTable(expectedTableId)
595 .withPriority(PRIORITY)
596 .makePermanent()
597 .withSelector(expectedSelector)
Yi Tseng1b154bd2017-11-20 17:48:19 -0800598 .withTreatment(treatment)
Yi Tseng0b809722017-11-03 10:23:26 -0700599 .fromApp(APP_ID)
600 .build();
601
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800602 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
603 .addFlowRule(expectedFlowRule)
604 .build();
605
606 assertEquals(expectedTranslation, actualTranslation);
Yi Tseng0b809722017-11-03 10:23:26 -0700607 }
Charles Chan384aea22018-08-23 22:08:02 -0700608
609 private TrafficSelector buildExpectedSelector(TrafficSelector selector) {
610 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
611 selector.criteria().forEach(c -> {
612 if (c.type() == Criterion.Type.ETH_DST) {
613 sbuilder.matchEthDstMasked(((EthCriterion) c).mac(), MacAddress.EXACT_MASK);
614 } else {
615 sbuilder.add(c);
616 }
617 });
618 return sbuilder.build();
619 }
Yi Tseng0b809722017-11-03 10:23:26 -0700620}