blob: c73eafff387a5b349902886b52af61b9dde69950 [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 */
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 Hart41349e92015-02-09 14:14:02 -080036import org.onosproject.routingapi.RouteListener;
37import org.onosproject.routingapi.RouteUpdate;
Jonathan Hart20d8e512014-10-16 11:05:52 -070038
Jonathan Hart41349e92015-02-09 14:14:02 -080039import java.net.InetAddress;
40import java.net.InetSocketAddress;
41import java.net.SocketAddress;
42import java.util.ArrayList;
43import java.util.Collection;
44import java.util.LinkedList;
45import java.util.concurrent.Executors;
46import java.util.concurrent.TimeUnit;
47
48import static org.hamcrest.Matchers.hasSize;
49import static org.hamcrest.Matchers.is;
50import static org.hamcrest.Matchers.notNullValue;
51import static org.junit.Assert.assertThat;
Jonathan Hart20d8e512014-10-16 11:05:52 -070052
53/**
54 * Unit tests for the BgpSessionManager class.
55 */
56public class BgpSessionManagerTest {
Pavlin Radoslavov6b570732014-11-06 13:16:45 -080057 private static final Ip4Address IP_LOOPBACK_ID =
58 Ip4Address.valueOf("127.0.0.1");
59 private static final Ip4Address BGP_PEER1_ID =
60 Ip4Address.valueOf("10.0.0.1");
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080061 private static final Ip4Address BGP_PEER2_ID =
62 Ip4Address.valueOf("10.0.0.2");
63 private static final Ip4Address BGP_PEER3_ID =
64 Ip4Address.valueOf("10.0.0.3");
65 private static final Ip4Address NEXT_HOP1_ROUTER =
66 Ip4Address.valueOf("10.20.30.41");
67 private static final Ip4Address NEXT_HOP2_ROUTER =
68 Ip4Address.valueOf("10.20.30.42");
69 private static final Ip4Address NEXT_HOP3_ROUTER =
70 Ip4Address.valueOf("10.20.30.43");
71
Jonathan Hart20d8e512014-10-16 11:05:52 -070072 private static final long DEFAULT_LOCAL_PREF = 10;
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080073 private static final long BETTER_LOCAL_PREF = 20;
Jonathan Hart20d8e512014-10-16 11:05:52 -070074 private static final long DEFAULT_MULTI_EXIT_DISC = 20;
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080075 private static final long BETTER_MULTI_EXIT_DISC = 30;
76
77 BgpRouteEntry.AsPath asPathShort;
78 BgpRouteEntry.AsPath asPathLong;
Jonathan Hart20d8e512014-10-16 11:05:52 -070079
Pavlin Radoslavov23c05692014-12-02 13:18:10 -080080 // Timeout waiting for a message to be received
81 private static final int MESSAGE_TIMEOUT_MS = 5000; // 5s
82
Jonathan Hart20d8e512014-10-16 11:05:52 -070083 // The BGP Session Manager to test
84 private BgpSessionManager bgpSessionManager;
85
86 // Remote Peer state
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -080087 private final Collection<TestBgpPeer> peers = new LinkedList<>();
88 TestBgpPeer peer1;
89 TestBgpPeer peer2;
90 TestBgpPeer peer3;
Jonathan Hart20d8e512014-10-16 11:05:52 -070091
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -080092 // Local BGP per-peer session state
93 BgpSession bgpSession1;
94 BgpSession bgpSession2;
95 BgpSession bgpSession3;
96
97 // The socket that the remote peers should connect to
Jonathan Hart20d8e512014-10-16 11:05:52 -070098 private InetSocketAddress connectToSocket;
99
100 private final DummyRouteListener dummyRouteListener =
101 new DummyRouteListener();
102
103 /**
104 * Dummy implementation for the RouteListener interface.
105 */
106 private class DummyRouteListener implements RouteListener {
107 @Override
Pavlin Radoslavov248c2ae2014-12-02 09:51:25 -0800108 public void update(Collection<RouteUpdate> routeUpdate) {
Jonathan Hart20d8e512014-10-16 11:05:52 -0700109 // Nothing to do
110 }
111 }
112
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800113 /**
114 * A class to capture the state for a BGP peer.
115 */
116 private final class TestBgpPeer {
117 private final Ip4Address peerId;
118 private ClientBootstrap peerBootstrap;
119 private TestBgpPeerChannelHandler peerChannelHandler;
120 private TestBgpPeerFrameDecoder peerFrameDecoder =
121 new TestBgpPeerFrameDecoder();
122
123 /**
124 * Constructor.
125 *
126 * @param peerId the peer ID
127 */
128 private TestBgpPeer(Ip4Address peerId) {
129 this.peerId = peerId;
130 peerChannelHandler = new TestBgpPeerChannelHandler(peerId);
131 }
132
133 /**
134 * Starts up the BGP peer and connects it to the tested SDN-IP
135 * instance.
136 *
137 * @param connectToSocket the socket to connect to
138 */
139 private void connect(InetSocketAddress connectToSocket)
140 throws InterruptedException {
141 //
142 // Setup the BGP Peer, i.e., the "remote" BGP router that will
143 // initiate the BGP connection, send BGP UPDATE messages, etc.
144 //
145 ChannelFactory channelFactory =
146 new NioClientSocketChannelFactory(
147 Executors.newCachedThreadPool(),
148 Executors.newCachedThreadPool());
149 ChannelPipelineFactory pipelineFactory =
150 new ChannelPipelineFactory() {
151 @Override
152 public ChannelPipeline getPipeline() throws Exception {
153 // Setup the transmitting pipeline
154 ChannelPipeline pipeline = Channels.pipeline();
155 pipeline.addLast("TestBgpPeerFrameDecoder",
156 peerFrameDecoder);
157 pipeline.addLast("TestBgpPeerChannelHandler",
158 peerChannelHandler);
159 return pipeline;
160 }
161 };
162
163 peerBootstrap = new ClientBootstrap(channelFactory);
164 peerBootstrap.setOption("child.keepAlive", true);
165 peerBootstrap.setOption("child.tcpNoDelay", true);
166 peerBootstrap.setPipelineFactory(pipelineFactory);
167 peerBootstrap.connect(connectToSocket);
168
169 boolean result;
170 // Wait until the OPEN message is received
171 result = peerFrameDecoder.receivedOpenMessageLatch.await(
172 MESSAGE_TIMEOUT_MS,
173 TimeUnit.MILLISECONDS);
174 assertThat(result, is(true));
175 // Wait until the KEEPALIVE message is received
176 result = peerFrameDecoder.receivedKeepaliveMessageLatch.await(
177 MESSAGE_TIMEOUT_MS,
178 TimeUnit.MILLISECONDS);
179 assertThat(result, is(true));
180
181 for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
Pavlin Radoslavov8a36ce32015-01-28 12:26:57 -0800182 if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER1_ID)) {
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800183 bgpSession1 = bgpSession;
184 }
Pavlin Radoslavov8a36ce32015-01-28 12:26:57 -0800185 if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER2_ID)) {
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800186 bgpSession2 = bgpSession;
187 }
Pavlin Radoslavov8a36ce32015-01-28 12:26:57 -0800188 if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER3_ID)) {
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800189 bgpSession3 = bgpSession;
190 }
191 }
192 }
193 }
194
195 /**
196 * Class that implements a matcher for BgpRouteEntry by considering
197 * the BGP peer the entry was received from.
198 */
199 private static final class BgpRouteEntryAndPeerMatcher
200 extends TypeSafeMatcher<Collection<BgpRouteEntry>> {
201 private final BgpRouteEntry bgpRouteEntry;
202
203 private BgpRouteEntryAndPeerMatcher(BgpRouteEntry bgpRouteEntry) {
204 this.bgpRouteEntry = bgpRouteEntry;
205 }
206
207 @Override
208 public boolean matchesSafely(Collection<BgpRouteEntry> entries) {
209 for (BgpRouteEntry entry : entries) {
210 if (bgpRouteEntry.equals(entry) &&
211 bgpRouteEntry.getBgpSession() == entry.getBgpSession()) {
212 return true;
213 }
214 }
215 return false;
216 }
217
218 @Override
219 public void describeTo(Description description) {
220 description.appendText("BGP route entry lookup for entry \"").
221 appendText(bgpRouteEntry.toString()).
222 appendText("\"");
223 }
224 }
225
226 /**
227 * A helper method used for testing whether a collection of
228 * BGP route entries contains an entry from a specific BGP peer.
229 *
230 * @param bgpRouteEntry the BGP route entry to test
231 * @return an instance of BgpRouteEntryAndPeerMatcher that implements
232 * the matching logic
233 */
234 private static BgpRouteEntryAndPeerMatcher hasBgpRouteEntry(
235 BgpRouteEntry bgpRouteEntry) {
236 return new BgpRouteEntryAndPeerMatcher(bgpRouteEntry);
237 }
238
Jonathan Hart20d8e512014-10-16 11:05:52 -0700239 @Before
240 public void setUp() throws Exception {
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800241 peer1 = new TestBgpPeer(BGP_PEER1_ID);
242 peer2 = new TestBgpPeer(BGP_PEER2_ID);
243 peer3 = new TestBgpPeer(BGP_PEER3_ID);
244 peers.clear();
245 peers.add(peer1);
246 peers.add(peer2);
247 peers.add(peer3);
248
Jonathan Hart20d8e512014-10-16 11:05:52 -0700249 //
250 // Setup the BGP Session Manager to test, and start listening for BGP
251 // connections.
252 //
Jonathan Hart41349e92015-02-09 14:14:02 -0800253 bgpSessionManager = new BgpSessionManager();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700254 // NOTE: We use port 0 to bind on any available port
Jonathan Hart41349e92015-02-09 14:14:02 -0800255 bgpSessionManager.start(dummyRouteListener, 0);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700256
257 // Get the port number the BGP Session Manager is listening on
258 Channel serverChannel = TestUtils.getField(bgpSessionManager,
259 "serverChannel");
260 SocketAddress socketAddress = serverChannel.getLocalAddress();
261 InetSocketAddress inetSocketAddress =
262 (InetSocketAddress) socketAddress;
Jonathan Hart20d8e512014-10-16 11:05:52 -0700263 InetAddress connectToAddress = InetAddresses.forString("127.0.0.1");
264 connectToSocket = new InetSocketAddress(connectToAddress,
265 inetSocketAddress.getPort());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800266
267 //
268 // Setup the AS Paths
269 //
270 ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
271 byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
272 ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
273 segmentAsNumbers1.add((long) 65010);
274 segmentAsNumbers1.add((long) 65020);
275 segmentAsNumbers1.add((long) 65030);
276 BgpRouteEntry.PathSegment pathSegment1 =
277 new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
278 pathSegments.add(pathSegment1);
279 asPathShort = new BgpRouteEntry.AsPath(new ArrayList(pathSegments));
280 //
281 byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
282 ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
283 segmentAsNumbers2.add((long) 65041);
284 segmentAsNumbers2.add((long) 65042);
285 segmentAsNumbers2.add((long) 65043);
286 BgpRouteEntry.PathSegment pathSegment2 =
287 new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
288 pathSegments.add(pathSegment2);
289 //
290 asPathLong = new BgpRouteEntry.AsPath(pathSegments);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700291 }
292
293 @After
294 public void tearDown() throws Exception {
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -0800295 bgpSessionManager.stop();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700296 bgpSessionManager = null;
297 }
298
299 /**
300 * Gets BGP RIB-IN routes by waiting until they are received.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800301 * <p>
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800302 * NOTE: We keep checking once every 10ms the number of received routes,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700303 * up to 5 seconds.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800304 * </p>
Jonathan Hart20d8e512014-10-16 11:05:52 -0700305 *
306 * @param bgpSession the BGP session that is expected to receive the
307 * routes
308 * @param expectedRoutes the expected number of routes
309 * @return the BGP RIB-IN routes as received within the expected
310 * time interval
311 */
312 private Collection<BgpRouteEntry> waitForBgpRibIn(BgpSession bgpSession,
313 long expectedRoutes)
314 throws InterruptedException {
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800315 Collection<BgpRouteEntry> bgpRibIn = bgpSession.getBgpRibIn4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700316
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800317 final int maxChecks = 500; // Max wait of 5 seconds
Jonathan Hart20d8e512014-10-16 11:05:52 -0700318 for (int i = 0; i < maxChecks; i++) {
319 if (bgpRibIn.size() == expectedRoutes) {
320 break;
321 }
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800322 Thread.sleep(10);
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800323 bgpRibIn = bgpSession.getBgpRibIn4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700324 }
325
326 return bgpRibIn;
327 }
328
329 /**
330 * Gets BGP merged routes by waiting until they are received.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800331 * <p>
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800332 * NOTE: We keep checking once every 10ms the number of received routes,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700333 * up to 5 seconds.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800334 * </p>
Jonathan Hart20d8e512014-10-16 11:05:52 -0700335 *
336 * @param expectedRoutes the expected number of routes
337 * @return the BGP Session Manager routes as received within the expected
338 * time interval
339 */
340 private Collection<BgpRouteEntry> waitForBgpRoutes(long expectedRoutes)
341 throws InterruptedException {
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800342 Collection<BgpRouteEntry> bgpRoutes =
343 bgpSessionManager.getBgpRoutes4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700344
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800345 final int maxChecks = 500; // Max wait of 5 seconds
Jonathan Hart20d8e512014-10-16 11:05:52 -0700346 for (int i = 0; i < maxChecks; i++) {
347 if (bgpRoutes.size() == expectedRoutes) {
348 break;
349 }
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800350 Thread.sleep(10);
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800351 bgpRoutes = bgpSessionManager.getBgpRoutes4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700352 }
353
354 return bgpRoutes;
355 }
356
357 /**
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800358 * Gets a merged BGP route by waiting until it is received.
359 * <p>
360 * NOTE: We keep checking once every 10ms whether the route is received,
361 * up to 5 seconds.
362 * </p>
363 *
364 * @param expectedRoute the expected route
365 * @return the merged BGP route if received within the expected time
366 * interval, otherwise null
367 */
368 private BgpRouteEntry waitForBgpRoute(BgpRouteEntry expectedRoute)
369 throws InterruptedException {
370 Collection<BgpRouteEntry> bgpRoutes =
371 bgpSessionManager.getBgpRoutes4();
372
373 final int maxChecks = 500; // Max wait of 5 seconds
374 for (int i = 0; i < maxChecks; i++) {
375 for (BgpRouteEntry bgpRouteEntry : bgpRoutes) {
376 if (bgpRouteEntry.equals(expectedRoute) &&
377 bgpRouteEntry.getBgpSession() ==
378 expectedRoute.getBgpSession()) {
379 return bgpRouteEntry;
380 }
381 }
382 Thread.sleep(10);
383 bgpRoutes = bgpSessionManager.getBgpRoutes4();
384 }
385
386 return null;
387 }
388
389 /**
Jonathan Hart20d8e512014-10-16 11:05:52 -0700390 * Tests that the BGP OPEN messages have been exchanged, followed by
391 * KEEPALIVE.
392 * <p>
393 * The BGP Peer opens the sessions and transmits OPEN Message, eventually
394 * followed by KEEPALIVE. The tested BGP listener should respond by
395 * OPEN Message, followed by KEEPALIVE.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800396 * </p>
Jonathan Hart20d8e512014-10-16 11:05:52 -0700397 *
398 * @throws TestUtilsException TestUtils error
399 */
400 @Test
401 public void testExchangedBgpOpenMessages()
402 throws InterruptedException, TestUtilsException {
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800403 // Initiate the connections
404 peer1.connect(connectToSocket);
405 peer2.connect(connectToSocket);
406 peer3.connect(connectToSocket);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700407
408 //
409 // Test the fields from the BGP OPEN message:
410 // BGP version, AS number, BGP ID
411 //
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800412 for (TestBgpPeer peer : peers) {
413 assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
414 is(BgpConstants.BGP_VERSION));
415 assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
416 is(IP_LOOPBACK_ID));
417 assertThat(peer.peerFrameDecoder.remoteInfo.asNumber(),
418 is(TestBgpPeerChannelHandler.PEER_AS));
419 }
Jonathan Hart20d8e512014-10-16 11:05:52 -0700420
421 //
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800422 // Test that the BgpSession instances have been created
Jonathan Hart20d8e512014-10-16 11:05:52 -0700423 //
424 assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800425 assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
426 assertThat(bgpSession1, notNullValue());
427 assertThat(bgpSession2, notNullValue());
428 assertThat(bgpSession3, notNullValue());
429 for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
Pavlin Radoslavov8a36ce32015-01-28 12:26:57 -0800430 long sessionAs = bgpSession.localInfo().asNumber();
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800431 assertThat(sessionAs, is(TestBgpPeerChannelHandler.PEER_AS));
432 }
Jonathan Hart20d8e512014-10-16 11:05:52 -0700433 }
434
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800435
436 /**
437 * Tests that the BGP OPEN with Capability messages have been exchanged,
438 * followed by KEEPALIVE.
439 * <p>
440 * The BGP Peer opens the sessions and transmits OPEN Message, eventually
441 * followed by KEEPALIVE. The tested BGP listener should respond by
442 * OPEN Message, followed by KEEPALIVE.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800443 * </p>
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800444 *
445 * @throws TestUtilsException TestUtils error
446 */
447 @Test
448 public void testExchangedBgpOpenCapabilityMessages()
449 throws InterruptedException, TestUtilsException {
450 //
451 // Setup the BGP Capabilities for all peers
452 //
453 for (TestBgpPeer peer : peers) {
454 peer.peerChannelHandler.localInfo.setIpv4Unicast();
455 peer.peerChannelHandler.localInfo.setIpv4Multicast();
456 peer.peerChannelHandler.localInfo.setIpv6Unicast();
457 peer.peerChannelHandler.localInfo.setIpv6Multicast();
458 peer.peerChannelHandler.localInfo.setAs4OctetCapability();
459 peer.peerChannelHandler.localInfo.setAs4Number(
460 TestBgpPeerChannelHandler.PEER_AS4);
461 }
462
463 // Initiate the connections
464 peer1.connect(connectToSocket);
465 peer2.connect(connectToSocket);
466 peer3.connect(connectToSocket);
467
468 //
469 // Test the fields from the BGP OPEN message:
470 // BGP version, BGP ID
471 //
472 for (TestBgpPeer peer : peers) {
473 assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
474 is(BgpConstants.BGP_VERSION));
475 assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
476 is(IP_LOOPBACK_ID));
477 }
478
479 //
480 // Test that the BgpSession instances have been created,
481 // and contain the appropriate BGP session information.
482 //
483 assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
484 assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
485 assertThat(bgpSession1, notNullValue());
486 assertThat(bgpSession2, notNullValue());
487 assertThat(bgpSession3, notNullValue());
488 for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
489 BgpSessionInfo localInfo = bgpSession.localInfo();
490 assertThat(localInfo.ipv4Unicast(), is(true));
491 assertThat(localInfo.ipv4Multicast(), is(true));
492 assertThat(localInfo.ipv6Unicast(), is(true));
493 assertThat(localInfo.ipv6Multicast(), is(true));
494 assertThat(localInfo.as4OctetCapability(), is(true));
495 assertThat(localInfo.asNumber(),
496 is(TestBgpPeerChannelHandler.PEER_AS4));
497 assertThat(localInfo.as4Number(),
498 is(TestBgpPeerChannelHandler.PEER_AS4));
499 }
500 }
501
Jonathan Hart20d8e512014-10-16 11:05:52 -0700502 /**
503 * Tests that the BGP UPDATE messages have been received and processed.
504 */
505 @Test
506 public void testProcessedBgpUpdateMessages() throws InterruptedException {
Jonathan Hart20d8e512014-10-16 11:05:52 -0700507 ChannelBuffer message;
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800508 BgpRouteEntry bgpRouteEntry;
509 Collection<BgpRouteEntry> bgpRibIn1;
510 Collection<BgpRouteEntry> bgpRibIn2;
511 Collection<BgpRouteEntry> bgpRibIn3;
Jonathan Hart20d8e512014-10-16 11:05:52 -0700512 Collection<BgpRouteEntry> bgpRoutes;
513
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800514 // Initiate the connections
515 peer1.connect(connectToSocket);
516 peer2.connect(connectToSocket);
517 peer3.connect(connectToSocket);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700518
519 // Prepare routes to add/delete
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800520 Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
521 Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800522
523 //
524 // Add and delete some routes
525 //
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800526 addedRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
527 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
528 addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
529 addedRoutes.add(Ip4Prefix.valueOf("40.0.0.0/24"));
530 addedRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
531 withdrawnRoutes.add(Ip4Prefix.valueOf("60.0.0.0/8"));
532 withdrawnRoutes.add(Ip4Prefix.valueOf("70.0.0.0/16"));
533 withdrawnRoutes.add(Ip4Prefix.valueOf("80.0.0.0/24"));
534 withdrawnRoutes.add(Ip4Prefix.valueOf("90.0.0.0/32"));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700535 // Write the routes
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800536 message = peer1.peerChannelHandler.prepareBgpUpdate(
537 NEXT_HOP1_ROUTER,
538 DEFAULT_LOCAL_PREF,
539 DEFAULT_MULTI_EXIT_DISC,
540 asPathLong,
541 addedRoutes,
542 withdrawnRoutes);
543 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
544 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700545 // Check that the routes have been received, processed and stored
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800546 //
547 bgpRibIn1 = waitForBgpRibIn(bgpSession1, 5);
548 assertThat(bgpRibIn1, hasSize(5));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700549 bgpRoutes = waitForBgpRoutes(5);
550 assertThat(bgpRoutes, hasSize(5));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700551 //
552 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800553 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800554 Ip4Prefix.valueOf("0.0.0.0/0"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800555 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700556 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800557 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700558 DEFAULT_LOCAL_PREF);
559 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800560 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800561 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700562 //
563 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800564 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800565 Ip4Prefix.valueOf("20.0.0.0/8"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800566 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700567 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800568 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700569 DEFAULT_LOCAL_PREF);
570 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800571 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800572 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700573 //
574 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800575 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800576 Ip4Prefix.valueOf("30.0.0.0/16"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800577 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700578 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800579 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700580 DEFAULT_LOCAL_PREF);
581 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800582 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800583 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700584 //
585 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800586 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800587 Ip4Prefix.valueOf("40.0.0.0/24"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800588 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700589 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800590 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700591 DEFAULT_LOCAL_PREF);
592 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800593 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800594 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700595 //
596 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800597 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800598 Ip4Prefix.valueOf("50.0.0.0/32"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800599 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700600 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800601 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700602 DEFAULT_LOCAL_PREF);
603 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800604 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800605 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700606
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800607 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700608 // Delete some routes
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800609 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700610 addedRoutes = new LinkedList<>();
611 withdrawnRoutes = new LinkedList<>();
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800612 withdrawnRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
613 withdrawnRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700614 // Write the routes
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800615 message = peer1.peerChannelHandler.prepareBgpUpdate(
616 NEXT_HOP1_ROUTER,
617 DEFAULT_LOCAL_PREF,
618 DEFAULT_MULTI_EXIT_DISC,
619 asPathLong,
620 addedRoutes,
621 withdrawnRoutes);
622 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
623 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700624 // Check that the routes have been received, processed and stored
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800625 //
626 bgpRibIn1 = waitForBgpRibIn(bgpSession1, 3);
627 assertThat(bgpRibIn1, hasSize(3));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700628 bgpRoutes = waitForBgpRoutes(3);
629 assertThat(bgpRoutes, hasSize(3));
630 //
631 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800632 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800633 Ip4Prefix.valueOf("20.0.0.0/8"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800634 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700635 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800636 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700637 DEFAULT_LOCAL_PREF);
638 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800639 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800640 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700641 //
642 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800643 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800644 Ip4Prefix.valueOf("30.0.0.0/16"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800645 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700646 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800647 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700648 DEFAULT_LOCAL_PREF);
649 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800650 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800651 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700652 //
653 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800654 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800655 Ip4Prefix.valueOf("40.0.0.0/24"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800656 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700657 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800658 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700659 DEFAULT_LOCAL_PREF);
660 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800661 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800662 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700663
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800664
665 // Close the channels and test there are no routes
666 peer1.peerChannelHandler.closeChannel();
667 peer2.peerChannelHandler.closeChannel();
668 peer3.peerChannelHandler.closeChannel();
669 bgpRoutes = waitForBgpRoutes(0);
670 assertThat(bgpRoutes, hasSize(0));
671 }
672
673 /**
674 * Tests the BGP route preference.
675 */
676 @Test
677 public void testBgpRoutePreference() throws InterruptedException {
678 ChannelBuffer message;
679 BgpRouteEntry bgpRouteEntry;
680 Collection<BgpRouteEntry> bgpRibIn1;
681 Collection<BgpRouteEntry> bgpRibIn2;
682 Collection<BgpRouteEntry> bgpRibIn3;
683 Collection<BgpRouteEntry> bgpRoutes;
684 Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
685 Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
686
687 // Initiate the connections
688 peer1.connect(connectToSocket);
689 peer2.connect(connectToSocket);
690 peer3.connect(connectToSocket);
691
692 //
693 // Setup the initial set of routes to Peer1
694 //
695 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
696 addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
697 // Write the routes
698 message = peer1.peerChannelHandler.prepareBgpUpdate(
699 NEXT_HOP1_ROUTER,
700 DEFAULT_LOCAL_PREF,
701 DEFAULT_MULTI_EXIT_DISC,
702 asPathLong,
703 addedRoutes,
704 withdrawnRoutes);
705 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
706 bgpRoutes = waitForBgpRoutes(2);
707 assertThat(bgpRoutes, hasSize(2));
708
709 //
710 // Add a route entry to Peer2 with a better LOCAL_PREF
711 //
712 addedRoutes = new LinkedList<>();
713 withdrawnRoutes = new LinkedList<>();
714 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
715 // Write the routes
716 message = peer2.peerChannelHandler.prepareBgpUpdate(
717 NEXT_HOP2_ROUTER,
718 BETTER_LOCAL_PREF,
719 DEFAULT_MULTI_EXIT_DISC,
720 asPathLong,
721 addedRoutes,
722 withdrawnRoutes);
723 peer2.peerChannelHandler.savedCtx.getChannel().write(message);
724 //
725 // Check that the routes have been received, processed and stored
726 //
727 bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
728 assertThat(bgpRibIn2, hasSize(1));
729 bgpRoutes = waitForBgpRoutes(2);
730 assertThat(bgpRoutes, hasSize(2));
731 //
732 bgpRouteEntry =
733 new BgpRouteEntry(bgpSession2,
734 Ip4Prefix.valueOf("20.0.0.0/8"),
735 NEXT_HOP2_ROUTER,
736 (byte) BgpConstants.Update.Origin.IGP,
737 asPathLong,
738 BETTER_LOCAL_PREF);
739 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
740 assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800741 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800742
743 //
744 // Add a route entry to Peer3 with a shorter AS path
745 //
746 addedRoutes = new LinkedList<>();
747 withdrawnRoutes = new LinkedList<>();
748 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
749 // Write the routes
750 message = peer3.peerChannelHandler.prepareBgpUpdate(
751 NEXT_HOP3_ROUTER,
752 BETTER_LOCAL_PREF,
753 DEFAULT_MULTI_EXIT_DISC,
754 asPathShort,
755 addedRoutes,
756 withdrawnRoutes);
757 peer3.peerChannelHandler.savedCtx.getChannel().write(message);
758 //
759 // Check that the routes have been received, processed and stored
760 //
761 bgpRibIn3 = waitForBgpRibIn(bgpSession3, 1);
762 assertThat(bgpRibIn3, hasSize(1));
763 bgpRoutes = waitForBgpRoutes(2);
764 assertThat(bgpRoutes, hasSize(2));
765 //
766 bgpRouteEntry =
767 new BgpRouteEntry(bgpSession3,
768 Ip4Prefix.valueOf("20.0.0.0/8"),
769 NEXT_HOP3_ROUTER,
770 (byte) BgpConstants.Update.Origin.IGP,
771 asPathShort,
772 BETTER_LOCAL_PREF);
773 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
774 assertThat(bgpRibIn3, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800775 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800776
777 //
778 // Cleanup in preparation for next test: delete old route entry from
779 // Peer2
780 //
781 addedRoutes = new LinkedList<>();
782 withdrawnRoutes = new LinkedList<>();
783 withdrawnRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
784 // Write the routes
785 message = peer2.peerChannelHandler.prepareBgpUpdate(
786 NEXT_HOP2_ROUTER,
787 BETTER_LOCAL_PREF,
788 BETTER_MULTI_EXIT_DISC,
789 asPathShort,
790 addedRoutes,
791 withdrawnRoutes);
792 peer2.peerChannelHandler.savedCtx.getChannel().write(message);
793 //
794 // Check that the routes have been received, processed and stored
795 //
796 bgpRibIn2 = waitForBgpRibIn(bgpSession2, 0);
797 assertThat(bgpRibIn2, hasSize(0));
798
799 //
800 // Add a route entry to Peer2 with a better MED
801 //
802 addedRoutes = new LinkedList<>();
803 withdrawnRoutes = new LinkedList<>();
804 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
805 // Write the routes
806 message = peer2.peerChannelHandler.prepareBgpUpdate(
807 NEXT_HOP2_ROUTER,
808 BETTER_LOCAL_PREF,
809 BETTER_MULTI_EXIT_DISC,
810 asPathShort,
811 addedRoutes,
812 withdrawnRoutes);
813 peer2.peerChannelHandler.savedCtx.getChannel().write(message);
814 //
815 // Check that the routes have been received, processed and stored
816 //
817 bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
818 assertThat(bgpRibIn2, hasSize(1));
819 bgpRoutes = waitForBgpRoutes(2);
820 assertThat(bgpRoutes, hasSize(2));
821 //
822 bgpRouteEntry =
823 new BgpRouteEntry(bgpSession2,
824 Ip4Prefix.valueOf("20.0.0.0/8"),
825 NEXT_HOP2_ROUTER,
826 (byte) BgpConstants.Update.Origin.IGP,
827 asPathShort,
828 BETTER_LOCAL_PREF);
829 bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
830 assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800831 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800832
833 //
834 // Add a route entry to Peer1 with a better (lower) BGP ID
835 //
836 addedRoutes = new LinkedList<>();
837 withdrawnRoutes = new LinkedList<>();
838 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
839 withdrawnRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
840 // Write the routes
841 message = peer1.peerChannelHandler.prepareBgpUpdate(
842 NEXT_HOP1_ROUTER,
843 BETTER_LOCAL_PREF,
844 BETTER_MULTI_EXIT_DISC,
845 asPathShort,
846 addedRoutes,
847 withdrawnRoutes);
848 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
849 //
850 // Check that the routes have been received, processed and stored
851 //
852 bgpRibIn1 = waitForBgpRibIn(bgpSession1, 1);
853 assertThat(bgpRibIn1, hasSize(1));
854 bgpRoutes = waitForBgpRoutes(1);
855 assertThat(bgpRoutes, hasSize(1));
856 //
857 bgpRouteEntry =
858 new BgpRouteEntry(bgpSession1,
859 Ip4Prefix.valueOf("20.0.0.0/8"),
860 NEXT_HOP1_ROUTER,
861 (byte) BgpConstants.Update.Origin.IGP,
862 asPathShort,
863 BETTER_LOCAL_PREF);
864 bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
865 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800866 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800867
868
869 // Close the channels and test there are no routes
870 peer1.peerChannelHandler.closeChannel();
871 peer2.peerChannelHandler.closeChannel();
872 peer3.peerChannelHandler.closeChannel();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700873 bgpRoutes = waitForBgpRoutes(0);
874 assertThat(bgpRoutes, hasSize(0));
875 }
876}