blob: 7ae8658c233ca1540c7e86175b42d69632f7af75 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 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 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.sdnip.bgp;
Jonathan Hart20d8e512014-10-16 11:05:52 -070017
Jonathan Hart20d8e512014-10-16 11:05:52 -070018import static org.hamcrest.Matchers.hasSize;
19import static org.hamcrest.Matchers.is;
20import static org.hamcrest.Matchers.notNullValue;
21import static org.junit.Assert.assertThat;
22
23import java.net.InetAddress;
24import java.net.InetSocketAddress;
25import java.net.SocketAddress;
26import java.util.ArrayList;
27import java.util.Collection;
28import java.util.LinkedList;
29import java.util.concurrent.Executors;
30import java.util.concurrent.TimeUnit;
31
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080032import org.hamcrest.Description;
33import org.hamcrest.TypeSafeMatcher;
Jonathan Hart20d8e512014-10-16 11:05:52 -070034import org.jboss.netty.bootstrap.ClientBootstrap;
35import org.jboss.netty.buffer.ChannelBuffer;
36import org.jboss.netty.channel.Channel;
37import org.jboss.netty.channel.ChannelFactory;
38import org.jboss.netty.channel.ChannelPipeline;
39import org.jboss.netty.channel.ChannelPipelineFactory;
40import org.jboss.netty.channel.Channels;
41import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
42import org.junit.After;
43import org.junit.Before;
44import org.junit.Test;
Pavlin Radoslavovd26f57a2014-10-23 17:19:45 -070045import org.onlab.junit.TestUtils;
46import org.onlab.junit.TestUtils.TestUtilsException;
Brian O'Connorabafb502014-12-02 22:26:20 -080047import org.onosproject.sdnip.RouteListener;
48import org.onosproject.sdnip.RouteUpdate;
Pavlin Radoslavov6b570732014-11-06 13:16:45 -080049import org.onlab.packet.Ip4Address;
50import org.onlab.packet.Ip4Prefix;
Jonathan Hart20d8e512014-10-16 11:05:52 -070051
52import com.google.common.net.InetAddresses;
53
54/**
55 * Unit tests for the BgpSessionManager class.
56 */
57public class BgpSessionManagerTest {
Pavlin Radoslavov6b570732014-11-06 13:16:45 -080058 private static final Ip4Address IP_LOOPBACK_ID =
59 Ip4Address.valueOf("127.0.0.1");
60 private static final Ip4Address BGP_PEER1_ID =
61 Ip4Address.valueOf("10.0.0.1");
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080062 private static final Ip4Address BGP_PEER2_ID =
63 Ip4Address.valueOf("10.0.0.2");
64 private static final Ip4Address BGP_PEER3_ID =
65 Ip4Address.valueOf("10.0.0.3");
66 private static final Ip4Address NEXT_HOP1_ROUTER =
67 Ip4Address.valueOf("10.20.30.41");
68 private static final Ip4Address NEXT_HOP2_ROUTER =
69 Ip4Address.valueOf("10.20.30.42");
70 private static final Ip4Address NEXT_HOP3_ROUTER =
71 Ip4Address.valueOf("10.20.30.43");
72
Jonathan Hart20d8e512014-10-16 11:05:52 -070073 private static final long DEFAULT_LOCAL_PREF = 10;
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080074 private static final long BETTER_LOCAL_PREF = 20;
Jonathan Hart20d8e512014-10-16 11:05:52 -070075 private static final long DEFAULT_MULTI_EXIT_DISC = 20;
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080076 private static final long BETTER_MULTI_EXIT_DISC = 30;
77
78 BgpRouteEntry.AsPath asPathShort;
79 BgpRouteEntry.AsPath asPathLong;
Jonathan Hart20d8e512014-10-16 11:05:52 -070080
Pavlin Radoslavov23c05692014-12-02 13:18:10 -080081 // Timeout waiting for a message to be received
82 private static final int MESSAGE_TIMEOUT_MS = 5000; // 5s
83
Jonathan Hart20d8e512014-10-16 11:05:52 -070084 // The BGP Session Manager to test
85 private BgpSessionManager bgpSessionManager;
86
87 // Remote Peer state
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -080088 private final Collection<TestBgpPeer> peers = new LinkedList<>();
89 TestBgpPeer peer1;
90 TestBgpPeer peer2;
91 TestBgpPeer peer3;
Jonathan Hart20d8e512014-10-16 11:05:52 -070092
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080093 // Local BGP per-peer session state
94 BgpSession bgpSession1;
95 BgpSession bgpSession2;
96 BgpSession bgpSession3;
97
98 // The socket that the remote peers should connect to
Jonathan Hart20d8e512014-10-16 11:05:52 -070099 private InetSocketAddress connectToSocket;
100
101 private final DummyRouteListener dummyRouteListener =
102 new DummyRouteListener();
103
104 /**
105 * Dummy implementation for the RouteListener interface.
106 */
107 private class DummyRouteListener implements RouteListener {
108 @Override
Pavlin Radoslavov248c2ae2014-12-02 09:51:25 -0800109 public void update(Collection<RouteUpdate> routeUpdate) {
Jonathan Hart20d8e512014-10-16 11:05:52 -0700110 // Nothing to do
111 }
112 }
113
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800114 /**
115 * A class to capture the state for a BGP peer.
116 */
117 private final class TestBgpPeer {
118 private final Ip4Address peerId;
119 private ClientBootstrap peerBootstrap;
120 private TestBgpPeerChannelHandler peerChannelHandler;
121 private TestBgpPeerFrameDecoder peerFrameDecoder =
122 new TestBgpPeerFrameDecoder();
123
124 /**
125 * Constructor.
126 *
127 * @param peerId the peer ID
128 */
129 private TestBgpPeer(Ip4Address peerId) {
130 this.peerId = peerId;
131 peerChannelHandler = new TestBgpPeerChannelHandler(peerId);
132 }
133
134 /**
135 * Starts up the BGP peer and connects it to the tested SDN-IP
136 * instance.
137 *
138 * @param connectToSocket the socket to connect to
139 */
140 private void connect(InetSocketAddress connectToSocket)
141 throws InterruptedException {
142 //
143 // Setup the BGP Peer, i.e., the "remote" BGP router that will
144 // initiate the BGP connection, send BGP UPDATE messages, etc.
145 //
146 ChannelFactory channelFactory =
147 new NioClientSocketChannelFactory(
148 Executors.newCachedThreadPool(),
149 Executors.newCachedThreadPool());
150 ChannelPipelineFactory pipelineFactory =
151 new ChannelPipelineFactory() {
152 @Override
153 public ChannelPipeline getPipeline() throws Exception {
154 // Setup the transmitting pipeline
155 ChannelPipeline pipeline = Channels.pipeline();
156 pipeline.addLast("TestBgpPeerFrameDecoder",
157 peerFrameDecoder);
158 pipeline.addLast("TestBgpPeerChannelHandler",
159 peerChannelHandler);
160 return pipeline;
161 }
162 };
163
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
Jonathan Hart20d8e512014-10-16 11:05:52 -0700240 @Before
241 public void setUp() throws Exception {
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800242 peer1 = new TestBgpPeer(BGP_PEER1_ID);
243 peer2 = new TestBgpPeer(BGP_PEER2_ID);
244 peer3 = new TestBgpPeer(BGP_PEER3_ID);
245 peers.clear();
246 peers.add(peer1);
247 peers.add(peer2);
248 peers.add(peer3);
249
Jonathan Hart20d8e512014-10-16 11:05:52 -0700250 //
251 // Setup the BGP Session Manager to test, and start listening for BGP
252 // connections.
253 //
254 bgpSessionManager = new BgpSessionManager(dummyRouteListener);
255 // NOTE: We use port 0 to bind on any available port
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -0800256 bgpSessionManager.start(0);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700257
258 // Get the port number the BGP Session Manager is listening on
259 Channel serverChannel = TestUtils.getField(bgpSessionManager,
260 "serverChannel");
261 SocketAddress socketAddress = serverChannel.getLocalAddress();
262 InetSocketAddress inetSocketAddress =
263 (InetSocketAddress) socketAddress;
Jonathan Hart20d8e512014-10-16 11:05:52 -0700264 InetAddress connectToAddress = InetAddresses.forString("127.0.0.1");
265 connectToSocket = new InetSocketAddress(connectToAddress,
266 inetSocketAddress.getPort());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800267
268 //
269 // Setup the AS Paths
270 //
271 ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
272 byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
273 ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
274 segmentAsNumbers1.add((long) 65010);
275 segmentAsNumbers1.add((long) 65020);
276 segmentAsNumbers1.add((long) 65030);
277 BgpRouteEntry.PathSegment pathSegment1 =
278 new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
279 pathSegments.add(pathSegment1);
280 asPathShort = new BgpRouteEntry.AsPath(new ArrayList(pathSegments));
281 //
282 byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
283 ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
284 segmentAsNumbers2.add((long) 65041);
285 segmentAsNumbers2.add((long) 65042);
286 segmentAsNumbers2.add((long) 65043);
287 BgpRouteEntry.PathSegment pathSegment2 =
288 new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
289 pathSegments.add(pathSegment2);
290 //
291 asPathLong = new BgpRouteEntry.AsPath(pathSegments);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700292 }
293
294 @After
295 public void tearDown() throws Exception {
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -0800296 bgpSessionManager.stop();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700297 bgpSessionManager = null;
298 }
299
300 /**
301 * Gets BGP RIB-IN routes by waiting until they are received.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800302 * <p>
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800303 * NOTE: We keep checking once every 10ms the number of received routes,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700304 * up to 5 seconds.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800305 * </p>
Jonathan Hart20d8e512014-10-16 11:05:52 -0700306 *
307 * @param bgpSession the BGP session that is expected to receive the
308 * routes
309 * @param expectedRoutes the expected number of routes
310 * @return the BGP RIB-IN routes as received within the expected
311 * time interval
312 */
313 private Collection<BgpRouteEntry> waitForBgpRibIn(BgpSession bgpSession,
314 long expectedRoutes)
315 throws InterruptedException {
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800316 Collection<BgpRouteEntry> bgpRibIn = bgpSession.getBgpRibIn4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700317
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800318 final int maxChecks = 500; // Max wait of 5 seconds
Jonathan Hart20d8e512014-10-16 11:05:52 -0700319 for (int i = 0; i < maxChecks; i++) {
320 if (bgpRibIn.size() == expectedRoutes) {
321 break;
322 }
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800323 Thread.sleep(10);
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800324 bgpRibIn = bgpSession.getBgpRibIn4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700325 }
326
327 return bgpRibIn;
328 }
329
330 /**
331 * Gets BGP merged routes by waiting until they are received.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800332 * <p>
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800333 * NOTE: We keep checking once every 10ms the number of received routes,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700334 * up to 5 seconds.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800335 * </p>
Jonathan Hart20d8e512014-10-16 11:05:52 -0700336 *
337 * @param expectedRoutes the expected number of routes
338 * @return the BGP Session Manager routes as received within the expected
339 * time interval
340 */
341 private Collection<BgpRouteEntry> waitForBgpRoutes(long expectedRoutes)
342 throws InterruptedException {
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800343 Collection<BgpRouteEntry> bgpRoutes =
344 bgpSessionManager.getBgpRoutes4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700345
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800346 final int maxChecks = 500; // Max wait of 5 seconds
Jonathan Hart20d8e512014-10-16 11:05:52 -0700347 for (int i = 0; i < maxChecks; i++) {
348 if (bgpRoutes.size() == expectedRoutes) {
349 break;
350 }
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800351 Thread.sleep(10);
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800352 bgpRoutes = bgpSessionManager.getBgpRoutes4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700353 }
354
355 return bgpRoutes;
356 }
357
358 /**
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800359 * Gets a merged BGP route by waiting until it is received.
360 * <p>
361 * NOTE: We keep checking once every 10ms whether the route is received,
362 * up to 5 seconds.
363 * </p>
364 *
365 * @param expectedRoute the expected route
366 * @return the merged BGP route if received within the expected time
367 * interval, otherwise null
368 */
369 private BgpRouteEntry waitForBgpRoute(BgpRouteEntry expectedRoute)
370 throws InterruptedException {
371 Collection<BgpRouteEntry> bgpRoutes =
372 bgpSessionManager.getBgpRoutes4();
373
374 final int maxChecks = 500; // Max wait of 5 seconds
375 for (int i = 0; i < maxChecks; i++) {
376 for (BgpRouteEntry bgpRouteEntry : bgpRoutes) {
377 if (bgpRouteEntry.equals(expectedRoute) &&
378 bgpRouteEntry.getBgpSession() ==
379 expectedRoute.getBgpSession()) {
380 return bgpRouteEntry;
381 }
382 }
383 Thread.sleep(10);
384 bgpRoutes = bgpSessionManager.getBgpRoutes4();
385 }
386
387 return null;
388 }
389
390 /**
Jonathan Hart20d8e512014-10-16 11:05:52 -0700391 * Tests that the BGP OPEN messages have been exchanged, followed by
392 * KEEPALIVE.
393 * <p>
394 * The BGP Peer opens the sessions and transmits OPEN Message, eventually
395 * followed by KEEPALIVE. The tested BGP listener should respond by
396 * OPEN Message, followed by KEEPALIVE.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800397 * </p>
Jonathan Hart20d8e512014-10-16 11:05:52 -0700398 *
399 * @throws TestUtilsException TestUtils error
400 */
401 @Test
402 public void testExchangedBgpOpenMessages()
403 throws InterruptedException, TestUtilsException {
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800404 // Initiate the connections
405 peer1.connect(connectToSocket);
406 peer2.connect(connectToSocket);
407 peer3.connect(connectToSocket);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700408
409 //
410 // Test the fields from the BGP OPEN message:
411 // BGP version, AS number, BGP ID
412 //
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800413 for (TestBgpPeer peer : peers) {
414 assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
415 is(BgpConstants.BGP_VERSION));
416 assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
417 is(IP_LOOPBACK_ID));
418 assertThat(peer.peerFrameDecoder.remoteInfo.asNumber(),
419 is(TestBgpPeerChannelHandler.PEER_AS));
420 }
Jonathan Hart20d8e512014-10-16 11:05:52 -0700421
422 //
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800423 // Test that the BgpSession instances have been created
Jonathan Hart20d8e512014-10-16 11:05:52 -0700424 //
425 assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800426 assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
427 assertThat(bgpSession1, notNullValue());
428 assertThat(bgpSession2, notNullValue());
429 assertThat(bgpSession3, notNullValue());
430 for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
Pavlin Radoslavov8a36ce32015-01-28 12:26:57 -0800431 long sessionAs = bgpSession.localInfo().asNumber();
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800432 assertThat(sessionAs, is(TestBgpPeerChannelHandler.PEER_AS));
433 }
Jonathan Hart20d8e512014-10-16 11:05:52 -0700434 }
435
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800436
437 /**
438 * Tests that the BGP OPEN with Capability messages have been exchanged,
439 * followed by KEEPALIVE.
440 * <p>
441 * The BGP Peer opens the sessions and transmits OPEN Message, eventually
442 * followed by KEEPALIVE. The tested BGP listener should respond by
443 * OPEN Message, followed by KEEPALIVE.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800444 * </p>
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800445 *
446 * @throws TestUtilsException TestUtils error
447 */
448 @Test
449 public void testExchangedBgpOpenCapabilityMessages()
450 throws InterruptedException, TestUtilsException {
451 //
452 // Setup the BGP Capabilities for all peers
453 //
454 for (TestBgpPeer peer : peers) {
455 peer.peerChannelHandler.localInfo.setIpv4Unicast();
456 peer.peerChannelHandler.localInfo.setIpv4Multicast();
457 peer.peerChannelHandler.localInfo.setIpv6Unicast();
458 peer.peerChannelHandler.localInfo.setIpv6Multicast();
459 peer.peerChannelHandler.localInfo.setAs4OctetCapability();
460 peer.peerChannelHandler.localInfo.setAs4Number(
461 TestBgpPeerChannelHandler.PEER_AS4);
462 }
463
464 // Initiate the connections
465 peer1.connect(connectToSocket);
466 peer2.connect(connectToSocket);
467 peer3.connect(connectToSocket);
468
469 //
470 // Test the fields from the BGP OPEN message:
471 // BGP version, BGP ID
472 //
473 for (TestBgpPeer peer : peers) {
474 assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
475 is(BgpConstants.BGP_VERSION));
476 assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
477 is(IP_LOOPBACK_ID));
478 }
479
480 //
481 // Test that the BgpSession instances have been created,
482 // and contain the appropriate BGP session information.
483 //
484 assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
485 assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
486 assertThat(bgpSession1, notNullValue());
487 assertThat(bgpSession2, notNullValue());
488 assertThat(bgpSession3, notNullValue());
489 for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
490 BgpSessionInfo localInfo = bgpSession.localInfo();
491 assertThat(localInfo.ipv4Unicast(), is(true));
492 assertThat(localInfo.ipv4Multicast(), is(true));
493 assertThat(localInfo.ipv6Unicast(), is(true));
494 assertThat(localInfo.ipv6Multicast(), is(true));
495 assertThat(localInfo.as4OctetCapability(), is(true));
496 assertThat(localInfo.asNumber(),
497 is(TestBgpPeerChannelHandler.PEER_AS4));
498 assertThat(localInfo.as4Number(),
499 is(TestBgpPeerChannelHandler.PEER_AS4));
500 }
501 }
502
Jonathan Hart20d8e512014-10-16 11:05:52 -0700503 /**
504 * Tests that the BGP UPDATE messages have been received and processed.
505 */
506 @Test
507 public void testProcessedBgpUpdateMessages() throws InterruptedException {
Jonathan Hart20d8e512014-10-16 11:05:52 -0700508 ChannelBuffer message;
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800509 BgpRouteEntry bgpRouteEntry;
510 Collection<BgpRouteEntry> bgpRibIn1;
511 Collection<BgpRouteEntry> bgpRibIn2;
512 Collection<BgpRouteEntry> bgpRibIn3;
Jonathan Hart20d8e512014-10-16 11:05:52 -0700513 Collection<BgpRouteEntry> bgpRoutes;
514
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800515 // Initiate the connections
516 peer1.connect(connectToSocket);
517 peer2.connect(connectToSocket);
518 peer3.connect(connectToSocket);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700519
520 // Prepare routes to add/delete
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800521 Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
522 Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800523
524 //
525 // Add and delete some routes
526 //
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800527 addedRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
528 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
529 addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
530 addedRoutes.add(Ip4Prefix.valueOf("40.0.0.0/24"));
531 addedRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
532 withdrawnRoutes.add(Ip4Prefix.valueOf("60.0.0.0/8"));
533 withdrawnRoutes.add(Ip4Prefix.valueOf("70.0.0.0/16"));
534 withdrawnRoutes.add(Ip4Prefix.valueOf("80.0.0.0/24"));
535 withdrawnRoutes.add(Ip4Prefix.valueOf("90.0.0.0/32"));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700536 // Write the routes
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800537 message = peer1.peerChannelHandler.prepareBgpUpdate(
538 NEXT_HOP1_ROUTER,
539 DEFAULT_LOCAL_PREF,
540 DEFAULT_MULTI_EXIT_DISC,
541 asPathLong,
542 addedRoutes,
543 withdrawnRoutes);
544 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
545 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700546 // Check that the routes have been received, processed and stored
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800547 //
548 bgpRibIn1 = waitForBgpRibIn(bgpSession1, 5);
549 assertThat(bgpRibIn1, hasSize(5));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700550 bgpRoutes = waitForBgpRoutes(5);
551 assertThat(bgpRoutes, hasSize(5));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700552 //
553 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800554 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800555 Ip4Prefix.valueOf("0.0.0.0/0"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800556 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700557 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800558 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700559 DEFAULT_LOCAL_PREF);
560 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800561 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800562 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700563 //
564 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800565 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800566 Ip4Prefix.valueOf("20.0.0.0/8"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800567 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700568 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800569 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700570 DEFAULT_LOCAL_PREF);
571 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800572 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800573 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700574 //
575 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800576 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800577 Ip4Prefix.valueOf("30.0.0.0/16"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800578 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700579 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800580 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700581 DEFAULT_LOCAL_PREF);
582 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800583 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800584 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700585 //
586 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800587 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800588 Ip4Prefix.valueOf("40.0.0.0/24"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800589 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700590 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800591 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700592 DEFAULT_LOCAL_PREF);
593 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800594 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800595 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700596 //
597 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800598 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800599 Ip4Prefix.valueOf("50.0.0.0/32"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800600 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700601 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800602 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700603 DEFAULT_LOCAL_PREF);
604 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800605 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800606 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700607
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800608 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700609 // Delete some routes
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800610 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700611 addedRoutes = new LinkedList<>();
612 withdrawnRoutes = new LinkedList<>();
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800613 withdrawnRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
614 withdrawnRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700615 // Write the routes
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800616 message = peer1.peerChannelHandler.prepareBgpUpdate(
617 NEXT_HOP1_ROUTER,
618 DEFAULT_LOCAL_PREF,
619 DEFAULT_MULTI_EXIT_DISC,
620 asPathLong,
621 addedRoutes,
622 withdrawnRoutes);
623 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
624 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700625 // Check that the routes have been received, processed and stored
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800626 //
627 bgpRibIn1 = waitForBgpRibIn(bgpSession1, 3);
628 assertThat(bgpRibIn1, hasSize(3));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700629 bgpRoutes = waitForBgpRoutes(3);
630 assertThat(bgpRoutes, hasSize(3));
631 //
632 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800633 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800634 Ip4Prefix.valueOf("20.0.0.0/8"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800635 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700636 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800637 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700638 DEFAULT_LOCAL_PREF);
639 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800640 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800641 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700642 //
643 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800644 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800645 Ip4Prefix.valueOf("30.0.0.0/16"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800646 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700647 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800648 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700649 DEFAULT_LOCAL_PREF);
650 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800651 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800652 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700653 //
654 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800655 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800656 Ip4Prefix.valueOf("40.0.0.0/24"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800657 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700658 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800659 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700660 DEFAULT_LOCAL_PREF);
661 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800662 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800663 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700664
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800665
666 // Close the channels and test there are no routes
667 peer1.peerChannelHandler.closeChannel();
668 peer2.peerChannelHandler.closeChannel();
669 peer3.peerChannelHandler.closeChannel();
670 bgpRoutes = waitForBgpRoutes(0);
671 assertThat(bgpRoutes, hasSize(0));
672 }
673
674 /**
675 * Tests the BGP route preference.
676 */
677 @Test
678 public void testBgpRoutePreference() throws InterruptedException {
679 ChannelBuffer message;
680 BgpRouteEntry bgpRouteEntry;
681 Collection<BgpRouteEntry> bgpRibIn1;
682 Collection<BgpRouteEntry> bgpRibIn2;
683 Collection<BgpRouteEntry> bgpRibIn3;
684 Collection<BgpRouteEntry> bgpRoutes;
685 Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
686 Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
687
688 // Initiate the connections
689 peer1.connect(connectToSocket);
690 peer2.connect(connectToSocket);
691 peer3.connect(connectToSocket);
692
693 //
694 // Setup the initial set of routes to Peer1
695 //
696 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
697 addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
698 // Write the routes
699 message = peer1.peerChannelHandler.prepareBgpUpdate(
700 NEXT_HOP1_ROUTER,
701 DEFAULT_LOCAL_PREF,
702 DEFAULT_MULTI_EXIT_DISC,
703 asPathLong,
704 addedRoutes,
705 withdrawnRoutes);
706 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
707 bgpRoutes = waitForBgpRoutes(2);
708 assertThat(bgpRoutes, hasSize(2));
709
710 //
711 // Add a route entry to Peer2 with a better LOCAL_PREF
712 //
713 addedRoutes = new LinkedList<>();
714 withdrawnRoutes = new LinkedList<>();
715 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
716 // Write the routes
717 message = peer2.peerChannelHandler.prepareBgpUpdate(
718 NEXT_HOP2_ROUTER,
719 BETTER_LOCAL_PREF,
720 DEFAULT_MULTI_EXIT_DISC,
721 asPathLong,
722 addedRoutes,
723 withdrawnRoutes);
724 peer2.peerChannelHandler.savedCtx.getChannel().write(message);
725 //
726 // Check that the routes have been received, processed and stored
727 //
728 bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
729 assertThat(bgpRibIn2, hasSize(1));
730 bgpRoutes = waitForBgpRoutes(2);
731 assertThat(bgpRoutes, hasSize(2));
732 //
733 bgpRouteEntry =
734 new BgpRouteEntry(bgpSession2,
735 Ip4Prefix.valueOf("20.0.0.0/8"),
736 NEXT_HOP2_ROUTER,
737 (byte) BgpConstants.Update.Origin.IGP,
738 asPathLong,
739 BETTER_LOCAL_PREF);
740 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
741 assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800742 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800743
744 //
745 // Add a route entry to Peer3 with a shorter AS path
746 //
747 addedRoutes = new LinkedList<>();
748 withdrawnRoutes = new LinkedList<>();
749 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
750 // Write the routes
751 message = peer3.peerChannelHandler.prepareBgpUpdate(
752 NEXT_HOP3_ROUTER,
753 BETTER_LOCAL_PREF,
754 DEFAULT_MULTI_EXIT_DISC,
755 asPathShort,
756 addedRoutes,
757 withdrawnRoutes);
758 peer3.peerChannelHandler.savedCtx.getChannel().write(message);
759 //
760 // Check that the routes have been received, processed and stored
761 //
762 bgpRibIn3 = waitForBgpRibIn(bgpSession3, 1);
763 assertThat(bgpRibIn3, hasSize(1));
764 bgpRoutes = waitForBgpRoutes(2);
765 assertThat(bgpRoutes, hasSize(2));
766 //
767 bgpRouteEntry =
768 new BgpRouteEntry(bgpSession3,
769 Ip4Prefix.valueOf("20.0.0.0/8"),
770 NEXT_HOP3_ROUTER,
771 (byte) BgpConstants.Update.Origin.IGP,
772 asPathShort,
773 BETTER_LOCAL_PREF);
774 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
775 assertThat(bgpRibIn3, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800776 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800777
778 //
779 // Cleanup in preparation for next test: delete old route entry from
780 // Peer2
781 //
782 addedRoutes = new LinkedList<>();
783 withdrawnRoutes = new LinkedList<>();
784 withdrawnRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
785 // Write the routes
786 message = peer2.peerChannelHandler.prepareBgpUpdate(
787 NEXT_HOP2_ROUTER,
788 BETTER_LOCAL_PREF,
789 BETTER_MULTI_EXIT_DISC,
790 asPathShort,
791 addedRoutes,
792 withdrawnRoutes);
793 peer2.peerChannelHandler.savedCtx.getChannel().write(message);
794 //
795 // Check that the routes have been received, processed and stored
796 //
797 bgpRibIn2 = waitForBgpRibIn(bgpSession2, 0);
798 assertThat(bgpRibIn2, hasSize(0));
799
800 //
801 // Add a route entry to Peer2 with a better MED
802 //
803 addedRoutes = new LinkedList<>();
804 withdrawnRoutes = new LinkedList<>();
805 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
806 // Write the routes
807 message = peer2.peerChannelHandler.prepareBgpUpdate(
808 NEXT_HOP2_ROUTER,
809 BETTER_LOCAL_PREF,
810 BETTER_MULTI_EXIT_DISC,
811 asPathShort,
812 addedRoutes,
813 withdrawnRoutes);
814 peer2.peerChannelHandler.savedCtx.getChannel().write(message);
815 //
816 // Check that the routes have been received, processed and stored
817 //
818 bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
819 assertThat(bgpRibIn2, hasSize(1));
820 bgpRoutes = waitForBgpRoutes(2);
821 assertThat(bgpRoutes, hasSize(2));
822 //
823 bgpRouteEntry =
824 new BgpRouteEntry(bgpSession2,
825 Ip4Prefix.valueOf("20.0.0.0/8"),
826 NEXT_HOP2_ROUTER,
827 (byte) BgpConstants.Update.Origin.IGP,
828 asPathShort,
829 BETTER_LOCAL_PREF);
830 bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
831 assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800832 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800833
834 //
835 // Add a route entry to Peer1 with a better (lower) BGP ID
836 //
837 addedRoutes = new LinkedList<>();
838 withdrawnRoutes = new LinkedList<>();
839 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
840 withdrawnRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
841 // Write the routes
842 message = peer1.peerChannelHandler.prepareBgpUpdate(
843 NEXT_HOP1_ROUTER,
844 BETTER_LOCAL_PREF,
845 BETTER_MULTI_EXIT_DISC,
846 asPathShort,
847 addedRoutes,
848 withdrawnRoutes);
849 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
850 //
851 // Check that the routes have been received, processed and stored
852 //
853 bgpRibIn1 = waitForBgpRibIn(bgpSession1, 1);
854 assertThat(bgpRibIn1, hasSize(1));
855 bgpRoutes = waitForBgpRoutes(1);
856 assertThat(bgpRoutes, hasSize(1));
857 //
858 bgpRouteEntry =
859 new BgpRouteEntry(bgpSession1,
860 Ip4Prefix.valueOf("20.0.0.0/8"),
861 NEXT_HOP1_ROUTER,
862 (byte) BgpConstants.Update.Origin.IGP,
863 asPathShort,
864 BETTER_LOCAL_PREF);
865 bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
866 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800867 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800868
869
870 // Close the channels and test there are no routes
871 peer1.peerChannelHandler.closeChannel();
872 peer2.peerChannelHandler.closeChannel();
873 peer3.peerChannelHandler.closeChannel();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700874 bgpRoutes = waitForBgpRoutes(0);
875 assertThat(bgpRoutes, hasSize(0));
876 }
877}