blob: c9c52b18ae748602c4ed9f58de2ccdf778a88a9f [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 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 /**
139 * Starts up the BGP peer and connects it to the tested SDN-IP
140 * 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());
154 ChannelPipelineFactory pipelineFactory =
155 new ChannelPipelineFactory() {
156 @Override
157 public ChannelPipeline getPipeline() throws Exception {
158 // Setup the transmitting pipeline
159 ChannelPipeline pipeline = Channels.pipeline();
160 pipeline.addLast("TestBgpPeerFrameDecoder",
161 peerFrameDecoder);
162 pipeline.addLast("TestBgpPeerChannelHandler",
163 peerChannelHandler);
164 return pipeline;
165 }
166 };
167
168 peerBootstrap = new ClientBootstrap(channelFactory);
169 peerBootstrap.setOption("child.keepAlive", true);
170 peerBootstrap.setOption("child.tcpNoDelay", true);
171 peerBootstrap.setPipelineFactory(pipelineFactory);
172 peerBootstrap.connect(connectToSocket);
173
174 boolean result;
175 // Wait until the OPEN message is received
176 result = peerFrameDecoder.receivedOpenMessageLatch.await(
177 MESSAGE_TIMEOUT_MS,
178 TimeUnit.MILLISECONDS);
179 assertThat(result, is(true));
180 // Wait until the KEEPALIVE message is received
181 result = peerFrameDecoder.receivedKeepaliveMessageLatch.await(
182 MESSAGE_TIMEOUT_MS,
183 TimeUnit.MILLISECONDS);
184 assertThat(result, is(true));
185
186 for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
Pavlin Radoslavov8a36ce32015-01-28 12:26:57 -0800187 if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER1_ID)) {
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800188 bgpSession1 = bgpSession;
189 }
Pavlin Radoslavov8a36ce32015-01-28 12:26:57 -0800190 if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER2_ID)) {
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800191 bgpSession2 = bgpSession;
192 }
Pavlin Radoslavov8a36ce32015-01-28 12:26:57 -0800193 if (bgpSession.remoteInfo().bgpId().equals(BGP_PEER3_ID)) {
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800194 bgpSession3 = bgpSession;
195 }
196 }
197 }
198 }
199
200 /**
201 * Class that implements a matcher for BgpRouteEntry by considering
202 * the BGP peer the entry was received from.
203 */
204 private static final class BgpRouteEntryAndPeerMatcher
205 extends TypeSafeMatcher<Collection<BgpRouteEntry>> {
206 private final BgpRouteEntry bgpRouteEntry;
207
208 private BgpRouteEntryAndPeerMatcher(BgpRouteEntry bgpRouteEntry) {
209 this.bgpRouteEntry = bgpRouteEntry;
210 }
211
212 @Override
213 public boolean matchesSafely(Collection<BgpRouteEntry> entries) {
214 for (BgpRouteEntry entry : entries) {
215 if (bgpRouteEntry.equals(entry) &&
216 bgpRouteEntry.getBgpSession() == entry.getBgpSession()) {
217 return true;
218 }
219 }
220 return false;
221 }
222
223 @Override
224 public void describeTo(Description description) {
225 description.appendText("BGP route entry lookup for entry \"").
226 appendText(bgpRouteEntry.toString()).
227 appendText("\"");
228 }
229 }
230
231 /**
232 * A helper method used for testing whether a collection of
233 * BGP route entries contains an entry from a specific BGP peer.
234 *
235 * @param bgpRouteEntry the BGP route entry to test
236 * @return an instance of BgpRouteEntryAndPeerMatcher that implements
237 * the matching logic
238 */
239 private static BgpRouteEntryAndPeerMatcher hasBgpRouteEntry(
240 BgpRouteEntry bgpRouteEntry) {
241 return new BgpRouteEntryAndPeerMatcher(bgpRouteEntry);
242 }
243
Jonathan Hart20d8e512014-10-16 11:05:52 -0700244 @Before
245 public void setUp() throws Exception {
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800246 peer1 = new TestBgpPeer(BGP_PEER1_ID);
247 peer2 = new TestBgpPeer(BGP_PEER2_ID);
248 peer3 = new TestBgpPeer(BGP_PEER3_ID);
249 peers.clear();
250 peers.add(peer1);
251 peers.add(peer2);
252 peers.add(peer3);
253
Jonathan Hart20d8e512014-10-16 11:05:52 -0700254 //
255 // Setup the BGP Session Manager to test, and start listening for BGP
256 // connections.
257 //
Jonathan Hart41349e92015-02-09 14:14:02 -0800258 bgpSessionManager = new BgpSessionManager();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700259 // NOTE: We use port 0 to bind on any available port
Jonathan Hartd24fafb2015-02-09 17:55:32 -0800260 ComponentContext componentContext = createMock(ComponentContext.class);
261 Dictionary<String, String> dictionary = createMock(Dictionary.class);
262 expect(dictionary.get("bgpPort")).andReturn("0");
263 replay(dictionary);
264 expect(componentContext.getProperties()).andReturn(dictionary);
265 replay(componentContext);
266 bgpSessionManager.activate(componentContext);
267 bgpSessionManager.start(dummyRouteListener);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700268
269 // Get the port number the BGP Session Manager is listening on
270 Channel serverChannel = TestUtils.getField(bgpSessionManager,
271 "serverChannel");
272 SocketAddress socketAddress = serverChannel.getLocalAddress();
273 InetSocketAddress inetSocketAddress =
274 (InetSocketAddress) socketAddress;
Jonathan Hart20d8e512014-10-16 11:05:52 -0700275 InetAddress connectToAddress = InetAddresses.forString("127.0.0.1");
276 connectToSocket = new InetSocketAddress(connectToAddress,
277 inetSocketAddress.getPort());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800278
279 //
280 // Setup the AS Paths
281 //
282 ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
283 byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
284 ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
285 segmentAsNumbers1.add((long) 65010);
286 segmentAsNumbers1.add((long) 65020);
287 segmentAsNumbers1.add((long) 65030);
288 BgpRouteEntry.PathSegment pathSegment1 =
289 new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
290 pathSegments.add(pathSegment1);
291 asPathShort = new BgpRouteEntry.AsPath(new ArrayList(pathSegments));
292 //
293 byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
294 ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
295 segmentAsNumbers2.add((long) 65041);
296 segmentAsNumbers2.add((long) 65042);
297 segmentAsNumbers2.add((long) 65043);
298 BgpRouteEntry.PathSegment pathSegment2 =
299 new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
300 pathSegments.add(pathSegment2);
301 //
302 asPathLong = new BgpRouteEntry.AsPath(pathSegments);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700303 }
304
305 @After
306 public void tearDown() throws Exception {
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -0800307 bgpSessionManager.stop();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700308 bgpSessionManager = null;
309 }
310
311 /**
312 * Gets BGP RIB-IN routes by waiting until they are received.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800313 * <p>
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800314 * NOTE: We keep checking once every 10ms the number of received routes,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700315 * up to 5 seconds.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800316 * </p>
Jonathan Hart20d8e512014-10-16 11:05:52 -0700317 *
318 * @param bgpSession the BGP session that is expected to receive the
319 * routes
320 * @param expectedRoutes the expected number of routes
321 * @return the BGP RIB-IN routes as received within the expected
322 * time interval
323 */
324 private Collection<BgpRouteEntry> waitForBgpRibIn(BgpSession bgpSession,
325 long expectedRoutes)
326 throws InterruptedException {
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800327 Collection<BgpRouteEntry> bgpRibIn = bgpSession.getBgpRibIn4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700328
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800329 final int maxChecks = 500; // Max wait of 5 seconds
Jonathan Hart20d8e512014-10-16 11:05:52 -0700330 for (int i = 0; i < maxChecks; i++) {
331 if (bgpRibIn.size() == expectedRoutes) {
332 break;
333 }
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800334 Thread.sleep(10);
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800335 bgpRibIn = bgpSession.getBgpRibIn4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700336 }
337
338 return bgpRibIn;
339 }
340
341 /**
342 * Gets BGP merged routes by waiting until they are received.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800343 * <p>
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800344 * NOTE: We keep checking once every 10ms the number of received routes,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700345 * up to 5 seconds.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800346 * </p>
Jonathan Hart20d8e512014-10-16 11:05:52 -0700347 *
348 * @param expectedRoutes the expected number of routes
349 * @return the BGP Session Manager routes as received within the expected
350 * time interval
351 */
352 private Collection<BgpRouteEntry> waitForBgpRoutes(long expectedRoutes)
353 throws InterruptedException {
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800354 Collection<BgpRouteEntry> bgpRoutes =
355 bgpSessionManager.getBgpRoutes4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700356
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800357 final int maxChecks = 500; // Max wait of 5 seconds
Jonathan Hart20d8e512014-10-16 11:05:52 -0700358 for (int i = 0; i < maxChecks; i++) {
359 if (bgpRoutes.size() == expectedRoutes) {
360 break;
361 }
Pavlin Radoslavov55b5f512014-12-08 09:59:35 -0800362 Thread.sleep(10);
Pavlin Radoslavov3a0a52e2015-01-06 17:41:37 -0800363 bgpRoutes = bgpSessionManager.getBgpRoutes4();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700364 }
365
366 return bgpRoutes;
367 }
368
369 /**
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800370 * Gets a merged BGP route by waiting until it is received.
371 * <p>
372 * NOTE: We keep checking once every 10ms whether the route is received,
373 * up to 5 seconds.
374 * </p>
375 *
376 * @param expectedRoute the expected route
377 * @return the merged BGP route if received within the expected time
378 * interval, otherwise null
379 */
380 private BgpRouteEntry waitForBgpRoute(BgpRouteEntry expectedRoute)
381 throws InterruptedException {
382 Collection<BgpRouteEntry> bgpRoutes =
383 bgpSessionManager.getBgpRoutes4();
384
385 final int maxChecks = 500; // Max wait of 5 seconds
386 for (int i = 0; i < maxChecks; i++) {
387 for (BgpRouteEntry bgpRouteEntry : bgpRoutes) {
388 if (bgpRouteEntry.equals(expectedRoute) &&
389 bgpRouteEntry.getBgpSession() ==
390 expectedRoute.getBgpSession()) {
391 return bgpRouteEntry;
392 }
393 }
394 Thread.sleep(10);
395 bgpRoutes = bgpSessionManager.getBgpRoutes4();
396 }
397
398 return null;
399 }
400
401 /**
Jonathan Hart20d8e512014-10-16 11:05:52 -0700402 * Tests that the BGP OPEN messages have been exchanged, followed by
403 * KEEPALIVE.
404 * <p>
405 * The BGP Peer opens the sessions and transmits OPEN Message, eventually
406 * followed by KEEPALIVE. The tested BGP listener should respond by
407 * OPEN Message, followed by KEEPALIVE.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800408 * </p>
Jonathan Hart20d8e512014-10-16 11:05:52 -0700409 *
410 * @throws TestUtilsException TestUtils error
411 */
412 @Test
413 public void testExchangedBgpOpenMessages()
414 throws InterruptedException, TestUtilsException {
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800415 // Initiate the connections
416 peer1.connect(connectToSocket);
417 peer2.connect(connectToSocket);
418 peer3.connect(connectToSocket);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700419
420 //
421 // Test the fields from the BGP OPEN message:
422 // BGP version, AS number, BGP ID
423 //
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800424 for (TestBgpPeer peer : peers) {
425 assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
426 is(BgpConstants.BGP_VERSION));
427 assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
428 is(IP_LOOPBACK_ID));
429 assertThat(peer.peerFrameDecoder.remoteInfo.asNumber(),
430 is(TestBgpPeerChannelHandler.PEER_AS));
431 }
Jonathan Hart20d8e512014-10-16 11:05:52 -0700432
433 //
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800434 // Test that the BgpSession instances have been created
Jonathan Hart20d8e512014-10-16 11:05:52 -0700435 //
436 assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800437 assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
438 assertThat(bgpSession1, notNullValue());
439 assertThat(bgpSession2, notNullValue());
440 assertThat(bgpSession3, notNullValue());
441 for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
Pavlin Radoslavov8a36ce32015-01-28 12:26:57 -0800442 long sessionAs = bgpSession.localInfo().asNumber();
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800443 assertThat(sessionAs, is(TestBgpPeerChannelHandler.PEER_AS));
444 }
Jonathan Hart20d8e512014-10-16 11:05:52 -0700445 }
446
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800447
448 /**
449 * Tests that the BGP OPEN with Capability messages have been exchanged,
450 * followed by KEEPALIVE.
451 * <p>
452 * The BGP Peer opens the sessions and transmits OPEN Message, eventually
453 * followed by KEEPALIVE. The tested BGP listener should respond by
454 * OPEN Message, followed by KEEPALIVE.
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800455 * </p>
Pavlin Radoslavov4b5acae2015-01-28 17:09:45 -0800456 *
457 * @throws TestUtilsException TestUtils error
458 */
459 @Test
460 public void testExchangedBgpOpenCapabilityMessages()
461 throws InterruptedException, TestUtilsException {
462 //
463 // Setup the BGP Capabilities for all peers
464 //
465 for (TestBgpPeer peer : peers) {
466 peer.peerChannelHandler.localInfo.setIpv4Unicast();
467 peer.peerChannelHandler.localInfo.setIpv4Multicast();
468 peer.peerChannelHandler.localInfo.setIpv6Unicast();
469 peer.peerChannelHandler.localInfo.setIpv6Multicast();
470 peer.peerChannelHandler.localInfo.setAs4OctetCapability();
471 peer.peerChannelHandler.localInfo.setAs4Number(
472 TestBgpPeerChannelHandler.PEER_AS4);
473 }
474
475 // Initiate the connections
476 peer1.connect(connectToSocket);
477 peer2.connect(connectToSocket);
478 peer3.connect(connectToSocket);
479
480 //
481 // Test the fields from the BGP OPEN message:
482 // BGP version, BGP ID
483 //
484 for (TestBgpPeer peer : peers) {
485 assertThat(peer.peerFrameDecoder.remoteInfo.bgpVersion(),
486 is(BgpConstants.BGP_VERSION));
487 assertThat(peer.peerFrameDecoder.remoteInfo.bgpId(),
488 is(IP_LOOPBACK_ID));
489 }
490
491 //
492 // Test that the BgpSession instances have been created,
493 // and contain the appropriate BGP session information.
494 //
495 assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
496 assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
497 assertThat(bgpSession1, notNullValue());
498 assertThat(bgpSession2, notNullValue());
499 assertThat(bgpSession3, notNullValue());
500 for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
501 BgpSessionInfo localInfo = bgpSession.localInfo();
502 assertThat(localInfo.ipv4Unicast(), is(true));
503 assertThat(localInfo.ipv4Multicast(), is(true));
504 assertThat(localInfo.ipv6Unicast(), is(true));
505 assertThat(localInfo.ipv6Multicast(), is(true));
506 assertThat(localInfo.as4OctetCapability(), is(true));
507 assertThat(localInfo.asNumber(),
508 is(TestBgpPeerChannelHandler.PEER_AS4));
509 assertThat(localInfo.as4Number(),
510 is(TestBgpPeerChannelHandler.PEER_AS4));
511 }
512 }
513
Jonathan Hart20d8e512014-10-16 11:05:52 -0700514 /**
515 * Tests that the BGP UPDATE messages have been received and processed.
516 */
517 @Test
518 public void testProcessedBgpUpdateMessages() throws InterruptedException {
Jonathan Hart20d8e512014-10-16 11:05:52 -0700519 ChannelBuffer message;
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800520 BgpRouteEntry bgpRouteEntry;
521 Collection<BgpRouteEntry> bgpRibIn1;
522 Collection<BgpRouteEntry> bgpRibIn2;
523 Collection<BgpRouteEntry> bgpRibIn3;
Jonathan Hart20d8e512014-10-16 11:05:52 -0700524 Collection<BgpRouteEntry> bgpRoutes;
525
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800526 // Initiate the connections
527 peer1.connect(connectToSocket);
528 peer2.connect(connectToSocket);
529 peer3.connect(connectToSocket);
Jonathan Hart20d8e512014-10-16 11:05:52 -0700530
531 // Prepare routes to add/delete
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800532 Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
533 Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800534
535 //
536 // Add and delete some routes
537 //
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800538 addedRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
539 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
540 addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
541 addedRoutes.add(Ip4Prefix.valueOf("40.0.0.0/24"));
542 addedRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
543 withdrawnRoutes.add(Ip4Prefix.valueOf("60.0.0.0/8"));
544 withdrawnRoutes.add(Ip4Prefix.valueOf("70.0.0.0/16"));
545 withdrawnRoutes.add(Ip4Prefix.valueOf("80.0.0.0/24"));
546 withdrawnRoutes.add(Ip4Prefix.valueOf("90.0.0.0/32"));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700547 // Write the routes
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800548 message = peer1.peerChannelHandler.prepareBgpUpdate(
549 NEXT_HOP1_ROUTER,
550 DEFAULT_LOCAL_PREF,
551 DEFAULT_MULTI_EXIT_DISC,
552 asPathLong,
553 addedRoutes,
554 withdrawnRoutes);
555 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
556 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700557 // Check that the routes have been received, processed and stored
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800558 //
559 bgpRibIn1 = waitForBgpRibIn(bgpSession1, 5);
560 assertThat(bgpRibIn1, hasSize(5));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700561 bgpRoutes = waitForBgpRoutes(5);
562 assertThat(bgpRoutes, hasSize(5));
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("0.0.0.0/0"),
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("20.0.0.0/8"),
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("30.0.0.0/16"),
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("40.0.0.0/24"),
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 //
608 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800609 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800610 Ip4Prefix.valueOf("50.0.0.0/32"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800611 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700612 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800613 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700614 DEFAULT_LOCAL_PREF);
615 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800616 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800617 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700618
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800619 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700620 // Delete some routes
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800621 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700622 addedRoutes = new LinkedList<>();
623 withdrawnRoutes = new LinkedList<>();
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800624 withdrawnRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
625 withdrawnRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700626 // Write the routes
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800627 message = peer1.peerChannelHandler.prepareBgpUpdate(
628 NEXT_HOP1_ROUTER,
629 DEFAULT_LOCAL_PREF,
630 DEFAULT_MULTI_EXIT_DISC,
631 asPathLong,
632 addedRoutes,
633 withdrawnRoutes);
634 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
635 //
Jonathan Hart20d8e512014-10-16 11:05:52 -0700636 // Check that the routes have been received, processed and stored
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800637 //
638 bgpRibIn1 = waitForBgpRibIn(bgpSession1, 3);
639 assertThat(bgpRibIn1, hasSize(3));
Jonathan Hart20d8e512014-10-16 11:05:52 -0700640 bgpRoutes = waitForBgpRoutes(3);
641 assertThat(bgpRoutes, hasSize(3));
642 //
643 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800644 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800645 Ip4Prefix.valueOf("20.0.0.0/8"),
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("30.0.0.0/16"),
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 //
665 bgpRouteEntry =
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800666 new BgpRouteEntry(bgpSession1,
Pavlin Radoslavov6b570732014-11-06 13:16:45 -0800667 Ip4Prefix.valueOf("40.0.0.0/24"),
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800668 NEXT_HOP1_ROUTER,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700669 (byte) BgpConstants.Update.Origin.IGP,
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800670 asPathLong,
Jonathan Hart20d8e512014-10-16 11:05:52 -0700671 DEFAULT_LOCAL_PREF);
672 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800673 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800674 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Jonathan Hart20d8e512014-10-16 11:05:52 -0700675
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800676
677 // Close the channels and test there are no routes
678 peer1.peerChannelHandler.closeChannel();
679 peer2.peerChannelHandler.closeChannel();
680 peer3.peerChannelHandler.closeChannel();
681 bgpRoutes = waitForBgpRoutes(0);
682 assertThat(bgpRoutes, hasSize(0));
683 }
684
685 /**
686 * Tests the BGP route preference.
687 */
688 @Test
689 public void testBgpRoutePreference() throws InterruptedException {
690 ChannelBuffer message;
691 BgpRouteEntry bgpRouteEntry;
692 Collection<BgpRouteEntry> bgpRibIn1;
693 Collection<BgpRouteEntry> bgpRibIn2;
694 Collection<BgpRouteEntry> bgpRibIn3;
695 Collection<BgpRouteEntry> bgpRoutes;
696 Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
697 Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
698
699 // Initiate the connections
700 peer1.connect(connectToSocket);
701 peer2.connect(connectToSocket);
702 peer3.connect(connectToSocket);
703
704 //
705 // Setup the initial set of routes to Peer1
706 //
707 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
708 addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
709 // Write the routes
710 message = peer1.peerChannelHandler.prepareBgpUpdate(
711 NEXT_HOP1_ROUTER,
712 DEFAULT_LOCAL_PREF,
713 DEFAULT_MULTI_EXIT_DISC,
714 asPathLong,
715 addedRoutes,
716 withdrawnRoutes);
717 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
718 bgpRoutes = waitForBgpRoutes(2);
719 assertThat(bgpRoutes, hasSize(2));
720
721 //
722 // Add a route entry to Peer2 with a better LOCAL_PREF
723 //
724 addedRoutes = new LinkedList<>();
725 withdrawnRoutes = new LinkedList<>();
726 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
727 // Write the routes
728 message = peer2.peerChannelHandler.prepareBgpUpdate(
729 NEXT_HOP2_ROUTER,
730 BETTER_LOCAL_PREF,
731 DEFAULT_MULTI_EXIT_DISC,
732 asPathLong,
733 addedRoutes,
734 withdrawnRoutes);
735 peer2.peerChannelHandler.savedCtx.getChannel().write(message);
736 //
737 // Check that the routes have been received, processed and stored
738 //
739 bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
740 assertThat(bgpRibIn2, hasSize(1));
741 bgpRoutes = waitForBgpRoutes(2);
742 assertThat(bgpRoutes, hasSize(2));
743 //
744 bgpRouteEntry =
745 new BgpRouteEntry(bgpSession2,
746 Ip4Prefix.valueOf("20.0.0.0/8"),
747 NEXT_HOP2_ROUTER,
748 (byte) BgpConstants.Update.Origin.IGP,
749 asPathLong,
750 BETTER_LOCAL_PREF);
751 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
752 assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800753 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800754
755 //
756 // Add a route entry to Peer3 with a shorter AS path
757 //
758 addedRoutes = new LinkedList<>();
759 withdrawnRoutes = new LinkedList<>();
760 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
761 // Write the routes
762 message = peer3.peerChannelHandler.prepareBgpUpdate(
763 NEXT_HOP3_ROUTER,
764 BETTER_LOCAL_PREF,
765 DEFAULT_MULTI_EXIT_DISC,
766 asPathShort,
767 addedRoutes,
768 withdrawnRoutes);
769 peer3.peerChannelHandler.savedCtx.getChannel().write(message);
770 //
771 // Check that the routes have been received, processed and stored
772 //
773 bgpRibIn3 = waitForBgpRibIn(bgpSession3, 1);
774 assertThat(bgpRibIn3, hasSize(1));
775 bgpRoutes = waitForBgpRoutes(2);
776 assertThat(bgpRoutes, hasSize(2));
777 //
778 bgpRouteEntry =
779 new BgpRouteEntry(bgpSession3,
780 Ip4Prefix.valueOf("20.0.0.0/8"),
781 NEXT_HOP3_ROUTER,
782 (byte) BgpConstants.Update.Origin.IGP,
783 asPathShort,
784 BETTER_LOCAL_PREF);
785 bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
786 assertThat(bgpRibIn3, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800787 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800788
789 //
790 // Cleanup in preparation for next test: delete old route entry from
791 // Peer2
792 //
793 addedRoutes = new LinkedList<>();
794 withdrawnRoutes = new LinkedList<>();
795 withdrawnRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
796 // Write the routes
797 message = peer2.peerChannelHandler.prepareBgpUpdate(
798 NEXT_HOP2_ROUTER,
799 BETTER_LOCAL_PREF,
800 BETTER_MULTI_EXIT_DISC,
801 asPathShort,
802 addedRoutes,
803 withdrawnRoutes);
804 peer2.peerChannelHandler.savedCtx.getChannel().write(message);
805 //
806 // Check that the routes have been received, processed and stored
807 //
808 bgpRibIn2 = waitForBgpRibIn(bgpSession2, 0);
809 assertThat(bgpRibIn2, hasSize(0));
810
811 //
812 // Add a route entry to Peer2 with a better MED
813 //
814 addedRoutes = new LinkedList<>();
815 withdrawnRoutes = new LinkedList<>();
816 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
817 // Write the routes
818 message = peer2.peerChannelHandler.prepareBgpUpdate(
819 NEXT_HOP2_ROUTER,
820 BETTER_LOCAL_PREF,
821 BETTER_MULTI_EXIT_DISC,
822 asPathShort,
823 addedRoutes,
824 withdrawnRoutes);
825 peer2.peerChannelHandler.savedCtx.getChannel().write(message);
826 //
827 // Check that the routes have been received, processed and stored
828 //
829 bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
830 assertThat(bgpRibIn2, hasSize(1));
831 bgpRoutes = waitForBgpRoutes(2);
832 assertThat(bgpRoutes, hasSize(2));
833 //
834 bgpRouteEntry =
835 new BgpRouteEntry(bgpSession2,
836 Ip4Prefix.valueOf("20.0.0.0/8"),
837 NEXT_HOP2_ROUTER,
838 (byte) BgpConstants.Update.Origin.IGP,
839 asPathShort,
840 BETTER_LOCAL_PREF);
841 bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
842 assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800843 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800844
845 //
846 // Add a route entry to Peer1 with a better (lower) BGP ID
847 //
848 addedRoutes = new LinkedList<>();
849 withdrawnRoutes = new LinkedList<>();
850 addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
851 withdrawnRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
852 // Write the routes
853 message = peer1.peerChannelHandler.prepareBgpUpdate(
854 NEXT_HOP1_ROUTER,
855 BETTER_LOCAL_PREF,
856 BETTER_MULTI_EXIT_DISC,
857 asPathShort,
858 addedRoutes,
859 withdrawnRoutes);
860 peer1.peerChannelHandler.savedCtx.getChannel().write(message);
861 //
862 // Check that the routes have been received, processed and stored
863 //
864 bgpRibIn1 = waitForBgpRibIn(bgpSession1, 1);
865 assertThat(bgpRibIn1, hasSize(1));
866 bgpRoutes = waitForBgpRoutes(1);
867 assertThat(bgpRoutes, hasSize(1));
868 //
869 bgpRouteEntry =
870 new BgpRouteEntry(bgpSession1,
871 Ip4Prefix.valueOf("20.0.0.0/8"),
872 NEXT_HOP1_ROUTER,
873 (byte) BgpConstants.Update.Origin.IGP,
874 asPathShort,
875 BETTER_LOCAL_PREF);
876 bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
877 assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
Pavlin Radoslavovf8a0f6c2015-02-04 15:31:47 -0800878 assertThat(waitForBgpRoute(bgpRouteEntry), notNullValue());
Pavlin Radoslavov0af11c12014-12-10 18:16:25 -0800879
880
881 // Close the channels and test there are no routes
882 peer1.peerChannelHandler.closeChannel();
883 peer2.peerChannelHandler.closeChannel();
884 peer3.peerChannelHandler.closeChannel();
Jonathan Hart20d8e512014-10-16 11:05:52 -0700885 bgpRoutes = waitForBgpRoutes(0);
886 assertThat(bgpRoutes, hasSize(0));
887 }
888}