Bug-2229: RFC6286 - AS-wide Unique BGP Identifier 85/14685/7
authorMilos Fabian <milfabia@cisco.com>
Tue, 3 Feb 2015 15:15:41 +0000 (16:15 +0100)
committerMilos Fabian <milfabia@cisco.com>
Mon, 9 Feb 2015 08:11:48 +0000 (08:11 +0000)
-extended Connection Collision Resolution
https://tools.ietf.org/html/rfc6286#section-2.3
-if BGP identifiers are same, compare AS numbers

-modified Open Message Error Handling
https://tools.ietf.org/html/rfc6286#section-2.2
-if BGP Identifier of local and remote speaker is the same -
return error "Bad BGP Identifier"

Change-Id: Idcf18390129805c2b78cf6070ba47f3d4ab0e9d0
Signed-off-by: Milos Fabian <milfabia@cisco.com>
bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/StrictBgpPeerRegistryModule.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AbstractBGPSessionNegotiator.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPClientSessionNegotiator.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPClientSessionValidator.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPServerSessionNegotiator.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/StrictBGPPeerRegistry.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/BGPPeerRegistry.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/FSMTest.java
bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/StrictBGPPeerRegistryTest.java
bgp/testtool/src/test/java/org/opendaylight/protocol/bgp/testtool/BGPSpeakerMock.java

index 928243a388502cd6ba31c78906149c4862053df3..13559c17379e66e30afb417ffc8d981487777503 100644 (file)
@@ -7,6 +7,7 @@ import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences;
 import org.opendaylight.protocol.bgp.rib.impl.spi.ReusableBGPPeer;
 import org.opendaylight.protocol.bgp.rib.spi.BGPSessionListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 
@@ -49,8 +50,9 @@ public class StrictBgpPeerRegistryModule extends org.opendaylight.controller.con
         }
 
         @Override
-        public BGPSessionListener getPeer(final IpAddress ip, final Ipv4Address sourceId, final Ipv4Address remoteId) throws BGPDocumentedException {
-            return this.global.getPeer(ip, sourceId, remoteId);
+        public BGPSessionListener getPeer(final IpAddress ip, final Ipv4Address sourceId, final Ipv4Address remoteId, final AsNumber asNumber)
+                throws BGPDocumentedException {
+            return this.global.getPeer(ip, sourceId, remoteId, asNumber);
         }
 
         @Override
index 99214bfd876ce1c13270be7218214c5a197783a6..58d6bf4fa2650523406da02f9012a1291e462536 100644 (file)
@@ -22,6 +22,7 @@ import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionValidator;
 import org.opendaylight.protocol.bgp.rib.spi.BGPSessionListener;
 import org.opendaylight.protocol.framework.AbstractSessionNegotiator;
 import org.opendaylight.protocol.util.Values;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Keepalive;
@@ -190,7 +191,8 @@ public abstract class AbstractBGPSessionNegotiator extends AbstractSessionNegoti
         }
 
         try {
-            final BGPSessionListener peer = this.registry.getPeer(getRemoteIp(), getSourceId(openObj, getPreferences()), getDestinationId(openObj, getPreferences()));
+            final BGPSessionListener peer = this.registry.getPeer(getRemoteIp(), getSourceId(openObj, getPreferences()),
+                    getDestinationId(openObj, getPreferences()), getAsNumber(openObj, getPreferences()));
             this.sendMessage(new KeepaliveBuilder().build());
             this.session = new BGPSessionImpl(peer, this.channel, openObj, getPreferences(), this.registry);
             this.state = State.OPEN_CONFIRM;
@@ -215,15 +217,26 @@ public abstract class AbstractBGPSessionNegotiator extends AbstractSessionNegoti
     }
 
     /**
+     * @param openMsg Open message received from remote BGP speaker
+     * @param preferences Local BGP speaker preferences
      * @return BGP Id of device that accepted the connection
      */
     protected abstract Ipv4Address getDestinationId(final Open openMsg, final BGPSessionPreferences preferences);
 
     /**
-     * @return BGP Id of device that initiated the connection
+     * @param openMsg Open message received from remote BGP speaker
+     * @param preferences Local BGP speaker preferences
+     * @return BGP Id of device that accepted the connection
      */
     protected abstract Ipv4Address getSourceId(final Open openMsg, final BGPSessionPreferences preferences);
 
