From: Milos Fabian Date: Tue, 3 Feb 2015 15:15:41 +0000 (+0100) Subject: Bug-2229: RFC6286 - AS-wide Unique BGP Identifier X-Git-Tag: release/lithium~258 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=a11bb1e25ce2f7e79bfd17bd42a50c558350077c;p=bgpcep.git Bug-2229: RFC6286 - AS-wide Unique BGP Identifier -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 --- diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/StrictBgpPeerRegistryModule.java b/bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/StrictBgpPeerRegistryModule.java index 928243a388..13559c1737 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/StrictBgpPeerRegistryModule.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/StrictBgpPeerRegistryModule.java @@ -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 diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AbstractBGPSessionNegotiator.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AbstractBGPSessionNegotiator.java index 99214bfd87..58d6bf4fa2 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AbstractBGPSessionNegotiator.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AbstractBGPSessionNegotiator.java @@ -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; } diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPClientSessionNegotiator.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPClientSessionNegotiator.java index b4a2e0b5cf..41e9b8cc27 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPClientSessionNegotiator.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPClientSessionNegotiator.java @@ -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(); + } } diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPClientSessionValidator.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPClientSessionValidator.java index 7547e12889..acbca1b389 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPClientSessionValidator.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPClientSessionValidator.java @@ -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 prefs = openObj.getBgpParameters(); if (prefs != null && !prefs.isEmpty()) { diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPServerSessionNegotiator.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPServerSessionNegotiator.java index a554081800..10cd5e3c11 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPServerSessionNegotiator.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPServerSessionNegotiator.java @@ -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()); + } } diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/StrictBGPPeerRegistry.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/StrictBGPPeerRegistry.java index 6eb975b120..403cad23ba 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/StrictBGPPeerRegistry.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/StrictBGPPeerRegistry.java @@ -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); diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/BGPPeerRegistry.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/BGPPeerRegistry.java index fad64a23e6..8d8b18afa7 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/BGPPeerRegistry.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/BGPPeerRegistry.java @@ -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 diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/FSMTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/FSMTest.java index c9e1942017..c1fae81e3b 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/FSMTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/FSMTest.java @@ -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() { diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/StrictBGPPeerRegistryTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/StrictBGPPeerRegistryTest.java index cee7899dd4..c8e59bf293 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/StrictBGPPeerRegistryTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/StrictBGPPeerRegistryTest.java @@ -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; diff --git a/bgp/testtool/src/test/java/org/opendaylight/protocol/bgp/testtool/BGPSpeakerMock.java b/bgp/testtool/src/test/java/org/opendaylight/protocol/bgp/testtool/BGPSpeakerMock.java index e5b9d9ae9c..8067920d2a 100644 --- a/bgp/testtool/src/test/java/org/opendaylight/protocol/bgp/testtool/BGPSpeakerMock.java +++ b/bgp/testtool/src/test/java/org/opendaylight/protocol/bgp/testtool/BGPSpeakerMock.java @@ -86,7 +86,7 @@ public class BGPSpeakerMock, 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(); }