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