aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/bgp/ctl/src
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/onos/bgp/ctl/src')
-rw-r--r--framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/AdjRibIn.java132
-rwxr-xr-xframework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java161
-rwxr-xr-xframework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java (renamed from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java)294
-rwxr-xr-xframework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java (renamed from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPConfig.java)56
-rwxr-xr-xframework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConnectPeerImpl.java133
-rwxr-xr-xframework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java (renamed from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java)84
-rwxr-xr-xframework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpKeepAliveTimer.java (renamed from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPKeepAliveTimer.java)8
-rwxr-xr-xframework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpMessageDecoder.java (renamed from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPMessageDecoder.java)20
-rwxr-xr-xframework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpMessageEncoder.java (renamed from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPMessageEncoder.java)10
-rwxr-xr-xframework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPacketStatsImpl.java (renamed from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPacketStatsImpl.java)6
-rwxr-xr-xframework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerConfig.java (renamed from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerConfig.java)6
-rw-r--r--framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java297
-rwxr-xr-xframework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPipelineFactory.java (renamed from framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java)14
-rw-r--r--framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java242
-rwxr-xr-xframework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSessionInfoImpl.java93
-rwxr-xr-xframework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java35
-rw-r--r--framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/VpnAdjRibIn.java209
-rwxr-xr-xframework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpControllerImplTest.java300
-rwxr-xr-xframework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerChannelHandlerTest.java107
-rwxr-xr-xframework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerFrameDecoderTest.java168
-rw-r--r--framework/src/onos/bgp/ctl/src/test/java/org/onosproject/controller/impl/BgpSelectionAlgoTest.java595
21 files changed, 2574 insertions, 396 deletions
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/AdjRibIn.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/AdjRibIn.java
new file mode 100644
index 00000000..9cbfbf65
--- /dev/null
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/AdjRibIn.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.bgp.controller.impl;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.onosproject.bgpio.protocol.BgpLSNlri;
+import org.onosproject.bgpio.protocol.linkstate.BgpLinkLSIdentifier;
+import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSIdentifier;
+import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpPrefixLSIdentifier;
+import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Implementation of Adj-RIB-In for each peer.
+ */
+public class AdjRibIn {
+ private Map<BgpNodeLSIdentifier, PathAttrNlriDetails> nodeTree = new TreeMap<>();
+ private Map<BgpLinkLSIdentifier, PathAttrNlriDetails> linkTree = new TreeMap<>();
+ private Map<BgpPrefixLSIdentifier, PathAttrNlriDetails> prefixTree = new TreeMap<>();
+
+ /**
+ * Returns the adjacency node.
+ *
+ * @return node adjacency RIB node
+ */
+ public Map<BgpNodeLSIdentifier, PathAttrNlriDetails> nodeTree() {
+ return nodeTree;
+ }
+
+ /**
+ * Returns the adjacency link.
+ *
+ * @return link adjacency RIB node
+ */
+ public Map<BgpLinkLSIdentifier, PathAttrNlriDetails> linkTree() {
+ return linkTree;
+ }
+
+ /**
+ * Returns the adjacency prefix.
+ *
+ * @return prefix adjacency RIB node
+ */
+ public Map<BgpPrefixLSIdentifier, PathAttrNlriDetails> prefixTree() {
+ return prefixTree;
+ }
+
+ /**
+ * Update nlri identifier into the tree if nlri identifier exists in tree otherwise add this to the tree.
+ *
+ * @param nlri NLRI Info
+ * @param details has pathattribute , protocolID and identifier
+ */
+ public void add(BgpLSNlri nlri, PathAttrNlriDetails details) {
+ if (nlri instanceof BgpNodeLSNlriVer4) {
+ BgpNodeLSIdentifier nodeLSIdentifier = ((BgpNodeLSNlriVer4) nlri).getLocalNodeDescriptors();
+ if (nodeTree.containsKey(nodeLSIdentifier)) {
+ nodeTree.replace(nodeLSIdentifier, details);
+ } else {
+ nodeTree.put(nodeLSIdentifier, details);
+ }
+ } else if (nlri instanceof BgpLinkLsNlriVer4) {
+ BgpLinkLSIdentifier linkLSIdentifier = ((BgpLinkLsNlriVer4) nlri).getLinkIdentifier();
+ if (linkTree.containsKey(linkLSIdentifier)) {
+ linkTree.replace(linkLSIdentifier, details);
+ } else {
+ linkTree.put(linkLSIdentifier, details);
+ }
+ } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) {
+ BgpPrefixLSIdentifier prefixIdentifier = ((BgpPrefixIPv4LSNlriVer4) nlri).getPrefixIdentifier();
+ if (prefixTree.containsKey(prefixIdentifier)) {
+ prefixTree.replace(prefixIdentifier, details);
+ } else {
+ prefixTree.put(prefixIdentifier, details);
+ }
+ }
+ }
+
+ /**
+ * Removes nlri identifier if it exists in the adjacency tree.
+ *
+ * @param nlri NLRI Info
+ */
+ public void remove(BgpLSNlri nlri) {
+ if (nlri instanceof BgpNodeLSNlriVer4) {
+ BgpNodeLSIdentifier nodeLSIdentifier = ((BgpNodeLSNlriVer4) nlri).getLocalNodeDescriptors();
+ if (nodeTree.containsKey(nodeLSIdentifier)) {
+ nodeTree.remove(nodeLSIdentifier);
+ }
+ } else if (nlri instanceof BgpLinkLsNlriVer4) {
+ BgpLinkLSIdentifier linkLSIdentifier = ((BgpLinkLsNlriVer4) nlri).getLinkIdentifier();
+ if (linkTree.containsKey(linkLSIdentifier)) {
+ linkTree.remove(linkLSIdentifier);
+ }
+ } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) {
+ BgpPrefixLSIdentifier prefixIdentifier = ((BgpPrefixIPv4LSNlriVer4) nlri).getPrefixIdentifier();
+ if (prefixTree.containsKey(prefixIdentifier)) {
+ prefixTree.remove(prefixIdentifier);
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .omitNullValues()
+ .add("nodeTree", nodeTree)
+ .add("linkTree", linkTree)
+ .add("prefixTree", prefixTree)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java
deleted file mode 100755
index 45f74634..00000000
--- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerImpl.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onosproject.bgp.controller.impl;
-
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.RejectedExecutionException;
-
-import org.jboss.netty.channel.Channel;
-import org.onlab.packet.IpAddress;
-import org.onosproject.bgp.controller.BGPController;
-import org.onosproject.bgp.controller.BGPPeer;
-import org.onosproject.bgp.controller.BgpSessionInfo;
-import org.onosproject.bgpio.protocol.BGPFactories;
-import org.onosproject.bgpio.protocol.BGPFactory;
-import org.onosproject.bgpio.protocol.BGPMessage;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * BGPPeerImpl implements BGPPeer, maintains peer information and store updates in RIB .
- */
-public class BGPPeerImpl implements BGPPeer {
-
- protected final Logger log = LoggerFactory.getLogger(BGPPeerImpl.class);
-
- private static final String SHUTDOWN_MSG = "Worker has already been shutdown";
-
- private BGPController bgpController;
- private Channel channel;
- protected String channelId;
- private boolean connected;
- protected boolean isHandShakeComplete = false;
- private BgpSessionInfo sessionInfo;
- private BGPPacketStatsImpl pktStats;
-
-
- @Override
- public BgpSessionInfo sessionInfo() {
- return sessionInfo;
- }
-
- /**
- * Initialize peer.
- *
- *@param bgpController controller instance
- *@param sessionInfo bgp session info
- *@param pktStats packet statistics
- */
- public BGPPeerImpl(BGPController bgpController, BgpSessionInfo sessionInfo, BGPPacketStatsImpl pktStats) {
- this.bgpController = bgpController;
- this.sessionInfo = sessionInfo;
- this.pktStats = pktStats;
- }
-
- // ************************
- // Channel related
- // ************************
-
- @Override
- public final void disconnectPeer() {
- this.channel.close();
- }
-
- @Override
- public final void sendMessage(BGPMessage m) {
- log.debug("Sending message to {}", channel.getRemoteAddress());
- try {
- channel.write(Collections.singletonList(m));
- this.pktStats.addOutPacket();
- } catch (RejectedExecutionException e) {
- log.warn(e.getMessage());
- if (!e.getMessage().contains(SHUTDOWN_MSG)) {
- throw e;
- }
- }
- }
-
- @Override
- public final void sendMessage(List<BGPMessage> msgs) {
- try {
- channel.write(msgs);
- this.pktStats.addOutPacket(msgs.size());
- } catch (RejectedExecutionException e) {
- log.warn(e.getMessage());
- if (!e.getMessage().contains(SHUTDOWN_MSG)) {
- throw e;
- }
- }
- }
-
- @Override
- public final boolean isConnected() {
- return this.connected;
- }
-
- @Override
- public final void setConnected(boolean connected) {
- this.connected = connected;
- };
-
- @Override
- public final void setChannel(Channel channel) {
- this.channel = channel;
- final SocketAddress address = channel.getRemoteAddress();
- if (address instanceof InetSocketAddress) {
- final InetSocketAddress inetAddress = (InetSocketAddress) address;
- final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress());
- if (ipAddress.isIp4()) {
- channelId = ipAddress.toString() + ':' + inetAddress.getPort();
- } else {
- channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort();
- }
- }
- };
-
- @Override
- public final Channel getChannel() {
- return this.channel;
- };
-
- @Override
- public String channelId() {
- return channelId;
- }
-
- @Override
- public BGPFactory factory() {
- return BGPFactories.getFactory(sessionInfo.remoteBgpVersion());
- }
-
- @Override
- public boolean isHandshakeComplete() {
- return isHandShakeComplete;
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(getClass()).omitNullValues()
- .add("channel", channelId())
- .add("bgpId", sessionInfo().remoteBgpId()).toString();
- }
-}
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java
index f21c311c..8754563d 100755
--- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPChannelHandler.java
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java
@@ -23,8 +23,8 @@ import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.nio.channels.ClosedChannelException;
import java.util.Collections;
-import java.util.List;
import java.util.LinkedList;
+import java.util.List;
import java.util.ListIterator;
import java.util.concurrent.RejectedExecutionException;
@@ -40,20 +40,20 @@ import org.jboss.netty.handler.timeout.ReadTimeoutException;
import org.jboss.netty.handler.timeout.ReadTimeoutHandler;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
-import org.onosproject.bgp.controller.BGPCfg;
-import org.onosproject.bgp.controller.BGPController;
-import org.onosproject.bgp.controller.BGPId;
-import org.onosproject.bgp.controller.BGPPeer;
-import org.onosproject.bgp.controller.BGPPeerCfg;
-import org.onosproject.bgp.controller.impl.BGPControllerImpl.BGPPeerManagerImpl;
-import org.onosproject.bgpio.exceptions.BGPParseException;
-import org.onosproject.bgpio.protocol.BGPFactory;
-import org.onosproject.bgpio.protocol.BGPMessage;
-import org.onosproject.bgpio.protocol.BGPOpenMsg;
-import org.onosproject.bgpio.protocol.BGPType;
-import org.onosproject.bgpio.protocol.BGPVersion;
-import org.onosproject.bgpio.types.BGPErrorType;
-import org.onosproject.bgpio.types.BGPValueType;
+import org.onosproject.bgp.controller.BgpCfg;
+import org.onosproject.bgp.controller.BgpController;
+import org.onosproject.bgp.controller.BgpId;
+import org.onosproject.bgp.controller.BgpPeer;
+import org.onosproject.bgp.controller.BgpPeerCfg;
+import org.onosproject.bgp.controller.impl.BgpControllerImpl.BgpPeerManagerImpl;
+import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.BgpFactory;
+import org.onosproject.bgpio.protocol.BgpMessage;
+import org.onosproject.bgpio.protocol.BgpOpenMsg;
+import org.onosproject.bgpio.protocol.BgpType;
+import org.onosproject.bgpio.protocol.BgpVersion;
+import org.onosproject.bgpio.types.BgpErrorType;
+import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.FourOctetAsNumCapabilityTlv;
import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv;
import org.slf4j.Logger;
@@ -62,20 +62,20 @@ import org.slf4j.LoggerFactory;
/**
* Channel handler deals with the bgp peer connection and dispatches messages from peer to the appropriate locations.
*/
-class BGPChannelHandler extends IdleStateAwareChannelHandler {
+class BgpChannelHandler extends IdleStateAwareChannelHandler {
- private static final Logger log = LoggerFactory.getLogger(BGPChannelHandler.class);
+ private static final Logger log = LoggerFactory.getLogger(BgpChannelHandler.class);
static final int BGP_MIN_HOLDTIME = 3;
static final int BGP_MAX_KEEPALIVE_INTERVAL = 3;
- private BGPPeer bgpPeer;
- private BGPId thisbgpId;
+ private BgpPeer bgpPeer;
+ private BgpId thisbgpId;
private Channel channel;
- private BGPKeepAliveTimer keepAliveTimer = null;
+ private BgpKeepAliveTimer keepAliveTimer = null;
private short peerHoldTime = 0;
private short negotiatedHoldTime = 0;
private long peerAsNum;
private int peerIdentifier;
- private BGPPacketStatsImpl bgpPacketStats;
+ private BgpPacketStatsImpl bgpPacketStats;
static final int MAX_WRONG_COUNT_PACKET = 5;
static final byte MULTI_PROTOCOL_EXTN_CAPA_TYPE = 1;
static final byte FOUR_OCTET_AS_NUM_CAPA_TYPE = 65;
@@ -97,30 +97,30 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
// peer state for the older (still connected) peer
private volatile Boolean duplicateBGPIdFound;
// Indicates the bgp version used by this bgp peer
- protected BGPVersion bgpVersion;
- private BGPController bgpController;
- protected BGPFactory factory4;
+ protected BgpVersion bgpVersion;
+ private BgpController bgpController;
+ protected BgpFactory factory4;
private boolean isIbgpSession;
private BgpSessionInfoImpl sessionInfo;
- private BGPPeerManagerImpl peerManager;
+ private BgpPeerManagerImpl peerManager;
private InetSocketAddress inetAddress;
private IpAddress ipAddress;
private SocketAddress address;
private String peerAddr;
- private BGPCfg bgpconfig;
+ private BgpCfg bgpconfig;
/**
* Create a new unconnected BGPChannelHandler.
*
* @param bgpController bgp controller
*/
- BGPChannelHandler(BGPController bgpController) {
+ BgpChannelHandler(BgpController bgpController) {
this.bgpController = bgpController;
- this.peerManager = (BGPPeerManagerImpl) bgpController.peerManager();
+ this.peerManager = (BgpPeerManagerImpl) bgpController.peerManager();
this.state = ChannelState.IDLE;
- this.factory4 = Controller.getBGPMessageFactory4();
+ this.factory4 = Controller.getBgpMessageFactory4();
this.duplicateBGPIdFound = Boolean.FALSE;
- this.bgpPacketStats = new BGPPacketStatsImpl();
+ this.bgpPacketStats = new BgpPacketStatsImpl();
this.bgpconfig = bgpController.getConfig();
}
@@ -147,24 +147,29 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
OPENSENT(false) {
@Override
- void processBGPMessage(BGPChannelHandler h, BGPMessage m) throws IOException, BGPParseException {
+ void processBgpMessage(BgpChannelHandler h, BgpMessage m) throws IOException, BgpParseException {
log.debug("message received in OPENSENT state");
// check for OPEN message
- if (m.getType() != BGPType.OPEN) {
+ if (m.getType() != BgpType.OPEN) {
// When the message type is not keep alive message increment the wrong packet statistics
- h.processUnknownMsg(BGPErrorType.FINITE_STATE_MACHINE_ERROR,
- BGPErrorType.RECEIVE_UNEXPECTED_MESSAGE_IN_OPENSENT_STATE, m.getType()
- .getType());
+ h.processUnknownMsg(BgpErrorType.FINITE_STATE_MACHINE_ERROR,
+ BgpErrorType.RECEIVE_UNEXPECTED_MESSAGE_IN_OPENSENT_STATE,
+ m.getType().getType());
log.debug("Message is not OPEN message");
} else {
log.debug("Sending keep alive message in OPENSENT state");
h.bgpPacketStats.addInPacket();
- BGPOpenMsg pOpenmsg = (BGPOpenMsg) m;
+ BgpOpenMsg pOpenmsg = (BgpOpenMsg) m;
h.peerIdentifier = pOpenmsg.getBgpId();
// validate capabilities and open msg
if (h.openMsgValidation(h, pOpenmsg)) {
+ if (h.connectionCollisionDetection(BgpPeerCfg.State.OPENCONFIRM,
+ h.peerIdentifier, h.peerAddr)) {
+ h.channel.close();
+ return;
+ }
log.debug("Sending handshake OPEN message");
/*
@@ -176,7 +181,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
if (h.peerHoldTime < h.bgpconfig.getHoldTime()) {
h.channel.getPipeline().replace("holdTime",
"holdTime",
- new ReadTimeoutHandler(BGPPipelineFactory.TIMER,
+ new ReadTimeoutHandler(BgpPipelineFactory.TIMER,
h.peerHoldTime));
}
@@ -190,30 +195,35 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
h.sendKeepAliveMessage();
h.bgpPacketStats.addOutPacket();
h.setState(OPENCONFIRM);
- h.bgpconfig.setPeerConnState(h.peerAddr, BGPPeerCfg.State.OPENCONFIRM);
+ h.bgpconfig.setPeerConnState(h.peerAddr, BgpPeerCfg.State.OPENCONFIRM);
}
}
},
OPENWAIT(false) {
@Override
- void processBGPMessage(BGPChannelHandler h, BGPMessage m) throws IOException, BGPParseException {
+ void processBgpMessage(BgpChannelHandler h, BgpMessage m) throws IOException, BgpParseException {
log.debug("Message received in OPEN WAIT State");
// check for open message
- if (m.getType() != BGPType.OPEN) {
+ if (m.getType() != BgpType.OPEN) {
// When the message type is not open message increment the wrong packet statistics
- h.processUnknownMsg(BGPErrorType.FINITE_STATE_MACHINE_ERROR, BGPErrorType.UNSPECIFIED_ERROR, m
- .getType().getType());
+ h.processUnknownMsg(BgpErrorType.FINITE_STATE_MACHINE_ERROR, BgpErrorType.UNSPECIFIED_ERROR,
+ m.getType().getType());
log.debug("Message is not OPEN message");
} else {
h.bgpPacketStats.addInPacket();
- BGPOpenMsg pOpenmsg = (BGPOpenMsg) m;
+ BgpOpenMsg pOpenmsg = (BgpOpenMsg) m;
h.peerIdentifier = pOpenmsg.getBgpId();
// Validate open message
if (h.openMsgValidation(h, pOpenmsg)) {
+ if (h.connectionCollisionDetection(BgpPeerCfg.State.OPENSENT,
+ h.peerIdentifier, h.peerAddr)) {
+ h.channel.close();
+ return;
+ }
log.debug("Sending handshake OPEN message");
/*
@@ -225,7 +235,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
if (h.peerHoldTime < h.bgpconfig.getHoldTime()) {
h.channel.getPipeline().replace("holdTime",
"holdTime",
- new ReadTimeoutHandler(BGPPipelineFactory.TIMER,
+ new ReadTimeoutHandler(BgpPipelineFactory.TIMER,
h.peerHoldTime));
}
@@ -237,6 +247,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
h.sendHandshakeOpenMessage();
h.bgpPacketStats.addOutPacket();
h.setState(OPENCONFIRM);
+ h.bgpconfig.setPeerConnState(h.peerAddr, BgpPeerCfg.State.OPENCONFIRM);
}
}
}
@@ -244,14 +255,14 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
OPENCONFIRM(false) {
@Override
- void processBGPMessage(BGPChannelHandler h, BGPMessage m) throws IOException, BGPParseException {
+ void processBgpMessage(BgpChannelHandler h, BgpMessage m) throws IOException, BgpParseException {
log.debug("Message received in OPENCONFIRM state");
// check for keep alive message
- if (m.getType() != BGPType.KEEP_ALIVE) {
+ if (m.getType() != BgpType.KEEP_ALIVE) {
// When the message type is not keep alive message handle the wrong packet
- h.processUnknownMsg(BGPErrorType.FINITE_STATE_MACHINE_ERROR,
- BGPErrorType.RECEIVE_UNEXPECTED_MESSAGE_IN_OPENCONFIRM_STATE, m.getType()
- .getType());
+ h.processUnknownMsg(BgpErrorType.FINITE_STATE_MACHINE_ERROR,
+ BgpErrorType.RECEIVE_UNEXPECTED_MESSAGE_IN_OPENCONFIRM_STATE,
+ m.getType().getType());
log.debug("Message is not KEEPALIVE message");
} else {
@@ -260,7 +271,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
log.debug("Sending keep alive message in OPENCONFIRM state");
final InetSocketAddress inetAddress = (InetSocketAddress) h.address;
- h.thisbgpId = BGPId.bgpId(IpAddress.valueOf(inetAddress.getAddress()));
+ h.thisbgpId = BgpId.bgpId(IpAddress.valueOf(inetAddress.getAddress()));
// set session parameters
h.negotiatedHoldTime = (h.peerHoldTime < h.bgpconfig.getHoldTime()) ? h.peerHoldTime
@@ -268,7 +279,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
h.sessionInfo = new BgpSessionInfoImpl(h.thisbgpId, h.bgpVersion, h.peerAsNum, h.peerHoldTime,
h.peerIdentifier, h.negotiatedHoldTime, h.isIbgpSession);
- h.bgpPeer = h.peerManager.getBGPPeerInstance(h.bgpController, h.sessionInfo, h.bgpPacketStats);
+ h.bgpPeer = h.peerManager.getBgpPeerInstance(h.bgpController, h.sessionInfo, h.bgpPacketStats);
// set the status of bgp as connected
h.bgpPeer.setConnected(true);
h.bgpPeer.setChannel(h.channel);
@@ -280,8 +291,8 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
*/
if (h.negotiatedHoldTime != 0) {
- h.keepAliveTimer = new BGPKeepAliveTimer(h,
- (h.negotiatedHoldTime / BGP_MAX_KEEPALIVE_INTERVAL));
+ h.keepAliveTimer = new BgpKeepAliveTimer(h,
+ (h.negotiatedHoldTime / BGP_MAX_KEEPALIVE_INTERVAL));
} else {
h.sendKeepAliveMessage();
}
@@ -292,17 +303,10 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
h.setHandshakeComplete(true);
if (!h.peerManager.addConnectedPeer(h.thisbgpId, h.bgpPeer)) {
- /*
- * RFC 4271, Section 6.8, Based on the value of the BGP identifier, a convention is established
- * for detecting which BGP connection is to be preserved when a collision occurs. The convention
- * is to compare the BGP Identifiers of the peers involved in the collision and to retain only
- * the connection initiated by the BGP speaker with the higher-valued BGP Identifier..
- */
- // TODO: Connection collision handling.
disconnectDuplicate(h);
} else {
h.setState(ESTABLISHED);
- h.bgpconfig.setPeerConnState(h.peerAddr, BGPPeerCfg.State.ESTABLISHED);
+ h.bgpconfig.setPeerConnState(h.peerAddr, BgpPeerCfg.State.ESTABLISHED);
}
}
}
@@ -310,7 +314,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
ESTABLISHED(true) {
@Override
- void processBGPMessage(BGPChannelHandler h, BGPMessage m) throws IOException, BGPParseException {
+ void processBgpMessage(BgpChannelHandler h, BgpMessage m) throws IOException, BgpParseException {
log.debug("Message received in established state " + m.getType());
// dispatch the message
h.dispatchMessage(m);
@@ -337,7 +341,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
*
* @param h channel handler
*/
- protected void disconnectDuplicate(BGPChannelHandler h) {
+ protected void disconnectDuplicate(BgpChannelHandler h) {
log.error("Duplicated BGP IP or incompleted cleanup - " + "" + "disconnecting channel {}",
h.getPeerInfoString());
h.duplicateBGPIdFound = Boolean.TRUE;
@@ -349,8 +353,8 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
this.handshakeComplete = handshakeComplete;
}
- void processBGPMessage(BGPChannelHandler bgpChannelHandler, BGPMessage pm)
- throws IOException, BGPParseException {
+ void processBgpMessage(BgpChannelHandler bgpChannelHandler, BgpMessage pm)
+ throws IOException, BgpParseException {
// TODO Auto-generated method stub
log.debug("BGP message stub");
}
@@ -373,7 +377,8 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
}
// Connection should establish only if local ip and Autonomous system number is configured.
- if (bgpconfig.getState() != BGPCfg.State.IP_AS_CONFIGURED) {
+ if (bgpconfig.getState() != BgpCfg.State.IP_AS_CONFIGURED) {
+ sendNotification(BgpErrorType.CEASE, BgpErrorType.CONNECTION_REJECTED, null);
channel.close();
log.info("BGP local AS and router ID not configured");
return;
@@ -385,12 +390,13 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
// if peer is not configured disconnect session
if (!bgpconfig.isPeerConfigured(peerAddr)) {
log.debug("Peer is not configured {}", peerAddr);
+ sendNotification(BgpErrorType.CEASE, BgpErrorType.CONNECTION_REJECTED, null);
channel.close();
return;
}
// if connection is already established close channel
- if (peerManager.isPeerConnected(BGPId.bgpId(IpAddress.valueOf(peerAddr)))) {
+ if (peerManager.isPeerConnected(BgpId.bgpId(IpAddress.valueOf(peerAddr)))) {
log.debug("Duplicate connection received, peer {}", peerAddr);
channel.close();
return;
@@ -406,7 +412,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
sendHandshakeOpenMessage();
bgpPacketStats.addOutPacket();
setState(ChannelState.OPENSENT);
- bgpconfig.setPeerConnState(peerAddr, BGPPeerCfg.State.OPENSENT);
+ bgpconfig.setPeerConnState(peerAddr, BgpPeerCfg.State.OPENSENT);
}
}
@@ -436,6 +442,25 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
if (bgpPeer != null) {
peerManager.removeConnectedPeer(thisbgpId);
}
+
+ // Retry connection if connection is lost to bgp speaker/peer
+ if ((channel != null) && (null != channel.getPipeline().get("ActiveHandler"))) {
+ BgpConnectPeerImpl connectPeer;
+ BgpPeerCfg.State peerCfgState;
+
+ peerCfgState = bgpconfig.getPeerConnState(peerAddr);
+ // on session disconnect using configuration, do not retry
+ if (!peerCfgState.equals(BgpPeerCfg.State.IDLE)) {
+ log.debug("Connection reset by peer, retry, STATE:{}", peerCfgState);
+ BgpPeerConfig peerConfig = (BgpPeerConfig) bgpconfig.displayPeers(peerAddr);
+
+ bgpconfig.setPeerConnState(peerAddr, BgpPeerCfg.State.IDLE);
+ connectPeer = new BgpConnectPeerImpl(bgpController, peerAddr, Controller.getBgpPortNum());
+ peerConfig.setConnectPeer(connectPeer);
+ }
+ } else {
+ bgpconfig.setPeerConnState(peerAddr, BgpPeerCfg.State.IDLE);
+ }
} else {
// A duplicate was disconnected on this ChannelHandler,
// this is the same peer reconnecting, but the original state was
@@ -448,6 +473,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
keepAliveTimer.getKeepAliveTimer().cancel();
}
} else {
+ bgpconfig.setPeerConnState(peerAddr, BgpPeerCfg.State.IDLE);
log.warn("No bgp ip in channelHandler registered for " + "disconnected peer {}", getPeerInfoString());
}
}
@@ -461,14 +487,14 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
if ((ChannelState.OPENWAIT == state) || (ChannelState.OPENSENT == state)) {
// When ReadTimeout timer is expired in OPENWAIT/OPENSENT state, it is considered
- sendNotification(BGPErrorType.HOLD_TIMER_EXPIRED, (byte) 0, null);
+ sendNotification(BgpErrorType.HOLD_TIMER_EXPIRED, (byte) 0, null);
channel.close();
state = ChannelState.IDLE;
return;
} else if (ChannelState.OPENCONFIRM == state) {
// When ReadTimeout timer is expired in OPENCONFIRM state.
- sendNotification(BGPErrorType.HOLD_TIMER_EXPIRED, (byte) 0, null);
+ sendNotification(BgpErrorType.HOLD_TIMER_EXPIRED, (byte) 0, null);
channel.close();
state = ChannelState.IDLE;
return;
@@ -482,9 +508,9 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
log.debug("StackTrace for previous Exception: ", e.getCause());
}
channel.close();
- } else if (e.getCause() instanceof BGPParseException) {
+ } else if (e.getCause() instanceof BgpParseException) {
byte[] data = new byte[] {};
- BGPParseException errMsg = (BGPParseException) e.getCause();
+ BgpParseException errMsg = (BgpParseException) e.getCause();
byte errorCode = errMsg.getErrorCode();
byte errorSubCode = errMsg.getErrorSubCode();
ChannelBuffer tempCb = errMsg.getData();
@@ -511,14 +537,47 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
if (e.getMessage() instanceof List) {
@SuppressWarnings("Unchecked")
- List<BGPMessage> msglist = (List<BGPMessage>) e.getMessage();
- for (BGPMessage pm : msglist) {
+ List<BgpMessage> msglist = (List<BgpMessage>) e.getMessage();
+ for (BgpMessage pm : msglist) {
// Do the actual packet processing
- state.processBGPMessage(this, pm);
+ state.processBgpMessage(this, pm);
}
} else {
- state.processBGPMessage(this, (BGPMessage) e.getMessage());
+ state.processBgpMessage(this, (BgpMessage) e.getMessage());
+ }
+ }
+
+ /**
+ * Check for connection collision.
+ *
+ * @param state connection state
+ * @param peerIdentifier BGP peer identifier
+ * @param peerAddr BGP peer address
+ * @return true if bgp spreakers initiated connection
+ * @throws BgpParseException on error while procession collision detection
+ * @throws IOException on error while procession collision detection
+ */
+ public boolean connectionCollisionDetection(BgpPeerCfg.State state, int peerIdentifier, String peerAddr)
+ throws IOException, BgpParseException {
+ /*
+ * RFC 4271, Section 6.8, Based on the value of the BGP identifier, a convention is established for detecting
+ * which BGP connection is to be preserved when a collision occurs. The convention is to compare the BGP
+ * Identifiers of the peers involved in the collision and to retain only the connection initiated by the BGP
+ * speaker with the higher-valued BGP Identifier..
+ */
+ BgpPeerCfg.State currentState = bgpconfig.getPeerConnState(peerAddr);
+ if (currentState.equals(state)) {
+ if (((Ip4Address.valueOf(bgpconfig.getRouterId())).compareTo(Ip4Address.valueOf(peerIdentifier))) > 0) {
+ // send notification
+ sendNotification(BgpErrorType.CEASE, BgpErrorType.CONNECTION_COLLISION_RESOLUTION, null);
+ log.debug("Connection collision detected, local id: {}, peer id: {}, peer state:{}, in state:{}",
+ (Ip4Address.valueOf(bgpconfig.getRouterId())), (Ip4Address.valueOf(peerIdentifier)),
+ currentState, state);
+ return true;
+ }
}
+
+ return false;
}
// *************************
@@ -546,9 +605,9 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
* To handle the BGP message.
*
* @param m bgp message
- * @throws BGPParseException throw exception
+ * @throws BgpParseException throw exception
*/
- private void dispatchMessage(BGPMessage m) throws BGPParseException {
+ private void dispatchMessage(BgpMessage m) throws BgpParseException {
bgpPacketStats.addInPacket();
bgpController.processBGPPacket(thisbgpId, m);
}
@@ -589,24 +648,22 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
*
* @return packet statistics
*/
- public BGPPacketStatsImpl getBgpPacketStats() {
+ public BgpPacketStatsImpl getBgpPacketStats() {
return bgpPacketStats;
}
/**
* Send handshake open message to the peer.
*
- * @throws IOException, BGPParseException
+ * @throws IOException, BgpParseException
*/
- private void sendHandshakeOpenMessage() throws IOException, BGPParseException {
+ private void sendHandshakeOpenMessage() throws IOException, BgpParseException {
int bgpId;
bgpId = Ip4Address.valueOf(bgpconfig.getRouterId()).toInt();
- BGPMessage msg = factory4.openMessageBuilder().setAsNumber((short) bgpconfig.getAsNumber())
- .setHoldTime(bgpconfig.getHoldTime()).setBgpId(bgpId)
- .setLsCapabilityTlv(bgpconfig.getLsCapability())
- .setLargeAsCapabilityTlv(bgpconfig.getLargeASCapability())
- .build();
+ BgpMessage msg = factory4.openMessageBuilder().setAsNumber((short) bgpconfig.getAsNumber())
+ .setHoldTime(bgpconfig.getHoldTime()).setBgpId(bgpId).setLsCapabilityTlv(bgpconfig.getLsCapability())
+ .setLargeAsCapabilityTlv(bgpconfig.getLargeASCapability()).build();
log.debug("Sending open message to {}", channel.getRemoteAddress());
channel.write(Collections.singletonList(msg));
@@ -618,12 +675,12 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
* @param errorCode error code send in notification
* @param errorSubCode sub error code send in notification
* @param data data to send in notification
- * @throws IOException, BGPParseException while building message
+ * @throws IOException, BgpParseException while building message
*/
private void sendNotification(byte errorCode, byte errorSubCode, byte[] data)
- throws IOException, BGPParseException {
- BGPMessage msg = factory4.notificationMessageBuilder().setErrorCode(errorCode).setErrorSubCode(errorSubCode)
- .setData(data).build();
+ throws IOException, BgpParseException {
+ BgpMessage msg = factory4.notificationMessageBuilder().setErrorCode(errorCode)
+ .setErrorSubCode(errorSubCode).setData(data).build();
log.debug("Sending notification message to {}", channel.getRemoteAddress());
channel.write(Collections.singletonList(msg));
}
@@ -632,11 +689,11 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
* Send keep alive message.
*
* @throws IOException when channel is disconnected
- * @throws BGPParseException while building keep alive message
+ * @throws BgpParseException while building keep alive message
*/
- synchronized void sendKeepAliveMessage() throws IOException, BGPParseException {
+ synchronized void sendKeepAliveMessage() throws IOException, BgpParseException {
- BGPMessage msg = factory4.keepaliveMessageBuilder().build();
+ BgpMessage msg = factory4.keepaliveMessageBuilder().build();
log.debug("Sending keepalive message to {}", channel.getRemoteAddress());
channel.write(Collections.singletonList(msg));
}
@@ -647,10 +704,10 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
* @param errorCode error code
* @param errorSubCode error sub code
* @param data message type
- * @throws BGPParseException while processing error messsage
+ * @throws BgpParseException while processing error messsage
* @throws IOException while processing error message
*/
- public void processUnknownMsg(byte errorCode, byte errorSubCode, byte data) throws BGPParseException, IOException {
+ public void processUnknownMsg(byte errorCode, byte errorSubCode, byte data) throws BgpParseException, IOException {
log.debug("UNKNOWN message received");
byte[] byteArray = new byte[1];
byteArray[0] = data;
@@ -664,26 +721,26 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
* @param h channel handler
* @param openMsg open message
* @return true if valid message, otherwise false
- * @throws BGPParseException throw exception
+ * @throws BgpParseException throw exception
*/
- public boolean openMsgValidation(BGPChannelHandler h, BGPOpenMsg openMsg) throws BGPParseException {
+ public boolean openMsgValidation(BgpChannelHandler h, BgpOpenMsg openMsg) throws BgpParseException {
boolean result;
// Validate BGP ID
result = bgpIdValidation(openMsg);
if (!result) {
- throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_BGP_IDENTIFIER, null);
+ throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.BAD_BGP_IDENTIFIER, null);
}
// Validate AS number
result = asNumberValidation(h, openMsg);
if (!result) {
- throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_PEER_AS, null);
+ throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.BAD_PEER_AS, null);
}
// Validate hold timer
if ((openMsg.getHoldTime() != 0) && (openMsg.getHoldTime() < BGP_MIN_HOLDTIME)) {
- throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.UNACCEPTABLE_HOLD_TIME, null);
+ throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.UNACCEPTABLE_HOLD_TIME, null);
}
// Validate capabilities
@@ -697,25 +754,25 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
* @param h channel handler
* @param openmsg open message
* @return success or failure
- * @throws BGPParseException
+ * @throws BgpParseException
*/
- private boolean capabilityValidation(BGPChannelHandler h, BGPOpenMsg openmsg) throws BGPParseException {
+ private boolean capabilityValidation(BgpChannelHandler h, BgpOpenMsg openmsg) throws BgpParseException {
log.debug("capabilityValidation");
boolean isMultiProtocolcapabilityExists = false;
boolean isFourOctetCapabilityExits = false;
int capAsNum = 0;
- List<BGPValueType> capabilityTlv = openmsg.getCapabilityTlv();
- ListIterator<BGPValueType> listIterator = capabilityTlv.listIterator();
- List<BGPValueType> unSupportedCapabilityTlv = new LinkedList<>();
- ListIterator<BGPValueType> unSupportedCaplistIterator = unSupportedCapabilityTlv.listIterator();
- BGPValueType tempTlv;
+ List<BgpValueType> capabilityTlv = openmsg.getCapabilityTlv();
+ ListIterator<BgpValueType> listIterator = capabilityTlv.listIterator();
+ List<BgpValueType> unSupportedCapabilityTlv = new LinkedList<>();
+ ListIterator<BgpValueType> unSupportedCaplistIterator = unSupportedCapabilityTlv.listIterator();
+ BgpValueType tempTlv;
boolean isLargeAsCapabilityCfg = h.bgpconfig.getLargeASCapability();
boolean isLsCapabilityCfg = h.bgpconfig.getLsCapability();
while (listIterator.hasNext()) {
- BGPValueType tlv = listIterator.next();
+ BgpValueType tlv = listIterator.next();
if (tlv.getType() == MULTI_PROTOCOL_EXTN_CAPA_TYPE) {
isMultiProtocolcapabilityExists = true;
}
@@ -728,11 +785,11 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
if (isFourOctetCapabilityExits) {
if (capAsNum > MAX_AS2_NUM) {
if (openmsg.getAsNumber() != AS_TRANS) {
- throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_PEER_AS, null);
+ throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.BAD_PEER_AS, null);
}
} else {
if (capAsNum != openmsg.getAsNumber()) {
- throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR, BGPErrorType.BAD_PEER_AS, null);
+ throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.BAD_PEER_AS, null);
}
}
}
@@ -754,11 +811,10 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
if (unSupportedCaplistIterator.hasNext()) {
ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
while (unSupportedCaplistIterator.hasNext()) {
- BGPValueType tlv = unSupportedCaplistIterator.next();
+ BgpValueType tlv = unSupportedCaplistIterator.next();
tlv.write(buffer);
}
- throw new BGPParseException(BGPErrorType.OPEN_MESSAGE_ERROR,
- BGPErrorType.UNSUPPORTED_CAPABILITY, buffer);
+ throw new BgpParseException(BgpErrorType.OPEN_MESSAGE_ERROR, BgpErrorType.UNSUPPORTED_CAPABILITY, buffer);
} else {
return true;
}
@@ -771,18 +827,18 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
* @param openMsg open message
* @return true or false
*/
- private boolean asNumberValidation(BGPChannelHandler h, BGPOpenMsg openMsg) {
+ private boolean asNumberValidation(BgpChannelHandler h, BgpOpenMsg openMsg) {
log.debug("AS Num validation");
int capAsNum = 0;
boolean isFourOctetCapabilityExits = false;
- BGPPeerCfg peerCfg = h.bgpconfig.displayPeers(peerAddr);
- List<BGPValueType> capabilityTlv = openMsg.getCapabilityTlv();
- ListIterator<BGPValueType> listIterator = capabilityTlv.listIterator();
+ BgpPeerCfg peerCfg = h.bgpconfig.displayPeers(peerAddr);
+ List<BgpValueType> capabilityTlv = openMsg.getCapabilityTlv();
+ ListIterator<BgpValueType> listIterator = capabilityTlv.listIterator();
while (listIterator.hasNext()) {
- BGPValueType tlv = listIterator.next();
+ BgpValueType tlv = listIterator.next();
if (tlv.getType() == FOUR_OCTET_AS_NUM_CAPA_TYPE) {
isFourOctetCapabilityExits = true;
capAsNum = ((FourOctetAsNumCapabilityTlv) tlv).getInt();
@@ -838,7 +894,7 @@ class BGPChannelHandler extends IdleStateAwareChannelHandler {
* @param openMsg open message
* @return true or false
*/
- private boolean bgpIdValidation(BGPOpenMsg openMsg) {
+ private boolean bgpIdValidation(BgpOpenMsg openMsg) {
String openMsgBgpId = Ip4Address.valueOf(openMsg.getBgpId()).toString();
InetAddress ipAddress;
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPConfig.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
index 56877a16..716cc0c5 100755
--- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPConfig.java
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
@@ -21,17 +21,17 @@ import java.util.Set;
import java.util.TreeMap;
import org.onlab.packet.Ip4Address;
-import org.onosproject.bgp.controller.BGPCfg;
-import org.onosproject.bgp.controller.BGPPeerCfg;
+import org.onosproject.bgp.controller.BgpCfg;
+import org.onosproject.bgp.controller.BgpPeerCfg;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Provides BGP configuration of this BGP speaker.
*/
-public class BGPConfig implements BGPCfg {
+public class BgpConfig implements BgpCfg {
- protected static final Logger log = LoggerFactory.getLogger(BGPConfig.class);
+ protected static final Logger log = LoggerFactory.getLogger(BgpConfig.class);
private static final short DEFAULT_HOLD_TIMER = 120;
private static final short DEFAULT_CONN_RETRY_TIME = 120;
@@ -47,12 +47,12 @@ public class BGPConfig implements BGPCfg {
private int maxConnRetryCount;
private Ip4Address routerId = null;
- private TreeMap<String, BGPPeerCfg> bgpPeerTree = new TreeMap<>();
+ private TreeMap<String, BgpPeerCfg> bgpPeerTree = new TreeMap<>();
/**
* Constructor to initialize the values.
*/
- public BGPConfig() {
+ public BgpConfig() {
this.holdTime = DEFAULT_HOLD_TIMER;
this.maxConnRetryTime = DEFAULT_CONN_RETRY_TIME;
@@ -142,13 +142,13 @@ public class BGPConfig implements BGPCfg {
@Override
public boolean addPeer(String routerid, int remoteAs, short holdTime) {
- BGPPeerConfig lspeer = new BGPPeerConfig();
+ BgpPeerConfig lspeer = new BgpPeerConfig();
if (this.bgpPeerTree.get(routerid) == null) {
lspeer.setPeerRouterId(routerid);
lspeer.setAsNumber(remoteAs);
lspeer.setHoldtime(holdTime);
- lspeer.setState(BGPPeerCfg.State.IDLE);
+ lspeer.setState(BgpPeerCfg.State.IDLE);
lspeer.setSelfInnitConnection(false);
if (this.getAsNumber() == remoteAs) {
@@ -168,7 +168,7 @@ public class BGPConfig implements BGPCfg {
@Override
public boolean connectPeer(String routerid) {
- BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid);
+ BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid);
if (lspeer != null) {
lspeer.setSelfInnitConnection(true);
@@ -181,7 +181,7 @@ public class BGPConfig implements BGPCfg {
@Override
public boolean removePeer(String routerid) {
- BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid);
+ BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid);
if (lspeer != null) {
@@ -200,12 +200,12 @@ public class BGPConfig implements BGPCfg {
@Override
public boolean disconnectPeer(String routerid) {
- BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid);
+ BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid);
if (lspeer != null) {
//TODO DISCONNECT PEER
- lspeer.setState(BGPPeerCfg.State.IDLE);
+ lspeer.setState(BgpPeerCfg.State.IDLE);
lspeer.setSelfInnitConnection(false);
log.debug("Disconnected : " + routerid + " successfully");
@@ -217,8 +217,8 @@ public class BGPConfig implements BGPCfg {
}
@Override
- public void setPeerConnState(String routerid, BGPPeerCfg.State state) {
- BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid);
+ public void setPeerConnState(String routerid, BgpPeerCfg.State state) {
+ BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid);
if (lspeer != null) {
lspeer.setState(state);
@@ -232,21 +232,21 @@ public class BGPConfig implements BGPCfg {
}
@Override
- public BGPPeerCfg.State getPeerConnState(String routerid) {
- BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid);
+ public BgpPeerCfg.State getPeerConnState(String routerid) {
+ BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid);
if (lspeer != null) {
return lspeer.getState();
} else {
- return BGPPeerCfg.State.INVALID; //No instance
+ return BgpPeerCfg.State.INVALID; //No instance
}
}
@Override
public boolean isPeerConnectable(String routerid) {
- BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid);
+ BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid);
- if ((lspeer != null) && lspeer.getState().equals(BGPPeerCfg.State.IDLE)) {
+ if ((lspeer != null) && lspeer.getState().equals(BgpPeerCfg.State.IDLE)) {
return true;
}
@@ -254,21 +254,21 @@ public class BGPConfig implements BGPCfg {
}
@Override
- public TreeMap<String, BGPPeerCfg> getPeerTree() {
+ public TreeMap<String, BgpPeerCfg> getPeerTree() {
return this.bgpPeerTree;
}
@Override
- public TreeMap<String, BGPPeerCfg> displayPeers() {
+ public TreeMap<String, BgpPeerCfg> displayPeers() {
if (this.bgpPeerTree.isEmpty()) {
log.debug("There are no BGP peers");
} else {
- Set<Entry<String, BGPPeerCfg>> set = this.bgpPeerTree.entrySet();
- Iterator<Entry<String, BGPPeerCfg>> list = set.iterator();
- BGPPeerCfg lspeer;
+ Set<Entry<String, BgpPeerCfg>> set = this.bgpPeerTree.entrySet();
+ Iterator<Entry<String, BgpPeerCfg>> list = set.iterator();
+ BgpPeerCfg lspeer;
while (list.hasNext()) {
- Entry<String, BGPPeerCfg> me = list.next();
+ Entry<String, BgpPeerCfg> me = list.next();
lspeer = me.getValue();
log.debug("Peer neighbor IP :" + me.getKey());
log.debug(", AS Number : " + lspeer.getAsNumber());
@@ -280,10 +280,10 @@ public class BGPConfig implements BGPCfg {
}
@Override
- public BGPPeerCfg displayPeers(String routerid) {
+ public BgpPeerCfg displayPeers(String routerid) {
if (this.bgpPeerTree.isEmpty()) {
- log.debug("There are no BGP peers");
+ log.debug("There are no Bgp peers");
} else {
return this.bgpPeerTree.get(routerid);
}
@@ -312,7 +312,7 @@ public class BGPConfig implements BGPCfg {
@Override
public boolean isPeerConfigured(String routerid) {
- BGPPeerCfg lspeer = this.bgpPeerTree.get(routerid);
+ BgpPeerCfg lspeer = this.bgpPeerTree.get(routerid);
return (lspeer != null) ? true : false;
}
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConnectPeerImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConnectPeerImpl.java
new file mode 100755
index 00000000..27db618d
--- /dev/null
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConnectPeerImpl.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.onosproject.bgp.controller.impl;
+
+import java.net.InetSocketAddress;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import org.jboss.netty.bootstrap.ClientBootstrap;
+import org.jboss.netty.channel.ChannelFuture;
+import org.jboss.netty.channel.ChannelFutureListener;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.onosproject.bgp.controller.BgpCfg;
+import org.onosproject.bgp.controller.BgpController;
+import org.onosproject.bgp.controller.BgpPeerCfg;
+import org.onosproject.bgp.controller.BgpConnectPeer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implements connection initiation to peer on peer configuration and manage channel using netty channel handler.
+ */
+public class BgpConnectPeerImpl implements BgpConnectPeer {
+ private static final Logger log = LoggerFactory.getLogger(BgpConnectPeerImpl.class);
+
+ private ScheduledExecutorService connectExecutor = null;
+ private final String peerHost;
+ private static final int RETRY_INTERVAL = 4;
+ private final int peerPort;
+ private int connectRetryCounter = 0;
+ private int connectRetryTime;
+ private ChannelPipelineFactory pfact;
+ private ClientBootstrap peerBootstrap;
+ private BgpCfg bgpconfig;
+
+ /**
+ * Initialize timer and initiate pipeline factory.
+ *
+ * @param bgpController parent BGP controller
+ * @param remoteHost remote host to connect
+ * @param remotePort remote port to connect
+ */
+ public BgpConnectPeerImpl(BgpController bgpController, String remoteHost, int remotePort) {
+
+ this.bgpconfig = bgpController.getConfig();
+ this.pfact = new BgpPipelineFactory(bgpController, false);
+ this.peerBootstrap = Controller.peerBootstrap();
+ this.peerBootstrap.setPipelineFactory(pfact);
+ this.peerHost = remoteHost;
+ this.peerPort = remotePort;
+ this.connectRetryTime = 0;
+ }
+
+ @Override
+ public void disconnectPeer() {
+ if (connectExecutor != null) {
+ connectExecutor.shutdown();
+ connectExecutor = null;
+ }
+ }
+
+ @Override
+ public void connectPeer() {
+ scheduleConnectionRetry(this.connectRetryTime);
+ }
+
+ /**
+ * Retry connection with exponential back-off mechanism.
+ *
+ * @param retryDelay retry delay
+ */
+ private void scheduleConnectionRetry(long retryDelay) {
+ if (this.connectExecutor == null) {
+ this.connectExecutor = Executors.newSingleThreadScheduledExecutor();
+ }
+ this.connectExecutor.schedule(new ConnectionRetry(), retryDelay, TimeUnit.MINUTES);
+ }
+
+ /**
+ * Implements BGP connection and manages connection to peer with back-off mechanism in case of failure.
+ */
+ class ConnectionRetry implements Runnable {
+ @Override
+ public void run() {
+ log.debug("Connect to peer {}", peerHost);
+
+ InetSocketAddress connectToSocket = new InetSocketAddress(peerHost, peerPort);
+
+ try {
+ bgpconfig.setPeerConnState(peerHost, BgpPeerCfg.State.CONNECT);
+ peerBootstrap.connect(connectToSocket).addListener(new ChannelFutureListener() {
+ @Override
+ public void operationComplete(ChannelFuture future) throws Exception {
+ if (!future.isSuccess()) {
+ bgpconfig.setPeerConnState(peerHost, BgpPeerCfg.State.ACTIVE);
+ connectRetryCounter++;
+ log.error("Connection failed, ConnectRetryCounter {} remote host {}", connectRetryCounter,
+ peerHost);
+ /*
+ * Reconnect to peer on failure is exponential till 4 mins, later on retry after every 4
+ * mins.
+ */
+ if (connectRetryTime < RETRY_INTERVAL) {
+ connectRetryTime = (connectRetryTime != 0) ? connectRetryTime * 2 : 1;
+ }
+ scheduleConnectionRetry(connectRetryTime);
+ } else {
+
+ connectRetryCounter++;
+ log.info("Connected to remote host {}, Connect Counter {}", peerHost, connectRetryCounter);
+ disconnectPeer();
+ return;
+ }
+ }
+ });
+ } catch (Exception e) {
+ log.info("Connect peer exception : " + e.toString());
+ disconnectPeer();
+ }
+ }
+ }
+}
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java
index 35c31ab7..6a14e85c 100755
--- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPControllerImpl.java
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java
@@ -26,34 +26,32 @@ import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
-import org.onosproject.bgp.controller.BGPCfg;
-import org.onosproject.bgp.controller.BGPController;
-import org.onosproject.bgp.controller.BGPId;
-import org.onosproject.bgp.controller.BGPPeer;
-import org.onosproject.bgp.controller.BgpLinkListener;
+import org.onosproject.bgp.controller.BgpCfg;
+import org.onosproject.bgp.controller.BgpController;
+import org.onosproject.bgp.controller.BgpId;
+import org.onosproject.bgp.controller.BgpPeer;
import org.onosproject.bgp.controller.BgpNodeListener;
import org.onosproject.bgp.controller.BgpPeerManager;
-import org.onosproject.bgpio.exceptions.BGPParseException;
-import org.onosproject.bgpio.protocol.BGPMessage;
+import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.BgpMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Component(immediate = true)
@Service
-public class BGPControllerImpl implements BGPController {
+public class BgpControllerImpl implements BgpController {
- private static final Logger log = LoggerFactory.getLogger(BGPControllerImpl.class);
+ private static final Logger log = LoggerFactory.getLogger(BgpControllerImpl.class);
- protected ConcurrentHashMap<BGPId, BGPPeer> connectedPeers = new ConcurrentHashMap<BGPId, BGPPeer>();
+ protected ConcurrentHashMap<BgpId, BgpPeer> connectedPeers = new ConcurrentHashMap<BgpId, BgpPeer>();
- protected BGPPeerManagerImpl peerManager = new BGPPeerManagerImpl();
+ protected BgpPeerManagerImpl peerManager = new BgpPeerManagerImpl();
protected Set<BgpNodeListener> bgpNodeListener = new CopyOnWriteArraySet<>();
- protected Set<BgpLinkListener> bgpLinkListener = new CopyOnWriteArraySet<>();
final Controller ctrl = new Controller(this);
- private BGPConfig bgpconfig = new BGPConfig();
+ private BgpConfig bgpconfig = new BgpConfig();
@Activate
public void activate() {
@@ -70,12 +68,12 @@ public class BGPControllerImpl implements BGPController {
}
@Override
- public Iterable<BGPPeer> getPeers() {
+ public Iterable<BgpPeer> getPeers() {
return this.connectedPeers.values();
}
@Override
- public BGPPeer getPeer(BGPId bgpId) {
+ public BgpPeer getPeer(BgpId bgpId) {
return this.connectedPeers.get(bgpId);
}
@@ -95,27 +93,12 @@ public class BGPControllerImpl implements BGPController {
}
@Override
- public void addLinkListener(BgpLinkListener listener) {
- this.bgpLinkListener.add(listener);
- }
-
- @Override
- public void removeLinkListener(BgpLinkListener listener) {
- this.bgpLinkListener.remove(listener);
- }
-
- @Override
- public Set<BgpLinkListener> linkListener() {
- return bgpLinkListener;
- }
-
- @Override
- public void writeMsg(BGPId bgpId, BGPMessage msg) {
+ public void writeMsg(BgpId bgpId, BgpMessage msg) {
this.getPeer(bgpId).sendMessage(msg);
}
@Override
- public void processBGPPacket(BGPId bgpId, BGPMessage msg) throws BGPParseException {
+ public void processBGPPacket(BgpId bgpId, BgpMessage msg) throws BgpParseException {
switch (msg.getType()) {
case OPEN:
@@ -138,8 +121,8 @@ public class BGPControllerImpl implements BGPController {
@Override
public void closeConnectedPeers() {
- BGPPeer bgpPeer;
- for (BGPId id : this.connectedPeers.keySet()) {
+ BgpPeer bgpPeer;
+ for (BgpId id : this.connectedPeers.keySet()) {
bgpPeer = getPeer(id);
bgpPeer.disconnectPeer();
}
@@ -149,13 +132,13 @@ public class BGPControllerImpl implements BGPController {
* Implementation of an BGP Peer which is responsible for keeping track of connected peers and the state in which
* they are.
*/
- public class BGPPeerManagerImpl implements BgpPeerManager {
+ public class BgpPeerManagerImpl implements BgpPeerManager {
- private final Logger log = LoggerFactory.getLogger(BGPPeerManagerImpl.class);
+ private final Logger log = LoggerFactory.getLogger(BgpPeerManagerImpl.class);
private final Lock peerLock = new ReentrantLock();
@Override
- public boolean addConnectedPeer(BGPId bgpId, BGPPeer bgpPeer) {
+ public boolean addConnectedPeer(BgpId bgpId, BgpPeer bgpPeer) {
if (connectedPeers.get(bgpId) != null) {
this.log.error("Trying to add connectedPeer but found previous " + "value for bgp ip: {}",
@@ -169,7 +152,7 @@ public class BGPControllerImpl implements BGPController {
}
@Override
- public boolean isPeerConnected(BGPId bgpId) {
+ public boolean isPeerConnected(BgpId bgpId) {
if (connectedPeers.get(bgpId) == null) {
this.log.error("Is peer connected: bgpIp {}.", bgpId.toString());
return false;
@@ -179,12 +162,12 @@ public class BGPControllerImpl implements BGPController {
}
@Override
- public void removeConnectedPeer(BGPId bgpId) {
+ public void removeConnectedPeer(BgpId bgpId) {
connectedPeers.remove(bgpId);
}
@Override
- public BGPPeer getPeer(BGPId bgpId) {
+ public BgpPeer getPeer(BgpId bgpId) {
return connectedPeers.get(bgpId);
}
@@ -196,26 +179,35 @@ public class BGPControllerImpl implements BGPController {
* @param pktStats packet statistics.
* @return BGPPeer peer instance.
*/
- public BGPPeer getBGPPeerInstance(BGPController bgpController, BgpSessionInfoImpl sessionInfo,
- BGPPacketStatsImpl pktStats) {
- BGPPeer bgpPeer = new BGPPeerImpl(bgpController, sessionInfo, pktStats);
+ public BgpPeer getBgpPeerInstance(BgpController bgpController, BgpSessionInfoImpl sessionInfo,
+ BgpPacketStatsImpl pktStats) {
+ BgpPeer bgpPeer = new BgpPeerImpl(bgpController, sessionInfo, pktStats);
return bgpPeer;
}
}
+ /**
+ * Returns controller.
+ *
+ * @return controller
+ */
+ public Controller controller() {
+ return this.ctrl;
+ }
+
@Override
- public ConcurrentHashMap<BGPId, BGPPeer> connectedPeers() {
+ public ConcurrentHashMap<BgpId, BgpPeer> connectedPeers() {
return connectedPeers;
}
@Override
- public BGPPeerManagerImpl peerManager() {
+ public BgpPeerManagerImpl peerManager() {
return peerManager;
}
@Override
- public BGPCfg getConfig() {
+ public BgpCfg getConfig() {
return this.bgpconfig;
}
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPKeepAliveTimer.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpKeepAliveTimer.java
index 1c95804a..524ac4c1 100755
--- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPKeepAliveTimer.java
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpKeepAliveTimer.java
@@ -25,11 +25,11 @@ import org.slf4j.LoggerFactory;
/**
* Implement sending keepalive message to connected peer periodically based on negotiated holdtime.
*/
-public class BGPKeepAliveTimer {
+public class BgpKeepAliveTimer {
private Timer keepAliveTimer;
- private BGPChannelHandler handler;
- private static final Logger log = LoggerFactory.getLogger(BGPKeepAliveTimer.class);
+ private BgpChannelHandler handler;
+ private static final Logger log = LoggerFactory.getLogger(BgpKeepAliveTimer.class);
/**
* Gets keepalive timer object.
@@ -46,7 +46,7 @@ public class BGPKeepAliveTimer {
* @param h channel handler
* @param seconds time interval.
*/
- public BGPKeepAliveTimer(BGPChannelHandler h, int seconds) {
+ public BgpKeepAliveTimer(BgpChannelHandler h, int seconds) {
this.handler = h;
this.keepAliveTimer = new Timer();
this.keepAliveTimer.schedule(new SendKeepAlive(), 0, seconds * 1000);
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPMessageDecoder.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpMessageDecoder.java
index 636b78cc..431c6210 100755
--- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPMessageDecoder.java
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpMessageDecoder.java
@@ -22,20 +22,20 @@ import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.frame.FrameDecoder;
-import org.onosproject.bgpio.protocol.BGPMessage;
+import org.onosproject.bgpio.protocol.BgpMessage;
import org.onlab.util.HexDump;
-import org.onosproject.bgpio.protocol.BGPFactories;
-import org.onosproject.bgpio.protocol.BGPMessageReader;
-import org.onosproject.bgpio.types.BGPHeader;
+import org.onosproject.bgpio.protocol.BgpFactories;
+import org.onosproject.bgpio.protocol.BgpMessageReader;
+import org.onosproject.bgpio.types.BgpHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Decode an bgp message from a Channel, for use in a netty pipeline.
*/
-public class BGPMessageDecoder extends FrameDecoder {
+public class BgpMessageDecoder extends FrameDecoder {
- protected static final Logger log = LoggerFactory.getLogger(BGPMessageDecoder.class);
+ protected static final Logger log = LoggerFactory.getLogger(BgpMessageDecoder.class);
@Override
protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
@@ -47,12 +47,12 @@ public class BGPMessageDecoder extends FrameDecoder {
HexDump.dump(buffer);
- BGPMessageReader<BGPMessage> reader = BGPFactories.getGenericReader();
- List<BGPMessage> msgList = new LinkedList<BGPMessage>();
+ BgpMessageReader<BgpMessage> reader = BgpFactories.getGenericReader();
+ List<BgpMessage> msgList = new LinkedList<BgpMessage>();
while (buffer.readableBytes() > 0) {
- BGPHeader bgpHeader = new BGPHeader();
- BGPMessage message = reader.readFrom(buffer, bgpHeader);
+ BgpHeader bgpHeader = new BgpHeader();
+ BgpMessage message = reader.readFrom(buffer, bgpHeader);
msgList.add(message);
}
return msgList;
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPMessageEncoder.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpMessageEncoder.java
index f0d38c3d..3e56d6ff 100755
--- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPMessageEncoder.java
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpMessageEncoder.java
@@ -22,7 +22,7 @@ import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
-import org.onosproject.bgpio.protocol.BGPMessage;
+import org.onosproject.bgpio.protocol.BgpMessage;
import org.onlab.util.HexDump;
import org.slf4j.Logger;
@@ -32,8 +32,8 @@ import org.slf4j.LoggerFactory;
* Encode an bgp message for output into a ChannelBuffer, for use in a
* netty pipeline.
*/
-public class BGPMessageEncoder extends OneToOneEncoder {
- protected static final Logger log = LoggerFactory.getLogger(BGPMessageEncoder.class);
+public class BgpMessageEncoder extends OneToOneEncoder {
+ protected static final Logger log = LoggerFactory.getLogger(BgpMessageEncoder.class);
@Override
protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
@@ -44,12 +44,12 @@ public class BGPMessageEncoder extends OneToOneEncoder {
}
@SuppressWarnings("unchecked")
- List<BGPMessage> msglist = (List<BGPMessage>) msg;
+ List<BgpMessage> msglist = (List<BgpMessage>) msg;
ChannelBuffer buf = ChannelBuffers.dynamicBuffer();
log.debug("SENDING MESSAGE");
- for (BGPMessage pm : msglist) {
+ for (BgpMessage pm : msglist) {
pm.writeTo(buf);
}
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPacketStatsImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPacketStatsImpl.java
index 09f4d452..7494c814 100755
--- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPacketStatsImpl.java
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPacketStatsImpl.java
@@ -15,7 +15,7 @@
*/
package org.onosproject.bgp.controller.impl;
-import org.onosproject.bgp.controller.BGPPacketStats;
+import org.onosproject.bgp.controller.BgpPacketStats;
/**
* A representation of a packet context which allows any provider
@@ -23,7 +23,7 @@ import org.onosproject.bgp.controller.BGPPacketStats;
* event if blocked has been called. This packet context can be used
* to react to the packet in event with a packet out.
*/
-public class BGPPacketStatsImpl implements BGPPacketStats {
+public class BgpPacketStatsImpl implements BgpPacketStats {
private int inPacketCount;
private int outPacketCount;
@@ -33,7 +33,7 @@ public class BGPPacketStatsImpl implements BGPPacketStats {
/**
* Resets parameter.
*/
- public BGPPacketStatsImpl() {
+ public BgpPacketStatsImpl() {
this.inPacketCount = 0;
this.outPacketCount = 0;
this.wrongPacketCount = 0;
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerConfig.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerConfig.java
index 14a68cf6..a8eaee3c 100755
--- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPeerConfig.java
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerConfig.java
@@ -17,12 +17,12 @@ package org.onosproject.bgp.controller.impl;
import org.onlab.packet.Ip4Address;
import org.onosproject.bgp.controller.BgpConnectPeer;
-import org.onosproject.bgp.controller.BGPPeerCfg;
+import org.onosproject.bgp.controller.BgpPeerCfg;
/**
* BGP Peer configuration information.
*/
-public class BGPPeerConfig implements BGPPeerCfg {
+public class BgpPeerConfig implements BgpPeerCfg {
private int asNumber;
private short holdTime;
private boolean isIBgp;
@@ -34,7 +34,7 @@ public class BGPPeerConfig implements BGPPeerCfg {
/**
* Constructor to initialize the values.
*/
- BGPPeerConfig() {
+ BgpPeerConfig() {
state = State.IDLE;
selfInitiated = false;
}
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
new file mode 100644
index 00000000..57a924a8
--- /dev/null
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.bgp.controller.impl;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.Collections;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.concurrent.RejectedExecutionException;
+
+import org.jboss.netty.channel.Channel;
+import org.onlab.packet.IpAddress;
+import org.onosproject.bgp.controller.BgpController;
+import org.onosproject.bgp.controller.BgpPeer;
+import org.onosproject.bgp.controller.BgpSessionInfo;
+import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.BgpFactories;
+import org.onosproject.bgpio.protocol.BgpFactory;
+import org.onosproject.bgpio.protocol.BgpLSNlri;
+import org.onosproject.bgpio.protocol.BgpMessage;
+import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
+import org.onosproject.bgpio.types.BgpValueType;
+import org.onosproject.bgpio.types.MpReachNlri;
+import org.onosproject.bgpio.types.MpUnReachNlri;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * BGPPeerImpl implements BGPPeer, maintains peer information and store updates in RIB .
+ */
+public class BgpPeerImpl implements BgpPeer {
+
+ protected final Logger log = LoggerFactory.getLogger(BgpPeerImpl.class);
+
+ private static final String SHUTDOWN_MSG = "Worker has already been shutdown";
+
+ private BgpController bgpController;
+ private Channel channel;
+ protected String channelId;
+ private boolean connected;
+ protected boolean isHandShakeComplete = false;
+ private BgpSessionInfo sessionInfo;
+ private BgpPacketStatsImpl pktStats;
+ private AdjRibIn adjRib;
+ private VpnAdjRibIn vpnAdjRib;
+
+
+ @Override
+ public BgpSessionInfo sessionInfo() {
+ return sessionInfo;
+ }
+
+ /**
+ * Initialize peer.
+ *
+ *@param bgpController controller instance
+ *@param sessionInfo bgp session info
+ *@param pktStats packet statistics
+ */
+ public BgpPeerImpl(BgpController bgpController, BgpSessionInfo sessionInfo, BgpPacketStatsImpl pktStats) {
+ this.bgpController = bgpController;
+ this.sessionInfo = sessionInfo;
+ this.pktStats = pktStats;
+ this.adjRib = new AdjRibIn();
+ this.vpnAdjRib = new VpnAdjRibIn();
+ }
+
+
+ @Override
+ public void buildAdjRibIn(List<BgpValueType> pathAttr) throws BgpParseException {
+ ListIterator<BgpValueType> iterator = pathAttr.listIterator();
+ while (iterator.hasNext()) {
+ BgpValueType attr = iterator.next();
+ if (attr instanceof MpReachNlri) {
+ List<BgpLSNlri> nlri = ((MpReachNlri) attr).mpReachNlri();
+ callAdd(this, nlri, pathAttr);
+ }
+ if (attr instanceof MpUnReachNlri) {
+ List<BgpLSNlri> nlri = ((MpUnReachNlri) attr).mpUnReachNlri();
+ callRemove(this, nlri);
+ }
+ }
+ }
+
+ /**
+ * Updates NLRI identifier node in a tree separately based on afi and safi.
+ *
+ * @param peerImpl BGP peer instance
+ * @param nlri MpReachNlri path attribute
+ * @param pathAttr list of BGP path attributes
+ * @throws BgpParseException throws exception
+ */
+ public void callAdd(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri, List<BgpValueType> pathAttr)
+ throws BgpParseException {
+ ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
+ while (listIterator.hasNext()) {
+ BgpLSNlri nlriInfo = listIterator.next();
+ if (nlriInfo instanceof BgpNodeLSNlriVer4) {
+ PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
+ if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
+ adjRib.add(nlriInfo, details);
+ } else {
+ vpnAdjRib.addVpn(nlriInfo, details, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
+ }
+ } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
+ PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
+ if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
+ adjRib.add(nlriInfo, details);
+ } else {
+ vpnAdjRib.addVpn(nlriInfo, details, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
+ }
+ } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
+ PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
+ if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
+ adjRib.add(nlriInfo, details);
+ } else {
+ vpnAdjRib.addVpn(nlriInfo, details, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets BGP path attribute and NLRI details.
+ *
+ * @param nlriInfo MpReachNlri path attribute
+ * @param pathAttr list of BGP path attributes
+ * @return details object of PathAttrNlriDetails
+ * @throws BgpParseException throw exception
+ */
+ public PathAttrNlriDetails setPathAttrDetails(BgpLSNlri nlriInfo, List<BgpValueType> pathAttr)
+ throws BgpParseException {
+ PathAttrNlriDetails details = new PathAttrNlriDetails();
+ details.setProtocolID(nlriInfo.getProtocolId());
+ details.setIdentifier(nlriInfo.getIdentifier());
+ details.setPathAttribute(pathAttr);
+ return details;
+ }
+
+ /**
+ * Removes NLRI identifier node in a tree separately based on afi and safi.
+ *
+ * @param peerImpl BGP peer instance
+ * @param nlri NLRI information
+ */
+ public void callRemove(BgpPeerImpl peerImpl, List<BgpLSNlri> nlri) {
+ ListIterator<BgpLSNlri> listIterator = nlri.listIterator();
+ while (listIterator.hasNext()) {
+ BgpLSNlri nlriInfo = listIterator.next();
+ if (nlriInfo instanceof BgpNodeLSNlriVer4) {
+ if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
+ adjRib.remove(nlriInfo);
+ } else {
+ vpnAdjRib.removeVpn(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
+ }
+ } else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
+ if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
+ adjRib.remove(nlriInfo);
+ } else {
+ vpnAdjRib.removeVpn(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
+ }
+ } else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
+ if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
+ adjRib.remove(nlriInfo);
+ } else {
+ vpnAdjRib.removeVpn(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
+ }
+ }
+ }
+ }
+
+ /**
+ * Return the adjacency RIB-IN.
+ *
+ * @return adjRib the adjacency RIB-IN
+ */
+ public AdjRibIn adjRib() {
+ return adjRib;
+ }
+
+ /**
+ * Return the adjacency RIB-IN with VPN.
+ *
+ * @return vpnAdjRib the adjacency RIB-IN with VPN
+ */
+ public VpnAdjRibIn vpnAdjRib() {
+ return vpnAdjRib;
+ }
+
+ // ************************
+ // Channel related
+ // ************************
+
+ @Override
+ public final void disconnectPeer() {
+ this.channel.close();
+ }
+
+ @Override
+ public final void sendMessage(BgpMessage m) {
+ log.debug("Sending message to {}", channel.getRemoteAddress());
+ try {
+ channel.write(Collections.singletonList(m));
+ this.pktStats.addOutPacket();
+ } catch (RejectedExecutionException e) {
+ log.warn(e.getMessage());
+ if (!e.getMessage().contains(SHUTDOWN_MSG)) {
+ throw e;
+ }
+ }
+ }
+
+ @Override
+ public final void sendMessage(List<BgpMessage> msgs) {
+ try {
+ channel.write(msgs);
+ this.pktStats.addOutPacket(msgs.size());
+ } catch (RejectedExecutionException e) {
+ log.warn(e.getMessage());
+ if (!e.getMessage().contains(SHUTDOWN_MSG)) {
+ throw e;
+ }
+ }
+ }
+
+ @Override
+ public final boolean isConnected() {
+ return this.connected;
+ }
+
+ @Override
+ public final void setConnected(boolean connected) {
+ this.connected = connected;
+ };
+
+ @Override
+ public final void setChannel(Channel channel) {
+ this.channel = channel;
+ final SocketAddress address = channel.getRemoteAddress();
+ if (address instanceof InetSocketAddress) {
+ final InetSocketAddress inetAddress = (InetSocketAddress) address;
+ final IpAddress ipAddress = IpAddress.valueOf(inetAddress.getAddress());
+ if (ipAddress.isIp4()) {
+ channelId = ipAddress.toString() + ':' + inetAddress.getPort();
+ } else {
+ channelId = '[' + ipAddress.toString() + "]:" + inetAddress.getPort();
+ }
+ }
+ };
+
+ @Override
+ public final Channel getChannel() {
+ return this.channel;
+ };
+
+ @Override
+ public String channelId() {
+ return channelId;
+ }
+
+ @Override
+ public BgpFactory factory() {
+ return BgpFactories.getFactory(sessionInfo.remoteBgpVersion());
+ }
+
+ @Override
+ public boolean isHandshakeComplete() {
+ return isHandShakeComplete;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass()).omitNullValues()
+ .add("channel", channelId())
+ .add("BgpId", sessionInfo().remoteBgpId()).toString();
+ }
+}
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPipelineFactory.java
index e6f09f20..28e1041c 100755
--- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BGPPipelineFactory.java
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPipelineFactory.java
@@ -23,18 +23,18 @@ import org.jboss.netty.handler.timeout.ReadTimeoutHandler;
import org.jboss.netty.util.ExternalResourceReleasable;
import org.jboss.netty.util.HashedWheelTimer;
import org.jboss.netty.util.Timer;
-import org.onosproject.bgp.controller.BGPController;
+import org.onosproject.bgp.controller.BgpController;
/**
* Creates a ChannelPipeline for a server-side bgp channel.
*/
-public class BGPPipelineFactory
+public class BgpPipelineFactory
implements ChannelPipelineFactory, ExternalResourceReleasable {
static final Timer TIMER = new HashedWheelTimer();
protected ReadTimeoutHandler readTimeoutHandler;
private boolean isBgpServ;
- private BGPController bgpController;
+ private BgpController bgpController;
/**
* Constructor to initialize the values.
@@ -42,7 +42,7 @@ public class BGPPipelineFactory
* @param bgpController parent controller
* @param isBgpServ if it is a server or remote peer
*/
- public BGPPipelineFactory(BGPController bgpController, boolean isBgpServ) {
+ public BgpPipelineFactory(BgpController bgpController, boolean isBgpServ) {
super();
this.isBgpServ = isBgpServ;
this.bgpController = bgpController;
@@ -52,11 +52,11 @@ public class BGPPipelineFactory
@Override
public ChannelPipeline getPipeline() throws Exception {
- BGPChannelHandler handler = new BGPChannelHandler(bgpController);
+ BgpChannelHandler handler = new BgpChannelHandler(bgpController);
ChannelPipeline pipeline = Channels.pipeline();
- pipeline.addLast("bgpmessagedecoder", new BGPMessageDecoder());
- pipeline.addLast("bgpmessageencoder", new BGPMessageEncoder());
+ pipeline.addLast("bgpmessagedecoder", new BgpMessageDecoder());
+ pipeline.addLast("bgpmessageencoder", new BgpMessageEncoder());
pipeline.addLast("holdTime", readTimeoutHandler);
if (isBgpServ) {
pipeline.addLast("PassiveHandler", handler);
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java
new file mode 100644
index 00000000..d3065f43
--- /dev/null
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSelectionAlgo.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgp.controller.impl;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetailsLocalRib;
+import org.onosproject.bgpio.types.AsPath;
+import org.onosproject.bgpio.types.BgpValueType;
+import org.onosproject.bgpio.types.LocalPref;
+import org.onosproject.bgpio.types.Med;
+import org.onosproject.bgpio.types.Origin;
+import org.onosproject.bgpio.types.Origin.ORIGINTYPE;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implementation of BGP best path Selection process.
+ */
+public final class BgpSelectionAlgo implements Comparator<PathAttrNlriDetailsLocalRib> {
+ private static final Logger log = LoggerFactory.getLogger(BgpSelectionAlgo.class);
+ LocalPref obj1LocPref = null;
+ AsPath obj1Aspath = null;
+ Origin obj1Origin = null;
+ Med obj1Med = null;
+ LocalPref obj2LocPref = null;
+ AsPath obj2Aspath = null;
+ Origin obj2Origin = null;
+ Med obj2Med = null;
+
+ @Override
+ public int compare(PathAttrNlriDetailsLocalRib pathNlriDetails1, PathAttrNlriDetailsLocalRib pathNlriDetails2) {
+ if (pathNlriDetails1 == null) {
+ return -1;
+ }
+ if (pathNlriDetails2 == null) {
+ return 1;
+ }
+ if (pathNlriDetails1.equals(pathNlriDetails2)) {
+ return 0;
+ }
+
+ List<BgpValueType> o1 = pathNlriDetails1.localRibNlridetails().pathAttributes();
+ List<BgpValueType> o2 = pathNlriDetails2.localRibNlridetails().pathAttributes();
+ ListIterator<BgpValueType> listIteratorObj1 = o1.listIterator();
+ ListIterator<BgpValueType> listIteratorObj2 = o2.listIterator();
+ storeAttr(listIteratorObj1, listIteratorObj2);
+
+ // prefer attribute with higher local preference
+ if (obj1LocPref != null || obj2LocPref != null && (obj1LocPref != null && !obj1LocPref.equals(obj2LocPref))) {
+ return compareLocalPref(obj1LocPref, obj2LocPref);
+ }
+
+ // prefer attribute with shortest Aspath
+ if (!obj1Aspath.equals(obj2Aspath)) {
+ Integer obj1Size = countASSize(obj1Aspath);
+ Integer obj2Size = countASSize(obj2Aspath);
+ if (obj1Size != obj2Size) {
+ return compareAsPath(obj1Size, obj2Size);
+ }
+ }
+
+ // prefer attribute with lowest origin type
+ if (!obj1Origin.equals(obj2Origin)) {
+ return compareOrigin(obj1Origin, obj2Origin);
+ }
+
+ // prefer attribute with lowest MED
+ if (obj1Med != null || obj2Med != null && (obj1Med != null && !obj1Med.equals(obj2Med))) {
+ return compareMed(obj1Med, obj2Med);
+ }
+
+ if ((pathNlriDetails1 != null || pathNlriDetails2 != null) && (pathNlriDetails1 != null && !pathNlriDetails1
+ .equals(pathNlriDetails2))) {
+ return comparePeerDetails(pathNlriDetails1, pathNlriDetails2);
+ }
+ return 0;
+ }
+
+ /**
+ * Compares local preference of two objects and returns object with higher preference.
+ *
+ * @param obj1LocPref local preference object1
+ * @param obj2LocPref local preference object2
+ * @return object with higher preference
+ */
+ int compareLocalPref(LocalPref obj1LocPref, LocalPref obj2LocPref) {
+ return ((Integer) (obj1LocPref.localPref())).compareTo((Integer) (obj2LocPref.localPref()));
+ }
+
+ /**
+ * Compares AsPath of two objects and returns object with shortest AsPath.
+ *
+ * @param obj1Size object1 AS count
+ * @param obj2Size object2 AS count
+ * @return
+ */
+ int compareAsPath(Integer obj1Size, Integer obj2Size) {
+ return obj1Size.compareTo(obj2Size);
+ }
+
+ /**
+ * Compare Origin of two objects and returns object with lowest origin value.
+ *
+ * @param obj1Origin Origin object1
+ * @param obj2Origin Origin object1
+ * @return object with lowest origin value
+ */
+ int compareOrigin(Origin obj1Origin, Origin obj2Origin) {
+ if (obj1Origin.origin() == ORIGINTYPE.IGP) {
+ return 1;
+ }
+ if (obj2Origin.origin() == ORIGINTYPE.IGP) {
+ return -1;
+ }
+ if (obj1Origin.origin() == ORIGINTYPE.EGP) {
+ return 1;
+ } else {
+ return -1;
+ }
+ }
+
+ /**
+ * Compare Med of two objects and returns object with lowestMed value.
+ *
+ * @param obj1Med Med object1
+ * @param obj2Med Med object2
+ * @return returns object with lowestMed value
+ */
+ int compareMed(Med obj1Med, Med obj2Med) {
+ return ((Integer) (obj2Med.med())).compareTo((Integer) (obj1Med.med()));
+ }
+
+ /**
+ * Compares EBGP over IBGP, BGP identifier value and peer address.
+ *
+ * @param pathNlriDetails1 PathAttrNlriDetailsLocalRib object1
+ * @param pathNlriDetails2 PathAttrNlriDetailsLocalRib object2
+ * @return object which as EBGP over IBGP, lowest BGP identifier value and lowest peer address
+ */
+ int comparePeerDetails(PathAttrNlriDetailsLocalRib pathNlriDetails1, PathAttrNlriDetailsLocalRib pathNlriDetails2) {
+ // consider EBGP over IBGP
+ if (pathNlriDetails1.isLocalRibIbgpSession() != pathNlriDetails2.isLocalRibIbgpSession()) {
+ if (pathNlriDetails1 == null || pathNlriDetails1.isLocalRibIbgpSession()) {
+ return -1;
+ }
+ if (pathNlriDetails2 == null || pathNlriDetails2.isLocalRibIbgpSession()) {
+ return 1;
+ }
+ }
+ // prefer lowest BGP identifier value.
+ if (pathNlriDetails1.localRibIdentifier() != pathNlriDetails2.localRibIdentifier()) {
+ return ((Integer) pathNlriDetails2.localRibIdentifier())
+ .compareTo(pathNlriDetails1.localRibIdentifier());
+ }
+ //prefer lowest peer address
+ if (pathNlriDetails1.localRibIpAddress() != pathNlriDetails2.localRibIpAddress()) {
+ return pathNlriDetails2.localRibIpAddress().compareTo(pathNlriDetails1.localRibIpAddress());
+ }
+ return 0;
+ }
+
+ /**
+ * Returns ASes count of AsPath attribute , if AS_SET is present then count as 1.
+ *
+ * @param aspath object of AsPath
+ * @return count of ASes
+ */
+ Integer countASSize(AsPath aspath) {
+ boolean isASSet = false;
+ int count = 0;
+ if (!aspath.asPathSet().isEmpty()) {
+ isASSet = true;
+ }
+ if (!aspath.asPathSeq().isEmpty()) {
+ count = aspath.asPathSeq().size();
+ }
+ return isASSet ? ++count : count;
+ }
+
+ /**
+ * Stores BGP basic attributes of two objects.
+ *
+ * @param listIteratorObj1 list iterator of object1
+ * @param listIteratorObj2 list iterator of object2
+ */
+ void storeAttr(ListIterator<BgpValueType> listIteratorObj1, ListIterator<BgpValueType> listIteratorObj2) {
+ while (listIteratorObj1.hasNext()) {
+ BgpValueType pathAttributeObj1 = listIteratorObj1.next();
+ switch (pathAttributeObj1.getType()) {
+ case LocalPref.LOCAL_PREF_TYPE:
+ obj1LocPref = (LocalPref) pathAttributeObj1;
+ break;
+ case AsPath.ASPATH_TYPE:
+ obj1Aspath = (AsPath) pathAttributeObj1;
+ break;
+ case Origin.ORIGIN_TYPE:
+ obj1Origin = (Origin) pathAttributeObj1;
+ break;
+ case Med.MED_TYPE:
+ obj1Med = (Med) pathAttributeObj1;
+ break;
+ default:
+ log.debug("Got other type, Not required: " + pathAttributeObj1.getType());
+ }
+ }
+ while (listIteratorObj2.hasNext()) {
+ BgpValueType pathAttributeObj2 = listIteratorObj2.next();
+ switch (pathAttributeObj2.getType()) {
+ case LocalPref.LOCAL_PREF_TYPE:
+ obj2LocPref = (LocalPref) pathAttributeObj2;
+ break;
+ case AsPath.ASPATH_TYPE:
+ obj2Aspath = (AsPath) pathAttributeObj2;
+ break;
+ case Origin.ORIGIN_TYPE:
+ obj2Origin = (Origin) pathAttributeObj2;
+ break;
+ case Med.MED_TYPE:
+ obj2Med = (Med) pathAttributeObj2;
+ break;
+ default:
+ log.debug("Got other type, Not required: " + pathAttributeObj2.getType());
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSessionInfoImpl.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSessionInfoImpl.java
new file mode 100755
index 00000000..33623dc2
--- /dev/null
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpSessionInfoImpl.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
+ * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+
+package org.onosproject.bgp.controller.impl;
+
+import org.onosproject.bgp.controller.BgpId;
+import org.onosproject.bgp.controller.BgpSessionInfo;
+import org.onosproject.bgpio.protocol.BgpVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class maintains BGP peer session info.
+ */
+public class BgpSessionInfoImpl implements BgpSessionInfo {
+
+ protected final Logger log = LoggerFactory.getLogger(BgpSessionInfoImpl.class);
+ private BgpId remoteBgpId;
+ private BgpVersion remoteBgpVersion;
+ private long remoteBgpASNum;
+ private short remoteBgpholdTime;
+ private int remoteBgpIdentifier;
+ private short negotiatedholdTime;
+ private boolean isIbgpSession;
+
+ /**
+ * Initialize session info.
+ *
+ *@param remoteBgpId remote peer id
+ *@param remoteBgpVersion remote peer version
+ *@param remoteBgpASNum remote peer AS number
+ *@param remoteBgpholdTime remote peer hold time
+ *@param remoteBgpIdentifier remote peer identifier
+ *@param negotiatedholdTime negotiated hold time
+ *@param isIbgpSession session type ibgp/ebgp
+ */
+ public BgpSessionInfoImpl(BgpId remoteBgpId, BgpVersion remoteBgpVersion, long remoteBgpASNum,
+ short remoteBgpholdTime, int remoteBgpIdentifier, short negotiatedholdTime,
+ boolean isIbgpSession) {
+ this.remoteBgpId = remoteBgpId;
+ this.remoteBgpVersion = remoteBgpVersion;
+ this.remoteBgpASNum = remoteBgpASNum;
+ this.remoteBgpholdTime = remoteBgpholdTime;
+ this.remoteBgpIdentifier = remoteBgpIdentifier;
+ this.negotiatedholdTime = negotiatedholdTime;
+ this.isIbgpSession = isIbgpSession;
+ }
+
+ @Override
+ public boolean isIbgpSession() {
+ return isIbgpSession;
+ }
+
+ @Override
+ public short negotiatedholdTime() {
+ return negotiatedholdTime;
+ }
+
+ @Override
+ public BgpId remoteBgpId() {
+ return remoteBgpId;
+ }
+
+ @Override
+ public BgpVersion remoteBgpVersion() {
+ return remoteBgpVersion;
+ }
+
+ @Override
+ public long remoteBgpASNum() {
+ return remoteBgpASNum;
+ }
+
+ @Override
+ public short remoteBgpHoldTime() {
+ return remoteBgpholdTime;
+ }
+
+ @Override
+ public int remoteBgpIdentifier() {
+ return remoteBgpIdentifier;
+ }
+}
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java
index 017c39e5..f02cee8a 100755
--- a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/Controller.java
@@ -26,15 +26,16 @@ import java.util.concurrent.Executors;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
-import org.onosproject.bgp.controller.BGPController;
-import org.onosproject.bgpio.protocol.BGPFactories;
-import org.onosproject.bgpio.protocol.BGPFactory;
-import org.onosproject.bgpio.protocol.BGPVersion;
+import org.onosproject.bgp.controller.BgpController;
+import org.onosproject.bgpio.protocol.BgpFactories;
+import org.onosproject.bgpio.protocol.BgpFactory;
+import org.onosproject.bgpio.protocol.BgpVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,12 +47,15 @@ public class Controller {
private static final Logger log = LoggerFactory.getLogger(Controller.class);
- private static final BGPFactory FACTORY4 = BGPFactories.getFactory(BGPVersion.BGP_4);
+ private static final BgpFactory FACTORY4 = BgpFactories.getFactory(BgpVersion.BGP_4);
private ChannelGroup cg;
+ public Channel serverChannel;
// Configuration options
private static final short BGP_PORT_NUM = 179;
+ private static final short PORT_NUM_ZERO = 0;
+ private static boolean isPortNumSet = false;
private final int workerThreads = 16;
private final int peerWorkerThreads = 16;
@@ -61,7 +65,7 @@ public class Controller {
private NioServerSocketChannelFactory serverExecFactory;
private NioClientSocketChannelFactory peerExecFactory;
private static ClientBootstrap peerBootstrap;
- private BGPController bgpController;
+ private BgpController bgpController;
// Perf. related configuration
private static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
@@ -71,7 +75,7 @@ public class Controller {
*
* @param bgpController bgp controller instance
*/
- public Controller(BGPController bgpController) {
+ public Controller(BgpController bgpController) {
this.bgpController = bgpController;
}
@@ -80,7 +84,7 @@ public class Controller {
*
* @return instance of factory version
*/
- static BGPFactory getBGPMessageFactory4() {
+ static BgpFactory getBgpMessageFactory4() {
return FACTORY4;
}
@@ -114,12 +118,13 @@ public class Controller {
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);
- ChannelPipelineFactory pfact = new BGPPipelineFactory(bgpController, true);
+ ChannelPipelineFactory pfact = new BgpPipelineFactory(bgpController, true);
bootstrap.setPipelineFactory(pfact);
InetSocketAddress sa = new InetSocketAddress(getBgpPortNum());
cg = new DefaultChannelGroup();
- cg.add(bootstrap.bind(sa));
+ serverChannel = bootstrap.bind(sa);
+ cg.add(serverChannel);
log.info("Listening for Peer connection on {}", sa);
} catch (Exception e) {
throw new RuntimeException(e);
@@ -234,6 +239,16 @@ public class Controller {
* @return port number
*/
public static short getBgpPortNum() {
+ if (isPortNumSet) {
+ return PORT_NUM_ZERO;
+ }
return BGP_PORT_NUM;
}
+
+ /**
+ * sets the isPortNumSet as true.
+ */
+ public void setBgpPortNum() {
+ isPortNumSet = true;
+ }
} \ No newline at end of file
diff --git a/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/VpnAdjRibIn.java b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/VpnAdjRibIn.java
new file mode 100644
index 00000000..8a9ea91c
--- /dev/null
+++ b/framework/src/onos/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/VpnAdjRibIn.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.bgp.controller.impl;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.onosproject.bgpio.protocol.BgpLSNlri;
+import org.onosproject.bgpio.protocol.linkstate.BgpLinkLSIdentifier;
+import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSIdentifier;
+import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
+import org.onosproject.bgpio.protocol.linkstate.BgpPrefixLSIdentifier;
+import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
+import org.onosproject.bgpio.types.RouteDistinguisher;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Implementation of Adj-RIB-In with VPN for each peer.
+ */
+public class VpnAdjRibIn {
+ private Map<BgpNodeLSIdentifier, PathAttrNlriDetails> nodeTree = new TreeMap<>();
+ private Map<BgpLinkLSIdentifier, PathAttrNlriDetails> linkTree = new TreeMap<>();
+ private Map<BgpPrefixLSIdentifier, PathAttrNlriDetails> prefixTree = new TreeMap<>();
+
+ private Map<RouteDistinguisher, Map<BgpNodeLSIdentifier, PathAttrNlriDetails>> vpnNodeTree
+ = new TreeMap<>();
+ private Map<RouteDistinguisher, Map<BgpLinkLSIdentifier, PathAttrNlriDetails>> vpnLinkTree
+ = new TreeMap<>();
+ private Map<RouteDistinguisher, Map<BgpPrefixLSIdentifier, PathAttrNlriDetails>> vpnPrefixTree
+ = new TreeMap<>();
+ /**
+ * Returns the adjacency node.
+ *
+ * @return node adjacency RIB node
+ */
+ public Map<BgpNodeLSIdentifier, PathAttrNlriDetails> nodeTree() {
+ return nodeTree;
+ }
+
+ /**
+ * Returns the adjacency link.
+ *
+ * @return link adjacency RIB node
+ */
+ public Map<BgpLinkLSIdentifier, PathAttrNlriDetails> linkTree() {
+ return linkTree;
+ }
+
+ /**
+ * Returns the adjacency prefix.
+ *
+ * @return prefix adjacency RIB node
+ */
+ public Map<BgpPrefixLSIdentifier, PathAttrNlriDetails> prefixTree() {
+ return prefixTree;
+ }
+
+ /**
+ * Returns the adjacency vpnNode.
+ *
+ * @return vpnNode adjacency RIB node
+ */
+ public Map<RouteDistinguisher, Map<BgpNodeLSIdentifier, PathAttrNlriDetails>> vpnNodeTree() {
+ return vpnNodeTree;
+ }
+
+ /**
+ * Returns the adjacency vpnLink.
+ *
+ * @return vpnLink adjacency RIB node
+ */
+ public Map<RouteDistinguisher, Map<BgpLinkLSIdentifier, PathAttrNlriDetails>> vpnLinkTree() {
+ return vpnLinkTree;
+ }
+
+ /**
+ * Returns the adjacency vpnPrefix.
+ *
+ * @return vpnPrefix adjacency RIB node
+ */
+ public Map<RouteDistinguisher, Map<BgpPrefixLSIdentifier, PathAttrNlriDetails>> vpnPrefixTree() {
+ return vpnPrefixTree;
+ }
+
+ /**
+ * Update vpn nlri identifier into the tree if nlri identifier exists in tree otherwise add this to the tree.
+ *
+ * @param nlri NLRI info
+ * @param details has pathattribute , protocolID and identifier
+ */
+ public void add(BgpLSNlri nlri, PathAttrNlriDetails details) {
+ if (nlri instanceof BgpNodeLSNlriVer4) {
+ BgpNodeLSIdentifier nodeLSIdentifier = ((BgpNodeLSNlriVer4) nlri).getLocalNodeDescriptors();
+ if (nodeTree.containsKey(nodeLSIdentifier)) {
+ nodeTree.replace(nodeLSIdentifier, details);
+ } else {
+ nodeTree.put(nodeLSIdentifier, details);
+ }
+ } else if (nlri instanceof BgpLinkLsNlriVer4) {
+ BgpLinkLSIdentifier linkLSIdentifier = ((BgpLinkLsNlriVer4) nlri).getLinkIdentifier();
+ if (linkTree.containsKey(linkLSIdentifier)) {
+ linkTree.replace(linkLSIdentifier, details);
+ } else {
+ linkTree.put(linkLSIdentifier, details);
+ }
+ } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) {
+ BgpPrefixLSIdentifier prefixIdentifier = ((BgpPrefixIPv4LSNlriVer4) nlri).getPrefixIdentifier();
+ if (prefixTree.containsKey(prefixIdentifier)) {
+ prefixTree.replace(prefixIdentifier, details);
+ } else {
+ prefixTree.put(prefixIdentifier, details);
+ }
+ }
+ }
+
+ /**
+ * Update nlri identifier mapped with route distinguisher if it exists in tree otherwise add nlri infomation mapped
+ * to respective route distinguisher in tree.
+ *
+ * @param nlri NLRI info
+ * @param details has pathattribute , protocolID and identifier
+ * @param routeDistinguisher unique for for each vpn
+ */
+ public void addVpn(BgpLSNlri nlri, PathAttrNlriDetails details, RouteDistinguisher routeDistinguisher) {
+ add(nlri, details);
+ if (nlri instanceof BgpNodeLSNlriVer4) {
+ if (!vpnNodeTree.containsKey(routeDistinguisher)) {
+ vpnNodeTree.put(routeDistinguisher, nodeTree);
+ }
+ } else if (nlri instanceof BgpLinkLsNlriVer4) {
+ if (!vpnLinkTree.containsKey(routeDistinguisher)) {
+ vpnLinkTree.put(routeDistinguisher, linkTree);
+ }
+ } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) {
+ if (!vpnPrefixTree.containsKey(routeDistinguisher)) {
+ vpnPrefixTree.put(routeDistinguisher, prefixTree);
+ }
+ }
+ }
+
+ /**
+ * Removes vpn nlri identifier mapped to route distinguisher if it exists in tree.
+ *
+ * @param nlri NLRI Info
+ * @param routeDistinguisher unique for for each vpn
+ */
+ public void removeVpn(BgpLSNlri nlri, RouteDistinguisher routeDistinguisher) {
+ if (nlri instanceof BgpNodeLSNlriVer4) {
+ if (vpnNodeTree.containsKey(routeDistinguisher)) {
+ BgpNodeLSIdentifier nodeLSIdentifier = ((BgpNodeLSNlriVer4) nlri).getLocalNodeDescriptors();
+ if (nodeTree.containsKey(nodeLSIdentifier)) {
+ nodeTree.remove(nodeLSIdentifier);
+ }
+ if ((vpnNodeTree.get(routeDistinguisher)).isEmpty()) {
+ vpnNodeTree.remove(routeDistinguisher);
+ }
+ }
+ } else if (nlri instanceof BgpLinkLsNlriVer4) {
+ if (vpnLinkTree.containsKey(routeDistinguisher)) {
+ BgpLinkLSIdentifier linkLSIdentifier = ((BgpLinkLsNlriVer4) nlri).getLinkIdentifier();
+ if (linkTree.containsKey(linkLSIdentifier)) {
+ linkTree.remove(linkLSIdentifier);
+ }
+ if ((vpnLinkTree.get(routeDistinguisher)).isEmpty()) {
+ vpnLinkTree.remove(routeDistinguisher);
+ }
+ }
+ } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) {
+ if (vpnPrefixTree.containsKey(routeDistinguisher)) {
+ BgpPrefixLSIdentifier prefixIdentifier = ((BgpPrefixIPv4LSNlriVer4) nlri).getPrefixIdentifier();
+ if (prefixTree.containsKey(prefixIdentifier)) {
+ prefixTree.remove(prefixIdentifier);
+ }
+ if ((vpnPrefixTree.get(routeDistinguisher)).isEmpty()) {
+ vpnPrefixTree.remove(routeDistinguisher);
+ }
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(getClass())
+ .omitNullValues().add("nodeTree", nodeTree)
+ .add("linkTree", linkTree)
+ .add("prefixTree", prefixTree)
+ .add("vpnNodeTree", vpnNodeTree)
+ .add("vpnLinkTree", vpnLinkTree)
+ .add("vpnPrefixTree", vpnPrefixTree)
+ .toString();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpControllerImplTest.java b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpControllerImplTest.java
new file mode 100755
index 00000000..36b1d6fc
--- /dev/null
+++ b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpControllerImplTest.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgp;
+
+import com.google.common.net.InetAddresses;
+import org.jboss.netty.bootstrap.ClientBootstrap;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelFactory;
+import org.jboss.netty.channel.ChannelPipeline;
+import org.jboss.netty.channel.ChannelPipelineFactory;
+import org.jboss.netty.channel.Channels;
+import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertThat;
+
+import org.onlab.junit.TestUtils;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.LinkedList;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.onosproject.bgp.controller.BgpCfg;
+import org.onosproject.bgp.controller.impl.BgpControllerImpl;
+import org.onosproject.bgpio.types.BgpValueType;
+import org.onosproject.bgpio.types.FourOctetAsNumCapabilityTlv;
+import org.onosproject.bgpio.types.MultiProtocolExtnCapabilityTlv;
+
+/**
+ * Test case for BGPControllerImpl.
+ */
+public class BgpControllerImplTest {
+
+ protected static final Logger log = LoggerFactory
+ .getLogger(BgpControllerImplTest.class);
+
+ private static final String IP_LOOPBACK_ID1 = "127.0.0.1";
+
+ private static final int MESSAGE_TIMEOUT_MS = 3000;
+ public byte version;
+ public short asNumber;
+ public short holdTime;
+ public int bgpId = InetAddresses.coerceToInteger(InetAddresses.forString(IP_LOOPBACK_ID1));
+ public boolean isLargeAsCapabilitySet = false;
+ public LinkedList<BgpValueType> capabilityTlv = new LinkedList<>();
+
+ @Before
+ public void setUp() throws Exception {
+ peer1 = new BgpPeerTest(version, asNumber,
+ holdTime, bgpId, isLargeAsCapabilitySet,
+ capabilityTlv);
+
+ bgpControllerImpl = new BgpControllerImpl();
+
+ // NOTE: We use port 0 to bind on any available port
+ bgpControllerImpl.controller().setBgpPortNum();
+ bgpControllerImpl.activate();
+
+ Channel serverChannel = TestUtils.getField(bgpControllerImpl.controller(),
+ "serverChannel");
+ SocketAddress socketAddress = serverChannel.getLocalAddress();
+ InetSocketAddress inetSocketAddress =
+ (InetSocketAddress) socketAddress;
+ InetAddress connectToAddress = InetAddresses.forString("127.0.0.1");
+ connectToSocket = new InetSocketAddress(connectToAddress,
+ inetSocketAddress.getPort());
+
+ bgpControllerImpl.getConfig().setRouterId("1.1.1.1");
+ bgpControllerImpl.getConfig().setAsNumber(200);
+ bgpControllerImpl.getConfig().setHoldTime((short) 120);
+ bgpControllerImpl.getConfig().setState(BgpCfg.State.IP_AS_CONFIGURED);
+
+ bgpControllerImpl.getConfig().addPeer("127.0.0.1", 200);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ bgpControllerImpl.deactivate();
+ bgpControllerImpl = null;
+ }
+
+ private BgpControllerImpl bgpControllerImpl;
+
+ BgpPeerTest peer1;
+
+ // The socket that the remote peers should connect to
+ private InetSocketAddress connectToSocket;
+
+ @Test
+ public void bgpOpenMessageTest1() throws InterruptedException {
+ peer1.peerChannelHandler.asNumber = 200;
+ peer1.peerChannelHandler.version = 4;
+ peer1.peerChannelHandler.holdTime = 120;
+ peer1.connect(connectToSocket);
+ boolean result;
+ result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+ result = peer1.peerFrameDecoder.receivedKeepaliveMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+ }
+
+ @Test
+ public void bgpOpenMessageTest2() throws InterruptedException {
+ // Open message with as number which is not configured at peer
+ peer1.peerChannelHandler.asNumber = 500;
+ peer1.peerChannelHandler.version = 4;
+ peer1.peerChannelHandler.holdTime = 120;
+ peer1.connect(connectToSocket);
+
+ boolean result;
+ result = peer1.peerFrameDecoder.receivedNotificationMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+ }
+
+ @Test
+ public void bgpOpenMessageTest3() throws InterruptedException {
+ // Open message with invalid hold time value
+ peer1.peerChannelHandler.asNumber = 200;
+ peer1.peerChannelHandler.version = 4;
+ peer1.peerChannelHandler.holdTime = 1;
+ peer1.connect(connectToSocket);
+
+ boolean result;
+ result = peer1.peerFrameDecoder.receivedNotificationMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+ }
+
+ @Test
+ public void bgpOpenMessageTest4() throws InterruptedException {
+ // Open message with invalid as number
+ peer1.peerChannelHandler.asNumber = 200;
+ peer1.peerChannelHandler.version = 4;
+ peer1.peerChannelHandler.holdTime = 120;
+ peer1.peerChannelHandler.isLargeAsCapabilitySet = true;
+ BgpValueType tempTlv = new FourOctetAsNumCapabilityTlv(766545);
+ peer1.peerChannelHandler.capabilityTlv.add(tempTlv);
+ peer1.connect(connectToSocket);
+
+ boolean result;
+ result = peer1.peerFrameDecoder.receivedNotificationMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+ }
+
+ @Test
+ public void bgpOpenMessageTest5() throws InterruptedException {
+ // Open message with LS capability
+ short afi = 16388;
+ byte res = 0;
+ byte safi = 71;
+ peer1.peerChannelHandler.asNumber = 200;
+ peer1.peerChannelHandler.version = 4;
+ peer1.peerChannelHandler.holdTime = 120;
+ bgpControllerImpl.getConfig().setLsCapability(true);
+ BgpValueType tempTlv1 = new MultiProtocolExtnCapabilityTlv(afi, res, safi);
+ peer1.peerChannelHandler.capabilityTlv.add(tempTlv1);
+ peer1.connect(connectToSocket);
+
+ boolean result;
+ result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+ result = peer1.peerFrameDecoder.receivedKeepaliveMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+ }
+
+ @Test
+ public void bgpOpenMessageTest6() throws InterruptedException {
+ // Open message with as4 capability
+ peer1.peerChannelHandler.asNumber = 200;
+ peer1.peerChannelHandler.version = 4;
+ peer1.peerChannelHandler.holdTime = 120;
+ peer1.peerChannelHandler.isLargeAsCapabilitySet = true;
+ bgpControllerImpl.getConfig().setLargeASCapability(true);
+ BgpValueType tempTlv = new FourOctetAsNumCapabilityTlv(200);
+ peer1.peerChannelHandler.capabilityTlv.add(tempTlv);
+ peer1.connect(connectToSocket);
+
+ boolean result;
+ result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+ result = peer1.peerFrameDecoder.receivedKeepaliveMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+
+ result = peer1.peerFrameDecoder.receivedKeepaliveMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+ }
+
+ @Test
+ public void bgpOpenMessageTest7() throws InterruptedException {
+ // Open message with both LS capability and as4 capability
+ short afi = 16388;
+ byte res = 0;
+ byte safi = 71;
+ peer1.peerChannelHandler.asNumber = 200;
+ peer1.peerChannelHandler.version = 4;
+ peer1.peerChannelHandler.holdTime = 120;
+
+ peer1.peerChannelHandler.isLargeAsCapabilitySet = true;
+ bgpControllerImpl.getConfig().setLargeASCapability(true);
+ BgpValueType tempTlv = new FourOctetAsNumCapabilityTlv(200);
+ peer1.peerChannelHandler.capabilityTlv.add(tempTlv);
+
+ bgpControllerImpl.getConfig().setLsCapability(true);
+ BgpValueType tempTlv1 = new MultiProtocolExtnCapabilityTlv(afi, res, safi);
+ peer1.peerChannelHandler.capabilityTlv.add(tempTlv1);
+ peer1.connect(connectToSocket);
+
+ boolean result;
+ result = peer1.peerFrameDecoder.receivedOpenMessageLatch.await(
+ MESSAGE_TIMEOUT_MS,
+ TimeUnit.MILLISECONDS);
+ assertThat(result, is(true));
+ }
+
+ /**
+ * A class to capture the state for a BGP peer.
+ */
+ private final class BgpPeerTest {
+ private ClientBootstrap peerBootstrap;
+ private BgpPeerFrameDecoderTest peerFrameDecoder =
+ new BgpPeerFrameDecoderTest();
+ private BgpPeerChannelHandlerTest peerChannelHandler;
+
+ private BgpPeerTest(byte version, short asNumber,
+ short holdTime, int bgpId, boolean isLargeAsCapabilitySet,
+ LinkedList<BgpValueType> capabilityTlv) {
+ peerChannelHandler = new BgpPeerChannelHandlerTest(version,
+ asNumber, holdTime, bgpId, isLargeAsCapabilitySet, capabilityTlv);
+ }
+
+ /**
+ * Starts the BGP peer.
+ *
+ * @param connectToSocket the socket to connect to
+ */
+ private void connect(InetSocketAddress connectToSocket)
+ throws InterruptedException {
+
+ ChannelFactory channelFactory =
+ new NioClientSocketChannelFactory(
+ Executors.newCachedThreadPool(),
+ Executors.newCachedThreadPool());
+ ChannelPipelineFactory pipelineFactory = () -> {
+ ChannelPipeline pipeline = Channels.pipeline();
+ pipeline.addLast("BgpPeerFrameDecoderTest",
+ peerFrameDecoder);
+ pipeline.addLast("BgpPeerChannelHandlerTest",
+ peerChannelHandler);
+ return pipeline;
+ };
+
+ peerBootstrap = new ClientBootstrap(channelFactory);
+ peerBootstrap.setOption("child.keepAlive", true);
+ peerBootstrap.setOption("child.tcpNoDelay", true);
+ peerBootstrap.setPipelineFactory(pipelineFactory);
+ peerBootstrap.connect(connectToSocket);
+ }
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerChannelHandlerTest.java b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerChannelHandlerTest.java
new file mode 100755
index 00000000..26ed36d8
--- /dev/null
+++ b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerChannelHandlerTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgp;
+
+import java.util.LinkedList;
+import java.util.concurrent.TimeUnit;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.channel.ChannelStateEvent;
+import org.jboss.netty.channel.SimpleChannelHandler;
+import org.onosproject.bgpio.protocol.ver4.BgpKeepaliveMsgVer4;
+import org.onosproject.bgpio.protocol.ver4.BgpOpenMsgVer4;
+import org.onosproject.bgpio.types.BgpHeader;
+import org.onosproject.bgpio.types.BgpValueType;
+
+public class BgpPeerChannelHandlerTest extends SimpleChannelHandler {
+ public static final int OPEN_MSG_MINIMUM_LENGTH = 29;
+ public static final byte[] MARKER = new byte[] {(byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff,
+ (byte) 0xff, (byte) 0xff};
+ public static final BgpHeader DEFAULT_OPEN_HEADER = new BgpHeader(MARKER,
+ (short) OPEN_MSG_MINIMUM_LENGTH, (byte) 0X01);
+ LinkedList<BgpValueType> capabilityTlv = new LinkedList<>();
+ public byte version;
+ public short asNumber;
+ public short holdTime;
+ public int bgpId;
+ public boolean isLargeAsCapabilitySet;
+
+ final BgpOpenMsgVer4 openMessage = new BgpOpenMsgVer4();
+ ChannelHandlerContext savedCtx;
+
+ /**
+ * Constructor to initialize all variables of BGP Open message.
+ *
+ * @param version BGP version in open message
+ * @param asNumber AS number in open message
+ * @param holdTime hold time in open message
+ * @param bgpId BGP identifier in open message
+ * @param capabilityTlv capabilities in open message
+ */
+ public BgpPeerChannelHandlerTest(byte version,
+ short asNumber,
+ short holdTime,
+ int bgpId,
+ boolean isLargeAsCapabilitySet,
+ LinkedList<BgpValueType> capabilityTlv) {
+ this.version = version;
+ this.asNumber = asNumber;
+ this.holdTime = holdTime;
+ this.bgpId = bgpId;
+ this.isLargeAsCapabilitySet = isLargeAsCapabilitySet;
+ this.capabilityTlv = capabilityTlv;
+ }
+
+ /**
+ * closes the channel.
+ */
+ void closeChannel() {
+ savedCtx.getChannel().close();
+ }
+
+ @Override
+ public void channelConnected(ChannelHandlerContext ctx,
+ ChannelStateEvent channelEvent) throws InterruptedException {
+ this.savedCtx = ctx;
+
+ BgpOpenMsgVer4 openMsg = new BgpOpenMsgVer4(DEFAULT_OPEN_HEADER,
+ this.version,
+ this.asNumber,
+ this.holdTime,
+ this.bgpId,
+ this.capabilityTlv);
+ ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+ openMsg.writeTo(buffer);
+ ctx.getChannel().write(buffer);
+
+ TimeUnit.MILLISECONDS.sleep(100);
+
+ BgpKeepaliveMsgVer4 keepaliveMsg = new BgpKeepaliveMsgVer4();
+ ChannelBuffer buffer1 = ChannelBuffers.dynamicBuffer();
+ keepaliveMsg.writeTo(buffer1);
+ ctx.getChannel().write(buffer1);
+ }
+
+ @Override
+ public void channelDisconnected(ChannelHandlerContext ctx,
+ ChannelStateEvent channelEvent) {
+ //Do Nothing
+ }
+}
diff --git a/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerFrameDecoderTest.java b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerFrameDecoderTest.java
new file mode 100755
index 00000000..7767053f
--- /dev/null
+++ b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/bgp/BgpPeerFrameDecoderTest.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.bgp;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.ChannelHandlerContext;
+import org.jboss.netty.handler.codec.frame.FrameDecoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Class to decode the message received.
+ */
+public class BgpPeerFrameDecoderTest extends FrameDecoder {
+ static final byte OPEN_MSG_TYPE = 0x1;
+ static final byte KEEPALIVE_MSG_TYPE = 0x4;
+ static final byte UPDATE_MSG_TYPE = 0x2;
+ static final byte NOTIFICATION_MSG_TYPE = 0x3;
+ static final int MINIMUM_COMMON_HEADER_LENGTH = 19;
+ static final int MINIMUM_OPEN_MSG_LENGTH = 29;
+ static final int MINIMUM_HEADER_MARKER_LENGTH = 16;
+ static final int HEADER_AND_MSG_LEN = 18;
+
+ protected static final Logger log = LoggerFactory
+ .getLogger(BgpPeerFrameDecoderTest.class);
+ final CountDownLatch receivedOpenMessageLatch = new CountDownLatch(1);
+ final CountDownLatch receivedKeepaliveMessageLatch = new CountDownLatch(1);
+ final CountDownLatch receivedNotificationMessageLatch = new CountDownLatch(1);
+
+ @Override
+ protected Object decode(ChannelHandlerContext ctx,
+ Channel channel,
+ ChannelBuffer cb) throws Exception {
+
+ if (cb.readableBytes() < MINIMUM_COMMON_HEADER_LENGTH) {
+ log.debug("Error: Packet length is less then minimum length");
+ return null;
+ }
+
+ byte[] marker = new byte[MINIMUM_HEADER_MARKER_LENGTH];
+ cb.readBytes(marker);
+ for (int i = 0; i < marker.length; i++) {
+ if (marker[i] != (byte) 0xff) {
+ log.debug("Error: Marker must be set all ones");
+ ctx.getChannel().close();
+ return null;
+ }
+ }
+
+ short length = cb.readShort();
+ if (length < MINIMUM_COMMON_HEADER_LENGTH) {
+ log.debug("Error: Bad message length");
+ ctx.getChannel().close();
+ return null;
+ }
+
+ if (length != (cb.readableBytes() + HEADER_AND_MSG_LEN)) {
+ log.debug("Error: Bad message length");
+ ctx.getChannel().close();
+ return null;
+ }
+
+ byte type = cb.readByte();
+ int len = length - MINIMUM_COMMON_HEADER_LENGTH;
+
+ ChannelBuffer message = cb.readBytes(len);
+
+ switch (type) {
+ case OPEN_MSG_TYPE:
+ processBgpOpen(ctx, message);
+ break;
+ case UPDATE_MSG_TYPE:
+ break;
+ case NOTIFICATION_MSG_TYPE:
+ processBgpNotification(ctx, message);
+ break;
+ case KEEPALIVE_MSG_TYPE:
+ processBgpKeepalive(ctx, message);
+ break;
+ default:
+ ctx.getChannel().close();
+ return null;
+ }
+
+ return null;
+ }
+
+ /**
+ * Processes BGP open message.
+ *
+ * @param ctx Channel handler context
+ * @param message open message
+ */
+ private void processBgpOpen(ChannelHandlerContext ctx,
+ ChannelBuffer message) {
+ int minLength =
+ MINIMUM_OPEN_MSG_LENGTH - MINIMUM_COMMON_HEADER_LENGTH;
+ if (message.readableBytes() < minLength) {
+ log.debug("Error: Bad message length");
+ ctx.getChannel().close();
+ return;
+ }
+
+ message.readByte(); // read version
+ message.readShort(); // read AS number
+ message.readShort(); // read Hold timer
+ message.readInt(); // read BGP Identifier
+ // Optional Parameters
+ int optParamLen = message.readUnsignedByte();
+ if (message.readableBytes() < optParamLen) {
+ log.debug("Error: Bad message length");
+ ctx.getChannel().close();
+ return;
+ }
+ message.readBytes(optParamLen);
+
+ // Open message received
+ receivedOpenMessageLatch.countDown();
+ }
+
+ /**
+ * Processes BGP keepalive message.
+ *
+ * @param ctx Channel handler context
+ * @param message keepalive message
+ */
+ private void processBgpKeepalive(ChannelHandlerContext ctx,
+ ChannelBuffer message) {
+
+ // Keepalive message received
+ receivedKeepaliveMessageLatch.countDown();
+ }
+
+ /**
+ * Processes BGP notification message.
+ *
+ * @param ctx Channel handler context
+ * @param message notification message
+ */
+ private void processBgpNotification(ChannelHandlerContext ctx,
+ ChannelBuffer message) {
+ byte[] data;
+ message.readByte(); //read error code
+ message.readByte(); // read error sub code
+ if (message.readableBytes() > 0) {
+ data = new byte[message.readableBytes()];
+ message.readBytes(data, 0, message.readableBytes());
+ }
+
+ // Notification message received
+ receivedNotificationMessageLatch.countDown();
+ }
+} \ No newline at end of file
diff --git a/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/controller/impl/BgpSelectionAlgoTest.java b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/controller/impl/BgpSelectionAlgoTest.java
new file mode 100644
index 00000000..7c0fa417
--- /dev/null
+++ b/framework/src/onos/bgp/ctl/src/test/java/org/onosproject/controller/impl/BgpSelectionAlgoTest.java
@@ -0,0 +1,595 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.controller.impl;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+
+import java.util.LinkedList;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.jboss.netty.buffer.ChannelBuffers;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpAddress.Version;
+import org.onosproject.bgpio.exceptions.BgpParseException;
+import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4.ProtocolType;
+import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
+import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetailsLocalRib;
+import org.onosproject.bgpio.types.AsPath;
+import org.onosproject.bgpio.types.BgpValueType;
+import org.onosproject.bgpio.types.LocalPref;
+import org.onosproject.bgpio.types.Med;
+import org.onosproject.bgpio.types.Origin;
+import org.onosproject.bgp.controller.impl.BgpSelectionAlgo;
+
+/**
+ * Test cases for BGP Selection Algorithm.
+ */
+public class BgpSelectionAlgoTest {
+
+ /**
+ * firstPathAttribute and secondPathAttribute has same AS count and firstPathAttribute
+ * has shortest Origin value than secondPathAttribute.
+ */
+ @Test
+ public void selectionAlgoTest1() throws BgpParseException {
+ byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a };
+ LinkedList<BgpValueType> pathAttributes1 = new LinkedList<>();
+ BgpValueType pathAttribute1;
+ //origin with IGP
+ byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 };
+ ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute1 = Origin.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+ //AsPath with AS_SEQ with one AS
+ byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xea };
+ buffer.writeBytes(asPath);
+ pathAttribute1 = AsPath.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+
+ IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ int bgpId = 168427777;
+ short locRIBASNum = 100;
+ boolean isIbgp = false;
+ PathAttrNlriDetails attrList1 = new PathAttrNlriDetails();
+ attrList1.setIdentifier(0);
+ attrList1.setPathAttribute(pathAttributes1);
+ attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE);
+ PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList1);
+
+ peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b };
+ LinkedList<BgpValueType> pathAttributes2 = new LinkedList<>();
+ BgpValueType pathAttribute2;
+ //origin with INCOMPLETE
+ origin = new byte[] {0x40, 0x01, 0x01, 0x02 };
+ buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute2 = Origin.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+ //AsPath with AS_SEQ with one AS
+ asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute2 = AsPath.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+
+ ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ bgpId = 536936448;
+ locRIBASNum = 200;
+ isIbgp = true;
+ PathAttrNlriDetails attrList2 = new PathAttrNlriDetails();
+ attrList2.setIdentifier(0);
+ attrList2.setPathAttribute(pathAttributes2);
+ attrList2.setProtocolID(ProtocolType.OSPF_V2);
+ PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList2);
+ BgpSelectionAlgo algo = new BgpSelectionAlgo();
+ int result = algo.compare(list1, list2);
+ assertThat(result, is(1));
+ }
+
+ /**
+ * firstPathAttribute has 1 AS count and secondPathAttribute has 2 AS count
+ * and firstPathAttribute has shortest Origin value than secondPathAttribute.
+ */
+ @Test
+ public void selectionAlgoTest2() throws BgpParseException {
+
+ byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a };
+ LinkedList<BgpValueType> pathAttributes1 = new LinkedList<>();
+ BgpValueType pathAttribute1;
+ byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 };
+ ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute1 = Origin.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+ byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute1 = AsPath.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+
+ IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ int bgpId = 168427777;
+ short locRIBASNum = 100;
+ boolean isIbgp = false;
+ PathAttrNlriDetails attrList1 = new PathAttrNlriDetails();
+ attrList1.setIdentifier(0);
+ attrList1.setPathAttribute(pathAttributes1);
+ attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE);
+ PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList1);
+
+ peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b };
+ LinkedList<BgpValueType> pathAttributes2 = new LinkedList<>();
+ BgpValueType pathAttribute2;
+ origin = new byte[] {0x40, 0x01, 0x01, 0x02 };
+ buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute2 = Origin.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+ asPath = new byte[] {0x40, 0x02, 0x08, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xea, 0x02, 0x01, (byte) 0xfd, (byte) 0xea };
+ buffer.writeBytes(asPath);
+ pathAttribute2 = AsPath.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+
+ ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ bgpId = 536936448;
+ locRIBASNum = 200;
+ isIbgp = true;
+ PathAttrNlriDetails attrList2 = new PathAttrNlriDetails();
+ attrList2.setIdentifier(0);
+ attrList2.setPathAttribute(pathAttributes2);
+ attrList2.setProtocolID(ProtocolType.OSPF_V2);
+ PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList2);
+ BgpSelectionAlgo algo = new BgpSelectionAlgo();
+ int result = algo.compare(list1, list2);
+ assertThat(result, is(-1));
+ }
+
+ /**
+ * firstPathAttribute and secondPathAttribute has same AS value
+ * and firstPathAttribute has shortest Origin value than secondPathAttribute.
+ */
+ @Test
+ public void selectionAlgoTest3() throws BgpParseException {
+
+ byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a };
+ LinkedList<BgpValueType> pathAttributes1 = new LinkedList<>();
+ BgpValueType pathAttribute1;
+ byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 };
+ ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute1 = Origin.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+ byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute1 = AsPath.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+
+ IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ int bgpId = 168427777;
+ short locRIBASNum = 100;
+ boolean isIbgp = false;
+ PathAttrNlriDetails attrList1 = new PathAttrNlriDetails();
+ attrList1.setIdentifier(0);
+ attrList1.setPathAttribute(pathAttributes1);
+ attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE);
+ PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList1);
+
+ peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b };
+ LinkedList<BgpValueType> pathAttributes2 = new LinkedList<>();
+ BgpValueType pathAttribute2;
+ origin = new byte[] {0x40, 0x01, 0x01, 0x02 };
+ buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute2 = Origin.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+ asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute2 = AsPath.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+
+ ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ bgpId = 536936448;
+ locRIBASNum = 200;
+ isIbgp = true;
+ PathAttrNlriDetails attrList2 = new PathAttrNlriDetails();
+ attrList2.setIdentifier(0);
+ attrList2.setPathAttribute(pathAttributes2);
+ attrList2.setProtocolID(ProtocolType.OSPF_V2);
+ PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList2);
+ BgpSelectionAlgo algo = new BgpSelectionAlgo();
+ int result = algo.compare(list1, list2);
+ assertThat(result, is(1));
+ }
+
+ /**
+ * firstPathAttribute has lowest med than secondPathAttribute.
+ */
+ @Test
+ public void selectionAlgoTest4() throws BgpParseException {
+
+ byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a };
+ LinkedList<BgpValueType> pathAttributes1 = new LinkedList<>();
+ BgpValueType pathAttribute1;
+ byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 };
+ ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute1 = Origin.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+ byte[] med = new byte[] {(byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00,
+ 0x00 };
+ buffer.writeBytes(med);
+ pathAttribute1 = Med.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+ byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute1 = AsPath.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+
+ IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ int bgpId = 168427777;
+ short locRIBASNum = 100;
+ boolean isIbgp = false;
+ PathAttrNlriDetails attrList1 = new PathAttrNlriDetails();
+ attrList1.setIdentifier(0);
+ attrList1.setPathAttribute(pathAttributes1);
+ attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE);
+ PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList1);
+
+ peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b };
+ LinkedList<BgpValueType> pathAttributes2 = new LinkedList<>();
+ BgpValueType pathAttribute2;
+ origin = new byte[] {0x40, 0x01, 0x01, 0x02 };
+ buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute2 = Origin.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+ med = new byte[] {(byte) 0x80, 0x04, 0x04, 0x00, 0x00, 0x00, 0x01 };
+ buffer.writeBytes(med);
+ pathAttribute2 = Med.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+ asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute2 = AsPath.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+
+ ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ bgpId = 536936448;
+ locRIBASNum = 200;
+ isIbgp = true;
+ PathAttrNlriDetails attrList2 = new PathAttrNlriDetails();
+ attrList2.setIdentifier(0);
+ attrList2.setPathAttribute(pathAttributes2);
+ attrList2.setProtocolID(ProtocolType.OSPF_V2);
+ PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList2);
+ BgpSelectionAlgo algo = new BgpSelectionAlgo();
+ int result = algo.compare(list1, list2);
+ assertThat(result, is(1));
+ }
+
+ /**
+ * secondPathAttribute has higher local preference than firstPathAttribute.
+ */
+ @Test
+ public void selectionAlgoTest5() throws BgpParseException {
+
+ byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a };
+ LinkedList<BgpValueType> pathAttributes1 = new LinkedList<>();
+ BgpValueType pathAttribute1;
+ byte[] locPref = new byte[] {(byte) 0x00, 0x05, 0x04, 0x00, 0x00,
+ 0x00, 0x01 };
+ ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(locPref);
+ pathAttribute1 = LocalPref.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+
+ IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ int bgpId = 168427777;
+ short locRIBASNum = 100;
+ boolean isIbgp = false;
+ PathAttrNlriDetails attrList1 = new PathAttrNlriDetails();
+ attrList1.setIdentifier(0);
+ attrList1.setPathAttribute(pathAttributes1);
+ attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE);
+ PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList1);
+
+ peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b };
+ LinkedList<BgpValueType> pathAttributes2 = new LinkedList<>();
+ BgpValueType pathAttribute2;
+ locPref = new byte[] {(byte) 0x00, 0x05, 0x04, 0x00, 0x00, 0x00, 0x0a };
+ buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(locPref);
+ pathAttribute2 = LocalPref.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+
+ ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ bgpId = 536936448;
+ locRIBASNum = 200;
+ isIbgp = true;
+ PathAttrNlriDetails attrList2 = new PathAttrNlriDetails();
+ attrList2.setIdentifier(0);
+ attrList2.setPathAttribute(pathAttributes2);
+ attrList2.setProtocolID(ProtocolType.OSPF_V2);
+ PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList2);
+ BgpSelectionAlgo algo = new BgpSelectionAlgo();
+ int result = algo.compare(list1, list2);
+ assertThat(result, is(-1));
+ }
+
+ /**
+ * secondPathAttribute is EBGP than firstPathAttribute is IBGP.
+ */
+ @Test
+ public void selectionAlgoTest6() throws BgpParseException {
+
+ byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a };
+ LinkedList<BgpValueType> pathAttributes1 = new LinkedList<>();
+ BgpValueType pathAttribute1;
+ byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 };
+ ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute1 = Origin.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+ byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute1 = AsPath.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+
+ IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ int bgpId = 168427777;
+ short locRIBASNum = 100;
+ boolean isIbgp = true;
+ PathAttrNlriDetails attrList1 = new PathAttrNlriDetails();
+ attrList1.setIdentifier(0);
+ attrList1.setPathAttribute(pathAttributes1);
+ attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE);
+ PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList1);
+
+ peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b };
+ LinkedList<BgpValueType> pathAttributes2 = new LinkedList<>();
+ BgpValueType pathAttribute2;
+ origin = new byte[] {0x40, 0x01, 0x01, 0x00 };
+ buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute2 = Origin.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+ asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute2 = AsPath.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+
+ ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ bgpId = 536936448;
+ locRIBASNum = 200;
+ isIbgp = false;
+ PathAttrNlriDetails attrList2 = new PathAttrNlriDetails();
+ attrList2.setIdentifier(0);
+ attrList2.setPathAttribute(pathAttributes2);
+ attrList2.setProtocolID(ProtocolType.OSPF_V2);
+ PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, false, attrList2);
+ BgpSelectionAlgo algo = new BgpSelectionAlgo();
+ int result = algo.compare(list1, list2);
+ assertThat(result, is(-1));
+ }
+
+ /**
+ * firstPathAttribute has lower BGPID than secondPathAttribute.
+ */
+ @Test
+ public void selectionAlgoTest7() throws BgpParseException {
+
+ byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a };
+ LinkedList<BgpValueType> pathAttributes1 = new LinkedList<>();
+ BgpValueType pathAttribute1;
+ byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 };
+ ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute1 = Origin.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+ byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute1 = AsPath.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+
+ IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ //A0A0A00
+ Integer bgpId = 168430080;
+ short locRIBASNum = 100;
+ boolean isIbgp = false;
+ PathAttrNlriDetails attrList1 = new PathAttrNlriDetails();
+ attrList1.setIdentifier(0);
+ attrList1.setPathAttribute(pathAttributes1);
+ attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE);
+ PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList1);
+
+ peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b };
+ LinkedList<BgpValueType> pathAttributes2 = new LinkedList<>();
+ BgpValueType pathAttribute2;
+ origin = new byte[] {0x40, 0x01, 0x01, 0x00 };
+ buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute2 = Origin.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+ asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute2 = AsPath.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+
+ ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ //B0A0A00
+ bgpId = 185207296;
+ locRIBASNum = 200;
+ isIbgp = false;
+ PathAttrNlriDetails attrList2 = new PathAttrNlriDetails();
+ attrList2.setIdentifier(0);
+ attrList2.setPathAttribute(pathAttributes2);
+ attrList2.setProtocolID(ProtocolType.OSPF_V2);
+ PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList2);
+ BgpSelectionAlgo algo = new BgpSelectionAlgo();
+ int result = algo.compare(list1, list2);
+ assertThat(result, is(1));
+ }
+
+ /**
+ * secondPathAttribute has lowest peer address than firstPathAttribute.
+ */
+ @Test
+ public void selectionAlgoTest8() throws BgpParseException {
+
+ byte[] peerIp = new byte[] {0x0b, 0x0b, 0x0b, 0x0b };
+ LinkedList<BgpValueType> pathAttributes1 = new LinkedList<>();
+ BgpValueType pathAttribute1;
+ byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 };
+ ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute1 = Origin.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+ byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute1 = AsPath.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+
+ IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ //A0A0A00
+ Integer bgpId = 168430080;
+ short locRIBASNum = 100;
+ boolean isIbgp = false;
+ PathAttrNlriDetails attrList1 = new PathAttrNlriDetails();
+ attrList1.setIdentifier(0);
+ attrList1.setPathAttribute(pathAttributes1);
+ attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE);
+ PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList1);
+
+ peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a };
+ LinkedList<BgpValueType> pathAttributes2 = new LinkedList<>();
+ BgpValueType pathAttribute2;
+ origin = new byte[] {0x40, 0x01, 0x01, 0x00 };
+ buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute2 = Origin.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+ asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute2 = AsPath.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+
+ ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ //A0A0A00
+ bgpId = 168430080;
+ locRIBASNum = 200;
+ isIbgp = false;
+ PathAttrNlriDetails attrList2 = new PathAttrNlriDetails();
+ attrList2.setIdentifier(0);
+ attrList2.setPathAttribute(pathAttributes2);
+ attrList2.setProtocolID(ProtocolType.OSPF_V2);
+ PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList2);
+ BgpSelectionAlgo algo = new BgpSelectionAlgo();
+ int result = algo.compare(list1, list2);
+ assertThat(result, is(-1));
+ }
+
+ /**
+ * firstPathAttribute and secondPathAttribute are same.
+ */
+ @Test
+ public void selectionAlgoTest9() throws BgpParseException {
+
+ byte[] peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a };
+ LinkedList<BgpValueType> pathAttributes1 = new LinkedList<>();
+ BgpValueType pathAttribute1;
+ byte[] origin = new byte[] {0x40, 0x01, 0x01, 0x00 };
+ ChannelBuffer buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute1 = Origin.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+ byte[] asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute1 = AsPath.read(buffer);
+ pathAttributes1.add(pathAttribute1);
+
+ IpAddress ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ //A0A0A00
+ Integer bgpId = 168430080;
+ short locRIBASNum = 100;
+ boolean isIbgp = false;
+ PathAttrNlriDetails attrList1 = new PathAttrNlriDetails();
+ attrList1.setIdentifier(0);
+ attrList1.setPathAttribute(pathAttributes1);
+ attrList1.setProtocolID(ProtocolType.ISIS_LEVEL_ONE);
+ PathAttrNlriDetailsLocalRib list1 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList1);
+
+ peerIp = new byte[] {0x0a, 0x0a, 0x0a, 0x0a };
+ LinkedList<BgpValueType> pathAttributes2 = new LinkedList<>();
+ BgpValueType pathAttribute2;
+ origin = new byte[] {0x40, 0x01, 0x01, 0x00 };
+ buffer = ChannelBuffers.dynamicBuffer();
+ buffer.writeBytes(origin);
+ pathAttribute2 = Origin.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+ asPath = new byte[] {0x40, 0x02, 0x04, 0x02, 0x01, (byte) 0xfd,
+ (byte) 0xe9 };
+ buffer.writeBytes(asPath);
+ pathAttribute2 = AsPath.read(buffer);
+ pathAttributes2.add(pathAttribute2);
+
+ ipAddress = IpAddress.valueOf(Version.INET, peerIp);
+ //A0A0A00
+ bgpId = 168430080;
+ locRIBASNum = 200;
+ isIbgp = false;
+ PathAttrNlriDetails attrList2 = new PathAttrNlriDetails();
+ attrList2.setIdentifier(0);
+ attrList2.setPathAttribute(pathAttributes2);
+ attrList2.setProtocolID(ProtocolType.OSPF_V2);
+ PathAttrNlriDetailsLocalRib list2 = new PathAttrNlriDetailsLocalRib(
+ ipAddress, bgpId, locRIBASNum, isIbgp, attrList2);
+ BgpSelectionAlgo algo = new BgpSelectionAlgo();
+ int result = algo.compare(list1, list2);
+ assertThat(result, is(0));
+ }
+}