blob: 9c04d8f931eebad40c861940901d3f0fbed2ad2e [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.Ignore;
21import org.junit.Test;
22import org.onlab.packet.Ethernet;
23import org.onlab.packet.IPv4;
Charles Chan384aea22018-08-23 22:08:02 -070024import org.onlab.packet.MacAddress;
Yi Tseng0b809722017-11-03 10:23:26 -070025import org.onlab.packet.TpPort;
26import org.onlab.packet.UDP;
Yi Tseng0b809722017-11-03 10:23:26 -070027import org.onosproject.net.flow.DefaultFlowRule;
28import org.onosproject.net.flow.DefaultTrafficSelector;
29import org.onosproject.net.flow.DefaultTrafficTreatment;
30import org.onosproject.net.flow.FlowRule;
31import org.onosproject.net.flow.TrafficSelector;
32import org.onosproject.net.flow.TrafficTreatment;
Charles Chan384aea22018-08-23 22:08:02 -070033import org.onosproject.net.flow.criteria.Criterion;
34import org.onosproject.net.flow.criteria.EthCriterion;
Yi Tseng0b809722017-11-03 10:23:26 -070035import org.onosproject.net.flowobjective.DefaultForwardingObjective;
36import org.onosproject.net.flowobjective.ForwardingObjective;
37import org.onosproject.net.group.GroupDescription;
38import org.onosproject.net.pi.model.PiTableId;
39import org.onosproject.net.pi.runtime.PiAction;
40import org.onosproject.net.pi.runtime.PiActionParam;
41import org.onosproject.pipelines.fabric.FabricConstants;
42
43import java.util.List;
44
45import static org.junit.Assert.assertEquals;
46import static org.junit.Assert.assertTrue;
47
48/**
49 * Test cases for fabric.p4 pipeline forwarding control block.
50 */
51public class FabricForwardingPipelineTest extends FabricPipelinerTest {
52
Carmelo Casconeb5324e72018-11-25 02:26:32 -080053 private ForwardingObjectiveTranslator translator;
54
55 @Before
56 public void setup() {
57 super.doSetup();
58 translator = new ForwardingObjectiveTranslator(DEVICE_ID, capabilitiesHashed);
59 }
60
Yi Tseng0b809722017-11-03 10:23:26 -070061 /**
62 * Test versatile flag of forwarding objective with ARP match.
63 */
64 @Test
65 public void testAclArp() {
66 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Yi Tseng0b809722017-11-03 10:23:26 -070067 .punt()
68 .build();
69 // ARP
70 TrafficSelector selector = DefaultTrafficSelector.builder()
71 .matchEthType(Ethernet.TYPE_ARP)
72 .build();
73 ForwardingObjective fwd = DefaultForwardingObjective.builder()
74 .withSelector(selector)
75 .withPriority(PRIORITY)
76 .fromApp(APP_ID)
77 .makePermanent()
78 .withFlag(ForwardingObjective.Flag.VERSATILE)
79 .withTreatment(treatment)
80 .add();
81
Carmelo Casconeb5324e72018-11-25 02:26:32 -080082 ObjectiveTranslation result = translator.translate(fwd);
Yi Tseng0b809722017-11-03 10:23:26 -070083
84 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
85 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
86 assertEquals(1, flowRulesInstalled.size());
87 assertTrue(groupsInstalled.isEmpty());
88
89 FlowRule actualFlowRule = flowRulesInstalled.get(0);
Carmelo Casconeb5324e72018-11-25 02:26:32 -080090 PiAction piAction = PiAction.builder()
91 .withId(FabricConstants.FABRIC_INGRESS_ACL_CLONE_TO_CPU)
92 .build();
Yi Tseng0b809722017-11-03 10:23:26 -070093 FlowRule expectedFlowRule = DefaultFlowRule.builder()
94 .forDevice(DEVICE_ID)
Carmelo Casconeb5324e72018-11-25 02:26:32 -080095 .forTable(FabricConstants.FABRIC_INGRESS_ACL_ACL)
Yi Tseng0b809722017-11-03 10:23:26 -070096 .withPriority(PRIORITY)
97 .makePermanent()
98 .withSelector(selector)
Carmelo Casconeb5324e72018-11-25 02:26:32 -080099 .withTreatment(DefaultTrafficTreatment.builder()
100 .piTableAction(piAction).build())
Yi Tseng0b809722017-11-03 10:23:26 -0700101 .fromApp(APP_ID)
102 .build();
103
104 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
105 }
106
107 /**
108 * Test versatile flag of forwarding objective with DHCP match.
109 */
110 @Test
111 public void testAclDhcp() {
112 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
113 .wipeDeferred()
114 .punt()
115 .build();
116 // DHCP
117 TrafficSelector selector = DefaultTrafficSelector.builder()
118 .matchEthType(Ethernet.TYPE_IPV4)
119 .matchIPProtocol(IPv4.PROTOCOL_UDP)
120 .matchUdpSrc(TpPort.tpPort(UDP.DHCP_CLIENT_PORT))
121 .matchUdpDst(TpPort.tpPort(UDP.DHCP_SERVER_PORT))
122 .build();
123 ForwardingObjective fwd = DefaultForwardingObjective.builder()
124 .withSelector(selector)
125 .withPriority(PRIORITY)
126 .fromApp(APP_ID)
127 .makePermanent()
128 .withFlag(ForwardingObjective.Flag.VERSATILE)
129 .withTreatment(treatment)
130 .add();
131
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800132 ObjectiveTranslation result = translator.translate(fwd);
Yi Tseng0b809722017-11-03 10:23:26 -0700133
134 List<FlowRule> flowRulesInstalled = (List<FlowRule>) result.flowRules();
135 List<GroupDescription> groupsInstalled = (List<GroupDescription>) result.groups();
136 assertEquals(1, flowRulesInstalled.size());
137 assertTrue(groupsInstalled.isEmpty());
138
139 FlowRule actualFlowRule = flowRulesInstalled.get(0);
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800140 PiAction piAction = PiAction.builder()
141 .withId(FabricConstants.FABRIC_INGRESS_ACL_PUNT_TO_CPU)
142 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700143 FlowRule expectedFlowRule = DefaultFlowRule.builder()
144 .forDevice(DEVICE_ID)
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800145 .forTable(FabricConstants.FABRIC_INGRESS_ACL_ACL)
Yi Tseng0b809722017-11-03 10:23:26 -0700146 .withPriority(PRIORITY)
147 .makePermanent()
148 .withSelector(selector)
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800149 .withTreatment(DefaultTrafficTreatment.builder()
150 .piTableAction(piAction).build())
Yi Tseng0b809722017-11-03 10:23:26 -0700151 .fromApp(APP_ID)
152 .build();
153
154 assertTrue(expectedFlowRule.exactMatch(actualFlowRule));
155 }
156
157 /**
158 * Test programming L2 unicast rule to bridging table.
159 */
160 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800161 public void testL2Unicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700162 TrafficSelector selector = DefaultTrafficSelector.builder()
163 .matchVlanId(VLAN_100)
164 .matchEthDst(HOST_MAC)
165 .build();
Yi Tseng43ee7e82018-04-12 16:37:34 +0800166 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_BRIDGING,
Charles Chan384aea22018-08-23 22:08:02 -0700167 buildExpectedSelector(selector), selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700168 }
169
170 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800171 public void testL2Broadcast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700172 TrafficSelector selector = DefaultTrafficSelector.builder()
173 .matchVlanId(VLAN_100)
174 .build();
Yi Tseng43ee7e82018-04-12 16:37:34 +0800175 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_BRIDGING,
176 selector, selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700177 }
178
179 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800180 public void testIPv4Unicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700181 TrafficSelector selector = DefaultTrafficSelector.builder()
182 .matchEthType(Ethernet.TYPE_IPV4)
183 .matchIPDst(IPV4_UNICAST_ADDR)
184 .build();
185 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
186 .matchIPDst(IPV4_UNICAST_ADDR)
187 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700188 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800189 expectedSelector, selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700190 }
191
192 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800193 public void testIPv4UnicastWithNoNextId() throws FabricPipelinerException {
Yi Tsengdf3eec52018-02-15 14:56:02 -0800194 TrafficSelector selector = DefaultTrafficSelector.builder()
195 .matchEthType(Ethernet.TYPE_IPV4)
196 .matchIPDst(IPV4_UNICAST_ADDR)
197 .build();
198 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
199 .matchIPDst(IPV4_UNICAST_ADDR)
200 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700201 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800202 expectedSelector, selector, null);
Yi Tsengdf3eec52018-02-15 14:56:02 -0800203 }
204
205 @Test
Yi Tseng0b809722017-11-03 10:23:26 -0700206 @Ignore
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800207 public void testIPv4Multicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700208 TrafficSelector selector = DefaultTrafficSelector.builder()
209 .matchEthType(Ethernet.TYPE_IPV4)
210 .matchVlanId(VLAN_100)
211 .matchIPDst(IPV4_MCAST_ADDR)
212 .build();
213 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
214 .matchIPDst(IPV4_MCAST_ADDR)
215 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700216 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800217 expectedSelector, selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700218 }
219
220 @Test
221 @Ignore
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800222 public void testIPv6Unicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700223 TrafficSelector selector = DefaultTrafficSelector.builder()
224 .matchEthType(Ethernet.TYPE_IPV6)
225 .matchIPDst(IPV6_UNICAST_ADDR)
226 .build();
227 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
228 .matchIPDst(IPV6_UNICAST_ADDR)
229 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700230 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V6,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800231 expectedSelector, selector, NEXT_ID_1);
232
Yi Tseng0b809722017-11-03 10:23:26 -0700233 }
234
235 @Test
236 @Ignore
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800237 public void testIPv6Multicast() throws FabricPipelinerException {
Yi Tseng0b809722017-11-03 10:23:26 -0700238 TrafficSelector selector = DefaultTrafficSelector.builder()
239 .matchEthType(Ethernet.TYPE_IPV6)
240 .matchVlanId(VLAN_100)
241 .matchIPDst(IPV6_MCAST_ADDR)
242 .build();
243 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
244 .matchIPDst(IPV6_MCAST_ADDR)
245 .build();
Charles Chan384aea22018-08-23 22:08:02 -0700246 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V6,
Yi Tseng43ee7e82018-04-12 16:37:34 +0800247 expectedSelector, selector, NEXT_ID_1);
Yi Tseng0b809722017-11-03 10:23:26 -0700248 }
249
250 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800251 public void testMpls() throws FabricPipelinerException {
Yi Tseng1b154bd2017-11-20 17:48:19 -0800252 TrafficSelector selector = DefaultTrafficSelector.builder()
253 .matchEthType(Ethernet.MPLS_UNICAST)
254 .matchMplsLabel(MPLS_10)
255 .matchMplsBos(true)
256 .build();
257 TrafficSelector expectedSelector = DefaultTrafficSelector.builder()
258 .matchMplsLabel(MPLS_10)
259 .build();
Yi Tseng0b809722017-11-03 10:23:26 -0700260
Charles Chanea89a1c2018-08-13 13:14:18 -0700261 PiActionParam nextIdParam = new PiActionParam(FabricConstants.NEXT_ID, NEXT_ID_1);
Yi Tseng1b154bd2017-11-20 17:48:19 -0800262 PiAction setNextIdAction = PiAction.builder()
Yi Tseng43ee7e82018-04-12 16:37:34 +0800263 .withId(FabricConstants.FABRIC_INGRESS_FORWARDING_POP_MPLS_AND_NEXT)
Yi Tseng1b154bd2017-11-20 17:48:19 -0800264 .withParameter(nextIdParam)
265 .build();
266 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
267 .piTableAction(setNextIdAction)
268 .build();
Yi Tseng43ee7e82018-04-12 16:37:34 +0800269 testSpecificForward(FabricConstants.FABRIC_INGRESS_FORWARDING_MPLS,
270 expectedSelector, selector, NEXT_ID_1, treatment);
Yi Tseng0b809722017-11-03 10:23:26 -0700271 }
272
273 private void testSpecificForward(PiTableId expectedTableId, TrafficSelector expectedSelector,
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800274 TrafficSelector selector, Integer nextId) throws FabricPipelinerException {
Yi Tsengdf3eec52018-02-15 14:56:02 -0800275 TrafficTreatment setNextIdTreatment;
276 if (nextId == null) {
277 // Ref: RoutingRulePopulator.java->revokeIpRuleForRouter
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800278
279 setNextIdTreatment = DefaultTrafficTreatment.builder().
280 piTableAction(PiAction.builder()
281 .withId(FabricConstants.FABRIC_INGRESS_FORWARDING_NOP_ROUTING_V4)
282 .build())
283 .build();
Yi Tsengdf3eec52018-02-15 14:56:02 -0800284 } else {
Charles Chanea89a1c2018-08-13 13:14:18 -0700285 PiActionParam nextIdParam = new PiActionParam(FabricConstants.NEXT_ID, nextId);
Yi Tseng47eac892018-07-11 02:17:04 +0800286 PiAction.Builder setNextIdAction = PiAction.builder()
287 .withParameter(nextIdParam);
288
289 if (expectedTableId.equals(FabricConstants.FABRIC_INGRESS_FORWARDING_BRIDGING)) {
290 setNextIdAction.withId(FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_BRIDGING);
Charles Chan384aea22018-08-23 22:08:02 -0700291 } else if (expectedTableId.equals(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4)) {
292 setNextIdAction.withId(FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_ROUTING_V4);
293 } else if (expectedTableId.equals(FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V6)) {
294 setNextIdAction.withId(FabricConstants.FABRIC_INGRESS_FORWARDING_SET_NEXT_ID_ROUTING_V6);
Yi Tseng47eac892018-07-11 02:17:04 +0800295 }
296
Yi Tsengdf3eec52018-02-15 14:56:02 -0800297 setNextIdTreatment = DefaultTrafficTreatment.builder()
Yi Tseng47eac892018-07-11 02:17:04 +0800298 .piTableAction(setNextIdAction.build())
Yi Tsengdf3eec52018-02-15 14:56:02 -0800299 .build();
300 }
Yi Tseng1b154bd2017-11-20 17:48:19 -0800301
302 testSpecificForward(expectedTableId, expectedSelector, selector, nextId, setNextIdTreatment);
303
304 }
305
306 private void testSpecificForward(PiTableId expectedTableId, TrafficSelector expectedSelector,
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800307 TrafficSelector selector, Integer nextId, TrafficTreatment treatment)
308 throws FabricPipelinerException {
Yi Tsengdf3eec52018-02-15 14:56:02 -0800309 ForwardingObjective.Builder fwd = DefaultForwardingObjective.builder()
Yi Tseng0b809722017-11-03 10:23:26 -0700310 .withSelector(selector)
311 .withPriority(PRIORITY)
312 .fromApp(APP_ID)
313 .makePermanent()
Yi Tsengdf3eec52018-02-15 14:56:02 -0800314 .withTreatment(treatment)
315 .withFlag(ForwardingObjective.Flag.SPECIFIC);
Yi Tseng0b809722017-11-03 10:23:26 -0700316
Yi Tsengdf3eec52018-02-15 14:56:02 -0800317 if (nextId != null) {
318 fwd.nextStep(nextId);
319 }
320
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800321 ObjectiveTranslation actualTranslation = translator.translate(fwd.add());
Yi Tseng0b809722017-11-03 10:23:26 -0700322
323 FlowRule expectedFlowRule = DefaultFlowRule.builder()
324 .forDevice(DEVICE_ID)
325 .forTable(expectedTableId)
326 .withPriority(PRIORITY)
327 .makePermanent()
328 .withSelector(expectedSelector)
Yi Tseng1b154bd2017-11-20 17:48:19 -0800329 .withTreatment(treatment)
Yi Tseng0b809722017-11-03 10:23:26 -0700330 .fromApp(APP_ID)
331 .build();
332
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800333 ObjectiveTranslation expectedTranslation = ObjectiveTranslation.builder()
334 .addFlowRule(expectedFlowRule)
335 .build();
336
337 assertEquals(expectedTranslation, actualTranslation);
Yi Tseng0b809722017-11-03 10:23:26 -0700338 }
Charles Chan384aea22018-08-23 22:08:02 -0700339
340 private TrafficSelector buildExpectedSelector(TrafficSelector selector) {
341 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
342 selector.criteria().forEach(c -> {
343 if (c.type() == Criterion.Type.ETH_DST) {
344 sbuilder.matchEthDstMasked(((EthCriterion) c).mac(), MacAddress.EXACT_MASK);
345 } else {
346 sbuilder.add(c);
347 }
348 });
349 return sbuilder.build();
350 }
Yi Tseng0b809722017-11-03 10:23:26 -0700351}