blob: 5c3243ff63ab8852c0544c7794a6d8e8d5f427d4 [file] [log] [blame]
Jonathan Hart9a426f82015-09-03 15:43:13 +02001/*
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 */
16
17package org.onosproject.sdnip;
18
19import com.google.common.collect.Sets;
20import org.junit.Before;
21import org.junit.Test;
22import org.onlab.packet.Ethernet;
23import org.onlab.packet.Ip4Address;
24import org.onlab.packet.Ip4Prefix;
25import org.onlab.packet.IpAddress;
26import org.onlab.packet.IpPrefix;
27import org.onlab.packet.MacAddress;
28import org.onlab.packet.VlanId;
29import org.onosproject.TestApplicationId;
30import org.onosproject.core.ApplicationId;
Jonathan Hart365335e2015-12-10 11:09:53 -080031import org.onosproject.core.CoreServiceAdapter;
Jonathan Hart9a426f82015-09-03 15:43:13 +020032import org.onosproject.incubator.net.intf.Interface;
33import org.onosproject.incubator.net.intf.InterfaceService;
34import org.onosproject.net.ConnectPoint;
35import org.onosproject.net.DeviceId;
36import org.onosproject.net.PortNumber;
37import org.onosproject.net.flow.DefaultTrafficSelector;
38import org.onosproject.net.flow.DefaultTrafficTreatment;
39import org.onosproject.net.flow.TrafficSelector;
40import org.onosproject.net.flow.TrafficTreatment;
41import org.onosproject.net.host.InterfaceIpAddress;
42import org.onosproject.net.intent.AbstractIntentTest;
43import org.onosproject.net.intent.Key;
44import org.onosproject.net.intent.MultiPointToSinglePointIntent;
45import org.onosproject.routing.FibEntry;
Jonathan Hart365335e2015-12-10 11:09:53 -080046import org.onosproject.routing.FibListener;
Jonathan Hart9a426f82015-09-03 15:43:13 +020047import org.onosproject.routing.FibUpdate;
48import org.onosproject.routing.IntentSynchronizationService;
Jonathan Hart365335e2015-12-10 11:09:53 -080049import org.onosproject.routing.RoutingServiceAdapter;
Jonathan Hart9a426f82015-09-03 15:43:13 +020050import org.onosproject.routing.config.BgpPeer;
51import org.onosproject.routing.config.RoutingConfigurationService;
52
53import java.util.Collections;
54import java.util.HashMap;
55import java.util.HashSet;
56import java.util.Map;
57import java.util.Set;
58
59import static org.easymock.EasyMock.createMock;
60import static org.easymock.EasyMock.expect;
61import static org.easymock.EasyMock.replay;
62import static org.easymock.EasyMock.reset;
63import static org.easymock.EasyMock.verify;
64import static org.onosproject.sdnip.TestIntentServiceHelper.eqExceptId;
65
66/**
67 * Unit tests for SdnIpFib.
68 */
69public class SdnIpFibTest extends AbstractIntentTest {
70
71 private RoutingConfigurationService routingConfig;
72 private InterfaceService interfaceService;
73
74 private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
75 DeviceId.deviceId("of:0000000000000001"),
76 PortNumber.portNumber(1));
77
78 private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
79 DeviceId.deviceId("of:0000000000000002"),
80 PortNumber.portNumber(1));
81
82 private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
83 DeviceId.deviceId("of:0000000000000003"),
84 PortNumber.portNumber(1));
85
86 private static final ConnectPoint SW4_ETH1 = new ConnectPoint(
87 DeviceId.deviceId("of:0000000000000004"),
88 PortNumber.portNumber(1));
89
90 private SdnIpFib sdnipFib;
91 private IntentSynchronizationService intentSynchronizer;
92 private final Set<Interface> interfaces = Sets.newHashSet();
93
94 private static final ApplicationId APPID = TestApplicationId.create("SDNIP");
95
Jonathan Hart365335e2015-12-10 11:09:53 -080096 private FibListener fibListener;
97
Jonathan Hart9a426f82015-09-03 15:43:13 +020098 @Before
99 public void setUp() throws Exception {
100 super.setUp();
101
102 routingConfig = createMock(RoutingConfigurationService.class);
103 interfaceService = createMock(InterfaceService.class);
104
105 // These will set expectations on routingConfig and interfaceService
106 setUpInterfaceService();
107 setUpBgpPeers();
108
109 replay(routingConfig);
110 replay(interfaceService);
111
112 intentSynchronizer = createMock(IntentSynchronizationService.class);
113
Jonathan Hart365335e2015-12-10 11:09:53 -0800114 sdnipFib = new SdnIpFib();
115 sdnipFib.routingService = new TestRoutingService();
116 sdnipFib.coreService = new TestCoreService();
117 sdnipFib.interfaceService = interfaceService;
118 sdnipFib.intentSynchronizer = intentSynchronizer;
119
120 sdnipFib.activate();
Jonathan Hart9a426f82015-09-03 15:43:13 +0200121 }
122
123 /**
124 * Sets up BGP peers in external networks.
125 */
126 private void setUpBgpPeers() {
127
128 Map<IpAddress, BgpPeer> peers = new HashMap<>();
129
130 String peerSw1Eth1 = "192.168.10.1";
131 peers.put(IpAddress.valueOf(peerSw1Eth1),
132 new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
133
134 // Two BGP peers are connected to switch 2 port 1.
135 String peer1Sw2Eth1 = "192.168.20.1";
136 peers.put(IpAddress.valueOf(peer1Sw2Eth1),
137 new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
138
139 String peer2Sw2Eth1 = "192.168.20.2";
140 peers.put(IpAddress.valueOf(peer2Sw2Eth1),
141 new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
142
143 String peer1Sw4Eth1 = "192.168.40.1";
144 peers.put(IpAddress.valueOf(peer1Sw4Eth1),
145 new BgpPeer("00:00:00:00:00:00:00:04", 1, peer1Sw4Eth1));
146
147 expect(routingConfig.getBgpPeers()).andReturn(peers).anyTimes();
148 }
149
150 /**
151 * Sets up InterfaceService.
152 */
153 private void setUpInterfaceService() {
154 Set<InterfaceIpAddress> interfaceIpAddresses1 = Sets.newHashSet();
155 interfaceIpAddresses1.add(new InterfaceIpAddress(
156 IpAddress.valueOf("192.168.10.101"),
157 IpPrefix.valueOf("192.168.10.0/24")));
158 Interface sw1Eth1 = new Interface(SW1_ETH1,
159 interfaceIpAddresses1, MacAddress.valueOf("00:00:00:00:00:01"),
160 VlanId.NONE);
161 interfaces.add(sw1Eth1);
162
163 Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
164 interfaceIpAddresses2.add(
165 new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"),
166 IpPrefix.valueOf("192.168.20.0/24")));
167 Interface sw2Eth1 = new Interface(SW2_ETH1,
168 interfaceIpAddresses2, MacAddress.valueOf("00:00:00:00:00:02"),
169 VlanId.NONE);
170 interfaces.add(sw2Eth1);
171
172 Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
173 interfaceIpAddresses3.add(
174 new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"),
175 IpPrefix.valueOf("192.168.30.0/24")));
176 Interface sw3Eth1 = new Interface(SW3_ETH1,
177 interfaceIpAddresses3, MacAddress.valueOf("00:00:00:00:00:03"),
178 VlanId.NONE);
179 interfaces.add(sw3Eth1);
180
181 InterfaceIpAddress interfaceIpAddress4 =
182 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"),
183 IpPrefix.valueOf("192.168.40.0/24"));
184 Interface sw4Eth1 = new Interface(SW4_ETH1,
185 Sets.newHashSet(interfaceIpAddress4),
186 MacAddress.valueOf("00:00:00:00:00:04"),
187 VlanId.vlanId((short) 1));
188
189 expect(interfaceService.getInterfacesByPort(SW4_ETH1)).andReturn(
190 Collections.singleton(sw4Eth1)).anyTimes();
191 expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.40.1")))
192 .andReturn(sw4Eth1).anyTimes();
193
194 interfaces.add(sw4Eth1);
195
196 expect(interfaceService.getInterfacesByPort(SW1_ETH1)).andReturn(
197 Collections.singleton(sw1Eth1)).anyTimes();
198 expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.10.1")))
199 .andReturn(sw1Eth1).anyTimes();
200 expect(interfaceService.getInterfacesByPort(SW2_ETH1)).andReturn(
201 Collections.singleton(sw2Eth1)).anyTimes();
202 expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.20.1")))
203 .andReturn(sw2Eth1).anyTimes();
204 expect(interfaceService.getInterfacesByPort(SW3_ETH1)).andReturn(
205 Collections.singleton(sw3Eth1)).anyTimes();
206 expect(interfaceService.getMatchingInterface(Ip4Address.valueOf("192.168.30.1")))
207 .andReturn(sw3Eth1).anyTimes();
208 expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
209 }
210
211 /**
212 * Tests adding a FIB entry to the IntentSynchronizer.
213 *
214 * We verify that the synchronizer records the correct state and that the
215 * correct intent is submitted to the IntentService.
216 */
217 @Test
218 public void testFibAdd() {
219 IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
220 FibEntry fibEntry = new FibEntry(prefix,
221 Ip4Address.valueOf("192.168.10.1"),
222 MacAddress.valueOf("00:00:00:00:00:01"));
223
224 // Construct a MultiPointToSinglePointIntent intent
225 TrafficSelector.Builder selectorBuilder =
226 DefaultTrafficSelector.builder();
227 selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
228 fibEntry.prefix());
229
230 TrafficTreatment.Builder treatmentBuilder =
231 DefaultTrafficTreatment.builder();
232 treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
233
234 Set<ConnectPoint> ingressPoints = new HashSet<>();
235 ingressPoints.add(SW2_ETH1);
236 ingressPoints.add(SW3_ETH1);
237 ingressPoints.add(SW4_ETH1);
238
239 MultiPointToSinglePointIntent intent =
240 MultiPointToSinglePointIntent.builder()
241 .appId(APPID)
242 .key(Key.of(prefix.toString(), APPID))
243 .selector(selectorBuilder.build())
244 .treatment(treatmentBuilder.build())
245 .ingressPoints(ingressPoints)
246 .egressPoint(SW1_ETH1)
247 .constraints(SdnIpFib.CONSTRAINTS)
248 .build();
249
250 // Setup the expected intents
251 intentSynchronizer.submit(eqExceptId(intent));
252 replay(intentSynchronizer);
253
254 // Send in the UPDATE FibUpdate
255 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
Jonathan Hart365335e2015-12-10 11:09:53 -0800256 fibListener.update(Collections.singleton(fibUpdate), Collections.emptyList());
Jonathan Hart9a426f82015-09-03 15:43:13 +0200257
258 verify(intentSynchronizer);
259 }
260
261 /**
262 * Tests adding a FIB entry with to a next hop in a VLAN.
263 *
264 * We verify that the synchronizer records the correct state and that the
265 * correct intent is submitted to the IntentService.
266 */
267 @Test
268 public void testFibAddWithVlan() {
269 IpPrefix prefix = Ip4Prefix.valueOf("3.3.3.0/24");
270 FibEntry fibEntry = new FibEntry(prefix,
271 Ip4Address.valueOf("192.168.40.1"),
272 MacAddress.valueOf("00:00:00:00:00:04"));
273
274 // Construct a MultiPointToSinglePointIntent intent
275 TrafficSelector.Builder selectorBuilder =
276 DefaultTrafficSelector.builder();
277 selectorBuilder.matchEthType(Ethernet.TYPE_IPV4)
278 .matchIPDst(fibEntry.prefix())
279 .matchVlanId(VlanId.ANY);
280
281 TrafficTreatment.Builder treatmentBuilder =
282 DefaultTrafficTreatment.builder();
283 treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:04"))
284 .setVlanId(VlanId.vlanId((short) 1));
285
286 Set<ConnectPoint> ingressPoints = new HashSet<>();
287 ingressPoints.add(SW1_ETH1);
288 ingressPoints.add(SW2_ETH1);
289 ingressPoints.add(SW3_ETH1);
290
291 MultiPointToSinglePointIntent intent =
292 MultiPointToSinglePointIntent.builder()
293 .appId(APPID)
294 .key(Key.of(prefix.toString(), APPID))
295 .selector(selectorBuilder.build())
296 .treatment(treatmentBuilder.build())
297 .ingressPoints(ingressPoints)
298 .egressPoint(SW4_ETH1)
299 .constraints(SdnIpFib.CONSTRAINTS)
300 .build();
301
302 // Setup the expected intents
303 intentSynchronizer.submit(eqExceptId(intent));
304
305 replay(intentSynchronizer);
306
307 // Send in the UPDATE FibUpdate
308 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
Jonathan Hart365335e2015-12-10 11:09:53 -0800309 fibListener.update(Collections.singleton(fibUpdate), Collections.emptyList());
Jonathan Hart9a426f82015-09-03 15:43:13 +0200310
311 verify(intentSynchronizer);
312 }
313
314 /**
315 * Tests updating a FIB entry.
316 *
317 * We verify that the synchronizer records the correct state and that the
318 * correct intent is submitted to the IntentService.
319 */
320 @Test
321 public void testFibUpdate() {
322 // Firstly add a route
323 testFibAdd();
324
325 IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
326
327 // Start to construct a new route entry and new intent
328 FibEntry fibEntryUpdate = new FibEntry(prefix,
329 Ip4Address.valueOf("192.168.20.1"),
330 MacAddress.valueOf("00:00:00:00:00:02"));
331
332 // Construct a new MultiPointToSinglePointIntent intent
333 TrafficSelector.Builder selectorBuilderNew =
334 DefaultTrafficSelector.builder();
335 selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
336 fibEntryUpdate.prefix());
337
338 TrafficTreatment.Builder treatmentBuilderNew =
339 DefaultTrafficTreatment.builder();
340 treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
341
342 Set<ConnectPoint> ingressPointsNew = new HashSet<>();
343 ingressPointsNew.add(SW1_ETH1);
344 ingressPointsNew.add(SW3_ETH1);
345 ingressPointsNew.add(SW4_ETH1);
346
347 MultiPointToSinglePointIntent intentNew =
348 MultiPointToSinglePointIntent.builder()
349 .appId(APPID)
350 .key(Key.of(prefix.toString(), APPID))
351 .selector(selectorBuilderNew.build())
352 .treatment(treatmentBuilderNew.build())
353 .ingressPoints(ingressPointsNew)
354 .egressPoint(SW2_ETH1)
355 .constraints(SdnIpFib.CONSTRAINTS)
356 .build();
357
358 // Set up test expectation
359 reset(intentSynchronizer);
360
361 // Setup the expected intents
362 intentSynchronizer.submit(eqExceptId(intentNew));
363 replay(intentSynchronizer);
364
365 // Send in the UPDATE FibUpdate
366 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
367 fibEntryUpdate);
Jonathan Hart365335e2015-12-10 11:09:53 -0800368 fibListener.update(Collections.singletonList(fibUpdate),
Jonathan Hart9a426f82015-09-03 15:43:13 +0200369 Collections.emptyList());
370
371 verify(intentSynchronizer);
372 }
373
374 /**
375 * Tests deleting a FIB entry.
376 *
377 * We verify that the synchronizer records the correct state and that the
378 * correct intent is withdrawn from the IntentService.
379 */
380 @Test
381 public void testFibDelete() {
382 // Firstly add a route
383 testFibAdd();
384
385 IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
386
387 // Construct the existing route entry
388 FibEntry fibEntry = new FibEntry(prefix, null, null);
389
390 // Construct the existing MultiPointToSinglePoint intent
391 TrafficSelector.Builder selectorBuilder =
392 DefaultTrafficSelector.builder();
393 selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
394 fibEntry.prefix());
395
396 TrafficTreatment.Builder treatmentBuilder =
397 DefaultTrafficTreatment.builder();
398 treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
399
400 Set<ConnectPoint> ingressPoints = new HashSet<>();
401 ingressPoints.add(SW2_ETH1);
402 ingressPoints.add(SW3_ETH1);
403 ingressPoints.add(SW4_ETH1);
404
405 MultiPointToSinglePointIntent addedIntent =
406 MultiPointToSinglePointIntent.builder()
407 .appId(APPID)
408 .key(Key.of(prefix.toString(), APPID))
409 .selector(selectorBuilder.build())
410 .treatment(treatmentBuilder.build())
411 .ingressPoints(ingressPoints)
412 .egressPoint(SW1_ETH1)
413 .constraints(SdnIpFib.CONSTRAINTS)
414 .build();
415
416 // Set up expectation
417 reset(intentSynchronizer);
418 // Setup the expected intents
419 intentSynchronizer.withdraw(eqExceptId(addedIntent));
420 replay(intentSynchronizer);
421
422 // Send in the DELETE FibUpdate
423 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.DELETE, fibEntry);
Jonathan Hart365335e2015-12-10 11:09:53 -0800424 fibListener.update(Collections.emptyList(), Collections.singletonList(fibUpdate));
Jonathan Hart9a426f82015-09-03 15:43:13 +0200425
426 verify(intentSynchronizer);
427 }
Jonathan Hart365335e2015-12-10 11:09:53 -0800428
429 private class TestCoreService extends CoreServiceAdapter {
430 @Override
431 public ApplicationId getAppId(String name) {
432 return APPID;
433 }
434 }
435
436 private class TestRoutingService extends RoutingServiceAdapter {
437
438 @Override
439 public void addFibListener(FibListener fibListener) {
440 SdnIpFibTest.this.fibListener = fibListener;
441 }
442 }
Jonathan Hart9a426f82015-09-03 15:43:13 +0200443}