* Add unit tests for the BGP route preference comparison mechanism
This addresses ONOS-134
* Refactor existing BGP unit tests
Change-Id: Ia0ad7954632ec6b856d1a8a972f1837179121abb
diff --git a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java
index 5893b18..5199f20 100644
--- a/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java
+++ b/apps/sdnip/src/test/java/org/onosproject/sdnip/bgp/BgpSessionManagerTest.java
@@ -15,7 +15,6 @@
*/
package org.onosproject.sdnip.bgp;
-import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
@@ -30,6 +29,8 @@
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
+import org.hamcrest.Description;
+import org.hamcrest.TypeSafeMatcher;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
@@ -58,8 +59,24 @@
Ip4Address.valueOf("127.0.0.1");
private static final Ip4Address BGP_PEER1_ID =
Ip4Address.valueOf("10.0.0.1");
+ private static final Ip4Address BGP_PEER2_ID =
+ Ip4Address.valueOf("10.0.0.2");
+ private static final Ip4Address BGP_PEER3_ID =
+ Ip4Address.valueOf("10.0.0.3");
+ private static final Ip4Address NEXT_HOP1_ROUTER =
+ Ip4Address.valueOf("10.20.30.41");
+ private static final Ip4Address NEXT_HOP2_ROUTER =
+ Ip4Address.valueOf("10.20.30.42");
+ private static final Ip4Address NEXT_HOP3_ROUTER =
+ Ip4Address.valueOf("10.20.30.43");
+
private static final long DEFAULT_LOCAL_PREF = 10;
+ private static final long BETTER_LOCAL_PREF = 20;
private static final long DEFAULT_MULTI_EXIT_DISC = 20;
+ private static final long BETTER_MULTI_EXIT_DISC = 30;
+
+ BgpRouteEntry.AsPath asPathShort;
+ BgpRouteEntry.AsPath asPathLong;
// Timeout waiting for a message to be received
private static final int MESSAGE_TIMEOUT_MS = 5000; // 5s
@@ -68,13 +85,16 @@
private BgpSessionManager bgpSessionManager;
// Remote Peer state
- private ClientBootstrap peerBootstrap;
- private TestBgpPeerChannelHandler peerChannelHandler =
- new TestBgpPeerChannelHandler(BGP_PEER1_ID, DEFAULT_LOCAL_PREF);
- private TestBgpPeerFrameDecoder peerFrameDecoder =
- new TestBgpPeerFrameDecoder();
+ TestBgpPeer peer1 = new TestBgpPeer(BGP_PEER1_ID);
+ TestBgpPeer peer2 = new TestBgpPeer(BGP_PEER2_ID);
+ TestBgpPeer peer3 = new TestBgpPeer(BGP_PEER3_ID);
- // The socket that the Remote Peer should connect to
+ // Local BGP per-peer session state
+ BgpSession bgpSession1;
+ BgpSession bgpSession2;
+ BgpSession bgpSession3;
+
+ // The socket that the remote peers should connect to
private InetSocketAddress connectToSocket;
private final DummyRouteListener dummyRouteListener =
@@ -90,6 +110,132 @@
}
}
+ /**
+ * A class to capture the state for a BGP peer.
+ */
+ private final class TestBgpPeer {
+ private final Ip4Address peerId;
+ private ClientBootstrap peerBootstrap;
+ private TestBgpPeerChannelHandler peerChannelHandler;
+ private TestBgpPeerFrameDecoder peerFrameDecoder =
+ new TestBgpPeerFrameDecoder();
+
+ /**
+ * Constructor.
+ *
+ * @param peerId the peer ID
+ */
+ private TestBgpPeer(Ip4Address peerId) {
+ this.peerId = peerId;
+ peerChannelHandler = new TestBgpPeerChannelHandler(peerId);
+ }
+
+ /**
+ * Starts up the BGP peer and connects it to the tested SDN-IP
+ * instance.
+ *
+ * @param connectToSocket the socket to connect to
+ */
+ private void connect(InetSocketAddress connectToSocket)
+ throws InterruptedException {
+ //
+ // Setup the BGP Peer, i.e., the "remote" BGP router that will
+ // initiate the BGP connection, send BGP UPDATE messages, etc.
+ //
+ ChannelFactory channelFactory =
+ new NioClientSocketChannelFactory(
+ Executors.newCachedThreadPool(),
+ Executors.newCachedThreadPool());
+ ChannelPipelineFactory pipelineFactory =
+ new ChannelPipelineFactory() {
+ @Override
+ public ChannelPipeline getPipeline() throws Exception {
+ // Setup the transmitting pipeline
+ ChannelPipeline pipeline = Channels.pipeline();
+ pipeline.addLast("TestBgpPeerFrameDecoder",
+ peerFrameDecoder);
+ pipeline.addLast("TestBgpPeerChannelHandler",
+ peerChannelHandler);
+ return pipeline;
+ }
+ };
+
+ peerBootstrap = new ClientBootstrap(channelFactory);
+ peerBootstrap.setOption("child.keepAlive", true);
+ peerBootstrap.setOption("child.tcpNoDelay", true);
+ peerBootstrap.setPipelineFactory(pipelineFactory);
+ peerBootstrap.connect(connectToSocket);
+
+ boolean result;
+ // Wait until the OPEN message is received
+ result = peerFrameDecoder.receivedOpenMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+ // Wait until the KEEPALIVE message is received
+ result = peerFrameDecoder.receivedKeepaliveMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+
+ for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
+ if (bgpSession.getRemoteBgpId().equals(BGP_PEER1_ID)) {
+ bgpSession1 = bgpSession;
+ }
+ if (bgpSession.getRemoteBgpId().equals(BGP_PEER2_ID)) {
+ bgpSession2 = bgpSession;
+ }
+ if (bgpSession.getRemoteBgpId().equals(BGP_PEER3_ID)) {
+ bgpSession3 = bgpSession;
+ }
+ }
+ }
+ }
+
+ /**
+ * Class that implements a matcher for BgpRouteEntry by considering
+ * the BGP peer the entry was received from.
+ */
+ private static final class BgpRouteEntryAndPeerMatcher
+ extends TypeSafeMatcher<Collection<BgpRouteEntry>> {
+ private final BgpRouteEntry bgpRouteEntry;
+
+ private BgpRouteEntryAndPeerMatcher(BgpRouteEntry bgpRouteEntry) {
+ this.bgpRouteEntry = bgpRouteEntry;
+ }
+
+ @Override
+ public boolean matchesSafely(Collection<BgpRouteEntry> entries) {
+ for (BgpRouteEntry entry : entries) {
+ if (bgpRouteEntry.equals(entry) &&
+ bgpRouteEntry.getBgpSession() == entry.getBgpSession()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("BGP route entry lookup for entry \"").
+ appendText(bgpRouteEntry.toString()).
+ appendText("\"");
+ }
+ }
+
+ /**
+ * A helper method used for testing whether a collection of
+ * BGP route entries contains an entry from a specific BGP peer.
+ *
+ * @param bgpRouteEntry the BGP route entry to test
+ * @return an instance of BgpRouteEntryAndPeerMatcher that implements
+ * the matching logic
+ */
+ private static BgpRouteEntryAndPeerMatcher hasBgpRouteEntry(
+ BgpRouteEntry bgpRouteEntry) {
+ return new BgpRouteEntryAndPeerMatcher(bgpRouteEntry);
+ }
+
@Before
public void setUp() throws Exception {
//
@@ -106,35 +252,34 @@
SocketAddress socketAddress = serverChannel.getLocalAddress();
InetSocketAddress inetSocketAddress =
(InetSocketAddress) socketAddress;
-
- //
- // Setup the BGP Peer, i.e., the "remote" BGP router that will
- // initiate the BGP connection, send BGP UPDATE messages, etc.
- //
- ChannelFactory channelFactory =
- new NioClientSocketChannelFactory(Executors.newCachedThreadPool(),
- Executors.newCachedThreadPool());
- ChannelPipelineFactory pipelineFactory = new ChannelPipelineFactory() {
- @Override
- public ChannelPipeline getPipeline() throws Exception {
- // Setup the transmitting pipeline
- ChannelPipeline pipeline = Channels.pipeline();
- pipeline.addLast("TestBgpPeerFrameDecoder",
- peerFrameDecoder);
- pipeline.addLast("TestBgpPeerChannelHandler",
- peerChannelHandler);
- return pipeline;
- }
- };
-
- peerBootstrap = new ClientBootstrap(channelFactory);
- peerBootstrap.setOption("child.keepAlive", true);
- peerBootstrap.setOption("child.tcpNoDelay", true);
- peerBootstrap.setPipelineFactory(pipelineFactory);
-
InetAddress connectToAddress = InetAddresses.forString("127.0.0.1");
connectToSocket = new InetSocketAddress(connectToAddress,
inetSocketAddress.getPort());
+
+ //
+ // Setup the AS Paths
+ //
+ ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
+ byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
+ ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
+ segmentAsNumbers1.add((long) 65010);
+ segmentAsNumbers1.add((long) 65020);
+ segmentAsNumbers1.add((long) 65030);
+ BgpRouteEntry.PathSegment pathSegment1 =
+ new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
+ pathSegments.add(pathSegment1);
+ asPathShort = new BgpRouteEntry.AsPath(new ArrayList(pathSegments));
+ //
+ byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
+ ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
+ segmentAsNumbers2.add((long) 65041);
+ segmentAsNumbers2.add((long) 65042);
+ segmentAsNumbers2.add((long) 65043);
+ BgpRouteEntry.PathSegment pathSegment2 =
+ new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
+ pathSegments.add(pathSegment2);
+ //
+ asPathLong = new BgpRouteEntry.AsPath(pathSegments);
}
@After
@@ -211,36 +356,46 @@
@Test
public void testExchangedBgpOpenMessages()
throws InterruptedException, TestUtilsException {
- // Initiate the connection
- peerBootstrap.connect(connectToSocket);
-
- // Wait until the OPEN message is received
- peerFrameDecoder.receivedOpenMessageLatch.await(MESSAGE_TIMEOUT_MS,
- TimeUnit.MILLISECONDS);
- // Wait until the KEEPALIVE message is received
- peerFrameDecoder.receivedKeepaliveMessageLatch.await(MESSAGE_TIMEOUT_MS,
- TimeUnit.MILLISECONDS);
+ // Initiate the connections
+ peer1.connect(connectToSocket);
+ peer2.connect(connectToSocket);
+ peer3.connect(connectToSocket);
//
// Test the fields from the BGP OPEN message:
// BGP version, AS number, BGP ID
//
- assertThat(peerFrameDecoder.remoteBgpVersion,
+ assertThat(peer1.peerFrameDecoder.remoteBgpVersion,
is(BgpConstants.BGP_VERSION));
- assertThat(peerFrameDecoder.remoteAs,
+ assertThat(peer1.peerFrameDecoder.remoteAs,
is(TestBgpPeerChannelHandler.PEER_AS));
- assertThat(peerFrameDecoder.remoteBgpIdentifier, is(IP_LOOPBACK_ID));
+ assertThat(peer1.peerFrameDecoder.remoteBgpIdentifier,
+ is(IP_LOOPBACK_ID));
+ assertThat(peer2.peerFrameDecoder.remoteBgpVersion,
+ is(BgpConstants.BGP_VERSION));
+ assertThat(peer2.peerFrameDecoder.remoteAs,
+ is(TestBgpPeerChannelHandler.PEER_AS));
+ assertThat(peer2.peerFrameDecoder.remoteBgpIdentifier,
+ is(IP_LOOPBACK_ID));
+ assertThat(peer3.peerFrameDecoder.remoteBgpVersion,
+ is(BgpConstants.BGP_VERSION));
+ assertThat(peer3.peerFrameDecoder.remoteAs,
+ is(TestBgpPeerChannelHandler.PEER_AS));
+ assertThat(peer3.peerFrameDecoder.remoteBgpIdentifier,
+ is(IP_LOOPBACK_ID));
//
- // Test that a BgpSession instance has been created
+ // Test that the BgpSession instances have been created
//
assertThat(bgpSessionManager.getMyBgpId(), is(IP_LOOPBACK_ID));
- assertThat(bgpSessionManager.getBgpSessions(), hasSize(1));
- BgpSession bgpSession =
- bgpSessionManager.getBgpSessions().iterator().next();
- assertThat(bgpSession, notNullValue());
- long sessionAs = TestUtils.getField(bgpSession, "localAs");
- assertThat(sessionAs, is(TestBgpPeerChannelHandler.PEER_AS));
+ assertThat(bgpSessionManager.getBgpSessions(), hasSize(3));
+ assertThat(bgpSession1, notNullValue());
+ assertThat(bgpSession2, notNullValue());
+ assertThat(bgpSession3, notNullValue());
+ for (BgpSession bgpSession : bgpSessionManager.getBgpSessions()) {
+ long sessionAs = TestUtils.getField(bgpSession, "localAs");
+ assertThat(sessionAs, is(TestBgpPeerChannelHandler.PEER_AS));
+ }
}
/**
@@ -248,30 +403,25 @@
*/
@Test
public void testProcessedBgpUpdateMessages() throws InterruptedException {
- BgpSession bgpSession;
- Ip4Address nextHopRouter;
- BgpRouteEntry bgpRouteEntry;
ChannelBuffer message;
- Collection<BgpRouteEntry> bgpRibIn;
+ BgpRouteEntry bgpRouteEntry;
+ Collection<BgpRouteEntry> bgpRibIn1;
+ Collection<BgpRouteEntry> bgpRibIn2;
+ Collection<BgpRouteEntry> bgpRibIn3;
Collection<BgpRouteEntry> bgpRoutes;
- // Initiate the connection
- peerBootstrap.connect(connectToSocket);
-
- // Wait until the OPEN message is received
- peerFrameDecoder.receivedOpenMessageLatch.await(MESSAGE_TIMEOUT_MS,
- TimeUnit.MILLISECONDS);
- // Wait until the KEEPALIVE message is received
- peerFrameDecoder.receivedKeepaliveMessageLatch.await(MESSAGE_TIMEOUT_MS,
- TimeUnit.MILLISECONDS);
-
- // Get the BGP Session handler
- bgpSession = bgpSessionManager.getBgpSessions().iterator().next();
+ // Initiate the connections
+ peer1.connect(connectToSocket);
+ peer2.connect(connectToSocket);
+ peer3.connect(connectToSocket);
// Prepare routes to add/delete
- nextHopRouter = Ip4Address.valueOf("10.20.30.40");
Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
+
+ //
+ // Add and delete some routes
+ //
addedRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
@@ -282,140 +432,343 @@
withdrawnRoutes.add(Ip4Prefix.valueOf("80.0.0.0/24"));
withdrawnRoutes.add(Ip4Prefix.valueOf("90.0.0.0/32"));
// Write the routes
- message = peerChannelHandler.prepareBgpUpdate(nextHopRouter,
- addedRoutes,
- withdrawnRoutes);
- peerChannelHandler.savedCtx.getChannel().write(message);
-
+ message = peer1.peerChannelHandler.prepareBgpUpdate(
+ NEXT_HOP1_ROUTER,
+ DEFAULT_LOCAL_PREF,
+ DEFAULT_MULTI_EXIT_DISC,
+ asPathLong,
+ addedRoutes,
+ withdrawnRoutes);
+ peer1.peerChannelHandler.savedCtx.getChannel().write(message);
+ //
// Check that the routes have been received, processed and stored
- bgpRibIn = waitForBgpRibIn(bgpSession, 5);
- assertThat(bgpRibIn, hasSize(5));
+ //
+ bgpRibIn1 = waitForBgpRibIn(bgpSession1, 5);
+ assertThat(bgpRibIn1, hasSize(5));
bgpRoutes = waitForBgpRoutes(5);
assertThat(bgpRoutes, hasSize(5));
-
- // Setup the AS Path
- ArrayList<BgpRouteEntry.PathSegment> pathSegments = new ArrayList<>();
- byte pathSegmentType1 = (byte) BgpConstants.Update.AsPath.AS_SEQUENCE;
- ArrayList<Long> segmentAsNumbers1 = new ArrayList<>();
- segmentAsNumbers1.add((long) 65010);
- segmentAsNumbers1.add((long) 65020);
- segmentAsNumbers1.add((long) 65030);
- BgpRouteEntry.PathSegment pathSegment1 =
- new BgpRouteEntry.PathSegment(pathSegmentType1, segmentAsNumbers1);
- pathSegments.add(pathSegment1);
- //
- byte pathSegmentType2 = (byte) BgpConstants.Update.AsPath.AS_SET;
- ArrayList<Long> segmentAsNumbers2 = new ArrayList<>();
- segmentAsNumbers2.add((long) 65041);
- segmentAsNumbers2.add((long) 65042);
- segmentAsNumbers2.add((long) 65043);
- BgpRouteEntry.PathSegment pathSegment2 =
- new BgpRouteEntry.PathSegment(pathSegmentType2, segmentAsNumbers2);
- pathSegments.add(pathSegment2);
- //
- BgpRouteEntry.AsPath asPath = new BgpRouteEntry.AsPath(pathSegments);
-
//
bgpRouteEntry =
- new BgpRouteEntry(bgpSession,
+ new BgpRouteEntry(bgpSession1,
Ip4Prefix.valueOf("0.0.0.0/0"),
- nextHopRouter,
+ NEXT_HOP1_ROUTER,
(byte) BgpConstants.Update.Origin.IGP,
- asPath,
+ asPathLong,
DEFAULT_LOCAL_PREF);
bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
- assertThat(bgpRibIn, hasItem(bgpRouteEntry));
+ assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+ assertThat(bgpRoutes, hasBgpRouteEntry(bgpRouteEntry));
//
bgpRouteEntry =
- new BgpRouteEntry(bgpSession,
+ new BgpRouteEntry(bgpSession1,
Ip4Prefix.valueOf("20.0.0.0/8"),
- nextHopRouter,
+ NEXT_HOP1_ROUTER,
(byte) BgpConstants.Update.Origin.IGP,
- asPath,
+ asPathLong,
DEFAULT_LOCAL_PREF);
bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
- assertThat(bgpRibIn, hasItem(bgpRouteEntry));
+ assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+ assertThat(bgpRoutes, hasBgpRouteEntry(bgpRouteEntry));
//
bgpRouteEntry =
- new BgpRouteEntry(bgpSession,
+ new BgpRouteEntry(bgpSession1,
Ip4Prefix.valueOf("30.0.0.0/16"),
- nextHopRouter,
+ NEXT_HOP1_ROUTER,
(byte) BgpConstants.Update.Origin.IGP,
- asPath,
+ asPathLong,
DEFAULT_LOCAL_PREF);
bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
- assertThat(bgpRibIn, hasItem(bgpRouteEntry));
+ assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+ assertThat(bgpRoutes, hasBgpRouteEntry(bgpRouteEntry));
//
bgpRouteEntry =
- new BgpRouteEntry(bgpSession,
+ new BgpRouteEntry(bgpSession1,
Ip4Prefix.valueOf("40.0.0.0/24"),
- nextHopRouter,
+ NEXT_HOP1_ROUTER,
(byte) BgpConstants.Update.Origin.IGP,
- asPath,
+ asPathLong,
DEFAULT_LOCAL_PREF);
bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
- assertThat(bgpRibIn, hasItem(bgpRouteEntry));
+ assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+ assertThat(bgpRoutes, hasBgpRouteEntry(bgpRouteEntry));
//
bgpRouteEntry =
- new BgpRouteEntry(bgpSession,
+ new BgpRouteEntry(bgpSession1,
Ip4Prefix.valueOf("50.0.0.0/32"),
- nextHopRouter,
+ NEXT_HOP1_ROUTER,
(byte) BgpConstants.Update.Origin.IGP,
- asPath,
+ asPathLong,
DEFAULT_LOCAL_PREF);
bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
- assertThat(bgpRibIn, hasItem(bgpRouteEntry));
+ assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+ assertThat(bgpRoutes, hasBgpRouteEntry(bgpRouteEntry));
+ //
// Delete some routes
+ //
addedRoutes = new LinkedList<>();
withdrawnRoutes = new LinkedList<>();
withdrawnRoutes.add(Ip4Prefix.valueOf("0.0.0.0/0"));
withdrawnRoutes.add(Ip4Prefix.valueOf("50.0.0.0/32"));
-
// Write the routes
- message = peerChannelHandler.prepareBgpUpdate(nextHopRouter,
- addedRoutes,
- withdrawnRoutes);
- peerChannelHandler.savedCtx.getChannel().write(message);
-
+ message = peer1.peerChannelHandler.prepareBgpUpdate(
+ NEXT_HOP1_ROUTER,
+ DEFAULT_LOCAL_PREF,
+ DEFAULT_MULTI_EXIT_DISC,
+ asPathLong,
+ addedRoutes,
+ withdrawnRoutes);
+ peer1.peerChannelHandler.savedCtx.getChannel().write(message);
+ //
// Check that the routes have been received, processed and stored
- bgpRibIn = waitForBgpRibIn(bgpSession, 3);
- assertThat(bgpRibIn, hasSize(3));
+ //
+ bgpRibIn1 = waitForBgpRibIn(bgpSession1, 3);
+ assertThat(bgpRibIn1, hasSize(3));
bgpRoutes = waitForBgpRoutes(3);
assertThat(bgpRoutes, hasSize(3));
//
bgpRouteEntry =
- new BgpRouteEntry(bgpSession,
+ new BgpRouteEntry(bgpSession1,
Ip4Prefix.valueOf("20.0.0.0/8"),
- nextHopRouter,
+ NEXT_HOP1_ROUTER,
(byte) BgpConstants.Update.Origin.IGP,
- asPath,
+ asPathLong,
DEFAULT_LOCAL_PREF);
bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
- assertThat(bgpRibIn, hasItem(bgpRouteEntry));
+ assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+ assertThat(bgpRoutes, hasBgpRouteEntry(bgpRouteEntry));
//
bgpRouteEntry =
- new BgpRouteEntry(bgpSession,
+ new BgpRouteEntry(bgpSession1,
Ip4Prefix.valueOf("30.0.0.0/16"),
- nextHopRouter,
+ NEXT_HOP1_ROUTER,
(byte) BgpConstants.Update.Origin.IGP,
- asPath,
+ asPathLong,
DEFAULT_LOCAL_PREF);
bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
- assertThat(bgpRibIn, hasItem(bgpRouteEntry));
+ assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+ assertThat(bgpRoutes, hasBgpRouteEntry(bgpRouteEntry));
//
bgpRouteEntry =
- new BgpRouteEntry(bgpSession,
+ new BgpRouteEntry(bgpSession1,
Ip4Prefix.valueOf("40.0.0.0/24"),
- nextHopRouter,
+ NEXT_HOP1_ROUTER,
(byte) BgpConstants.Update.Origin.IGP,
- asPath,
+ asPathLong,
DEFAULT_LOCAL_PREF);
bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
- assertThat(bgpRibIn, hasItem(bgpRouteEntry));
+ assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+ assertThat(bgpRoutes, hasBgpRouteEntry(bgpRouteEntry));
- // Close the channel and test there are no routes
- peerChannelHandler.closeChannel();
+
+ // Close the channels and test there are no routes
+ peer1.peerChannelHandler.closeChannel();
+ peer2.peerChannelHandler.closeChannel();
+ peer3.peerChannelHandler.closeChannel();
+ bgpRoutes = waitForBgpRoutes(0);
+ assertThat(bgpRoutes, hasSize(0));
+ }
+
+ /**
+ * Tests the BGP route preference.
+ */
+ @Test
+ public void testBgpRoutePreference() throws InterruptedException {
+ ChannelBuffer message;
+ BgpRouteEntry bgpRouteEntry;
+ Collection<BgpRouteEntry> bgpRibIn1;
+ Collection<BgpRouteEntry> bgpRibIn2;
+ Collection<BgpRouteEntry> bgpRibIn3;
+ Collection<BgpRouteEntry> bgpRoutes;
+ Collection<Ip4Prefix> addedRoutes = new LinkedList<>();
+ Collection<Ip4Prefix> withdrawnRoutes = new LinkedList<>();
+
+ // Initiate the connections
+ peer1.connect(connectToSocket);
+ peer2.connect(connectToSocket);
+ peer3.connect(connectToSocket);
+
+ //
+ // Setup the initial set of routes to Peer1
+ //
+ addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+ addedRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
+ // Write the routes
+ message = peer1.peerChannelHandler.prepareBgpUpdate(
+ NEXT_HOP1_ROUTER,
+ DEFAULT_LOCAL_PREF,
+ DEFAULT_MULTI_EXIT_DISC,
+ asPathLong,
+ addedRoutes,
+ withdrawnRoutes);
+ peer1.peerChannelHandler.savedCtx.getChannel().write(message);
+ bgpRoutes = waitForBgpRoutes(2);
+ assertThat(bgpRoutes, hasSize(2));
+
+ //
+ // Add a route entry to Peer2 with a better LOCAL_PREF
+ //
+ addedRoutes = new LinkedList<>();
+ withdrawnRoutes = new LinkedList<>();
+ addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+ // Write the routes
+ message = peer2.peerChannelHandler.prepareBgpUpdate(
+ NEXT_HOP2_ROUTER,
+ BETTER_LOCAL_PREF,
+ DEFAULT_MULTI_EXIT_DISC,
+ asPathLong,
+ addedRoutes,
+ withdrawnRoutes);
+ peer2.peerChannelHandler.savedCtx.getChannel().write(message);
+ //
+ // Check that the routes have been received, processed and stored
+ //
+ bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
+ assertThat(bgpRibIn2, hasSize(1));
+ bgpRoutes = waitForBgpRoutes(2);
+ assertThat(bgpRoutes, hasSize(2));
+ //
+ bgpRouteEntry =
+ new BgpRouteEntry(bgpSession2,
+ Ip4Prefix.valueOf("20.0.0.0/8"),
+ NEXT_HOP2_ROUTER,
+ (byte) BgpConstants.Update.Origin.IGP,
+ asPathLong,
+ BETTER_LOCAL_PREF);
+ bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+ assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
+ assertThat(bgpRoutes, hasBgpRouteEntry(bgpRouteEntry));
+
+ //
+ // Add a route entry to Peer3 with a shorter AS path
+ //
+ addedRoutes = new LinkedList<>();
+ withdrawnRoutes = new LinkedList<>();
+ addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+ // Write the routes
+ message = peer3.peerChannelHandler.prepareBgpUpdate(
+ NEXT_HOP3_ROUTER,
+ BETTER_LOCAL_PREF,
+ DEFAULT_MULTI_EXIT_DISC,
+ asPathShort,
+ addedRoutes,
+ withdrawnRoutes);
+ peer3.peerChannelHandler.savedCtx.getChannel().write(message);
+ //
+ // Check that the routes have been received, processed and stored
+ //
+ bgpRibIn3 = waitForBgpRibIn(bgpSession3, 1);
+ assertThat(bgpRibIn3, hasSize(1));
+ bgpRoutes = waitForBgpRoutes(2);
+ assertThat(bgpRoutes, hasSize(2));
+ //
+ bgpRouteEntry =
+ new BgpRouteEntry(bgpSession3,
+ Ip4Prefix.valueOf("20.0.0.0/8"),
+ NEXT_HOP3_ROUTER,
+ (byte) BgpConstants.Update.Origin.IGP,
+ asPathShort,
+ BETTER_LOCAL_PREF);
+ bgpRouteEntry.setMultiExitDisc(DEFAULT_MULTI_EXIT_DISC);
+ assertThat(bgpRibIn3, hasBgpRouteEntry(bgpRouteEntry));
+ assertThat(bgpRoutes, hasBgpRouteEntry(bgpRouteEntry));
+
+ //
+ // Cleanup in preparation for next test: delete old route entry from
+ // Peer2
+ //
+ addedRoutes = new LinkedList<>();
+ withdrawnRoutes = new LinkedList<>();
+ withdrawnRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+ // Write the routes
+ message = peer2.peerChannelHandler.prepareBgpUpdate(
+ NEXT_HOP2_ROUTER,
+ BETTER_LOCAL_PREF,
+ BETTER_MULTI_EXIT_DISC,
+ asPathShort,
+ addedRoutes,
+ withdrawnRoutes);
+ peer2.peerChannelHandler.savedCtx.getChannel().write(message);
+ //
+ // Check that the routes have been received, processed and stored
+ //
+ bgpRibIn2 = waitForBgpRibIn(bgpSession2, 0);
+ assertThat(bgpRibIn2, hasSize(0));
+
+ //
+ // Add a route entry to Peer2 with a better MED
+ //
+ addedRoutes = new LinkedList<>();
+ withdrawnRoutes = new LinkedList<>();
+ addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+ // Write the routes
+ message = peer2.peerChannelHandler.prepareBgpUpdate(
+ NEXT_HOP2_ROUTER,
+ BETTER_LOCAL_PREF,
+ BETTER_MULTI_EXIT_DISC,
+ asPathShort,
+ addedRoutes,
+ withdrawnRoutes);
+ peer2.peerChannelHandler.savedCtx.getChannel().write(message);
+ //
+ // Check that the routes have been received, processed and stored
+ //
+ bgpRibIn2 = waitForBgpRibIn(bgpSession2, 1);
+ assertThat(bgpRibIn2, hasSize(1));
+ bgpRoutes = waitForBgpRoutes(2);
+ assertThat(bgpRoutes, hasSize(2));
+ //
+ bgpRouteEntry =
+ new BgpRouteEntry(bgpSession2,
+ Ip4Prefix.valueOf("20.0.0.0/8"),
+ NEXT_HOP2_ROUTER,
+ (byte) BgpConstants.Update.Origin.IGP,
+ asPathShort,
+ BETTER_LOCAL_PREF);
+ bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
+ assertThat(bgpRibIn2, hasBgpRouteEntry(bgpRouteEntry));
+ assertThat(bgpRoutes, hasBgpRouteEntry(bgpRouteEntry));
+
+ //
+ // Add a route entry to Peer1 with a better (lower) BGP ID
+ //
+ addedRoutes = new LinkedList<>();
+ withdrawnRoutes = new LinkedList<>();
+ addedRoutes.add(Ip4Prefix.valueOf("20.0.0.0/8"));
+ withdrawnRoutes.add(Ip4Prefix.valueOf("30.0.0.0/16"));
+ // Write the routes
+ message = peer1.peerChannelHandler.prepareBgpUpdate(
+ NEXT_HOP1_ROUTER,
+ BETTER_LOCAL_PREF,
+ BETTER_MULTI_EXIT_DISC,
+ asPathShort,
+ addedRoutes,
+ withdrawnRoutes);
+ peer1.peerChannelHandler.savedCtx.getChannel().write(message);
+ //
+ // Check that the routes have been received, processed and stored
+ //
+ bgpRibIn1 = waitForBgpRibIn(bgpSession1, 1);
+ assertThat(bgpRibIn1, hasSize(1));
+ bgpRoutes = waitForBgpRoutes(1);
+ assertThat(bgpRoutes, hasSize(1));
+ //
+ bgpRouteEntry =
+ new BgpRouteEntry(bgpSession1,
+ Ip4Prefix.valueOf("20.0.0.0/8"),
+ NEXT_HOP1_ROUTER,
+ (byte) BgpConstants.Update.Origin.IGP,
+ asPathShort,
+ BETTER_LOCAL_PREF);
+ bgpRouteEntry.setMultiExitDisc(BETTER_MULTI_EXIT_DISC);
+ assertThat(bgpRibIn1, hasBgpRouteEntry(bgpRouteEntry));
+ assertThat(bgpRoutes, hasBgpRouteEntry(bgpRouteEntry));
+
+
+ // Close the channels and test there are no routes
+ peer1.peerChannelHandler.closeChannel();
+ peer2.peerChannelHandler.closeChannel();
+ peer3.peerChannelHandler.closeChannel();
bgpRoutes = waitForBgpRoutes(0);
assertThat(bgpRoutes, hasSize(0));
}