blob: 14253e75be46ba7620b3addfe5531c5c8d691386 [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;
Yi Tseng0b809722017-11-03 10:23:26 -070037import org.onosproject.net.flowobjective.DefaultForwardingObjective;
38import org.onosproject.net.flowobjective.ForwardingObjective;
Daniele Moro01ca2ab2019-06-25 11:48:48 -070039import org.onosproject.net.group.DefaultGroupBucket;
40import org.onosproject.net.group.DefaultGroupDescription;
41import org.onosproject.net.group.DefaultGroupKey;
42import org.onosproject.net.group.GroupBucket;
43import org.onosproject.net.group.GroupBuckets;
Yi Tseng0b809722017-11-03 10:23:26 -070044import org.onosproject.net.group.GroupDescription;
Daniele Moro01ca2ab2019-06-25 11:48:48 -070045import org.onosproject.net.group.GroupKey;
Yi Tseng0b809722017-11-03 10:23:26 -070046import org.onosproject.net.pi.model.PiTableId;
47import org.onosproject.net.pi.runtime.PiAction;
48import org.onosproject.net.pi.runtime.PiActionParam;
Carmelo Cascone2102bfb2020-12-04 16:54:24 -080049import org.onosproject.pipelines.fabric.FabricConstants;
Yi Tseng0b809722017-11-03 10:23:26 -070050
51import java.util.List;
52
53import static org.junit.Assert.assertEquals;
54import static org.junit.Assert.assertTrue;
55
56/**
57 * Test cases for fabric.p4 pipeline forwarding control block.
58 */
Carmelo Cascone2388cc12021-05-26 19:30:30 +020059public class ForwardingObjectiveTranslatorTest extends BaseObjectiveTranslatorTest {
Yi Tseng0b809722017-11-03 10:23:26 -070060
Carmelo Casconeb5324e72018-11-25 02:26:32 -080061 private ForwardingObjectiveTranslator translator;
62
63 @Before
64 public void setup() {
65 super.doSetup();
66 translator = new ForwardingObjectiveTranslator(DEVICE_ID, capabilitiesHashed);
67 }
68
Yi Tseng0b809722017-11-03 10:23:26 -070069 /**
70 * Test versatile flag of forwarding objective with ARP match.
71 */
72 @Test
73 public void testAclArp() {
74 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Yi Tseng0b809722017-11-03 10:23:26 -070075 .punt()
76 .build();
77 // ARP
78 TrafficSelector selector = DefaultTrafficSelector.builder()
79 .matchEthType(Ethernet.TYPE_ARP)
80 .build();
81 ForwardingObjective fwd = DefaultForwardingObjective.builder()
82 .withSelector(selector)
83 .withPriority(PRIORITY)
84 .fromApp(APP_ID)
85 .makePermanent()
86 .withFlag(ForwardingObjective.Flag.VERSATILE)
87 .withTreatment(treatment)
88 .add();
89
Carmelo Casconeb5324e72018-11-25 02:26:32 -080090 ObjectiveTranslation result = translator.translate(fwd);
Yi Tseng0b809722017-11-03 10:23:26 -070091
92 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
93 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
94 assertEquals(1, flowRulesInstalled.size());
Daniele Moro01ca2ab2019-06-25 11:48:48 -070095 assertEquals(1, groupsInstalled.size());
Yi Tseng0b809722017-11-03 10:23:26 -070096
97 FlowRule actualFlowRule = flowRulesInstalled.get(0);
Carmelo Casconeb5324e72018-11-25 02:26:32 -080098 PiAction piAction = PiAction.builder()
Daniele Moro01ca2ab2019-06-25 11:48:48 -070099 .withId(FabricConstants.FABRIC_INGRESS_ACL_SET_CLONE_SESSION_ID)
100 .withParameter(new PiActionParam(
101 FabricConstants.CLONE_ID,
102 ForwardingObjectiveTranslator.CLONE_TO_CPU_ID))
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800103 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700104 FlowRule expectedFlowRule = DefaultFlowRule.builder()
105 .forDevice(DEVICE_ID)
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800106 .forTable(FabricConstants.FABRIC_INGRESS_ACL_ACL)
Yi Tseng0b809722017-11-03 10:23:26 -0700107 .withPriority(PRIORITY)
108 .makePermanent()
109 .withSelector(selector)
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800110 .withTreatment(DefaultTrafficTreatment.builder()
111 .piTableAction(piAction).build())
Yi Tseng0b809722017-11-03 10:23:26 -0700112 .fromApp(APP_ID)
113 .build();
114
Daniele Moro01ca2ab2019-06-25 11:48:48 -0700115 GroupDescription actualCloneGroup = groupsInstalled.get(0);
116 TrafficTreatment cloneGroupTreatment = DefaultTrafficTreatment.builder()
117 .setOutput(PortNumber.CONTROLLER)
118 .build();
119
120 List<GroupBucket> cloneBuckets = ImmutableList.of(
121 DefaultGroupBucket.createCloneGroupBucket(cloneGroupTreatment));
122
123 GroupBuckets cloneGroupBuckets = new GroupBuckets(cloneBuckets);
124 GroupKey cloneGroupKey = new DefaultGroupKey(
125 FabricPipeliner.KRYO.serialize(ForwardingObjectiveTranslator.CLONE_TO_CPU_ID));
126 GroupDescription expectedCloneGroup = new DefaultGroupDescription(
127 DEVICE_ID,
128 GroupDescription.Type.CLONE,
129 cloneGroupBuckets,
130 cloneGroupKey,
131 ForwardingObjectiveTranslator.CLONE_TO_CPU_ID,
132 APP_ID
133 );
134
Yi Tseng0b809722017-11-03 10:23:26 -0700135 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
Daniele Moro01ca2ab2019-06-25 11:48:48 -0700136 assertTrue(expectedCloneGroup.equals(actualCloneGroup));
Yi Tseng0b809722017-11-03 10:23:26 -0700137 }
138
139 /**
140 * Test versatile flag of forwarding objective with DHCP match.
141 */
142 @Test
143 public void testAclDhcp() {
144 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
145 .wipeDeferred()
146 .punt()
147 .build();
148 // DHCP
149 TrafficSelector selector = DefaultTrafficSelector.builder()
150 .matchEthType(Ethernet.TYPE_IPV4)
151 .matchIPProtocol(IPv4.PROTOCOL_UDP)
152 .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT))
153 .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
154 .build();
155 ForwardingObjective fwd = DefaultForwardingObjective.builder()
156 .withSelector(selector)
157 .withPriority(PRIORITY)
158 .fromApp(APP_ID)
159 .makePermanent()
160 .withFlag(ForwardingObjective.Flag.VERSATILE)
161 .withTreatment(treatment)
162 .add();
163
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800164 ObjectiveTranslation result = translator.translate(fwd);
Yi Tseng0b809722017-11-03 10:23:26 -0700165
166 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
167 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
168 assertEquals(1, flowRulesInstalled.size());
169 assertTrue(groupsInstalled.isEmpty());
170
171 FlowRule actualFlowRule = flowRulesInstalled.get(0);
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800172 PiAction piAction = PiAction.builder()
173 .withId(FabricConstants.FABRIC_INGRESS_ACL_PUNT_TO_CPU)
174 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700175 FlowRule expectedFlowRule = DefaultFlowRule.builder()
176 .forDevice(DEVICE_ID)
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800177 .forTable(FabricConstants.FABRIC_INGRESS_ACL_ACL)
Yi Tseng0b809722017-11-03 10:23:26 -0700178 .withPriority(PRIORITY)
179 .makePermanent()
180 .withSelector(selector)
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800181 .withTreatment(DefaultTrafficTreatment.builder()
182 .piTableAction(piAction).build())
Yi Tseng0b809722017-11-03 10:23:26 -0700183 .fromApp(APP_ID)
184 .build();
185
186 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
187 }
Wailok Shum4f51bde2021-06-11 22:48:41 +0800188/**
189 * Test versatile flag of forwarding objective with acl drop.
190 */
191 @Test
192 public void testAclDrop() {
193 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
194 .wipeDeferred()
195 .build();
196 // ACL 8-tuples like
197 TrafficSelector selector = DefaultTrafficSelector.builder()
198 .matchIPDst(IPV4_UNICAST_ADDR)
199 .build();
200 ForwardingObjective fwd = DefaultForwardingObjective.builder()
201 .withSelector(selector)
202 .withPriority(PRIORITY)
203 .fromApp(APP_ID)
204 .makePermanent()
205 .withFlag(ForwardingObjective.Flag.VERSATILE)
206 .withTreatment(treatment)
207 .add();
208
209 ObjectiveTranslation result = translator.translate(fwd);
210
211 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
212 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
213 assertEquals(1, flowRulesInstalled.size());
214 assertTrue(groupsInstalled.isEmpty());
215
216 FlowRule actualFlowRule = flowRulesInstalled.get(0);
217 PiAction piAction = PiAction.builder()
218 .withId(FabricConstants.FABRIC_INGRESS_ACL_DROP)
219 .build();
220 FlowRule expectedFlowRule = DefaultFlowRule.builder()
221 .forDevice(DEVICE_ID)
222 .forTable(FabricConstants.FABRIC_INGRESS_ACL_ACL)
223 .withPriority(PRIORITY)
224 .makePermanent()
225 .withSelector(selector)
226 .withTreatment(DefaultTrafficTreatment.builder()
227 .piTableAction(piAction).build())
228 .fromApp(APP_ID)
229 .build();
230
231 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
232 }
233
234 /**
235 * Test versatile flag of forwarding objective with acl nop.
236 */
237 @Test
238 public void testAclNop() {
239 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
240 .build();
241 // ACL 8-tuples like
242 TrafficSelector selector = DefaultTrafficSelector.builder()
243 .matchIPDst(IPV4_UNICAST_ADDR)
244 .build();
245 ForwardingObjective fwd = DefaultForwardingObjective.builder()
246 .withSelector(selector)
247 .withPriority(PRIORITY)
248 .fromApp(APP_ID)
249 .makePermanent()
250 .withFlag(ForwardingObjective.Flag.VERSATILE)
251 .withTreatment(treatment)
252 .add();
253
254 ObjectiveTranslation result = translator.translate(fwd);
255
256 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
257 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
258 assertEquals(1, flowRulesInstalled.size());
259 assertTrue(groupsInstalled.isEmpty());
260
261 FlowRule actualFlowRule = flowRulesInstalled.get(0);
262 PiAction piAction = PiAction.builder()
263 .withId(FabricConstants.FABRIC_INGRESS_ACL_NOP_ACL)
264 .build();
265 FlowRule expectedFlowRule = DefaultFlowRule.builder()
266 .forDevice(DEVICE_ID)
267 .forTable(FabricConstants.FABRIC_INGRESS_ACL_ACL)
268 .withPriority(PRIORITY)
269 .makePermanent()
270 .withSelector(selector)
271 .withTreatment(DefaultTrafficTreatment.builder()
272 .piTableAction(piAction).build())
273 .fromApp(APP_ID)
274 .build();
275
276 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
277 }
Yi Tseng0b809722017-11-03 10:23:26 -0700278
279 /**
280 * Test programming L2 unicast rule to bridging table.
281 */
282 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800283 public void testL2Unicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700284 TrafficSelector selector = DefaultTrafficSelector.builder()
285 .matchVlanId(VLAN_100)
286 .matchEthDst(HOST_MAC)
287 .build();
Yi Tseng43ee7e82018-04-12 16:37:34 +0800288 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_BRIDGING,
Charles Chan384aea22018-08-23 22:08:02 -0700289 buildExpectedSelector(selector), selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700290 }
291
292 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800293 public void testL2Broadcast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700294 TrafficSelector selector = DefaultTrafficSelector.builder()
295 .matchVlanId(VLAN_100)
296 .build();
Yi Tseng43ee7e82018-04-12 16:37:34 +0800297 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_BRIDGING,
298 selector, selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700299 }
300
301 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800302 public void testIPv4Unicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700303 TrafficSelector selector = DefaultTrafficSelector.builder()
304 .matchEthType(Ethernet.TYPE_IPV4)
305 .matchIPDst(IPV4_UNICAST_ADDR)
306 .build();
307 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
308 .matchIPDst(IPV4_UNICAST_ADDR)
309 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700310 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800311 expectedSelector, selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700312 }
313
314 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800315 public void testIPv4UnicastWithNoNextId() throws FabricPipelinerException {
Yi Tsengdf3eec52018-02-15 14:56:02 -0800316 TrafficSelector selector = DefaultTrafficSelector.builder()
317 .matchEthType(Ethernet.TYPE_IPV4)
318 .matchIPDst(IPV4_UNICAST_ADDR)
319 .build();
320 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
321 .matchIPDst(IPV4_UNICAST_ADDR)
322 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700323 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800324 expectedSelector, selector, null);
Yi Tsengdf3eec52018-02-15 14:56:02 -0800325 }
326
327 @Test
Yi Tseng0b809722017-11-03 10:23:26 -0700328 @Ignore
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800329 public void testIPv4Multicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700330 TrafficSelector selector = DefaultTrafficSelector.builder()
331 .matchEthType(Ethernet.TYPE_IPV4)
332 .matchVlanId(VLAN_100)
333 .matchIPDst(IPV4_MCAST_ADDR)
334 .build();
335 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
336 .matchIPDst(IPV4_MCAST_ADDR)
337 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700338 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800339 expectedSelector, selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700340 }
341
342 @Test
343 @Ignore
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800344 public void testIPv6Unicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700345 TrafficSelector selector = DefaultTrafficSelector.builder()
346 .matchEthType(Ethernet.TYPE_IPV6)
347 .matchIPDst(IPV6_UNICAST_ADDR)
348 .build();
349 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
350 .matchIPDst(IPV6_UNICAST_ADDR)
351 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700352 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V6,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800353 expectedSelector, selector, NEXT_ID_1);
354
Yi Tseng0b809722017-11-03 10:23:26 -0700355 }
356
357 @Test
358 @Ignore
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800359 public void testIPv6Multicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700360 TrafficSelector selector = DefaultTrafficSelector.builder()
361 .matchEthType(Ethernet.TYPE_IPV6)
362 .matchVlanId(VLAN_100)
363 .matchIPDst(IPV6_MCAST_ADDR)
364 .build();
365 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
366 .matchIPDst(IPV6_MCAST_ADDR)
367 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700368 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V6,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800369 expectedSelector, selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700370 }
371
372 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800373 public void testMpls() throws FabricPipelinerException {
Yi Tseng1b154bd2017-11-20 17:48:19 -0800374 TrafficSelector selector = DefaultTrafficSelector.builder()
375 .matchEthType(Ethernet.MPLS_UNICAST)
376 .matchMplsLabel(MPLS_10)
377 .matchMplsBos(true)
378 .build();
379 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
380 .matchMplsLabel(MPLS_10)
381 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700382
Charles Chanea89a1c2018-08-13 13:14:18 -0700383 PiActionParam nextIdParam = new PiActionParam(FabricConstants.NEXT_ID, NEXT_ID_1);
Yi Tseng1b154bd2017-11-20 17:48:19 -0800384 PiAction setNextIdAction = PiAction.builder()
Yi Tseng43ee7e82018-04-12 16:37:34 +0800385 .withId(FabricConstants.FABRIC_INGRESS_FORWARDING_POP_MPLS_AND_NEXT)
Yi Tseng1b154bd2017-11-20 17:48:19 -0800386 .withParameter(nextIdParam)
387 .build();
388 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
389 .piTableAction(setNextIdAction)
390 .build();
Yi Tseng43ee7e82018-04-12 16:37:34 +0800391 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_MPLS,
392 expectedSelector, selector, NEXT_ID_1, treatment);
Yi Tseng0b809722017-11-03 10:23:26 -0700393 }
394
395 private void testSpecificForward(PiTableId expectedTableId, TrafficSelector expectedSelector,
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800396 TrafficSelector selector, Integer nextId) throws FabricPipelinerException {
Yi Tsengdf3eec52018-02-15 14:56:02 -0800397 TrafficTreatment setNextIdTreatment;
398 if (nextId == null) {
399 // Ref: RoutingRulePopulator.java->revokeIpRuleForRouter
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800400
401 setNextIdTreatment = DefaultTrafficTreatment.builder().
402 piTableAction(PiAction.builder()
403 .withId(FabricConstants.FABRIC_INGRESS_FORWARDING_NOP_ROUTING_V4)
404 .build())
405 .build();
Yi Tsengdf3eec52018-02-15 14:56:02 -0800406 } else {
Charles Chanea89a1c2018-08-13 13:14:18 -0700407 PiActionParam nextIdParam = new PiActionParam(FabricConstants.NEXT_ID, nextId);
Yi Tseng47eac892018-07-11 02:17:04 +0800408 PiAction.Builder setNextIdAction = PiAction.builder()
409 .withParameter(nextIdParam);
410
411 if (expectedTableId.equals(FabricConstants.FABRIC_INGRESS_FORWARDING_BRIDGING)) {
412 setNextIdAction.withId(FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_BRIDGING);
Charles Chan384aea22018-08-23 22:08:02 -0700413 } else if (expectedTableId.equals(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4)) {
414 setNextIdAction.withId(FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_ROUTING_V4);
415 } else if (expectedTableId.equals(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V6)) {
416 setNextIdAction.withId(FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_ROUTING_V6);
Yi Tseng47eac892018-07-11 02:17:04 +0800417 }
418
Yi Tsengdf3eec52018-02-15 14:56:02 -0800419 setNextIdTreatment = DefaultTrafficTreatment.builder()
Yi Tseng47eac892018-07-11 02:17:04 +0800420 .piTableAction(setNextIdAction.build())
Yi Tsengdf3eec52018-02-15 14:56:02 -0800421 .build();
422 }
Yi Tseng1b154bd2017-11-20 17:48:19 -0800423
424 testSpecificForward(expectedTableId, expectedSelector, selector, nextId, setNextIdTreatment);
425
426 }
427
428 private void testSpecificForward(PiTableId expectedTableId, TrafficSelector expectedSelector,
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800429 TrafficSelector selector, Integer nextId, TrafficTreatment treatment)
430 throws FabricPipelinerException {
Yi Tsengdf3eec52018-02-15 14:56:02 -0800431 ForwardingObjective.Builder fwd = DefaultForwardingObjective.builder()
Yi Tseng0b809722017-11-03 10:23:26 -0700432 .withSelector(selector)
433 .withPriority(PRIORITY)
434 .fromApp(APP_ID)
435 .makePermanent()
Yi Tsengdf3eec52018-02-15 14:56:02 -0800436 .withTreatment(treatment)
437 .withFlag(ForwardingObjective.Flag.SPECIFIC);
Yi Tseng0b809722017-11-03 10:23:26 -0700438
Yi Tsengdf3eec52018-02-15 14:56:02 -0800439 if (nextId != null) {
440 fwd.nextStep(nextId);
441 }
442
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800443 ObjectiveTranslation actualTranslation = translator.translate(fwd.add());
Yi Tseng0b809722017-11-03 10:23:26 -0700444
445 FlowRule expectedFlowRule = DefaultFlowRule.builder()
446 .forDevice(DEVICE_ID)
447 .forTable(expectedTableId)
448 .withPriority(PRIORITY)
449 .makePermanent()
450 .withSelector(expectedSelector)
Yi Tseng1b154bd2017-11-20 17:48:19 -0800451 .withTreatment(treatment)
Yi Tseng0b809722017-11-03 10:23:26 -0700452 .fromApp(APP_ID)
453 .build();
454
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800455 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
456 .addFlowRule(expectedFlowRule)
457 .build();
458
459 assertEquals(expectedTranslation, actualTranslation);
Yi Tseng0b809722017-11-03 10:23:26 -0700460 }
Charles Chan384aea22018-08-23 22:08:02 -0700461
462 private TrafficSelector buildExpectedSelector(TrafficSelector selector) {
463 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
464 selector.criteria().forEach(c -> {
465 if (c.type() == Criterion.Type.ETH_DST) {
466 sbuilder.matchEthDstMasked(((EthCriterion) c).mac(), MacAddress.EXACT_MASK);
467 } else {
468 sbuilder.add(c);
469 }
470 });
471 return sbuilder.build();
472 }
Yi Tseng0b809722017-11-03 10:23:26 -0700473}