blob: 29c83527ad9f7f006623bc24544b33ac04606880 [file] [log] [blame]
gaurav36785932016-03-10 17:24:04 +05301/*
2 * Copyright 2015 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.routing.impl;
17
18import static org.easymock.EasyMock.anyObject;
19import static org.easymock.EasyMock.createMock;
20import static org.easymock.EasyMock.expect;
21import static org.easymock.EasyMock.replay;
22import static org.easymock.EasyMock.reset;
23import static org.easymock.EasyMock.verify;
24
25import java.util.ArrayList;
26import java.util.Collections;
27import java.util.Dictionary;
gaurav164cf6d2016-03-25 21:43:04 +053028import java.util.HashSet;
gaurav36785932016-03-10 17:24:04 +053029import java.util.List;
30import java.util.Set;
31
32import org.easymock.EasyMock;
33import org.junit.Before;
34import org.junit.Test;
35import org.onlab.packet.Ethernet;
36import org.onlab.packet.Ip4Address;
37import org.onlab.packet.Ip4Prefix;
38import org.onlab.packet.IpAddress;
39import org.onlab.packet.IpPrefix;
40import org.onlab.packet.MacAddress;
41import org.onlab.packet.VlanId;
42import org.onosproject.TestApplicationId;
43import org.onosproject.core.ApplicationId;
44import org.onosproject.core.CoreService;
45import org.onosproject.core.CoreServiceAdapter;
46import org.osgi.service.component.ComponentContext;
47import org.onosproject.cfg.ComponentConfigService;
48import org.onosproject.incubator.net.intf.Interface;
gaurav164cf6d2016-03-25 21:43:04 +053049import org.onosproject.incubator.net.intf.InterfaceListener;
gaurav36785932016-03-10 17:24:04 +053050import org.onosproject.incubator.net.intf.InterfaceService;
gaurav164cf6d2016-03-25 21:43:04 +053051import org.onosproject.incubator.net.intf.InterfaceServiceAdapter;
gaurav36785932016-03-10 17:24:04 +053052import org.onosproject.net.ConnectPoint;
53import org.onosproject.net.DeviceId;
54import org.onosproject.net.PortNumber;
55import org.onosproject.net.config.NetworkConfigService;
56import org.onosproject.net.device.DeviceListener;
57import org.onosproject.net.device.DeviceService;
58import org.onosproject.net.device.DeviceServiceAdapter;
59import org.onosproject.net.flow.DefaultTrafficSelector;
60import org.onosproject.net.flow.DefaultTrafficTreatment;
61import org.onosproject.net.flow.TrafficSelector;
62import org.onosproject.net.flow.TrafficTreatment;
63import org.onosproject.net.flowobjective.DefaultForwardingObjective;
64import org.onosproject.net.flowobjective.DefaultNextObjective;
65import org.onosproject.net.flowobjective.FlowObjectiveService;
66import org.onosproject.net.flowobjective.ForwardingObjective;
67import org.onosproject.net.flowobjective.NextObjective;
68import org.onosproject.net.host.InterfaceIpAddress;
69import org.onosproject.net.intent.AbstractIntentTest;
70import org.onosproject.routing.FibEntry;
71import org.onosproject.routing.FibListener;
72import org.onosproject.routing.FibUpdate;
73import org.onosproject.routing.RoutingService;
74import org.onosproject.routing.RoutingServiceAdapter;
75import org.onosproject.routing.config.RouterConfig;
gaurav36785932016-03-10 17:24:04 +053076import com.google.common.collect.ImmutableSet;
77import com.google.common.collect.Sets;
78
79/**
80 * Unit tests for SingleSwitchFibInstaller.
81 */
82public class SingleSwitchFibInstallerTest extends AbstractIntentTest {
83
84 //for interface service setup
85 private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
86 DeviceId.deviceId("of:0000000000000001"),
87 PortNumber.portNumber(1));
88
89 private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
90 DeviceId.deviceId("of:0000000000000002"),
91 PortNumber.portNumber(1));
92
93 private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
94 DeviceId.deviceId("of:0000000000000003"),
95 PortNumber.portNumber(1));
96
97 private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
98 DeviceId.deviceId("of:0000000000000004"),
99 PortNumber.portNumber(1));
100
101 private DeviceId deviceId = DeviceId.deviceId("of:0000000000000001");
102 private final Set<Interface> interfaces = Sets.newHashSet();
103 private InterfaceService interfaceService;
104 private NetworkConfigService networkConfigService;
105 private FlowObjectiveService flowObjectiveService;
106 private DeviceService deviceService;
107 private static final ApplicationId APPID = TestApplicationId.create("update fib");
108 private FibListener fibListener;
109 private DeviceListener deviceListener;
110 private CoreService coreService;
111 private RouterConfig routerConfig;
112 private RoutingService routingService;
gaurav164cf6d2016-03-25 21:43:04 +0530113 private SingleSwitchFibInstaller sSfibInstaller;
114 private InterfaceListener interfaceListener;
gaurav36785932016-03-10 17:24:04 +0530115
116 @Before
117 public void setUp() throws Exception {
118 super.setUp();
119 sSfibInstaller = new SingleSwitchFibInstaller();
120
121 //component config service
122 ComponentConfigService mockComponenetConfigServ = EasyMock.createMock(ComponentConfigService.class);
123 expect(mockComponenetConfigServ.getProperties(anyObject())).andReturn(ImmutableSet.of());
124 mockComponenetConfigServ.registerProperties(sSfibInstaller.getClass());
125 EasyMock.expectLastCall();
126 mockComponenetConfigServ.unregisterProperties(sSfibInstaller.getClass(), false);
127 EasyMock.expectLastCall();
128 expect(mockComponenetConfigServ.getProperties(anyObject())).andReturn(ImmutableSet.of());
129 sSfibInstaller.componentConfigService = mockComponenetConfigServ;
130 replay(mockComponenetConfigServ);
131
132 //component context
133 ComponentContext mockContext = EasyMock.createMock(ComponentContext.class);
134 Dictionary<String, Boolean> properties = null;
135 expect(mockContext.getProperties()).andReturn(properties);
136 replay(mockContext);
137
138 coreService = new TestCoreService();
139 routingService = new TestRoutingService();
140 routerConfig = new TestRouterConfig();
gaurav164cf6d2016-03-25 21:43:04 +0530141 //interfaceService = createMock(InterfaceService.class);
142 interfaceService = new TestInterfaceService();
gaurav36785932016-03-10 17:24:04 +0530143 networkConfigService = createMock(NetworkConfigService.class);
144 flowObjectiveService = createMock(FlowObjectiveService.class);
145 deviceService = new TestDeviceService();
146
147 sSfibInstaller.networkConfigService = networkConfigService;
148 sSfibInstaller.interfaceService = interfaceService;
149 sSfibInstaller.flowObjectiveService = flowObjectiveService;
150 sSfibInstaller.coreService = coreService;
151 sSfibInstaller.routingService = new TestRoutingService();
152 sSfibInstaller.deviceService = deviceService;
153
154 setUpNetworkConfigService();
155 setUpInterfaceService();
156 sSfibInstaller.activate(mockContext);
157 }
158
159 /**
160 * Sets up InterfaceService.
161 */
162 private void setUpInterfaceService() {
163 Set<InterfaceIpAddress> interfaceIpAddresses1 = Sets.newHashSet();
164 interfaceIpAddresses1.add(new InterfaceIpAddress(
gaurav164cf6d2016-03-25 21:43:04 +0530165 IpAddress.valueOf("192.168.10.1"),
gaurav36785932016-03-10 17:24:04 +0530166 IpPrefix.valueOf("192.168.10.0/24")));
167 Interface sw1Eth1 = new Interface(SW1_ETH1.deviceId().toString(), SW1_ETH1,
168 interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
169 VlanId.NONE);
170 interfaces.add(sw1Eth1);
171
172 Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
gaurav164cf6d2016-03-25 21:43:04 +0530173 interfaceIpAddresses2.add(new InterfaceIpAddress(IpAddress.valueOf("192.168.20.1"),
gaurav36785932016-03-10 17:24:04 +0530174 IpPrefix.valueOf("192.168.20.0/24")));
175 Interface sw2Eth1 = new Interface(SW2_ETH1.deviceId().toString(), SW2_ETH1,
176 interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
177 VlanId.NONE);
178 interfaces.add(sw2Eth1);
179
180 Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
181 interfaceIpAddresses3.add(
182 new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"),
183 IpPrefix.valueOf("192.168.30.0/24")));
184 Interface sw3Eth1 = new Interface(SW3_ETH1.deviceId().toString(), SW3_ETH1,
185 interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"), VlanId.NONE);
186 interfaces.add(sw3Eth1);
187
188 InterfaceIpAddress interfaceIpAddress4 =
gaurav164cf6d2016-03-25 21:43:04 +0530189 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.1"),
gaurav36785932016-03-10 17:24:04 +0530190 IpPrefix.valueOf("192.168.40.0/24"));
191
192 Interface sw4Eth1 = new Interface(SW4_ETH1.deviceId().toString(), SW4_ETH1,
193 Sets.newHashSet(interfaceIpAddress4),
194 MacAddress.valueOf("00:00:00:00:00:04"),
195 VlanId.vlanId((short) 1));
gaurav36785932016-03-10 17:24:04 +0530196 interfaces.add(sw4Eth1);
gaurav36785932016-03-10 17:24:04 +0530197 }
198
199 /*
200 * Sets up NetworkConfigService.
201 */
202 private void setUpNetworkConfigService() {
203 ApplicationId routerAppId = coreService.registerApplication(RoutingService.ROUTER_APP_ID);
204 expect(networkConfigService.getConfig(routerAppId, RoutingService.ROUTER_CONFIG_CLASS)).
205 andReturn(routerConfig);
206 replay(networkConfigService);
207 }
208
209 /**
210 * Sets up FlowObjectiveService.
211 */
212 private void setUpFlowObjectiveService() {
213 expect(flowObjectiveService.allocateNextId()).andReturn(11);
214 replay(flowObjectiveService);
215 }
216
217 /**
218 * Tests adding a FIB entry to the flowObjectiveService.
219 *
220 * We verify that the flowObjectiveService records the correct state and that the
221 * correct flow is submitted to the flowObjectiveService.
222 */
223 @Test
224 public void testFibAdd() {
225 IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
226 FibEntry fibEntry = new FibEntry(prefix,
227 Ip4Address.valueOf("192.168.10.1"),
228 MacAddress.valueOf("00:00:00:00:00:01"));
229
230 //create the next Objective
231 Interface egressIntf = interfaceService.getMatchingInterface(fibEntry.nextHopIp());
232 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
233 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:01"))
234 .setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
235 TrafficSelector.Builder metabuilder = null;
236 if (!egressIntf.vlan().equals(VlanId.NONE)) {
237 treatment.pushVlan()
238 .setVlanId(egressIntf.vlan())
239 .setVlanPcp((byte) 0);
240 } else {
241 metabuilder = DefaultTrafficSelector.builder();
242 metabuilder.matchVlanId(VlanId.vlanId(SingleSwitchFibInstaller.ASSIGNED_VLAN));
243 }
244 treatment.setOutput(PortNumber.portNumber(1));
245 int nextId = 11;
246 NextObjective.Builder nextBuilder = DefaultNextObjective.builder()
247 .withId(nextId)
248 .addTreatment(treatment.build())
249 .withType(NextObjective.Type.SIMPLE)
250 .fromApp(APPID);
251 if (metabuilder != null) {
252 nextBuilder.withMeta(metabuilder.build());
253 }
254
255 NextObjective nextObjective = nextBuilder.add();
256 flowObjectiveService.next(deviceId, nextObjective);
257
258 //set up the flowObjective
259 TrafficSelector selector = DefaultTrafficSelector.builder()
260 .matchEthType(Ethernet.TYPE_IPV4)
261 .matchIPDst(prefix)
262 .build();
263
264 int priority = prefix.prefixLength() * 5 + 100;
265 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder()
266 .fromApp(APPID)
267 .makePermanent()
268 .withSelector(selector)
269 .withPriority(priority)
270 .withFlag(ForwardingObjective.Flag.SPECIFIC);
271
272 Integer nextId1 = 11;
273 fwdBuilder.nextStep(nextId1);
274 flowObjectiveService.forward(deviceId, fwdBuilder.add());
275 EasyMock.expectLastCall().once();
276 setUpFlowObjectiveService();
277
278 // Send in the UPDATE FibUpdate
279 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
280 fibListener.update(Collections.singleton(fibUpdate), Collections.emptyList());
281 verify(flowObjectiveService);
282 }
283
284 /**
285 * Tests adding a FIB entry with to a next hop in a VLAN.
286 *
287 * We verify that the flowObjectiveService records the correct state and that the
288 * correct flowObjectiveService is submitted to the flowObjectiveService.
289 */
290 @Test
291 public void testFibAddWithVlan() {
292 IpPrefix prefix = Ip4Prefix.valueOf("3.3.3.0/24");
293 FibEntry fibEntry = new FibEntry(prefix,
294 Ip4Address.valueOf("192.168.40.1"),
295 MacAddress.valueOf("00:00:00:00:00:04"));
296
297 //create the next Objective
298 Interface egressIntf = interfaceService.getMatchingInterface(fibEntry.nextHopIp());
299 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
300 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:04"))
301 .setEthDst(MacAddress.valueOf("00:00:00:00:00:04"));
302 TrafficSelector.Builder metabuilder = null;
303 if (!egressIntf.vlan().equals(VlanId.NONE)) {
304 treatment.pushVlan()
305 .setVlanId(egressIntf.vlan())
306 .setVlanPcp((byte) 0);
307 } else {
308 metabuilder = DefaultTrafficSelector.builder();
309 metabuilder.matchVlanId(VlanId.vlanId(SingleSwitchFibInstaller.ASSIGNED_VLAN));
310 }
311 treatment.setOutput(PortNumber.portNumber(1));
312 int nextId = 11;
313 NextObjective.Builder nextBuilder = DefaultNextObjective.builder()
314 .withId(nextId)
315 .addTreatment(treatment.build())
316 .withType(NextObjective.Type.SIMPLE)
317 .fromApp(APPID);
318 if (metabuilder != null) {
319 nextBuilder.withMeta(metabuilder.build());
320 }
321
322 NextObjective nextObjective = nextBuilder.add();
323 flowObjectiveService.next(deviceId, nextObjective);
324
325 //set up the flowObjective
326 TrafficSelector selector = DefaultTrafficSelector.builder()
327 .matchEthType(Ethernet.TYPE_IPV4)
328 .matchIPDst(prefix)
329 .build();
330
331 int priority = prefix.prefixLength() * 5 + 100;
332 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder()
333 .fromApp(APPID)
334 .makePermanent()
335 .withSelector(selector)
336 .withPriority(priority)
337 .withFlag(ForwardingObjective.Flag.SPECIFIC);
338
339 Integer nextId1 = 11;
340 fwdBuilder.nextStep(nextId1);
341 flowObjectiveService.forward(deviceId, fwdBuilder.add());
342 EasyMock.expectLastCall().once();
343 setUpFlowObjectiveService();
344
345 // Send in the UPDATE FibUpdate
346 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
347 fibListener.update(Collections.singleton(fibUpdate), Collections.emptyList());
348
349 verify(flowObjectiveService);
350 }
351
352 /**
353 * Tests updating a FIB entry.
354 *
355 * We verify that the flowObjectiveService records the correct state and that the
356 * correct flow is submitted to the flowObjectiveService.
357 */
358 @Test
359 public void testFibUpdate() {
360 // Firstly add a route
361 testFibAdd();
362 reset(flowObjectiveService);
363 IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
364 // Start to construct a new route entry and new intent
365 FibEntry fibEntryUpdate = new FibEntry(prefix,
366 Ip4Address.valueOf("192.168.20.1"),
367 MacAddress.valueOf("00:00:00:00:00:02"));
368
369 //create the next Objective
370 Interface egressIntf = interfaceService.getMatchingInterface(fibEntryUpdate.nextHopIp());
371 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
372 .setEthSrc(MacAddress.valueOf("00:00:00:00:00:02"))
373 .setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
374 TrafficSelector.Builder metabuilder = null;
375 if (!egressIntf.vlan().equals(VlanId.NONE)) {
376 treatment.pushVlan()
377 .setVlanId(egressIntf.vlan())
378 .setVlanPcp((byte) 0);
379 } else {
380 metabuilder = DefaultTrafficSelector.builder();
381 metabuilder.matchVlanId(VlanId.vlanId(SingleSwitchFibInstaller.ASSIGNED_VLAN));
382 }
383 treatment.setOutput(PortNumber.portNumber(1));
384 int nextId = 11;
385 NextObjective.Builder nextBuilder = DefaultNextObjective.builder()
386 .withId(nextId)
387 .addTreatment(treatment.build())
388 .withType(NextObjective.Type.SIMPLE)
389 .fromApp(APPID);
390 if (metabuilder != null) {
391 nextBuilder.withMeta(metabuilder.build());
392 }
393
394 NextObjective nextObjective = nextBuilder.add();
395 flowObjectiveService.next(deviceId, nextObjective);
396
397 //set up the flowObjective
398 TrafficSelector selector = DefaultTrafficSelector.builder()
399 .matchEthType(Ethernet.TYPE_IPV4)
400 .matchIPDst(prefix)
401 .build();
402
403 int priority = prefix.prefixLength() * 5 + 100;
404 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder()
405 .fromApp(APPID)
406 .makePermanent()
407 .withSelector(selector)
408 .withPriority(priority)
409 .withFlag(ForwardingObjective.Flag.SPECIFIC);
410
411 Integer nextId1 = 11;
412 fwdBuilder.nextStep(nextId1);
413 flowObjectiveService.forward(deviceId, fwdBuilder.add());
414 EasyMock.expectLastCall().once();
415 setUpFlowObjectiveService();
416
417 // Send in the UPDATE FibUpdate
418 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
419 fibEntryUpdate);
420 fibListener.update(Collections.singletonList(fibUpdate),
421 Collections.emptyList());
422
423 verify(flowObjectiveService);
424 }
425
426 /**
427 * Tests deleting a FIB entry.
428 *
429 * We verify that the flowObjectiveService records the correct state and that the
430 * correct flow is withdrawn from the flowObjectiveService.
431 */
432
433 @Test
434 public void testFibDelete() {
435 // Firstly add a route
436 testFibAdd();
437 IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
438
439 // Construct the existing route entry
440 FibEntry fibEntry = new FibEntry(prefix, null, null);
441
442 //set up the flowObjective
443 TrafficSelector selector = DefaultTrafficSelector.builder()
444 .matchEthType(Ethernet.TYPE_IPV4)
445 .matchIPDst(prefix)
446 .build();
447
448 int priority = prefix.prefixLength() * 5 + 100;
449
450 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder()
451 .fromApp(APPID)
452 .makePermanent()
453 .withSelector(selector)
454 .withPriority(priority)
455 .withFlag(ForwardingObjective.Flag.SPECIFIC);
456 fwdBuilder.withTreatment(DefaultTrafficTreatment.builder().build());
457 reset(flowObjectiveService);
458 flowObjectiveService.forward(deviceId, fwdBuilder.remove());
459 replay(flowObjectiveService);
460
461 // Send in the DELETE FibUpdate
462 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.DELETE, fibEntry);
463 fibListener.update(Collections.emptyList(), Collections.singletonList(fibUpdate));
464
465 verify(flowObjectiveService);
466 }
467
gaurav164cf6d2016-03-25 21:43:04 +0530468 private class TestInterfaceService extends InterfaceServiceAdapter {
469
470 @Override
471 public void addListener(InterfaceListener listener) {
472 SingleSwitchFibInstallerTest.this.interfaceListener = listener;
473 }
474
475 @Override
476 public Set<Interface> getInterfaces() {
477 return interfaces;
478 }
479
480 @Override
481 public Set<Interface> getInterfacesByPort(ConnectPoint port) {
482
483 Set<Interface> setIntf = new HashSet<Interface>();
484 for (Interface intf : interfaces) {
485 if (intf.connectPoint().equals(port)) {
486 setIntf.add(intf);
487
488 }
489 }
490 return setIntf;
491 }
492
493 @Override
494 public Interface getMatchingInterface(IpAddress ip) {
495 Interface intff = null;
496 for (Interface intf : interfaces) {
497 for (InterfaceIpAddress address : intf.ipAddresses()) {
498 if (address.ipAddress().equals(ip)) {
499 intff = intf;
500 break;
501 }
502 }
503 }
504
505 return intff;
506 }
507 }
508
gaurav36785932016-03-10 17:24:04 +0530509 private class TestCoreService extends CoreServiceAdapter {
510
511 @Override
512 public ApplicationId getAppId(String name) {
513 return APPID;
514 }
515
516 @Override
517 public ApplicationId registerApplication(String name) {
518 return APPID;
519 }
520 }
521
522 private class TestRoutingService extends RoutingServiceAdapter {
523
524 @Override
525 public void addFibListener(FibListener fibListener) {
526 SingleSwitchFibInstallerTest.this.fibListener = fibListener;
527 }
528 }
529
530 private class TestRouterConfig extends RouterConfig {
531
532 @Override
533 public List<String> getInterfaces() {
534 ArrayList<String> interfaces = new ArrayList<>();
535 interfaces.add("of:0000000000000001/1");
536 interfaces.add("of:0000000000000002/1");
537 interfaces.add("of:0000000000000003/1");
538 interfaces.add("of:0000000000000004/1");
539 return interfaces;
540 }
541
542 @Override
543 public ConnectPoint getControlPlaneConnectPoint() {
544 return SW1_ETH1;
545 }
546
547 @Override
548 public boolean getOspfEnabled() {
549 return true;
550 }
551 }
552
553 private class TestDeviceService extends DeviceServiceAdapter {
554
555 @Override
556 public boolean isAvailable(DeviceId deviceId) {
557 return true;
558 }
559
560 @Override
561 public void addListener(DeviceListener listener) {
562 SingleSwitchFibInstallerTest.this.deviceListener = listener;
563 }
564 }
565}