+    /**
+     * @param openMsg Open message received from remote BGP speaker
+     * @param preferences Local BGP speaker preferences
+     * @return AS Number of device that initiate connection
+     */
+    protected abstract AsNumber getAsNumber(final Open openMsg, final BGPSessionPreferences preferences);
+
     public synchronized State getState() {
         return this.state;
     }
index b4a2e0b5cf12154e9aca7c12e2dd0758a2705feb..41e9b8cc27441d047a1357ace5416acc9743f1b8 100644 (file)
@@ -9,10 +9,10 @@ package org.opendaylight.protocol.bgp.rib.impl;
 
 import io.netty.channel.Channel;
 import io.netty.util.concurrent.Promise;
-
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences;
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionValidator;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Open;
 
@@ -35,4 +35,9 @@ public final class BGPClientSessionNegotiator extends AbstractBGPSessionNegotiat
     protected Ipv4Address getSourceId(final Open openMsg, final BGPSessionPreferences preferences) {
         return openMsg.getBgpIdentifier();
     }
+
+    @Override
+    protected AsNumber getAsNumber(Open openMsg, BGPSessionPreferences preferences) {
+        return preferences.getMyAs();
+    }
 }
index 7547e12889ab19d14df048d9a82212641b2afbbe..acbca1b38914d5e9b7616e84215bae83c6c59356 100644 (file)
@@ -59,6 +59,11 @@ public class BGPClientSessionValidator implements BGPSessionValidator {
             LOG.warn("Unexpected remote AS number. Expecting {}, got {}", this.remoteAs, as);
             throw new BGPDocumentedException("Peer AS number mismatch", BGPError.BAD_PEER_AS);
         }
+        //https://tools.ietf.org/html/rfc6286#section-2.2
+        if (openObj.getBgpIdentifier() != null &&  openObj.getBgpIdentifier().equals(localPref.getBgpId())) {
+            LOG.warn("Remote and local BGP Identifiers are the same: {}", openObj.getBgpIdentifier());
+            throw new BGPDocumentedException("Remote and local BGP Identifiers are the same.", BGPError.BAD_BGP_ID);
+        }
 
         final List<BgpParameters> prefs = openObj.getBgpParameters();
         if (prefs != null && !prefs.isEmpty()) {
index a5540818008b39fc6b4cba38834055a2e907e672..10cd5e3c110f135cdb491dc359aa5fdbd0e3cb63 100644 (file)
@@ -10,10 +10,10 @@ package org.opendaylight.protocol.bgp.rib.impl;
 
 import io.netty.channel.Channel;
 import io.netty.util.concurrent.Promise;
-
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences;
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionValidator;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Open;
 
@@ -36,4 +36,9 @@ public final class BGPServerSessionNegotiator extends AbstractBGPSessionNegotiat
     protected Ipv4Address getDestinationId(final Open openMsg, final BGPSessionPreferences preferences) {
         return openMsg.getBgpIdentifier();
     }
+
+    @Override
+    protected AsNumber getAsNumber(Open openMsg, BGPSessionPreferences preferences) {
+        return new AsNumber(openMsg.getMyAsNumber().longValue());
+    }
 }
index 6eb975b120906671e5f431f6b6f4b187e0e26e14..403cad23ba28d1e38eb09a3cc1148b3a63f201f8 100644 (file)
@@ -27,6 +27,7 @@ import org.opendaylight.protocol.bgp.rib.impl.spi.BGPPeerRegistry;
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences;
 import org.opendaylight.protocol.bgp.rib.impl.spi.ReusableBGPPeer;
 import org.opendaylight.protocol.bgp.rib.spi.BGPSessionListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;
