blob: 2d2731a40b96678a2584231b5ce034196763174a [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Jonathan Hart41349e92015-02-09 14:14:02 -080016package org.onosproject.routing.bgp;
Jonathan Hart20d8e512014-10-16 11:05:52 -070017
Jonathan Hart41349e92015-02-09 14:14:02 -080018import com.google.common.net.InetAddresses;
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080019import org.hamcrest.Description;
20import org.hamcrest.TypeSafeMatcher;
Jonathan Hart20d8e512014-10-16 11:05:52 -070021import org.jboss.netty.bootstrap.ClientBootstrap;
22import org.jboss.netty.buffer.ChannelBuffer;
23import org.jboss.netty.channel.Channel;
24import org.jboss.netty.channel.ChannelFactory;
25import org.jboss.netty.channel.ChannelPipeline;
26import org.jboss.netty.channel.ChannelPipelineFactory;
27import org.jboss.netty.channel.Channels;
28import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
29import org.junit.After;
30import org.junit.Before;
31import org.junit.Test;
Pavlin Radoslavovd26f57a2014-10-23 17:19:45 -070032import org.onlab.junit.TestUtils;
33import org.onlab.junit.TestUtils.TestUtilsException;
Pavlin Radoslavov6b570732014-11-06 13:16:45 -080034import org.onlab.packet.Ip4Address;
35import org.onlab.packet.Ip4Prefix;
Jonathan Hart2da1e602015-02-18 19:09:24 -080036import org.onosproject.routing.RouteListener;
37import org.onosproject.routing.RouteUpdate;
Jonathan Hartd24fafb2015-02-09 17:55:32 -080038import org.osgi.service.component.ComponentContext;
Jonathan Hart20d8e512014-10-16 11:05:52 -070039
Jonathan Hart41349e92015-02-09 14:14:02 -080040import java.net.InetAddress;
41import java.net.InetSocketAddress;
42import java.net.SocketAddress;
43import java.util.ArrayList;
44import java.util.Collection;
Jonathan Hartd24fafb2015-02-09 17:55:32 -080045import java.util.Dictionary;
Jonathan Hart41349e92015-02-09 14:14:02 -080046import java.util.LinkedList;
47import java.util.concurrent.Executors;
48import java.util.concurrent.TimeUnit;
49
Jonathan Hartd24fafb2015-02-09 17:55:32 -080050import static org.easymock.EasyMock.createMock;
51import static org.easymock.EasyMock.expect;
52import static org.easymock.EasyMock.replay;
Jonathan Hart41349e92015-02-09 14:14:02 -080053import static org.hamcrest.Matchers.hasSize;
54import static org.hamcrest.Matchers.is;
55import static org.hamcrest.Matchers.notNullValue;
56import static org.junit.Assert.assertThat;
Jonathan Hart20d8e512014-10-16 11:05:52 -070057
58/**
59 * Unit tests for the BgpSessionManager class.
60 */
61public class BgpSessionManagerTest {
Pavlin Radoslavov6b570732014-11-06 13:16:45 -080062 private static final Ip4Address IP_LOOPBACK_ID =
63 Ip4Address.valueOf("127.0.0.1");
64 private static final Ip4Address BGP_PEER1_ID =
65 Ip4Address.valueOf("10.0.0.1");
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080066 private static final Ip4Address BGP_PEER2_ID =
67 Ip4Address.valueOf("10.0.0.2");
68 private static final Ip4Address BGP_PEER3_ID =
69 Ip4Address.valueOf("10.0.0.3");
70 private static final Ip4Address NEXT_HOP1_ROUTER =
71 Ip4Address.valueOf("10.20.30.41");
72 private static final Ip4Address NEXT_HOP2_ROUTER =
73 Ip4Address.valueOf("10.20.30.42");
74 private static final Ip4Address NEXT_HOP3_ROUTER =
75 Ip4Address.valueOf("10.20.30.43");
76
Jonathan Hart20d8e512014-10-16 11:05:52 -070077 private static final long DEFAULT_LOCAL_PREF = 10;
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080078 private static final long BETTER_LOCAL_PREF = 20;
Jonathan Hart20d8e512014-10-16 11:05:52 -070079 private static final long DEFAULT_MULTI_EXIT_DISC = 20;
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080080 private static final long BETTER_MULTI_EXIT_DISC = 30;
81
82 BgpRouteEntry.AsPath asPathShort;
83 BgpRouteEntry.AsPath asPathLong;
Jonathan Hart20d8e512014-10-16 11:05:52 -070084
Pavlin Radoslavov23c05692014-12-02 13:18:10 -080085 // Timeout waiting for a message to be received
86 private static final int MESSAGE_TIMEOUT_MS = 5000; // 5s
87
Jonathan Hart20d8e512014-10-16 11:05:52 -070088 // The BGP Session Manager to test
89 private BgpSessionManager bgpSessionManager;
90
91 // Remote Peer state
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -080092 private final Collection<TestBgpPeer> peers = new LinkedList<>();
93 TestBgpPeer peer1;
94 TestBgpPeer peer2;
95 TestBgpPeer peer3;
Jonathan Hart20d8e512014-10-16 11:05:52 -070096
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080097 // Local BGP per-peer session state
98 BgpSession bgpSession1;
99 BgpSession bgpSession2;
100 BgpSession bgpSession3;
101
102 // The socket that the remote peers should connect to
Jonathan Hart20d8e512014-10-16 11:05:52 -0700103 private InetSocketAddress connectToSocket;
104
105 private final DummyRouteListener dummyRouteListener =
106 new DummyRouteListener();
107
108 /**
109 * Dummy implementation for the RouteListener interface.
110 */
111 private class DummyRouteListener implements RouteListener {
112 @Override
Pavlin Radoslavov248c2ae2014-12-02 09:51:25 -0800113 public void update(Collection<RouteUpdate> routeUpdate) {
Jonathan Hart20d8e512014-10-16 11:05:52 -0700114 // Nothing to do
115 }
116 }
117
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800118 /**
119 * A class to capture the state for a BGP peer.
120 */
121 private final class TestBgpPeer {
122 private final Ip4Address peerId;
123 private ClientBootstrap peerBootstrap;
124 private TestBgpPeerChannelHandler peerChannelHandler;
125 private TestBgpPeerFrameDecoder peerFrameDecoder =
126 new TestBgpPeerFrameDecoder();
127
128 /**
129 * Constructor.
130 *
131 * @param peerId the peer ID
132 */
133 private TestBgpPeer(Ip4Address peerId) {
134 this.peerId = peerId;
135 peerChannelHandler = new TestBgpPeerChannelHandler(peerId);
136 }
137
138 /**
Jonathan Hartde15e1c2016-02-03 10:51:50 -0800139 * Starts up the BGP peer and connects it to the tested BgpSessionManager
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800140 * instance.
141 *
142 * @param connectToSocket the socket to connect to
143 */
144 private void connect(InetSocketAddress connectToSocket)
145 throws InterruptedException {
146 //
147 // Setup the BGP Peer, i.e., the "remote" BGP router that will
148 // initiate the BGP connection, send BGP UPDATE messages, etc.
149 //
150 ChannelFactory channelFactory =
151 new NioClientSocketChannelFactory(
152 Executors.newCachedThreadPool(),
153 Executors.newCachedThreadPool());
Sho SHIMIZU74626412015-09-11 11:46:27 -0700154 ChannelPipelineFactory pipelineFactory = () -> {
155 // Setup the transmitting pipeline
156 ChannelPipeline pipeline = Channels.pipeline();
157 pipeline.addLast("TestBgpPeerFrameDecoder",
158 peerFrameDecoder);
159 pipeline.addLast("TestBgpPeerChannelHandler",
160 peerChannelHandler);
161 return pipeline;
162 };
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800163
164 peerBootstrap = new ClientBootstrap(channelFactory);
165 peerBootstrap.setOption("child.keepAlive", true);
166 peerBootstrap.setOption("child.tcpNoDelay", true);
167 peerBootstrap.setPipelineFactory(pipelineFactory);
168 peerBootstrap.connect(connectToSocket);
169
170 boolean result;
171 // Wait until the OPEN message is received
172 result = peerFrameDecoder.receivedOpenMessageLatch.await(
173 MESSAGE_TIMEOUT_MS,
174 TimeUnit.MILLISECONDS);
175 assertThat(result, is(true));
176 // Wait until the KEEPALIVE message is received
177 result = peerFrameDecoder.receivedKeepaliveMessageLatch.await(
178 MESSAGE_TIMEOUT_MS,
179 TimeUnit.MILLISECONDS);
180 assertThat(result, is(true));
181
182 for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
Pavlin Radoslavov8a36ce32015-01-28 12:26:57 -0800183 if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER1_ID)) {
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800184 bgpSession1 = bgpSession;
185 }
Pavlin Radoslavov8a36ce32015-01-28 12:26:57 -0800186 if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER2_ID)) {
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800187 bgpSession2 = bgpSession;
188 }
Pavlin Radoslavov8a36ce32015-01-28 12:26:57 -0800189 if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER3_ID)) {
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800190 bgpSession3 = bgpSession;
191 }
192 }
193 }
194 }
195
196 /**
197 * Class that implements a matcher for BgpRouteEntry by considering
198 * the BGP peer the entry was received from.
199 */
200 private static final class BgpRouteEntryAndPeerMatcher
201 extends TypeSafeMatcher<Collection<BgpRouteEntry>> {
202 private final BgpRouteEntry bgpRouteEntry;
203
204 private BgpRouteEntryAndPeerMatcher(BgpRouteEntry bgpRouteEntry) {
205 this.bgpRouteEntry = bgpRouteEntry;
206 }
207
208 @Override
209 public boolean matchesSafely(Collection<BgpRouteEntry> entries) {
210 for (BgpRouteEntry entry : entries) {
211 if (bgpRouteEntry.equals(entry) &&
212 bgpRouteEntry.getBgpSession() == entry.getBgpSession()) {
213 return true;
214 }
215 }
216 return false;
217 }
218
219 @Override
220 public void describeTo(Description description) {
221 description.appendText("BGP route entry lookup for entry \"").
222 appendText(bgpRouteEntry.toString()).
223 appendText("\"");
224 }
225 }
226
227 /**
228 * A helper method used for testing whether a collection of
229 * BGP route entries contains an entry from a specific BGP peer.
230 *
231 * @param bgpRouteEntry the BGP route entry to test
232 * @return an instance of BgpRouteEntryAndPeerMatcher that implements
233 * the matching logic
234 */
235 private static BgpRouteEntryAndPeerMatcher hasBgpRouteEntry(
236 BgpRouteEntry bgpRouteEntry) {
237 return new BgpRouteEntryAndPeerMatcher(bgpRouteEntry);
238 }
239
Ray Milkey8dc82082015-02-20 16:22:38 -0800240 @SuppressWarnings("unchecked")
Ray Milkey7c251822016-04-06 17:38:25 -0700241 private Dictionary
Ray Milkey8dc82082015-02-20 16:22:38 -0800242 getDictionaryMock(ComponentContext componentContext) {
Ray Milkey7c251822016-04-06 17:38:25 -0700243 Dictionary dictionary = createMock(Dictionary.class);
Ray Milkey8dc82082015-02-20 16:22:38 -0800244 expect(dictionary.get("bgpPort")).andReturn("0");
245 replay(dictionary);
246 expect(componentContext.getProperties()).andReturn(dictionary);
247 return dictionary;
248 }
249
Jonathan Hart20d8e512014-10-16 11:05:52 -0700250 @Before
251 public void setUp() throws Exception {
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800252 peer1 = new TestBgpPeer(BGP_PEER1_ID);
253 peer2 = new TestBgpPeer(BGP_PEER2_ID);
254 peer3 = new TestBgpPeer(BGP_PEER3_ID);
255 peers.clear();
256 peers.add(peer1);
257 peers.add(peer2);
258 peers.add(peer3);
259
Jonathan Hart20d8e512014-10-16 11:05:52 -0700260 //
261 // Setup the BGP Session Manager to test, and start listening for BGP
262 // connections.
263 //
Jonathan Hart41349e92015-02-09 14:14:02 -0800264 bgpSessionManager = new BgpSessionManager();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700265 // NOTE: We use port 0 to bind on any available port
Jonathan Hartd24fafb2015-02-09 17:55:32 -0800266 ComponentContext componentContext = createMock(ComponentContext.class);
Ray Milkey7c251822016-04-06 17:38:25 -0700267 Dictionary dictionary = getDictionaryMock(componentContext);
Jonathan Hartd24fafb2015-02-09 17:55:32 -0800268 replay(componentContext);
269 bgpSessionManager.activate(componentContext);
270 bgpSessionManager.start(dummyRouteListener);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700271
272 // Get the port number the BGP Session Manager is listening on
273 Channel serverChannel = TestUtils.getField(bgpSessionManager,
274 "serverChannel");
275 SocketAddress socketAddress = serverChannel.getLocalAddress();
276 InetSocketAddress inetSocketAddress =
277 (InetSocketAddress) socketAddress;
Jonathan Hart20d8e512014-10-16 11:05:52 -0700278 InetAddress connectToAddress = InetAddresses.forString("127.0.0.1");
279 connectToSocket = new InetSocketAddress(connectToAddress,
280 inetSocketAddress.getPort());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800281
282 //
283 // Setup the AS Paths
284 //
285 ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
286 byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
287 ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700288 segmentAsNumbers1.add(65010L);
289 segmentAsNumbers1.add(65020L);
290 segmentAsNumbers1.add(65030L);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800291 BgpRouteEntry.PathSegment pathSegment1 =
292 new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
293 pathSegments.add(pathSegment1);
Ray Milkey8dc82082015-02-20 16:22:38 -0800294 asPathShort = new BgpRouteEntry.AsPath(new ArrayList<>(pathSegments));
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800295 //
296 byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
297 ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
Sho SHIMIZUc14b2a22015-05-05 18:15:13 -0700298 segmentAsNumbers2.add(65041L);
299 segmentAsNumbers2.add(65042L);
300 segmentAsNumbers2.add(65043L);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800301 BgpRouteEntry.PathSegment pathSegment2 =
302 new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
303 pathSegments.add(pathSegment2);
304 //
305 asPathLong = new BgpRouteEntry.AsPath(pathSegments);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700306 }
307
308 @After
309 public void tearDown() throws Exception {
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -0800310 bgpSessionManager.stop();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700311 bgpSessionManager = null;
312 }
313
314 /**
315 * Gets BGP RIB-IN routes by waiting until they are received.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800316 * <p>
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800317 * NOTE: We keep checking once every 10ms the number of received routes,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700318 * up to 5 seconds.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800319 * </p>
Jonathan Hart20d8e512014-10-16 11:05:52 -0700320 *
321 * @param bgpSession the BGP session that is expected to receive the
322 * routes
323 * @param expectedRoutes the expected number of routes
324 * @return the BGP RIB-IN routes as received within the expected
325 * time interval
326 */
327 private Collection<BgpRouteEntry> waitForBgpRibIn(BgpSession bgpSession,
328 long expectedRoutes)
329 throws InterruptedException {
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800330 Collection<BgpRouteEntry> bgpRibIn = bgpSession.getBgpRibIn4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700331
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800332 final int maxChecks = 500; // Max wait of 5 seconds
Jonathan Hart20d8e512014-10-16 11:05:52 -0700333 for (int i = 0; i < maxChecks; i++) {
334 if (bgpRibIn.size() == expectedRoutes) {
335 break;
336 }
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800337 Thread.sleep(10);
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800338 bgpRibIn = bgpSession.getBgpRibIn4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700339 }
340
341 return bgpRibIn;
342 }
343
344 /**
345 * Gets BGP merged routes by waiting until they are received.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800346 * <p>
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800347 * NOTE: We keep checking once every 10ms the number of received routes,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700348 * up to 5 seconds.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800349 * </p>
Jonathan Hart20d8e512014-10-16 11:05:52 -0700350 *
351 * @param expectedRoutes the expected number of routes
352 * @return the BGP Session Manager routes as received within the expected
353 * time interval
354 */
355 private Collection<BgpRouteEntry> waitForBgpRoutes(long expectedRoutes)
356 throws InterruptedException {
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800357 Collection<BgpRouteEntry> bgpRoutes =
358 bgpSessionManager.getBgpRoutes4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700359
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800360 final int maxChecks = 500; // Max wait of 5 seconds
Jonathan Hart20d8e512014-10-16 11:05:52 -0700361 for (int i = 0; i < maxChecks; i++) {
362 if (bgpRoutes.size() == expectedRoutes) {
363 break;
364 }
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800365 Thread.sleep(10);
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800366 bgpRoutes = bgpSessionManager.getBgpRoutes4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700367 }
368
369 return bgpRoutes;
370 }
371
372 /**
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800373 * Gets a merged BGP route by waiting until it is received.
374 * <p>
375 * NOTE: We keep checking once every 10ms whether the route is received,
376 * up to 5 seconds.
377 * </p>
378 *
379 * @param expectedRoute the expected route
380 * @return the merged BGP route if received within the expected time
381 * interval, otherwise null
382 */
383 private BgpRouteEntry waitForBgpRoute(BgpRouteEntry expectedRoute)
384 throws InterruptedException {
385 Collection<BgpRouteEntry> bgpRoutes =
386 bgpSessionManager.getBgpRoutes4();
387
388 final int maxChecks = 500; // Max wait of 5 seconds
389 for (int i = 0; i < maxChecks; i++) {
390 for (BgpRouteEntry bgpRouteEntry : bgpRoutes) {
391 if (bgpRouteEntry.equals(expectedRoute) &&
392 bgpRouteEntry.getBgpSession() ==
393 expectedRoute.getBgpSession()) {
394 return bgpRouteEntry;
395 }
396 }
397 Thread.sleep(10);
398 bgpRoutes = bgpSessionManager.getBgpRoutes4();
399 }
400
401 return null;
402 }
403
404 /**
Jonathan Hart20d8e512014-10-16 11:05:52 -0700405 * Tests that the BGP OPEN messages have been exchanged, followed by
406 * KEEPALIVE.
407 * <p>
408 * The BGP Peer opens the sessions and transmits OPEN Message, eventually
409 * followed by KEEPALIVE. The tested BGP listener should respond by
410 * OPEN Message, followed by KEEPALIVE.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800411 * </p>
Jonathan Hart20d8e512014-10-16 11:05:52 -0700412 *
413 * @throws TestUtilsException TestUtils error
414 */
415 @Test
416 public void testExchangedBgpOpenMessages()
417 throws InterruptedException, TestUtilsException {
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800418 // Initiate the connections
419 peer1.connect(connectToSocket);
420 peer2.connect(connectToSocket);
421 peer3.connect(connectToSocket);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700422
423 //
424 // Test the fields from the BGP OPEN message:
425 // BGP version, AS number, BGP ID
426 //
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800427 for (TestBgpPeer peer : peers) {
428 assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
429 is(BgpConstants.BGP_VERSION));
430 assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
431 is(IP_LOOPBACK_ID));
432 assertThat(peer.peerFrameDecoder.remoteInfo.asNumber(),
433 is(TestBgpPeerChannelHandler.PEER_AS));
434 }
Jonathan Hart20d8e512014-10-16 11:05:52 -0700435
436 //
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800437 // Test that the BgpSession instances have been created
Jonathan Hart20d8e512014-10-16 11:05:52 -0700438 //
439 assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800440 assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
441 assertThat(bgpSession1, notNullValue());
442 assertThat(bgpSession2, notNullValue());
443 assertThat(bgpSession3, notNullValue());
444 for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
Pavlin Radoslavov8a36ce32015-01-28 12:26:57 -0800445 long sessionAs = bgpSession.localInfo().asNumber();
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800446 assertThat(sessionAs, is(TestBgpPeerChannelHandler.PEER_AS));
447 }
Jonathan Hart20d8e512014-10-16 11:05:52 -0700448 }
449
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800450
451 /**
452 * Tests that the BGP OPEN with Capability messages have been exchanged,
453 * followed by KEEPALIVE.
454 * <p>
455 * The BGP Peer opens the sessions and transmits OPEN Message, eventually
456 * followed by KEEPALIVE. The tested BGP listener should respond by
457 * OPEN Message, followed by KEEPALIVE.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800458 * </p>
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800459 *
460 * @throws TestUtilsException TestUtils error
461 */
462 @Test
463 public void testExchangedBgpOpenCapabilityMessages()
464 throws InterruptedException, TestUtilsException {
465 //
466 // Setup the BGP Capabilities for all peers
467 //
468 for (TestBgpPeer peer : peers) {
469 peer.peerChannelHandler.localInfo.setIpv4Unicast();
470 peer.peerChannelHandler.localInfo.setIpv4Multicast();
471 peer.peerChannelHandler.localInfo.setIpv6Unicast();
472 peer.peerChannelHandler.localInfo.setIpv6Multicast();
473 peer.peerChannelHandler.localInfo.setAs4OctetCapability();
474 peer.peerChannelHandler.localInfo.setAs4Number(
475 TestBgpPeerChannelHandler.PEER_AS4);
476 }
477
478 // Initiate the connections
479 peer1.connect(connectToSocket);
480 peer2.connect(connectToSocket);
481 peer3.connect(connectToSocket);
482
483 //
484 // Test the fields from the BGP OPEN message:
485 // BGP version, BGP ID
486 //
487 for (TestBgpPeer peer : peers) {
488 assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
489 is(BgpConstants.BGP_VERSION));
490 assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
491 is(IP_LOOPBACK_ID));
492 }
493
494 //
495 // Test that the BgpSession instances have been created,
496 // and contain the appropriate BGP session information.
497 //
498 assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
499 assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
500 assertThat(bgpSession1, notNullValue());
501 assertThat(bgpSession2, notNullValue());
502 assertThat(bgpSession3, notNullValue());
503 for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
504 BgpSessionInfo localInfo = bgpSession.localInfo();
505 assertThat(localInfo.ipv4Unicast(), is(true));
506 assertThat(localInfo.ipv4Multicast(), is(true));
507 assertThat(localInfo.ipv6Unicast(), is(true));
508 assertThat(localInfo.ipv6Multicast(), is(true));
509 assertThat(localInfo.as4OctetCapability(), is(true));
510 assertThat(localInfo.asNumber(),
511 is(TestBgpPeerChannelHandler.PEER_AS4));
512 assertThat(localInfo.as4Number(),
513 is(TestBgpPeerChannelHandler.PEER_AS4));
514 }
515 }
516
Jonathan Hart20d8e512014-10-16 11:05:52 -0700517 /**
518 * Tests that the BGP UPDATE messages have been received and processed.
519 */
520 @Test
521 public void testProcessedBgpUpdateMessages() throws InterruptedException {
Jonathan Hart20d8e512014-10-16 11:05:52 -0700522 ChannelBuffer message;
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800523 BgpRouteEntry bgpRouteEntry;
524 Collection<BgpRouteEntry> bgpRibIn1;
525 Collection<BgpRouteEntry> bgpRibIn2;
526 Collection<BgpRouteEntry> bgpRibIn3;
Jonathan Hart20d8e512014-10-16 11:05:52 -0700527 Collection<BgpRouteEntry> bgpRoutes;
528
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800529 // Initiate the connections
530 peer1.connect(connectToSocket);
531 peer2.connect(connectToSocket);
532 peer3.connect(connectToSocket);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700533
534 // Prepare routes to add/delete
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800535 Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
536 Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800537
538 //
539 // Add and delete some routes
540 //
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800541 addedRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
542 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
543 addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
544 addedRoutes.add(Ip4Prefix.valueOf("40.0.0.0/24"));
545 addedRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
546 withdrawnRoutes.add(Ip4Prefix.valueOf("60.0.0.0/8"));
547 withdrawnRoutes.add(Ip4Prefix.valueOf("70.0.0.0/16"));
548 withdrawnRoutes.add(Ip4Prefix.valueOf("80.0.0.0/24"));
549 withdrawnRoutes.add(Ip4Prefix.valueOf("90.0.0.0/32"));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700550 // Write the routes
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800551 message = peer1.peerChannelHandler.prepareBgpUpdate(
552 NEXT_HOP1_ROUTER,
553 DEFAULT_LOCAL_PREF,
554 DEFAULT_MULTI_EXIT_DISC,
555 asPathLong,
556 addedRoutes,
557 withdrawnRoutes);
558 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
559 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700560 // Check that the routes have been received, processed and stored
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800561 //
562 bgpRibIn1 = waitForBgpRibIn(bgpSession1, 5);
563 assertThat(bgpRibIn1, hasSize(5));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700564 bgpRoutes = waitForBgpRoutes(5);
565 assertThat(bgpRoutes, hasSize(5));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700566 //
567 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800568 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800569 Ip4Prefix.valueOf("0.0.0.0/0"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800570 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700571 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800572 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700573 DEFAULT_LOCAL_PREF);
574 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800575 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800576 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700577 //
578 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800579 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800580 Ip4Prefix.valueOf("20.0.0.0/8"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800581 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700582 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800583 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700584 DEFAULT_LOCAL_PREF);
585 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800586 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800587 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700588 //
589 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800590 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800591 Ip4Prefix.valueOf("30.0.0.0/16"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800592 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700593 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800594 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700595 DEFAULT_LOCAL_PREF);
596 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800597 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800598 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700599 //
600 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800601 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800602 Ip4Prefix.valueOf("40.0.0.0/24"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800603 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700604 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800605 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700606 DEFAULT_LOCAL_PREF);
607 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800608 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800609 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700610 //
611 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800612 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800613 Ip4Prefix.valueOf("50.0.0.0/32"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800614 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700615 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800616 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700617 DEFAULT_LOCAL_PREF);
618 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800619 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800620 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700621
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800622 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700623 // Delete some routes
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800624 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700625 addedRoutes = new LinkedList<>();
626 withdrawnRoutes = new LinkedList<>();
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800627 withdrawnRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
628 withdrawnRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700629 // Write the routes
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800630 message = peer1.peerChannelHandler.prepareBgpUpdate(
631 NEXT_HOP1_ROUTER,
632 DEFAULT_LOCAL_PREF,
633 DEFAULT_MULTI_EXIT_DISC,
634 asPathLong,
635 addedRoutes,
636 withdrawnRoutes);
637 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
638 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700639 // Check that the routes have been received, processed and stored
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800640 //
641 bgpRibIn1 = waitForBgpRibIn(bgpSession1, 3);
642 assertThat(bgpRibIn1, hasSize(3));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700643 bgpRoutes = waitForBgpRoutes(3);
644 assertThat(bgpRoutes, hasSize(3));
645 //
646 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800647 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800648 Ip4Prefix.valueOf("20.0.0.0/8"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800649 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700650 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800651 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700652 DEFAULT_LOCAL_PREF);
653 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800654 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800655 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700656 //
657 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800658 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800659 Ip4Prefix.valueOf("30.0.0.0/16"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800660 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700661 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800662 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700663 DEFAULT_LOCAL_PREF);
664 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800665 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800666 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700667 //
668 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800669 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800670 Ip4Prefix.valueOf("40.0.0.0/24"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800671 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700672 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800673 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700674 DEFAULT_LOCAL_PREF);
675 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800676 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800677 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700678
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800679
680 // Close the channels and test there are no routes
681 peer1.peerChannelHandler.closeChannel();
682 peer2.peerChannelHandler.closeChannel();
683 peer3.peerChannelHandler.closeChannel();
684 bgpRoutes = waitForBgpRoutes(0);
685 assertThat(bgpRoutes, hasSize(0));
686 }
687
688 /**
689 * Tests the BGP route preference.
690 */
691 @Test
692 public void testBgpRoutePreference() throws InterruptedException {
693 ChannelBuffer message;
694 BgpRouteEntry bgpRouteEntry;
695 Collection<BgpRouteEntry> bgpRibIn1;
696 Collection<BgpRouteEntry> bgpRibIn2;
697 Collection<BgpRouteEntry> bgpRibIn3;
698 Collection<BgpRouteEntry> bgpRoutes;
699 Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
700 Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
701
702 // Initiate the connections
703 peer1.connect(connectToSocket);
704 peer2.connect(connectToSocket);
705 peer3.connect(connectToSocket);
706
707 //
708 // Setup the initial set of routes to Peer1
709 //
710 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
711 addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
712 // Write the routes
713 message = peer1.peerChannelHandler.prepareBgpUpdate(
714 NEXT_HOP1_ROUTER,
715 DEFAULT_LOCAL_PREF,
716 DEFAULT_MULTI_EXIT_DISC,
717 asPathLong,
718 addedRoutes,
719 withdrawnRoutes);
720 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
721 bgpRoutes = waitForBgpRoutes(2);
722 assertThat(bgpRoutes, hasSize(2));
723
724 //
725 // Add a route entry to Peer2 with a better LOCAL_PREF
726 //
727 addedRoutes = new LinkedList<>();
728 withdrawnRoutes = new LinkedList<>();
729 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
730 // Write the routes
731 message = peer2.peerChannelHandler.prepareBgpUpdate(
732 NEXT_HOP2_ROUTER,
733 BETTER_LOCAL_PREF,
734 DEFAULT_MULTI_EXIT_DISC,
735 asPathLong,
736 addedRoutes,
737 withdrawnRoutes);
738 peer2.peerChannelHandler.savedCtx.getChannel().write(message);
739 //
740 // Check that the routes have been received, processed and stored
741 //
742 bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
743 assertThat(bgpRibIn2, hasSize(1));
744 bgpRoutes = waitForBgpRoutes(2);
745 assertThat(bgpRoutes, hasSize(2));
746 //
747 bgpRouteEntry =
748 new BgpRouteEntry(bgpSession2,
749 Ip4Prefix.valueOf("20.0.0.0/8"),
750 NEXT_HOP2_ROUTER,
751 (byte) BgpConstants.Update.Origin.IGP,
752 asPathLong,
753 BETTER_LOCAL_PREF);
754 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
755 assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800756 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800757
758 //
759 // Add a route entry to Peer3 with a shorter AS path
760 //
761 addedRoutes = new LinkedList<>();
762 withdrawnRoutes = new LinkedList<>();
763 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
764 // Write the routes
765 message = peer3.peerChannelHandler.prepareBgpUpdate(
766 NEXT_HOP3_ROUTER,
767 BETTER_LOCAL_PREF,
768 DEFAULT_MULTI_EXIT_DISC,
769 asPathShort,
770 addedRoutes,
771 withdrawnRoutes);
772 peer3.peerChannelHandler.savedCtx.getChannel().write(message);
773 //
774 // Check that the routes have been received, processed and stored
775 //
776 bgpRibIn3 = waitForBgpRibIn(bgpSession3, 1);
777 assertThat(bgpRibIn3, hasSize(1));
778 bgpRoutes = waitForBgpRoutes(2);
779 assertThat(bgpRoutes, hasSize(2));
780 //
781 bgpRouteEntry =
782 new BgpRouteEntry(bgpSession3,
783 Ip4Prefix.valueOf("20.0.0.0/8"),
784 NEXT_HOP3_ROUTER,
785 (byte) BgpConstants.Update.Origin.IGP,
786 asPathShort,
787 BETTER_LOCAL_PREF);
788 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
789 assertThat(bgpRibIn3, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800790 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800791
792 //
793 // Cleanup in preparation for next test: delete old route entry from
794 // Peer2
795 //
796 addedRoutes = new LinkedList<>();
797 withdrawnRoutes = new LinkedList<>();
798 withdrawnRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
799 // Write the routes
800 message = peer2.peerChannelHandler.prepareBgpUpdate(
801 NEXT_HOP2_ROUTER,
802 BETTER_LOCAL_PREF,
803 BETTER_MULTI_EXIT_DISC,
804 asPathShort,
805 addedRoutes,
806 withdrawnRoutes);
807 peer2.peerChannelHandler.savedCtx.getChannel().write(message);
808 //
809 // Check that the routes have been received, processed and stored
810 //
811 bgpRibIn2 = waitForBgpRibIn(bgpSession2, 0);
812 assertThat(bgpRibIn2, hasSize(0));
813
814 //
815 // Add a route entry to Peer2 with a better MED
816 //
817 addedRoutes = new LinkedList<>();
818 withdrawnRoutes = new LinkedList<>();
819 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
820 // Write the routes
821 message = peer2.peerChannelHandler.prepareBgpUpdate(
822 NEXT_HOP2_ROUTER,
823 BETTER_LOCAL_PREF,
824 BETTER_MULTI_EXIT_DISC,
825 asPathShort,
826 addedRoutes,
827 withdrawnRoutes);
828 peer2.peerChannelHandler.savedCtx.getChannel().write(message);
829 //
830 // Check that the routes have been received, processed and stored
831 //
832 bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
833 assertThat(bgpRibIn2, hasSize(1));
834 bgpRoutes = waitForBgpRoutes(2);
835 assertThat(bgpRoutes, hasSize(2));
836 //
837 bgpRouteEntry =
838 new BgpRouteEntry(bgpSession2,
839 Ip4Prefix.valueOf("20.0.0.0/8"),
840 NEXT_HOP2_ROUTER,
841 (byte) BgpConstants.Update.Origin.IGP,
842 asPathShort,
843 BETTER_LOCAL_PREF);
844 bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
845 assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800846 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800847
848 //
849 // Add a route entry to Peer1 with a better (lower) BGP ID
850 //
851 addedRoutes = new LinkedList<>();
852 withdrawnRoutes = new LinkedList<>();
853 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
854 withdrawnRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
855 // Write the routes
856 message = peer1.peerChannelHandler.prepareBgpUpdate(
857 NEXT_HOP1_ROUTER,
858 BETTER_LOCAL_PREF,
859 BETTER_MULTI_EXIT_DISC,
860 asPathShort,
861 addedRoutes,
862 withdrawnRoutes);
863 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
864 //
865 // Check that the routes have been received, processed and stored
866 //
867 bgpRibIn1 = waitForBgpRibIn(bgpSession1, 1);
868 assertThat(bgpRibIn1, hasSize(1));
869 bgpRoutes = waitForBgpRoutes(1);
870 assertThat(bgpRoutes, hasSize(1));
871 //
872 bgpRouteEntry =
873 new BgpRouteEntry(bgpSession1,
874 Ip4Prefix.valueOf("20.0.0.0/8"),
875 NEXT_HOP1_ROUTER,
876 (byte) BgpConstants.Update.Origin.IGP,
877 asPathShort,
878 BETTER_LOCAL_PREF);
879 bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
880 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800881 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800882
883
884 // Close the channels and test there are no routes
885 peer1.peerChannelHandler.closeChannel();
886 peer2.peerChannelHandler.closeChannel();
887 peer3.peerChannelHandler.closeChannel();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700888 bgpRoutes = waitForBgpRoutes(0);
889 assertThat(bgpRoutes, hasSize(0));
890 }
891}