blob: bd57937ff30d253b076090a74fedc0df23016753 [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
Yi Tseng1b154bd2017-11-20 17:48:19 -080019import com.google.common.collect.ImmutableList;
Yi Tseng0b809722017-11-03 10:23:26 -070020import org.junit.Test;
Esin Karaman24fda8a2018-01-26 11:52:28 +000021import org.onlab.util.ImmutableByteSequence;
Yi Tseng0b809722017-11-03 10:23:26 -070022import org.onosproject.net.flow.DefaultFlowRule;
23import org.onosproject.net.flow.DefaultTrafficSelector;
24import org.onosproject.net.flow.DefaultTrafficTreatment;
25import org.onosproject.net.flow.FlowRule;
26import org.onosproject.net.flow.TrafficSelector;
27import org.onosproject.net.flow.TrafficTreatment;
28import org.onosproject.net.flow.criteria.PiCriterion;
29import org.onosproject.net.flowobjective.DefaultNextObjective;
30import org.onosproject.net.flowobjective.NextObjective;
Yi Tseng1b154bd2017-11-20 17:48:19 -080031import org.onosproject.net.group.DefaultGroupBucket;
32import org.onosproject.net.group.DefaultGroupDescription;
Esin Karaman24fda8a2018-01-26 11:52:28 +000033import org.onosproject.net.group.DefaultGroupKey;
Yi Tseng1b154bd2017-11-20 17:48:19 -080034import org.onosproject.net.group.GroupBucket;
35import org.onosproject.net.group.GroupBuckets;
Yi Tseng0b809722017-11-03 10:23:26 -070036import org.onosproject.net.group.GroupDescription;
Esin Karaman24fda8a2018-01-26 11:52:28 +000037import org.onosproject.net.group.GroupKey;
38import org.onosproject.net.pi.runtime.PiAction;
Yi Tseng1b154bd2017-11-20 17:48:19 -080039import org.onosproject.net.pi.runtime.PiActionGroupId;
Esin Karaman24fda8a2018-01-26 11:52:28 +000040import org.onosproject.net.pi.runtime.PiActionParam;
Yi Tseng1b154bd2017-11-20 17:48:19 -080041import org.onosproject.net.pi.runtime.PiGroupKey;
Yi Tseng0b809722017-11-03 10:23:26 -070042import org.onosproject.pipelines.fabric.FabricConstants;
43
44import java.util.List;
Yi Tseng1b154bd2017-11-20 17:48:19 -080045import java.util.stream.Collectors;
Yi Tseng0b809722017-11-03 10:23:26 -070046
47import static org.junit.Assert.assertEquals;
48import static org.junit.Assert.assertTrue;
49
50/**
51 * Test cases for fabric.p4 pipeline next control block.
52 */
53public class FabricNextPipelinerTest extends FabricPipelinerTest {
Yi Tseng20f9e7b2018-05-24 23:27:39 +080054 private FlowRule vlanMetaFlowRule;
55
56 public FabricNextPipelinerTest() {
57 PiCriterion nextIdCriterion = PiCriterion.builder()
Yi Tseng43ee7e82018-04-12 16:37:34 +080058 .matchExact(FabricConstants.FABRIC_METADATA_NEXT_ID, NEXT_ID_1)
Yi Tseng20f9e7b2018-05-24 23:27:39 +080059 .build();
60 TrafficSelector selector = DefaultTrafficSelector.builder()
61 .matchPi(nextIdCriterion)
62 .build();
63 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
64 .setVlanId(VLAN_100)
65 .build();
66
67 vlanMetaFlowRule = DefaultFlowRule.builder()
68 .withSelector(selector)
69 .withTreatment(treatment)
Yi Tseng43ee7e82018-04-12 16:37:34 +080070 .forTable(FabricConstants.FABRIC_INGRESS_NEXT_VLAN_META)
Yi Tseng20f9e7b2018-05-24 23:27:39 +080071 .makePermanent()
72 // FIXME: currently next objective doesn't support priority, ignore this
73 .withPriority(0)
74 .forDevice(DEVICE_ID)
75 .fromApp(APP_ID)
76 .build();
77 }
Yi Tseng0b809722017-11-03 10:23:26 -070078
79 /**
80 * Test program output rule for Simple table.
81 */
82 @Test
83 public void testSimpleOutput() {
84 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
85 .setOutput(PORT_1)
86 .build();
87 testSimple(treatment);
88 }
89
90 /**
91 * Test program set vlan and output rule for Simple table.
92 */
93 @Test
94 public void testSimpleOutputWithVlanTranslation() {
95 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
96 .setVlanId(VLAN_100)
97 .setOutput(PORT_1)
98 .build();
99 testSimple(treatment);
100 }
101
Yi Tsengdbe05602017-11-17 18:02:43 -0800102 /**
103 * Test program set mac and output rule for Simple table.
104 */
105 @Test
106 public void testSimpleOutputWithMacTranslation() {
107 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
108 .setEthSrc(ROUTER_MAC)
109 .setEthDst(HOST_MAC)
110 .setOutput(PORT_1)
111 .build();
112 testSimple(treatment);
113 }
114
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800115 /**
116 * Test program set mac, set vlan, and output rule for Simple table.
117 */
118 @Test
119 public void testSimpleOutputWithVlanAndMacTranslation() {
120 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
121 .setEthSrc(ROUTER_MAC)
122 .setEthDst(HOST_MAC)
123 .setVlanId(VLAN_100)
124 .setOutput(PORT_1)
125 .build();
126 testSimple(treatment);
127 }
128
Yi Tseng0b809722017-11-03 10:23:26 -0700129 private void testSimple(TrafficTreatment treatment) {
130 NextObjective nextObjective = DefaultNextObjective.builder()
131 .withId(NEXT_ID_1)
132 .withPriority(PRIORITY)
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800133 .withMeta(VLAN_META)
Yi Tseng0b809722017-11-03 10:23:26 -0700134 .addTreatment(treatment)
135 .withType(NextObjective.Type.SIMPLE)
136 .makePermanent()
137 .fromApp(APP_ID)
138 .add();
139
140 PipelinerTranslationResult result = pipeliner.pipelinerNext.next(nextObjective);
141
142 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
143 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800144 assertEquals(2, flowRulesInstalled.size());
Yi Tseng0b809722017-11-03 10:23:26 -0700145 assertTrue(groupsInstalled.isEmpty());
146
Yi Tseng1b154bd2017-11-20 17:48:19 -0800147 // Simple table
Yi Tseng0b809722017-11-03 10:23:26 -0700148 PiCriterion nextIdCriterion = PiCriterion.builder()
Yi Tseng43ee7e82018-04-12 16:37:34 +0800149 .matchExact(FabricConstants.FABRIC_METADATA_NEXT_ID, NEXT_ID_1)
Yi Tseng1b154bd2017-11-20 17:48:19 -0800150 .build();
151 TrafficSelector nextIdSelector = DefaultTrafficSelector.builder()
152 .matchPi(nextIdCriterion)
153 .build();
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800154
155 // VLAN meta table
Yi Tsengf55eaa82017-11-29 15:51:28 -0800156 FlowRule actualFlowRule = flowRulesInstalled.get(0);
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800157 assertTrue(actualFlowRule.exactMatch(vlanMetaFlowRule));
158
159 actualFlowRule = flowRulesInstalled.get(1);
Yi Tseng1b154bd2017-11-20 17:48:19 -0800160 FlowRule expectedFlowRule = DefaultFlowRule.builder()
161 .forDevice(DEVICE_ID)
162 .fromApp(APP_ID)
163 .makePermanent()
164 // FIXME: currently next objective doesn't support priority, ignore this
165 .withPriority(0)
Yi Tseng43ee7e82018-04-12 16:37:34 +0800166 .forTable(FabricConstants.FABRIC_INGRESS_NEXT_SIMPLE)
Yi Tseng1b154bd2017-11-20 17:48:19 -0800167 .withSelector(nextIdSelector)
168 .withTreatment(treatment)
169 .build();
170 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
171 }
172
Yi Tseng0b809722017-11-03 10:23:26 -0700173 /**
174 * Test program ecmp output group for Hashed table.
175 */
176 @Test
Yi Tseng1b154bd2017-11-20 17:48:19 -0800177 public void testHashedOutput() throws Exception {
178 TrafficTreatment treatment1 = DefaultTrafficTreatment.builder()
179 .setEthSrc(ROUTER_MAC)
180 .setEthDst(HOST_MAC)
181 .setOutput(PORT_1)
182 .build();
183 TrafficTreatment treatment2 = DefaultTrafficTreatment.builder()
184 .setEthSrc(ROUTER_MAC)
185 .setEthDst(HOST_MAC)
186 .setOutput(PORT_2)
187 .build();
188
189 NextObjective nextObjective = DefaultNextObjective.builder()
190 .withId(NEXT_ID_1)
191 .withPriority(PRIORITY)
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800192 .withMeta(VLAN_META)
Yi Tseng1b154bd2017-11-20 17:48:19 -0800193 .addTreatment(treatment1)
194 .addTreatment(treatment2)
195 .withType(NextObjective.Type.HASHED)
196 .makePermanent()
197 .fromApp(APP_ID)
198 .add();
199
200 PipelinerTranslationResult result = pipeliner.pipelinerNext.next(nextObjective);
201
202 // Should generates 2 flows and 1 group
203 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
204 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800205 assertEquals(2, flowRulesInstalled.size());
Yi Tseng1b154bd2017-11-20 17:48:19 -0800206 assertEquals(1, groupsInstalled.size());
207
Yi Tseng1b154bd2017-11-20 17:48:19 -0800208 // Hashed table
209 PiCriterion nextIdCriterion = PiCriterion.builder()
Yi Tseng43ee7e82018-04-12 16:37:34 +0800210 .matchExact(FabricConstants.FABRIC_METADATA_NEXT_ID, NEXT_ID_1)
Yi Tseng1b154bd2017-11-20 17:48:19 -0800211 .build();
212 TrafficSelector nextIdSelector = DefaultTrafficSelector.builder()
213 .matchPi(nextIdCriterion)
214 .build();
215 PiActionGroupId actionGroupId = PiActionGroupId.of(NEXT_ID_1);
216 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
217 .piTableAction(actionGroupId)
218 .build();
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800219
220 // VLAN meta table
Yi Tsengf55eaa82017-11-29 15:51:28 -0800221 FlowRule actualFlowRule = flowRulesInstalled.get(0);
Yi Tseng20f9e7b2018-05-24 23:27:39 +0800222 assertTrue(actualFlowRule.exactMatch(vlanMetaFlowRule));
223
224 actualFlowRule = flowRulesInstalled.get(1);
Yi Tseng1b154bd2017-11-20 17:48:19 -0800225 FlowRule expectedFlowRule = DefaultFlowRule.builder()
226 .forDevice(DEVICE_ID)
227 .fromApp(APP_ID)
228 .makePermanent()
229 // FIXME: currently next objective doesn't support priority, ignore this
230 .withPriority(0)
Yi Tseng43ee7e82018-04-12 16:37:34 +0800231 .forTable(FabricConstants.FABRIC_INGRESS_NEXT_HASHED)
Yi Tseng1b154bd2017-11-20 17:48:19 -0800232 .withSelector(nextIdSelector)
233 .withTreatment(treatment)
234 .build();
235 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
236
237 // Group
238 GroupDescription actualGroup = groupsInstalled.get(0);
239 List<TrafficTreatment> treatments = ImmutableList.of(treatment1, treatment2);
240
241 List<GroupBucket> buckets = treatments.stream()
242 .map(DefaultGroupBucket::createSelectGroupBucket)
243 .collect(Collectors.toList());
244 GroupBuckets groupBuckets = new GroupBuckets(buckets);
Yi Tseng43ee7e82018-04-12 16:37:34 +0800245 PiGroupKey groupKey = new PiGroupKey(FabricConstants.FABRIC_INGRESS_NEXT_HASHED,
246 FabricConstants.FABRIC_INGRESS_NEXT_ECMP_SELECTOR,
247 NEXT_ID_1);
Yi Tseng1b154bd2017-11-20 17:48:19 -0800248 GroupDescription expectedGroup = new DefaultGroupDescription(
249 DEVICE_ID,
250 GroupDescription.Type.SELECT,
251 groupBuckets,
252 groupKey,
253 NEXT_ID_1,
254 APP_ID
255 );
256 assertEquals(expectedGroup, actualGroup);
Yi Tseng0b809722017-11-03 10:23:26 -0700257
258 }
259
260 /**
261 * Test program output group for Broadcast table.
262 */
263 @Test
Yi Tseng0b809722017-11-03 10:23:26 -0700264 public void testBroadcastOutput() {
Esin Karaman24fda8a2018-01-26 11:52:28 +0000265 TrafficTreatment treatment1 = DefaultTrafficTreatment.builder()
266 .setOutput(PORT_1)
267 .build();
268 TrafficTreatment treatment2 = DefaultTrafficTreatment.builder()
269 .popVlan()
270 .setOutput(PORT_2)
271 .build();
272 NextObjective nextObjective = DefaultNextObjective.builder()
273 .withId(NEXT_ID_1)
274 .withPriority(PRIORITY)
275 .addTreatment(treatment1)
276 .addTreatment(treatment2)
277 .withMeta(VLAN_META)
278 .withType(NextObjective.Type.BROADCAST)
279 .makePermanent()
280 .fromApp(APP_ID)
281 .add();
Yi Tseng0b809722017-11-03 10:23:26 -0700282
Esin Karaman24fda8a2018-01-26 11:52:28 +0000283 PipelinerTranslationResult result = pipeliner.pipelinerNext.next(nextObjective);
284
285 // Should generate 1 flow, 1 group and 2 buckets in it
286 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
287 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
288 assertEquals(3, flowRulesInstalled.size());
289 assertEquals(1, groupsInstalled.size());
290 assertEquals(2, groupsInstalled.get(0).buckets().buckets().size());
291
292 //create the expected flow rule
293 PiCriterion nextIdCriterion = PiCriterion.builder()
294 .matchExact(FabricConstants.FABRIC_METADATA_NEXT_ID, NEXT_ID_1)
295 .build();
296 TrafficSelector nextIdSelector = DefaultTrafficSelector.builder()
297 .matchPi(nextIdCriterion)
298 .build();
299
300 PiActionParam groupIdParam = new PiActionParam(FabricConstants.GID,
301 ImmutableByteSequence.copyFrom(NEXT_ID_1));
302 PiAction setMcGroupAction = PiAction.builder()
303 .withId(FabricConstants.FABRIC_INGRESS_NEXT_SET_MCAST_GROUP)
304 .withParameter(groupIdParam)
305 .build();
306 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
307 .piTableAction(setMcGroupAction)
308 .build();
309 FlowRule expectedFlowRule = DefaultFlowRule.builder()
310 .forDevice(DEVICE_ID)
311 .fromApp(APP_ID)
312 .makePermanent()
313 .withPriority(nextObjective.priority())
314 .forTable(FabricConstants.FABRIC_INGRESS_NEXT_MULTICAST)
315 .withSelector(nextIdSelector)
316 .withTreatment(treatment)
317 .build();
318
319 // VLAN meta table
320 FlowRule vmFlowRule = flowRulesInstalled.get(0);
321 assertTrue(vmFlowRule.exactMatch(vlanMetaFlowRule));
322
323 FlowRule actualFlowRule = flowRulesInstalled.get(1);
324 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
325
326 //prepare expected egress rule for the egress vlan pipeline
327 PiCriterion egressVlanTableMatch = PiCriterion.builder()
328 .matchExact(FabricConstants.STANDARD_METADATA_EGRESS_PORT,
329 (short) PORT_2.toLong())
330 .build();
331 TrafficSelector selectorForEgressVlan = DefaultTrafficSelector.builder()
332 .matchPi(egressVlanTableMatch)
333 .matchVlanId(VLAN_100)
334 .build();
335 TrafficTreatment treatmentForEgressVlan = DefaultTrafficTreatment.builder()
336 .popVlan()
337 .build();
338 FlowRule expectedEgressVlanRule = DefaultFlowRule.builder()
339 .withSelector(selectorForEgressVlan)
340 .withTreatment(treatmentForEgressVlan)
341 .forTable(FabricConstants.FABRIC_EGRESS_EGRESS_NEXT_EGRESS_VLAN)
342 .makePermanent()
343 .withPriority(nextObjective.priority())
344 .forDevice(DEVICE_ID)
345 .fromApp(APP_ID)
346 .build();
347 //egress vlan table
348 FlowRule actualEgressVlanFlowRule = flowRulesInstalled.get(2);
349 assertTrue(expectedEgressVlanRule.exactMatch(actualEgressVlanFlowRule));
350
351 //create the expected group
352 GroupDescription actualGroup = groupsInstalled.get(0);
Carmelo Cascone58136812018-07-19 03:40:16 +0200353 TrafficTreatment groupTreatment1 = DefaultTrafficTreatment.builder()
354 .setOutput(PORT_1)
355 .build();
356 TrafficTreatment groupTreatment2 = DefaultTrafficTreatment.builder()
357 .setOutput(PORT_2)
358 .build();
359 List<TrafficTreatment> treatments = ImmutableList.of(groupTreatment1, groupTreatment2);
Esin Karaman24fda8a2018-01-26 11:52:28 +0000360
361 List<GroupBucket> buckets = treatments.stream()
362 .map(DefaultGroupBucket::createAllGroupBucket)
363 .collect(Collectors.toList());
364
365 GroupBuckets groupBuckets = new GroupBuckets(buckets);
366
367 GroupKey groupKey = new DefaultGroupKey(FabricPipeliner.KRYO.serialize(NEXT_ID_1));
368
369 GroupDescription expectedGroup = new DefaultGroupDescription(
370 DEVICE_ID,
371 GroupDescription.Type.ALL,
372 groupBuckets,
373 groupKey,
374 NEXT_ID_1,
375 APP_ID
376 );
377 assertEquals(expectedGroup, actualGroup);
Yi Tseng0b809722017-11-03 10:23:26 -0700378 }
379}