@@ -85,7 +86,7 @@ public final class StrictBGPPeerRegistry implements BGPPeerRegistry {
 
     @Override
     public synchronized BGPSessionListener getPeer(final IpAddress ip,
-        final Ipv4Address sourceId, final Ipv4Address remoteId)
+        final Ipv4Address sourceId, final Ipv4Address remoteId, final AsNumber asNumber)
             throws BGPDocumentedException {
         Preconditions.checkNotNull(ip);
         Preconditions.checkNotNull(sourceId);
@@ -93,7 +94,7 @@ public final class StrictBGPPeerRegistry implements BGPPeerRegistry {
 
         checkPeerConfigured(ip);
 
-        final BGPSessionId currentConnection = new BGPSessionId(sourceId, remoteId);
+        final BGPSessionId currentConnection = new BGPSessionId(sourceId, remoteId, asNumber);
         final BGPSessionListener p = this.peers.get(ip);
 
         final BGPSessionId previousConnection = this.sessionIds.get(ip);
@@ -124,7 +125,17 @@ public final class StrictBGPPeerRegistry implements BGPPeerRegistry {
                 this.peers.get(ip).releaseConnection();
                 return this.peers.get(ip);
 
-                // Session reestablished with same source bgp id, dropping current as duplicate
+            } else if (previousConnection.hasHigherAsNumber(currentConnection)) {
+                LOG.warn("BGP session with {} {} has to be dropped. Opposite session already present", ip, currentConnection);
+                throw new BGPDocumentedException(
+                    String.format("BGP session with %s initiated %s has to be dropped. Opposite session already present",
+                        ip, currentConnection),
+                        BGPError.CEASE);
+            } else if (currentConnection.hasHigherAsNumber(previousConnection)) {
+                LOG.warn("BGP session with {} {} released. Replaced by opposite session", ip, previousConnection);
+                this.peers.get(ip).releaseConnection();
+                return this.peers.get(ip);
+            // Session reestablished with same source bgp id, dropping current as duplicate
             } else {
                 LOG.warn("BGP session with %s initiated from %s to %s has to be dropped. Same session already present", ip, sourceId, remoteId);
                 throw new BGPDocumentedException(
@@ -185,10 +196,12 @@ public final class StrictBGPPeerRegistry implements BGPPeerRegistry {
     private static final class BGPSessionId {
 
         private final Ipv4Address from, to;
+        private final AsNumber asNumber;
 
-        BGPSessionId(final Ipv4Address from, final Ipv4Address to) {
+        BGPSessionId(final Ipv4Address from, final Ipv4Address to, final AsNumber asNumber) {
             this.from = Preconditions.checkNotNull(from);
             this.to = Preconditions.checkNotNull(to);
+            this.asNumber = Preconditions.checkNotNull(asNumber);
         }
 
         /**
@@ -230,6 +243,10 @@ public final class StrictBGPPeerRegistry implements BGPPeerRegistry {
             return toLong(this.from) > toLong(other.from);
         }
 
+        boolean hasHigherAsNumber(final BGPSessionId other) {
+            return this.asNumber.getValue() > other.asNumber.getValue();
+        }
+
         private long toLong(final Ipv4Address from) {
             final int i = InetAddresses.coerceToInteger(InetAddresses.forString(from.getValue()));
             return UnsignedInts.toLong(i);
index fad64a23e60273a36c9f69a222ed9bc85a1ed8d7..8d8b18afa79c7faf29cfa14580b9eb752b879a27 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.protocol.bgp.rib.impl.spi;
 
 import org.opendaylight.protocol.bgp.parser.BGPDocumentedException;
 import org.opendaylight.protocol.bgp.rib.spi.BGPSessionListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 
@@ -61,7 +62,7 @@ public interface BGPPeerRegistry extends AutoCloseable {
      * @throws BGPDocumentedException if session establishment cannot be finished successfully
      * @throws java.lang.IllegalStateException if there is no peer configured for provided ip address
      */
-    BGPSessionListener getPeer(IpAddress ip, Ipv4Address sourceId, Ipv4Address remoteId) throws BGPDocumentedException;
+    BGPSessionListener getPeer(IpAddress ip, Ipv4Address sourceId, Ipv4Address remoteId, AsNumber asNumber) throws BGPDocumentedException;
 
     /**
      * @param ip address of remote peer
index c9e19420178027ac60a00ceb72ec4dbcb4127f9e..c1fae81e3bc3d2d3f264fe7671e6198e11f1bf48 100644 (file)
@@ -205,6 +205,19 @@ public class FSMTest {
         assertEquals(BGPError.FSM_ERROR.getSubcode(), ((Notify) m).getErrorSubcode().shortValue());
     }
 
+    @Test
+    public void sameBGPIDs() {
+        this.clientSession.channelActive(null);
+        assertEquals(1, this.receivedMsgs.size());
+        assertTrue(this.receivedMsgs.get(0) instanceof Open);
+
+        this.clientSession.handleMessage(new OpenBuilder(this.classicOpen).setBgpIdentifier(new Ipv4Address("1.1.1.1")).build());
+        assertEquals(2, this.receivedMsgs.size());
+        assertTrue(this.receivedMsgs.get(1) instanceof Notify);
+        final Notification m = this.receivedMsgs.get(this.receivedMsgs.size() - 1);
+        assertEquals(BGPError.BAD_BGP_ID, BGPError.forValue(((Notify) m).getErrorCode(), ((Notify) m).getErrorSubcode()));
+    }
+
     @After
     public void tearDown() {
 
index cee7899dd43c380e7b1de3375fd2cca82b91c311..c8e59bf29306d5f9ee758bf9f3444a7de2a3a2df 100644 (file)
@@ -21,6 +21,7 @@ import org.opendaylight.protocol.bgp.parser.BGPError;
 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionPreferences;
 import org.opendaylight.protocol.bgp.rib.impl.spi.ReusableBGPPeer;
 import org.opendaylight.protocol.bgp.rib.spi.BGPSessionListener;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
 
@@ -47,13 +48,14 @@ public class StrictBGPPeerRegistryTest {
         final Ipv4Address from = new Ipv4Address("0.0.0.1");
         final IpAddress remoteIp = new IpAddress(from);
         final Ipv4Address to = new Ipv4Address("255.255.255.255");
+        final AsNumber as = new AsNumber(1234L);
 
         final ReusableBGPPeer session1 = getMockSession();
         this.droppingBGPSessionRegistry.addPeer(remoteIp, session1, this.mockPreferences);
 
-        this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to);
+        this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to, as);
         try {
-            this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to);
+            this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to, as);
         } catch (final BGPDocumentedException e) {
             assertEquals(BGPError.CEASE, e.getError());
             return;
@@ -67,9 +69,10 @@ public class StrictBGPPeerRegistryTest {
         final Ipv4Address from = new Ipv4Address("0.0.0.1");
         final IpAddress remoteIp = new IpAddress(from);
         final Ipv4Address to = new Ipv4Address("255.255.255.255");
+        final AsNumber as = new AsNumber(1234L);
 
         try {
-            this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to);
+            this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to, as);
         } catch (final IllegalStateException e) {
             return;
         }
@@ -84,15 +87,16 @@ public class StrictBGPPeerRegistryTest {
         final IpAddress remoteIp = new IpAddress(to);
         final Ipv4Address to2 = new Ipv4Address("255.255.255.254");
         final IpAddress remoteIp2 = new IpAddress(to2);
+        final AsNumber as = new AsNumber(1234L);
 
         final ReusableBGPPeer session1 = getMockSession();
         this.droppingBGPSessionRegistry.addPeer(remoteIp, session1, this.mockPreferences);
         final ReusableBGPPeer session2 = getMockSession();
         this.droppingBGPSessionRegistry.addPeer(remoteIp2, session2, this.mockPreferences);
 
-        final BGPSessionListener returnedSession1 = this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to);
+        final BGPSessionListener returnedSession1 = this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to, as);
         assertSame(session1, returnedSession1);
-        final BGPSessionListener returnedSession2 = this.droppingBGPSessionRegistry.getPeer(remoteIp2, from, to2);
+        final BGPSessionListener returnedSession2 = this.droppingBGPSessionRegistry.getPeer(remoteIp2, from, to2, as);
         assertSame(session2, returnedSession2);
 
         Mockito.verifyZeroInteractions(session1);
@@ -104,13 +108,14 @@ public class StrictBGPPeerRegistryTest {
         final Ipv4Address higher = new Ipv4Address("192.168.200.200");
         final Ipv4Address lower = new Ipv4Address("10.10.10.10");
         final IpAddress remoteIp = new IpAddress(lower);
+        final AsNumber as = new AsNumber(1234L);
 
         final ReusableBGPPeer session1 = getMockSession();
         this.droppingBGPSessionRegistry.addPeer(remoteIp, session1, this.mockPreferences);
 
-        this.droppingBGPSessionRegistry.getPeer(remoteIp, higher, lower);
+        this.droppingBGPSessionRegistry.getPeer(remoteIp, higher, lower, as);
         try {
-            this.droppingBGPSessionRegistry.getPeer(remoteIp, lower, higher);
+            this.droppingBGPSessionRegistry.getPeer(remoteIp, lower, higher, as);
         } catch (final BGPDocumentedException e) {
             assertEquals(BGPError.CEASE, e.getError());
             return;
@@ -124,12 +129,13 @@ public class StrictBGPPeerRegistryTest {
         final Ipv4Address higher = new Ipv4Address("123.123.123.123");
         final Ipv4Address lower = new Ipv4Address("123.123.123.122");
         final IpAddress remoteIp = new IpAddress(lower);
+        final AsNumber as = new AsNumber(1234L);
 
         final ReusableBGPPeer session1 = getMockSession();
         this.droppingBGPSessionRegistry.addPeer(remoteIp, session1, this.mockPreferences);
 
-        this.droppingBGPSessionRegistry.getPeer(remoteIp, lower, higher);
-        this.droppingBGPSessionRegistry.getPeer(remoteIp, higher, lower);
+        this.droppingBGPSessionRegistry.getPeer(remoteIp, lower, higher, as);
+        this.droppingBGPSessionRegistry.getPeer(remoteIp, higher, lower, as);
         Mockito.verify(session1).releaseConnection();
     }
 
@@ -138,13 +144,52 @@ public class StrictBGPPeerRegistryTest {
         final Ipv4Address from = new Ipv4Address("0.0.0.1");
         final IpAddress remoteIp = new IpAddress(from);
         final Ipv4Address to = new Ipv4Address("255.255.255.255");
+        final AsNumber as = new AsNumber(1234L);
 
         final ReusableBGPPeer session1 = getMockSession();
         this.droppingBGPSessionRegistry.addPeer(remoteIp, session1, this.mockPreferences);
 
-        this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to);
+        this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to, as);
         try {
-            this.droppingBGPSessionRegistry.getPeer(remoteIp, to, to);
+            this.droppingBGPSessionRegistry.getPeer(remoteIp, to, to, as);
+        } catch (final BGPDocumentedException e) {
+            assertEquals(BGPError.CEASE, e.getError());
+            return;
+        }
+
+        fail("Same peer cannot be connected twice");
+    }
+
+    @Test
+    public void testDuplicateHigerAs() throws Exception {
+        final Ipv4Address from = new Ipv4Address("0.0.0.1");
+        final IpAddress remoteIp = new IpAddress(from);
+        final Ipv4Address to = new Ipv4Address("255.255.255.255");
+        final AsNumber as1 = new AsNumber(1L);
+        final AsNumber as2 = new AsNumber(3L);
+
+        final ReusableBGPPeer session1 = getMockSession();
+        this.droppingBGPSessionRegistry.addPeer(remoteIp, session1, this.mockPreferences);
+
+        this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to, as1);
+        this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to, as2);
+        Mockito.verify(session1).releaseConnection();
+    }
+
+    @Test
+    public void testDuplicateLowerAs() throws Exception {
+        final Ipv4Address from = new Ipv4Address("0.0.0.1");
+        final IpAddress remoteIp = new IpAddress(from);
+        final Ipv4Address to = new Ipv4Address("255.255.255.255");
+        final AsNumber as1 = new AsNumber(10L);
+        final AsNumber as2 = new AsNumber(3L);
+
+        final ReusableBGPPeer session1 = getMockSession();
+        this.droppingBGPSessionRegistry.addPeer(remoteIp, session1, this.mockPreferences);
+
+        this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to, as1);
+        try {
+            this.droppingBGPSessionRegistry.getPeer(remoteIp, from, to, as2);
         } catch (final BGPDocumentedException e) {
             assertEquals(BGPError.CEASE, e.getError());
             return;
index e5b9d9ae9c0d6fb3fef68d0dd9384e7e57d52e32..8067920d2a009c315eea76695425c20d59995fa3 100644 (file)
@@ -86,7 +86,7 @@ public class BGPSpeakerMock<M, S extends ProtocolSession<M>, L extends SessionLi
             }
 
             @Override
-            public BGPSessionListener getPeer(final IpAddress ip, final Ipv4Address sourceId, final Ipv4Address remoteId) throws BGPDocumentedException {
+            public BGPSessionListener getPeer(final IpAddress ip, final Ipv4Address sourceId, final Ipv4Address remoteId, final AsNumber asNumber) throws BGPDocumentedException {
                 return new SpeakerSessionListener();
             }