blob: 1248caa5aa5624a984a9d1311f721fdd32dfa9ac [file] [log] [blame]
Andreas Papazoisb85190b2016-02-05 09:44:31 -08001/*
2 * Copyright 2016 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.sdxl3;
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;
31import org.onosproject.core.CoreServiceAdapter;
32import 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;
46import org.onosproject.routing.FibListener;
47import org.onosproject.routing.FibUpdate;
48import org.onosproject.routing.IntentSynchronizationService;
49import org.onosproject.routing.RoutingServiceAdapter;
50import 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.routing.TestIntentServiceHelper.eqExceptId;
65
66/**
67 * Unit tests for SdxL3Fib.
68 */
69public class SdxL3FibTest extends AbstractIntentTest {
70
71 private RoutingConfigurationService routingConfig;
72 private InterfaceService interfaceService;
73 private SdxL3PeerService peerService;
74
75 private static final String DEVICE1_ID = "of:0000000000000001";
76 private static final String DEVICE2_ID = "of:0000000000000002";
77 private static final String DEVICE3_ID = "of:0000000000000003";
78 private static final String DEVICE4_ID = "of:0000000000000004";
79
80 private static final String PEER1_IP = "192.168.10.1";
81 private static final String PEER2_IP = "192.168.10.2";
82 private static final String PEER3_IP = "192.168.10.3";
83 private static final String PEER4_IP = "192.168.20.4";
84
85 private static final String SPEAKER1_IP = "192.168.10.101";
86 private static final String SPEAKER2_IP = "192.168.20.101";
87
88 private static final String MAC1 = "00:00:00:00:00:01";
89 private static final String MAC2 = "00:00:00:00:00:02";
90
91 private Interface interface1;
92 private Interface interface2;
93 private Interface interface3;
94 private Interface interface4;
95
96 private static final ConnectPoint CONN_POINT1 = new ConnectPoint(
97 DeviceId.deviceId(DEVICE1_ID),
98 PortNumber.portNumber(1));
99
100 private static final ConnectPoint CONN_POINT2 = new ConnectPoint(
101 DeviceId.deviceId(DEVICE2_ID),
102 PortNumber.portNumber(1));
103
104 private static final ConnectPoint CONN_POINT3 = new ConnectPoint(
105 DeviceId.deviceId(DEVICE3_ID),
106 PortNumber.portNumber(1));
107
108 private static final ConnectPoint CONN_POINT4 = new ConnectPoint(
109 DeviceId.deviceId(DEVICE4_ID),
110 PortNumber.portNumber(1));
111
112 private SdxL3Fib sdxL3Fib;
113 private IntentSynchronizationService intentSynchronizer;
114 private final Set<Interface> interfaces = Sets.newHashSet();
115
116 private static final ApplicationId APPID = TestApplicationId.create("sdxl3");
117
118 private FibListener fibListener;
119
120 @Before
121 public void setUp() throws Exception {
122 super.setUp();
123
124 routingConfig = createMock(RoutingConfigurationService.class);
125 interfaceService = createMock(InterfaceService.class);
126 peerService = createMock(SdxL3PeerService.class);
127
128 // These will set expectations on routingConfig and interfaceService
129 setUpInterfaceService();
130 setUpBgpPeers();
131
132 replay(routingConfig);
133 replay(interfaceService);
134 replay(peerService);
135
136 intentSynchronizer = createMock(IntentSynchronizationService.class);
137
138 sdxL3Fib = new SdxL3Fib();
139 sdxL3Fib.routingService = new TestRoutingService();
140 sdxL3Fib.coreService = new TestCoreService();
141 sdxL3Fib.interfaceService = interfaceService;
142 sdxL3Fib.intentSynchronizer = intentSynchronizer;
143 sdxL3Fib.peerService = peerService;
144
145 sdxL3Fib.activate();
146 }
147
148 /**
149 * Sets up InterfaceService.
150 */
151 private void setUpInterfaceService() {
152 Set<InterfaceIpAddress> interfaceIpAddresses1 = Sets.newHashSet();
153 interfaceIpAddresses1.add(new InterfaceIpAddress(
154 IpAddress.valueOf(SPEAKER1_IP),
155 IpPrefix.valueOf("192.168.10.0/24")));
156 interface1 = new Interface(CONN_POINT1,
157 interfaceIpAddresses1, MacAddress.valueOf(MAC1),
158 VlanId.NONE);
159 interfaces.add(interface1);
160
161 Set<InterfaceIpAddress> interfaceIpAddresses2 = Sets.newHashSet();
162 interfaceIpAddresses2.add(
163 new InterfaceIpAddress(IpAddress.valueOf(SPEAKER1_IP),
164 IpPrefix.valueOf("192.168.10.0/24")));
165 interface2 = new Interface(CONN_POINT2,
166 interfaceIpAddresses2, MacAddress.valueOf(MAC1),
167 VlanId.NONE);
168 interfaces.add(interface2);
169
170 Set<InterfaceIpAddress> interfaceIpAddresses3 = Sets.newHashSet();
171 interfaceIpAddresses3.add(
172 new InterfaceIpAddress(IpAddress.valueOf(SPEAKER1_IP),
173 IpPrefix.valueOf("192.168.10.0/24")));
174 interface3 = new Interface(CONN_POINT3,
175 interfaceIpAddresses3, MacAddress.valueOf(MAC1),
176 VlanId.vlanId((short) 1));
177 interfaces.add(interface3);
178
179 Set<InterfaceIpAddress> interfaceIpAddresses4 = Sets.newHashSet();
180 interfaceIpAddresses4.add(
181 new InterfaceIpAddress(IpAddress.valueOf(SPEAKER2_IP),
182 IpPrefix.valueOf("192.168.20.0/24")));
183 interface4 = new Interface(CONN_POINT4,
184 interfaceIpAddresses4, MacAddress.valueOf(MAC2),
185 VlanId.NONE);
186 interfaces.add(interface4);
187
188 expect(interfaceService.getInterfacesByPort(CONN_POINT1)).andReturn(
189 Collections.singleton(interface1)).anyTimes();
190 expect(interfaceService.getMatchingInterface(Ip4Address.valueOf(PEER1_IP)))
191 .andReturn(interface1).anyTimes();
192 expect(interfaceService.getInterfacesByPort(CONN_POINT2)).andReturn(
193 Collections.singleton(interface2)).anyTimes();
194 expect(interfaceService.getMatchingInterface(Ip4Address.valueOf(PEER4_IP)))
195 .andReturn(interface1).anyTimes();
196 expect(interfaceService.getInterfacesByPort(CONN_POINT4)).andReturn(
197 Collections.singleton(interface4)).anyTimes();
198
199 expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
200 }
201
202 /**
203 * Sets up BGP peers in external networks.
204 */
205 private void setUpBgpPeers() {
206
207 Map<IpAddress, BgpPeer> peers = new HashMap<>();
208
209 peers.put(IpAddress.valueOf(PEER1_IP),
210 new BgpPeer("00:00:00:00:00:00:00:01", 1, PEER1_IP));
211 expect(peerService.getInterfaceForPeer(IpAddress.valueOf(PEER1_IP)))
212 .andReturn(interface1).anyTimes();
213
214 peers.put(IpAddress.valueOf(PEER2_IP),
215 new BgpPeer("00:00:00:00:00:00:00:02", 1, PEER2_IP));
216 expect(peerService.getInterfaceForPeer(IpAddress.valueOf(PEER2_IP)))
217 .andReturn(interface2).anyTimes();
218
219 peers.put(IpAddress.valueOf(PEER3_IP),
220 new BgpPeer("00:00:00:00:00:00:00:03", 1, PEER4_IP));
221 expect(peerService.getInterfaceForPeer(IpAddress.valueOf(PEER3_IP)))
222 .andReturn(interface3).anyTimes();
223
224 peers.put(IpAddress.valueOf(PEER4_IP),
225 new BgpPeer("00:00:00:00:00:00:00:04", 1, PEER4_IP));
226 expect(peerService.getInterfaceForPeer(IpAddress.valueOf(PEER4_IP)))
227 .andReturn(null).anyTimes();
228
229 expect(routingConfig.getBgpPeers()).andReturn(peers).anyTimes();
230 }
231
232 /**
233 * Tests adding a FIB entry to the IntentSynchronizer. Peers within the same
234 * subnet exist.
235 *
236 * We verify that the synchronizer records the correct state and that the
237 * correct intent is submitted to the IntentService.
238 */
239 @Test
240 public void testFibAdd() {
241 IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
242 FibEntry fibEntry = new FibEntry(prefix,
243 Ip4Address.valueOf(PEER1_IP),
244 MacAddress.valueOf(MAC1));
245
246 // Construct a MultiPointToSinglePointIntent intent
247 TrafficSelector.Builder selectorBuilder =
248 DefaultTrafficSelector.builder();
249 selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
250 fibEntry.prefix());
251
252 TrafficTreatment.Builder treatmentBuilder =
253 DefaultTrafficTreatment.builder();
254 treatmentBuilder.setEthDst(MacAddress.valueOf(MAC1));
255
256 Set<ConnectPoint> ingressPoints = new HashSet<>();
257 ingressPoints.add(CONN_POINT2);
258 ingressPoints.add(CONN_POINT3);
259 ingressPoints.add(CONN_POINT4);
260
261 MultiPointToSinglePointIntent intent =
262 MultiPointToSinglePointIntent.builder()
263 .appId(APPID)
264 .key(Key.of(prefix.toString(), APPID))
265 .selector(selectorBuilder.build())
266 .treatment(treatmentBuilder.build())
267 .ingressPoints(ingressPoints)
268 .egressPoint(CONN_POINT1)
269 .constraints(SdxL3Fib.CONSTRAINTS)
270 .build();
271
272 // Setup the expected intents
273 intentSynchronizer.submit(eqExceptId(intent));
274 replay(intentSynchronizer);
275
276 // Send in the UPDATE FibUpdate
277 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
278 fibListener.update(Collections.singleton(fibUpdate), Collections.emptyList());
279
280 verify(intentSynchronizer);
281 }
282
283 /**
284 * Tests adding a FIB entry with to a next hop in a VLAN.
285 *
286 * We verify that the synchronizer records the correct state and that the
287 * correct intent is submitted to the IntentService.
288 */
289 @Test
290 public void testFibAddWithVlan() {
291 IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
292 FibEntry fibEntry = new FibEntry(prefix,
293 Ip4Address.valueOf(PEER3_IP),
294 MacAddress.valueOf(MAC1));
295
296 // Construct a MultiPointToSinglePointIntent intent
297 TrafficSelector.Builder selectorBuilder =
298 DefaultTrafficSelector.builder();
299 selectorBuilder.matchEthType(Ethernet.TYPE_IPV4)
300 .matchIPDst(fibEntry.prefix())
301 .matchVlanId(VlanId.ANY);
302
303 TrafficTreatment.Builder treatmentBuilder =
304 DefaultTrafficTreatment.builder();
305 treatmentBuilder.setEthDst(MacAddress.valueOf(MAC1))
306 .setVlanId(VlanId.vlanId((short) 1));
307
308 Set<ConnectPoint> ingressPoints = new HashSet<>();
309 ingressPoints.add(CONN_POINT1);
310 ingressPoints.add(CONN_POINT2);
311 ingressPoints.add(CONN_POINT4);
312
313 MultiPointToSinglePointIntent intent =
314 MultiPointToSinglePointIntent.builder()
315 .appId(APPID)
316 .key(Key.of(prefix.toString(), APPID))
317 .selector(selectorBuilder.build())
318 .treatment(treatmentBuilder.build())
319 .ingressPoints(ingressPoints)
320 .egressPoint(CONN_POINT3)
321 .constraints(SdxL3Fib.CONSTRAINTS)
322 .build();
323
324 // Setup the expected intents
325 intentSynchronizer.submit(eqExceptId(intent));
326
327 replay(intentSynchronizer);
328
329 // Send in the UPDATE FibUpdate
330 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
331 fibListener.update(Collections.singleton(fibUpdate), Collections.emptyList());
332
333 verify(intentSynchronizer);
334 }
335
336 /**
337 * Tests updating a FIB entry.
338 *
339 * We verify that the synchronizer records the correct state and that the
340 * correct intent is submitted to the IntentService.
341 */
342 @Test
343 public void testFibUpdate() {
344 // Firstly add a route
345 testFibAdd();
346
347 IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
348
349 // Start to construct a new route entry and new intent
350 FibEntry fibEntryUpdate = new FibEntry(prefix,
351 Ip4Address.valueOf(PEER2_IP),
352 MacAddress.valueOf(MAC1));
353
354 // Construct a new MultiPointToSinglePointIntent intent
355 TrafficSelector.Builder selectorBuilderNew =
356 DefaultTrafficSelector.builder();
357 selectorBuilderNew.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
358 fibEntryUpdate.prefix());
359
360 TrafficTreatment.Builder treatmentBuilderNew =
361 DefaultTrafficTreatment.builder();
362 treatmentBuilderNew.setEthDst(MacAddress.valueOf(MAC1));
363
364 Set<ConnectPoint> ingressPointsNew = new HashSet<>();
365 ingressPointsNew.add(CONN_POINT1);
366 ingressPointsNew.add(CONN_POINT3);
367 ingressPointsNew.add(CONN_POINT4);
368
369 MultiPointToSinglePointIntent intentNew =
370 MultiPointToSinglePointIntent.builder()
371 .appId(APPID)
372 .key(Key.of(prefix.toString(), APPID))
373 .selector(selectorBuilderNew.build())
374 .treatment(treatmentBuilderNew.build())
375 .ingressPoints(ingressPointsNew)
376 .egressPoint(CONN_POINT2)
377 .constraints(SdxL3Fib.CONSTRAINTS)
378 .build();
379
380 // Set up test expectation
381 reset(intentSynchronizer);
382
383 // Setup the expected intents
384 intentSynchronizer.submit(eqExceptId(intentNew));
385 replay(intentSynchronizer);
386
387 // Send in the UPDATE FibUpdate
388 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE,
389 fibEntryUpdate);
390 fibListener.update(Collections.singletonList(fibUpdate),
391 Collections.emptyList());
392
393 verify(intentSynchronizer);
394 }
395
396 /**
397 * Tests deleting a FIB entry.
398 *
399 * We verify that the synchronizer records the correct state and that the
400 * correct intent is withdrawn from the IntentService.
401 */
402 @Test
403 public void testFibDelete() {
404 // Firstly add a route
405 testFibAdd();
406
407 IpPrefix prefix = Ip4Prefix.valueOf("1.1.1.0/24");
408
409 // Construct the existing route entry
410 FibEntry fibEntry = new FibEntry(prefix, null, null);
411
412 // Construct the existing MultiPointToSinglePoint intent
413 TrafficSelector.Builder selectorBuilder =
414 DefaultTrafficSelector.builder();
415 selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPDst(
416 fibEntry.prefix());
417
418 TrafficTreatment.Builder treatmentBuilder =
419 DefaultTrafficTreatment.builder();
420 treatmentBuilder.setEthDst(MacAddress.valueOf(MAC1));
421
422 Set<ConnectPoint> ingressPoints = new HashSet<>();
423 ingressPoints.add(CONN_POINT2);
424 ingressPoints.add(CONN_POINT3);
425 ingressPoints.add(CONN_POINT4);
426
427 MultiPointToSinglePointIntent addedIntent =
428 MultiPointToSinglePointIntent.builder()
429 .appId(APPID)
430 .key(Key.of(prefix.toString(), APPID))
431 .selector(selectorBuilder.build())
432 .treatment(treatmentBuilder.build())
433 .ingressPoints(ingressPoints)
434 .egressPoint(CONN_POINT1)
435 .constraints(SdxL3Fib.CONSTRAINTS)
436 .build();
437
438 // Set up expectation
439 reset(intentSynchronizer);
440 // Setup the expected intents
441 intentSynchronizer.withdraw(eqExceptId(addedIntent));
442 replay(intentSynchronizer);
443
444 // Send in the DELETE FibUpdate
445 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.DELETE, fibEntry);
446 fibListener.update(Collections.emptyList(), Collections.singletonList(fibUpdate));
447
448 verify(intentSynchronizer);
449 }
450
451 private class TestCoreService extends CoreServiceAdapter {
452 @Override
453 public ApplicationId getAppId(String name) {
454 return APPID;
455 }
456 }
457
458 private class TestRoutingService extends RoutingServiceAdapter {
459
460 @Override
461 public void addFibListener(FibListener fibListener) {
462 SdxL3FibTest.this.fibListener = fibListener;
463 }
464 }
465}
466