blob: 24aad06148b064a0f914990ae5fad06624816dcb [file] [log] [blame]
Sean Condonfae8e662016-12-15 10:25:13 +00001/*
2 * Copyright 2017-present Open Networking Laboratory
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 */
16package org.onosproject.drivers.microsemi;
17
18import static org.junit.Assert.assertEquals;
19import static org.junit.Assert.assertNotNull;
20import static org.junit.Assert.assertTrue;
21import static org.junit.Assert.fail;
22
23import java.util.Collection;
24import java.util.HashSet;
25import java.util.Iterator;
26import java.util.List;
27import java.util.Map;
28import java.util.Set;
29
30import org.junit.After;
31import org.junit.Before;
32import org.junit.Test;
33import org.onlab.packet.EthType.EtherType;
34import org.onlab.packet.IpPrefix;
35import org.onlab.packet.VlanId;
36import org.onosproject.core.ApplicationId;
37import org.onosproject.core.DefaultApplicationId;
38import org.onosproject.net.PortNumber;
39import org.onosproject.net.flow.DefaultFlowEntry;
40import org.onosproject.net.flow.DefaultFlowRule;
41import org.onosproject.net.flow.DefaultTrafficSelector;
42import org.onosproject.net.flow.DefaultTrafficTreatment;
43import org.onosproject.net.flow.FlowEntry;
44import org.onosproject.net.flow.FlowEntry.FlowEntryState;
45import org.onosproject.net.flow.FlowRule;
46import org.onosproject.net.flow.TrafficSelector;
47import org.onosproject.net.flow.TrafficTreatment;
48import org.onosproject.net.flow.criteria.Criteria;
49import org.onosproject.net.flow.criteria.Criterion;
50import org.onosproject.net.flow.criteria.Criterion.Type;
51import org.onosproject.net.flow.criteria.IPCriterion;
52import org.onosproject.net.flow.criteria.PortCriterion;
53import org.onosproject.net.flow.criteria.VlanIdCriterion;
54import org.onosproject.net.flow.instructions.Instruction;
55
56import com.google.common.collect.Lists;
57import com.google.common.collect.Maps;
58
59public class EA1000FlowRuleProgrammableTest {
60 EA1000FlowRuleProgrammable frProgramable;
61
62 @Before
63 public void setUp() throws Exception {
64 frProgramable = new EA1000FlowRuleProgrammable();
65 frProgramable.setHandler(new MockEa1000DriverHandler());
66 assertNotNull(frProgramable.handler().data().deviceId());
67 }
68
69 @After
70 public void tearDown() throws Exception {
71 }
72
73 @Test
74 public void testGetFlowEntries() {
75 //From MockNetconfSession sample of MseaSaFiltering
76 Collection<FlowEntry> flowEntries = frProgramable.getFlowEntries();
77
78 assertNotNull(flowEntries);
79 //There will be 12 flow entries
80 // 2 for IP Src Address filtering
81 // 2 for EVC 7 - one each port
82 // 8 for EVC 8 - one for host port, 7 on optics port because of ceVlanMap 12:14,20:22,25
83 assertEquals(12, flowEntries.size());
84
85 //Test the first Flow Entry
86 Iterator<FlowEntry> feIter = flowEntries.iterator();
87 while (feIter.hasNext()) {
88 FlowEntry fe = feIter.next();
89 assertTrue(fe.isPermanent());
90 assertEquals(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT, fe.priority());
91
92 Set<Criterion> criteria = fe.selector().criteria();
93 IPCriterion ipCr = null;
94 PortNumber port = null;
95 for (Criterion cr:criteria.toArray(new Criterion[criteria.size()])) {
96 if (cr.type() == Criterion.Type.IPV4_SRC) {
97 ipCr = (IPCriterion) cr;
98 } else if (cr.type() == Criterion.Type.IN_PORT) {
99 port = ((PortCriterion) cr).port();
100 } else if (cr.type() == Criterion.Type.VLAN_VID) {
101 VlanId vid = ((VlanIdCriterion) cr).vlanId();
102 } else {
103 fail("Unexpected Criterion type: " + cr.type().toString());
104 }
105 }
106 if (ipCr != null && (port == null || port.toLong() != 0L)) {
107 fail("Port number not equal 0 when IP Src Address filter is present");
108 }
109
110 List<Instruction> instructions = fe.treatment().allInstructions();
111
112 if (fe.tableId() == 1) {
113 //Note that in MockNetconf session 10.10.10.10/16 was entered
114 //but it has been corrected to the following by the OF implementation
115 assertEquals("10.10.0.0/16", ipCr.ip().toString());
116 assertEquals(FlowEntryState.ADDED, fe.state());
117 } else if (fe.tableId() == 2) {
118 //Likewise 20.30.40.50 has been truncated because of the 18 bit mask
119 assertEquals("20.30.0.0/18", ipCr.ip().toString());
120 assertEquals(FlowEntryState.ADDED, fe.state());
121 } else if (fe.tableId() == 7 || fe.tableId() == 8) {
122 // 7 and 8 are EVC entries - 2 elements - IN_PORT and VLAN_ID
123 assertEquals(2, fe.selector().criteria().size());
124 //In MockNetconfSession we're rigged it so that the last two chars of the
125 //flow id is the same as the VlanId
126 short vlanId = ((VlanIdCriterion) fe.selector().getCriterion(Type.VLAN_VID)).vlanId().toShort();
127 long flowId = fe.id().id();
128 String flowIdStr = String.valueOf(flowId).substring(String.valueOf(flowId).length() - 2);
129 assertEquals(flowIdStr, String.valueOf(vlanId));
130 if (((PortCriterion) fe.selector().getCriterion(Type.IN_PORT)).port().toLong() == 1L) {
131 assertEquals(Instruction.Type.L2MODIFICATION, instructions.get(0).type());
132 }
133 } else {
134 fail("Unexpected Flow Entry Rule " + fe.tableId());
135 }
136 }
137 }
138
139 @Test
140 public void testSetFlowEntries() {
141 Criterion matchInPort = Criteria.matchInPort(PortNumber.portNumber(0));
142
143 TrafficTreatment treatmentDrop = DefaultTrafficTreatment.builder().drop().build();
144
145 Collection<FlowRule> frAddedList = new HashSet<FlowRule>();
146
147 FlowRule fr4 = new DefaultFlowRule.Builder()
148 .forDevice(frProgramable.handler().data().deviceId())
149 .forTable(4)
150 .withSelector(DefaultTrafficSelector.builder()
151 .matchIPSrc(IpPrefix.valueOf("192.168.60.0/22"))
152 .add(matchInPort).build())
153 .withTreatment(treatmentDrop)
154 .fromApp(new DefaultApplicationId(4, "Filter4"))
155 .makePermanent()
156 .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
157 .build();
158 frAddedList.add(fr4);
159
160 FlowRule fr5 = new DefaultFlowRule.Builder()
161 .forDevice(frProgramable.handler().data().deviceId())
162 .forTable(5)
163 .withSelector(DefaultTrafficSelector.builder()
164 .matchIPSrc(IpPrefix.valueOf("192.168.50.0/23"))
165 .add(matchInPort).build())
166 .withTreatment(treatmentDrop)
167 .withCookie(Long.valueOf("5e0000abaa2772", 16))
168 .makePermanent()
169 .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
170 .build();
171 frAddedList.add(fr5);
172
173 //Add in some EVCs - especially with complex ceVlanMaps
174 FlowRule frEvc1Vid19P0 = new DefaultFlowRule.Builder()
175 .forDevice(frProgramable.handler().data().deviceId())
176 .forTable(1)
177 .withSelector(DefaultTrafficSelector.builder()
178 .matchInPort(PortNumber.portNumber(0L))
179 .matchVlanId(VlanId.vlanId((short) 19))
180 .build())
181 .withTreatment(DefaultTrafficTreatment.builder()
182 .popVlan()
183 .build())
184 .withCookie(Long.valueOf("1e0000abaa0019", 16))
185 .makePermanent()
186 .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
187 .build();
188 frAddedList.add(frEvc1Vid19P0);
189
190 FlowRule frEvc1Vid20P0 = new DefaultFlowRule.Builder()
191 .forDevice(frProgramable.handler().data().deviceId())
192 .forTable(1)
193 .withSelector(DefaultTrafficSelector.builder()
194 .matchInPort(PortNumber.portNumber(0L))
195 .matchVlanId(VlanId.vlanId((short) 20))
196 .build())
197 .withTreatment(DefaultTrafficTreatment.builder()
198 .popVlan()
199 .build())
200 .withCookie(Long.valueOf("1e0000abaa0020", 16))
201 .makePermanent()
202 .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
203 .build();
204 frAddedList.add(frEvc1Vid20P0);
205
206 FlowRule frEvc1Vid21P1 = new DefaultFlowRule.Builder()
207 .forDevice(frProgramable.handler().data().deviceId())
208 .forTable(1)
209 .withSelector(DefaultTrafficSelector.builder()
210 .matchInPort(PortNumber.portNumber(1L))
211 .matchVlanId(VlanId.vlanId((short) 21))
212 .build())
213 .withTreatment(DefaultTrafficTreatment.builder()
214 .setVlanId(VlanId.vlanId((short) 250))
215 .pushVlan(EtherType.QINQ.ethType())
216 .build())
217 .withCookie(Long.valueOf("1e0000abaa0121", 16))
218 .makePermanent()
219 .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
220 .build();
221 frAddedList.add(frEvc1Vid21P1);
222
223 FlowRule frEvc1Vid22P1 = new DefaultFlowRule.Builder()
224 .forDevice(frProgramable.handler().data().deviceId())
225 .forTable(1)
226 .withSelector(DefaultTrafficSelector.builder()
227 .matchInPort(PortNumber.portNumber(1L))
228 .matchVlanId(VlanId.vlanId((short) 22))
229 .build())
230 .withTreatment(DefaultTrafficTreatment.builder()
231 .setVlanId(VlanId.vlanId((short) 250))
232 .pushVlan(EtherType.QINQ.ethType())
233 .build())
234 .withCookie(Long.valueOf("1e0000abaa0122", 16))
235 .makePermanent()
236 .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
237 .build();
238 frAddedList.add(frEvc1Vid22P1);
239
240 Collection<FlowRule> returnedFrList = frProgramable.applyFlowRules(frAddedList);
241
242 assertNotNull(returnedFrList);
243 assertEquals(6, returnedFrList.size());
244
245 //Test the scenario like in FlowRuleManager$InternalFlowRuleProviderService.pushFlowMetricsInternal()
246 Map<FlowEntry, FlowEntry> storedRules = Maps.newHashMap();
247 frAddedList.forEach(f -> storedRules.put(new DefaultFlowEntry(f), new DefaultFlowEntry(f)));
248 List<FlowEntry> feList = Lists.newArrayList();
249 returnedFrList.forEach(f -> feList.add(new DefaultFlowEntry(f)));
250
251 for (FlowEntry rule : feList) {
252 FlowEntry fer = storedRules.remove(rule);
253 assertNotNull(fer);
254 assertTrue(fer.exactMatch(rule));
255 }
256
257 for (FlowRule fr:returnedFrList.toArray(new FlowRule[2])) {
258 if (fr.tableId() == 4) {
259 assertEquals("IPV4_SRC:192.168.60.0/22",
260 ((IPCriterion) fr.selector().getCriterion(Type.IPV4_SRC)).toString());
261 } else if (fr.tableId() == 5) {
262 assertEquals("IPV4_SRC:192.168.50.0/23",
263 ((IPCriterion) fr.selector().getCriterion(Type.IPV4_SRC)).toString());
264 assertEquals(Long.valueOf("5e0000abaa2772", 16), fr.id().id());
265 } else if (fr.tableId() == 1) {
266 //TODO add in tests
267 } else {
268 fail("Unexpected flow rule " + fr.tableId() + " in test");
269 }
270 }
271 }
272
273 @Test
274 public void testRemoveFlowEntries() {
275 TrafficSelector.Builder tsBuilder = DefaultTrafficSelector.builder();
276 Criterion matchInPort0 = Criteria.matchInPort(PortNumber.portNumber(0));
277 Criterion matchInPort1 = Criteria.matchInPort(PortNumber.portNumber(1));
278
279 TrafficTreatment.Builder trDropBuilder = DefaultTrafficTreatment.builder();
280 TrafficTreatment treatmentDrop = trDropBuilder.drop().build();
281
282 Collection<FlowRule> frRemoveList = new HashSet<FlowRule>();
283 ApplicationId app = new DefaultApplicationId(1, "org.onosproject.rest");
284
285 Criterion matchIpSrc1 = Criteria.matchIPSrc(IpPrefix.valueOf("10.10.10.10/16"));
286 TrafficSelector selector1 = tsBuilder.add(matchIpSrc1).add(matchInPort0).build();
287 FlowRule.Builder frBuilder1 = new DefaultFlowRule.Builder();
288 frBuilder1.forDevice(frProgramable.handler().data().deviceId())
289 .withSelector(selector1)
290 .withTreatment(treatmentDrop)
291 .forTable(2)
292 .fromApp(app)
293 .makePermanent()
294 .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT);
295 frRemoveList.add(frBuilder1.build());
296
297 Criterion matchIpSrc2 = Criteria.matchIPSrc(IpPrefix.valueOf("10.30.10.10/16"));
298 TrafficSelector selector2 = tsBuilder.add(matchIpSrc2).add(matchInPort0).build();
299 FlowRule.Builder frBuilder2 = new DefaultFlowRule.Builder();
300 frBuilder2.forDevice(frProgramable.handler().data().deviceId())
301 .withSelector(selector2)
302 .withTreatment(treatmentDrop)
303 .forTable(3)
304 .fromApp(app)
305 .makePermanent()
306 .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
307 .build();
308 frRemoveList.add(frBuilder2.build());
309
310
311 TrafficTreatment.Builder trVlanPopBuilder = DefaultTrafficTreatment.builder();
312 TrafficTreatment treatmentVlanPop = trVlanPopBuilder.popVlan().build();
313
314
315 Criterion matchVlan710 = Criteria.matchVlanId(VlanId.vlanId((short) 710));
316 TrafficSelector selector3 = DefaultTrafficSelector.builder().add(matchVlan710).add(matchInPort1).build();
317 FlowRule.Builder frBuilder3 = new DefaultFlowRule.Builder();
318 frBuilder3.forDevice(frProgramable.handler().data().deviceId())
319 .withSelector(selector3)
320 .withTreatment(treatmentVlanPop)
321 .forTable(7)
322 .fromApp(app)
323 .makePermanent()
324 .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
325 .build();
326 frRemoveList.add(frBuilder3.build());
327
328
329 Criterion matchVlan101 = Criteria.matchVlanId(VlanId.vlanId((short) 101));
330 TrafficSelector selector4 = DefaultTrafficSelector.builder().add(matchVlan101).add(matchInPort1).build();
331 FlowRule.Builder frBuilder4 = new DefaultFlowRule.Builder();
332 frBuilder4.forDevice(frProgramable.handler().data().deviceId())
333 .withSelector(selector4)
334 .withTreatment(treatmentVlanPop)
335 .forTable(1)
336 .fromApp(app)
337 .makePermanent()
338 .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
339 .build();
340 frRemoveList.add(frBuilder4.build());
341
342 Criterion matchVlan102 = Criteria.matchVlanId(VlanId.vlanId((short) 102));
343 TrafficSelector selector5 = DefaultTrafficSelector.builder().add(matchVlan102).add(matchInPort0).build();
344 FlowRule.Builder frBuilder5 = new DefaultFlowRule.Builder();
345 frBuilder5.forDevice(frProgramable.handler().data().deviceId())
346 .withSelector(selector5)
347 .withTreatment(treatmentVlanPop)
348 .forTable(1)
349 .fromApp(app)
350 .makePermanent()
351 .withPriority(EA1000FlowRuleProgrammable.PRIORITY_DEFAULT)
352 .build();
353 frRemoveList.add(frBuilder5.build());
354
355 Collection<FlowRule> removedFrList = frProgramable.removeFlowRules(frRemoveList);
356 assertNotNull(removedFrList);
357 assertEquals(5, removedFrList.size());
358
359 for (FlowRule frRemoved:removedFrList) {
360 assertNotNull(frRemoved);
361 }
362 }
363}