[ONOS-2606] Bgp local RIB implementation.
Change-Id: I39eadec95fa1e1328c73efabb2a50bb438075809
diff --git a/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpController.java b/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpController.java
index cc87eb3..0930e8e 100755
--- a/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpController.java
+++ b/bgp/api/src/main/java/org/onosproject/bgp/controller/BgpController.java
@@ -95,6 +95,20 @@
int connectedPeerCount();
/**
+ * Return BGP local RIB instance with VPN.
+ *
+ * @return BGPLocalRibImpl local RIB with VPN
+ */
+ BgpLocalRib bgpLocalRibVpn();
+
+ /**
+ * Return BGP local RIB instance.
+ *
+ * @return BGPLocalRibImpl local RIB
+ */
+ BgpLocalRib bgpLocalRib();
+
+ /**
* Return BGP peer manager.
*
* @return BGPPeerManager peer manager instance
diff --git a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java
index 8754563..45be255 100755
--- a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java
+++ b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpChannelHandler.java
@@ -440,7 +440,9 @@
// which we obviously don't want.
log.debug("{}:removal called", getPeerInfoString());
if (bgpPeer != null) {
+ BgpPeerImpl peer = (BgpPeerImpl) bgpPeer;
peerManager.removeConnectedPeer(thisbgpId);
+ peer.updateLocalRIBOnPeerDisconnect();
}
// Retry connection if connection is lost to bgp speaker/peer
diff --git a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
index 716cc0c..ac94822 100755
--- a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
+++ b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpConfig.java
@@ -21,8 +21,14 @@
import java.util.TreeMap;
import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpAddress;
import org.onosproject.bgp.controller.BgpCfg;
+import org.onosproject.bgp.controller.BgpConnectPeer;
+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.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,12 +54,16 @@
private Ip4Address routerId = null;
private TreeMap<String, BgpPeerCfg> bgpPeerTree = new TreeMap<>();
+ private BgpConnectPeer connectPeer;
+ private BgpPeerManagerImpl peerManager;
+ private BgpController bgpController;
- /**
+ /*
* Constructor to initialize the values.
*/
- public BgpConfig() {
-
+ public BgpConfig(BgpController bgpController) {
+ this.bgpController = bgpController;
+ this.peerManager = (BgpPeerManagerImpl) bgpController.peerManager();
this.holdTime = DEFAULT_HOLD_TIMER;
this.maxConnRetryTime = DEFAULT_CONN_RETRY_TIME;
this.maxConnRetryCount = DEFAULT_CONN_RETRY_COUNT;
@@ -172,7 +182,12 @@
if (lspeer != null) {
lspeer.setSelfInnitConnection(true);
- // TODO: initiate peer connection
+
+ if (lspeer.connectPeer() == null) {
+ connectPeer = new BgpConnectPeerImpl(bgpController, routerid, Controller.getBgpPortNum());
+ lspeer.setConnectPeer(connectPeer);
+ connectPeer.connectPeer();
+ }
return true;
}
@@ -185,7 +200,6 @@
if (lspeer != null) {
- //TODO DISCONNECT PEER
disconnectPeer(routerid);
lspeer.setSelfInnitConnection(false);
lspeer = this.bgpPeerTree.remove(routerid);
@@ -204,7 +218,12 @@
if (lspeer != null) {
- //TODO DISCONNECT PEER
+ BgpPeer disconnPeer = peerManager.getPeer(BgpId.bgpId(IpAddress.valueOf(routerid)));
+ if (disconnPeer != null) {
+ // TODO: send notification peer deconfigured
+ disconnPeer.disconnectPeer();
+ }
+ lspeer.connectPeer().disconnectPeer();
lspeer.setState(BgpPeerCfg.State.IDLE);
lspeer.setSelfInnitConnection(false);
log.debug("Disconnected : " + routerid + " successfully");
diff --git a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java
index 6a14e85..51ab68b 100755
--- a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java
+++ b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpControllerImpl.java
@@ -16,6 +16,8 @@
package org.onosproject.bgp.controller.impl;
+import java.util.Iterator;
+import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
@@ -29,11 +31,16 @@
import org.onosproject.bgp.controller.BgpCfg;
import org.onosproject.bgp.controller.BgpController;
import org.onosproject.bgp.controller.BgpId;
+import org.onosproject.bgp.controller.BgpLocalRib;
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.protocol.BgpUpdateMsg;
+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;
@@ -47,11 +54,14 @@
protected BgpPeerManagerImpl peerManager = new BgpPeerManagerImpl();
+ private BgpLocalRib bgplocalRIB = new BgpLocalRibImpl(this);
+ private BgpLocalRib bgplocalRIBVpn = new BgpLocalRibImpl(this);
+
protected Set<BgpNodeListener> bgpNodeListener = new CopyOnWriteArraySet<>();
final Controller ctrl = new Controller(this);
- private BgpConfig bgpconfig = new BgpConfig();
+ private BgpConfig bgpconfig = new BgpConfig(this);
@Activate
public void activate() {
@@ -100,6 +110,8 @@
@Override
public void processBGPPacket(BgpId bgpId, BgpMessage msg) throws BgpParseException {
+ BgpPeer peer = getPeer(bgpId);
+
switch (msg.getType()) {
case OPEN:
// TODO: Process Open message
@@ -111,7 +123,23 @@
// TODO: Process notificatoin message
break;
case UPDATE:
- // TODO: Process update message
+ BgpUpdateMsg updateMsg = (BgpUpdateMsg) msg;
+ List<BgpValueType> pathAttr = updateMsg.bgpPathAttributes().pathAttributes();
+ if (pathAttr == null) {
+ log.debug("llPathAttr is null, cannot process update message");
+ break;
+ }
+ Iterator<BgpValueType> listIterator = pathAttr.iterator();
+ boolean isLinkstate = false;
+ while (listIterator.hasNext()) {
+ BgpValueType attr = listIterator.next();
+ if ((attr instanceof MpReachNlri) || (attr instanceof MpUnReachNlri)) {
+ isLinkstate = true;
+ }
+ }
+ if (isLinkstate) {
+ peer.buildAdjRibIn(pathAttr);
+ }
break;
default:
// TODO: Process other message
@@ -215,4 +243,24 @@
public int connectedPeerCount() {
return connectedPeers.size();
}
+
+ /**
+ * Gets the BGP local RIB.
+ *
+ * @return bgplocalRIB BGP local RIB.
+ */
+ @Override
+ public BgpLocalRib bgpLocalRib() {
+ return bgplocalRIB;
+ }
+
+ /**
+ * Gets the BGP local RIB with VPN.
+ *
+ * @return bgplocalRIBVpn BGP VPN local RIB .
+ */
+ @Override
+ public BgpLocalRib bgpLocalRibVpn() {
+ return bgplocalRIBVpn;
+ }
}
diff --git a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpLocalRibImpl.java b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpLocalRibImpl.java
new file mode 100755
index 0000000..44b1905
--- /dev/null
+++ b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpLocalRibImpl.java
@@ -0,0 +1,603 @@
+/*
+ * 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.Set;
+import java.util.TreeMap;
+
+import org.onosproject.bgp.controller.BgpController;
+import org.onosproject.bgp.controller.BgpId;
+import org.onosproject.bgp.controller.BgpLocalRib;
+import org.onosproject.bgp.controller.BgpNodeListener;
+import org.onosproject.bgp.controller.BgpSessionInfo;
+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.protocol.linkstate.PathAttrNlriDetailsLocalRib;
+import org.onosproject.bgpio.types.RouteDistinguisher;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.MoreObjects;
+
+/**
+ * Implementation of local RIB.
+ */
+public class BgpLocalRibImpl implements BgpLocalRib {
+
+ private static final Logger log = LoggerFactory.getLogger(BgpLocalRibImpl.class);
+ private BgpController bgpController;
+
+ private Map<BgpNodeLSIdentifier, PathAttrNlriDetailsLocalRib> nodeTree = new TreeMap<>();
+ private Map<BgpLinkLSIdentifier, PathAttrNlriDetailsLocalRib> linkTree = new TreeMap<>();
+ private Map<BgpPrefixLSIdentifier, PathAttrNlriDetailsLocalRib> prefixTree = new TreeMap<>();
+
+ private Map<RouteDistinguisher, Map<BgpNodeLSIdentifier, PathAttrNlriDetailsLocalRib>> vpnNodeTree
+ = new TreeMap<>();
+ private Map<RouteDistinguisher, Map<BgpLinkLSIdentifier, PathAttrNlriDetailsLocalRib>> vpnLinkTree
+ = new TreeMap<>();
+ private Map<RouteDistinguisher, Map<BgpPrefixLSIdentifier, PathAttrNlriDetailsLocalRib>> vpnPrefixTree
+ = new TreeMap<>();
+
+ public BgpLocalRibImpl(BgpController bgpController) {
+ this.bgpController = bgpController;
+ }
+
+ /**
+ * Gets node NLRI tree.
+ *
+ * @return node tree
+ */
+ public Map<BgpNodeLSIdentifier, PathAttrNlriDetailsLocalRib> nodeTree() {
+ return nodeTree;
+ }
+
+ /**
+ * Gets link NLRI tree.
+ *
+ * @return link tree
+ */
+ public Map<BgpLinkLSIdentifier, PathAttrNlriDetailsLocalRib> linkTree() {
+ return linkTree;
+ }
+
+ /**
+ * Gets prefix NLRI tree.
+ *
+ * @return prefix tree
+ */
+ public Map<BgpPrefixLSIdentifier, PathAttrNlriDetailsLocalRib> prefixTree() {
+ return prefixTree;
+ }
+
+ /**
+ * Gets VPN node NLRI tree.
+ *
+ * @return vpn node NLRI tree
+ */
+ public Map<RouteDistinguisher, Map<BgpNodeLSIdentifier, PathAttrNlriDetailsLocalRib>> vpnNodeTree() {
+ return vpnNodeTree;
+ }
+
+ /**
+ * Gets VPN link NLRI tree.
+ *
+ * @return vpn link NLRI Tree
+ */
+ public Map<RouteDistinguisher, Map<BgpLinkLSIdentifier, PathAttrNlriDetailsLocalRib>> vpnLinkTree() {
+ return vpnLinkTree;
+ }
+
+ /**
+ * Gets VPN prefix NLRI tree.
+ *
+ * @return vpn prefix NLRI Tree
+ */
+ public Map<RouteDistinguisher, Map<BgpPrefixLSIdentifier, PathAttrNlriDetailsLocalRib>> vpnPrefixTree() {
+ return vpnPrefixTree;
+ }
+
+ @Override
+ public void add(BgpSessionInfo sessionInfo, BgpLSNlri nlri, PathAttrNlriDetails details) {
+ int decisionResult;
+
+ log.debug("Add to local RIB {}", details.toString());
+
+ PathAttrNlriDetailsLocalRib detailsLocRib = new PathAttrNlriDetailsLocalRib(
+ sessionInfo.remoteBgpId().ipAddress(),
+ sessionInfo.remoteBgpIdentifier(),
+ sessionInfo.remoteBgpASNum(),
+ sessionInfo.isIbgpSession(), details);
+ if (nlri instanceof BgpNodeLSNlriVer4) {
+ BgpNodeLSIdentifier nodeLsIdentifier = ((BgpNodeLSNlriVer4) nlri).getLocalNodeDescriptors();
+ if (nodeTree.containsKey(nodeLsIdentifier)) {
+ BgpSelectionAlgo selectionAlgo = new BgpSelectionAlgo();
+ // Compare local RIB entry with the current attribute
+ decisionResult = selectionAlgo.compare(nodeTree.get(nodeLsIdentifier), detailsLocRib);
+ if (decisionResult < 0) {
+ nodeTree.replace(nodeLsIdentifier, detailsLocRib);
+ log.debug("Local RIB update node: {}", detailsLocRib.toString());
+ }
+ } else {
+ nodeTree.put(nodeLsIdentifier, detailsLocRib);
+ for (BgpNodeListener l : bgpController.listener()) {
+ l.addNode((BgpNodeLSNlriVer4) nlri);
+ }
+ log.debug("Local RIB ad node: {}", detailsLocRib.toString());
+ }
+ } else if (nlri instanceof BgpLinkLsNlriVer4) {
+ BgpLinkLSIdentifier linkLsIdentifier = ((BgpLinkLsNlriVer4) nlri).getLinkIdentifier();
+ if (linkTree.containsKey(linkLsIdentifier)) {
+ BgpSelectionAlgo selectionAlgo = new BgpSelectionAlgo();
+ // Compare local RIB entry with the current attribute
+ decisionResult = selectionAlgo.compare(linkTree.get(linkLsIdentifier), detailsLocRib);
+ if (decisionResult < 0) {
+ linkTree.replace(linkLsIdentifier, detailsLocRib);
+ log.debug("Local RIB update link: {}", detailsLocRib.toString());
+ }
+ } else {
+ linkTree.put(linkLsIdentifier, detailsLocRib);
+ log.debug("Local RIB add link: {}", detailsLocRib.toString());
+ }
+ } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) {
+ BgpPrefixLSIdentifier prefixIdentifier = ((BgpPrefixIPv4LSNlriVer4) nlri).getPrefixIdentifier();
+ if (prefixTree.containsKey(prefixIdentifier)) {
+ BgpSelectionAlgo selectionAlgo = new BgpSelectionAlgo();
+ // Compare local RIB entry with the current attribute
+ decisionResult = selectionAlgo.compare(prefixTree.get(prefixIdentifier), detailsLocRib);
+ if (decisionResult < 0) {
+ prefixTree.replace(prefixIdentifier, detailsLocRib);
+ log.debug("Local RIB update prefix: {}", detailsLocRib.toString());
+ }
+ } else {
+ prefixTree.put(prefixIdentifier, detailsLocRib);
+ log.debug("Local RIB add prefix: {}", detailsLocRib.toString());
+ }
+ }
+ }
+
+ @Override
+ public void delete(BgpLSNlri nlri) {
+ log.debug("Delete from local RIB.");
+
+ // Update local RIB
+ decisionProcess(nlri);
+ }
+
+ /**
+ * Update local RIB based on selection algorithm.
+ *
+ * @param nlri NLRI to update
+ */
+ public void decisionProcess(BgpLSNlri nlri) {
+ checkNotNull(nlri);
+ if (nlri instanceof BgpNodeLSNlriVer4) {
+ selectionProcessNode(nlri, false);
+ } else if (nlri instanceof BgpLinkLsNlriVer4) {
+ selectionProcessLink(nlri, false);
+ } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) {
+ selectionProcessPrefix(nlri, false);
+ }
+ }
+
+ /**
+ * Update VPN local RIB .
+ *
+ * @param nlri NLRI to update
+ * @param routeDistinguisher VPN id to update
+ */
+ public void decisionProcess(BgpLSNlri nlri, RouteDistinguisher routeDistinguisher) {
+ checkNotNull(nlri);
+ if (nlri instanceof BgpNodeLSNlriVer4) {
+ if (vpnNodeTree.containsKey(routeDistinguisher)) {
+ selectionProcessNode(nlri, true);
+ if (nodeTree.size() == 0) {
+ vpnNodeTree.remove(routeDistinguisher);
+ }
+ }
+ } else if (nlri instanceof BgpLinkLsNlriVer4) {
+ if (vpnLinkTree.containsKey(routeDistinguisher)) {
+ selectionProcessLink(nlri, true);
+ if (linkTree.size() == 0) {
+ vpnLinkTree.remove(routeDistinguisher);
+ }
+ }
+ } else if (nlri instanceof BgpPrefixIPv4LSNlriVer4) {
+ if (vpnPrefixTree.containsKey(routeDistinguisher)) {
+ selectionProcessPrefix(nlri, true);
+ if (prefixTree.size() == 0) {
+ vpnPrefixTree.remove(routeDistinguisher);
+ }
+ }
+ }
+ }
+
+ /**
+ * Selection process for local RIB node.
+ *
+ * @param nlri NLRI to update
+ * @param isVpnRib true if VPN local RIB, otherwise false
+ */
+ public void selectionProcessNode(BgpLSNlri nlri, boolean isVpnRib) {
+ BgpPeerImpl peer;
+ BgpSessionInfo sessionInfo;
+ int decisionResult;
+ boolean containsKey;
+
+ BgpNodeLSIdentifier nodeLsIdentifier = ((BgpNodeLSNlriVer4) nlri).getLocalNodeDescriptors();
+
+ if (nodeTree.containsKey(nodeLsIdentifier)) {
+ for (BgpNodeListener l : bgpController.listener()) {
+ l.deleteNode((BgpNodeLSNlriVer4) nlri);
+ }
+ log.debug("Local RIB delete node: {}", nodeLsIdentifier.toString());
+ nodeTree.remove(nodeLsIdentifier);
+ }
+
+ for (BgpId bgpId : bgpController.connectedPeers().keySet()) {
+ peer = (BgpPeerImpl) (bgpController.getPeer(bgpId));
+
+ if (nodeTree.containsKey(nodeLsIdentifier)) {
+ containsKey = (!isVpnRib) ? (peer.adjacencyRib().nodeTree().containsKey(nodeLsIdentifier)) :
+ (peer.vpnAdjacencyRib().nodeTree().containsKey(nodeLsIdentifier));
+
+ if (!containsKey) {
+ continue;
+ }
+ sessionInfo = peer.sessionInfo();
+ PathAttrNlriDetailsLocalRib detailsLocRib = new PathAttrNlriDetailsLocalRib(
+ sessionInfo.remoteBgpId().ipAddress(),
+ sessionInfo.remoteBgpIdentifier(),
+ sessionInfo.remoteBgpASNum(),
+ sessionInfo.isIbgpSession(),
+ (!isVpnRib) ?
+ (peer.adjacencyRib().nodeTree()
+ .get(nodeLsIdentifier)) :
+ (peer.vpnAdjacencyRib().nodeTree()
+ .get(nodeLsIdentifier)));
+ BgpSelectionAlgo selectionAlgo = new BgpSelectionAlgo();
+ decisionResult = selectionAlgo.compare(nodeTree.get(nodeLsIdentifier), detailsLocRib);
+ if (decisionResult < 0) {
+ nodeTree.replace(nodeLsIdentifier, detailsLocRib);
+ log.debug("Local RIB node updated: {}", detailsLocRib.toString());
+ }
+ } else {
+ if (!isVpnRib) {
+ if (peer.adjacencyRib().nodeTree().containsKey(nodeLsIdentifier)) {
+ add(peer.sessionInfo(), nlri, peer.adjacencyRib().nodeTree().get(nodeLsIdentifier));
+ }
+ } else {
+ if (peer.vpnAdjacencyRib().nodeTree().containsKey(nodeLsIdentifier)) {
+ add(peer.sessionInfo(), nlri, peer.vpnAdjacencyRib().nodeTree().get(nodeLsIdentifier));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Selection process for local RIB link.
+ *
+ * @param nlri NLRI to update
+ * @param isVpnRib true if VPN local RIB, otherwise false
+ */
+ public void selectionProcessLink(BgpLSNlri nlri, boolean isVpnRib) {
+ BgpPeerImpl peer;
+ BgpSessionInfo sessionInfo;
+ int decisionResult;
+ boolean containsKey;
+
+ BgpLinkLSIdentifier linkLsIdentifier = ((BgpLinkLsNlriVer4) nlri).getLinkIdentifier();
+
+ if (linkTree.containsKey(linkLsIdentifier)) {
+ log.debug("Local RIB remove link: {}", linkLsIdentifier.toString());
+ linkTree.remove(linkLsIdentifier);
+ }
+
+ for (BgpId bgpId : bgpController.connectedPeers().keySet()) {
+ peer = (BgpPeerImpl) (bgpController.getPeer(bgpId));
+
+ if (linkTree.containsKey(linkLsIdentifier)) {
+
+ containsKey = (!isVpnRib) ? (peer.adjacencyRib().linkTree().containsKey(linkLsIdentifier)) :
+ (peer.vpnAdjacencyRib().linkTree().containsKey(linkLsIdentifier));
+
+ if (!containsKey) {
+ continue;
+ }
+
+ sessionInfo = peer.sessionInfo();
+
+ PathAttrNlriDetailsLocalRib detailsLocRib = new PathAttrNlriDetailsLocalRib(
+ sessionInfo.remoteBgpId().ipAddress(),
+ sessionInfo.remoteBgpIdentifier(),
+ sessionInfo.remoteBgpASNum(),
+ sessionInfo.isIbgpSession(),
+ ((!isVpnRib) ?
+ (peer.adjacencyRib().linkTree().get(linkLsIdentifier)) :
+ (peer.vpnAdjacencyRib().linkTree()
+ .get(linkLsIdentifier))));
+
+ BgpSelectionAlgo selectionAlgo = new BgpSelectionAlgo();
+ decisionResult = selectionAlgo.compare(linkTree.get(linkLsIdentifier), detailsLocRib);
+ if (decisionResult < 0) {
+ linkTree.replace(linkLsIdentifier, detailsLocRib);
+ log.debug("Local RIB link updated: {}", detailsLocRib.toString());
+ }
+ } else {
+ if (!isVpnRib) {
+ if (peer.adjacencyRib().linkTree().containsKey(linkLsIdentifier)) {
+ add(peer.sessionInfo(), nlri, peer.adjacencyRib().linkTree().get(linkLsIdentifier));
+ }
+ } else {
+ if (peer.vpnAdjacencyRib().linkTree().containsKey(linkLsIdentifier)) {
+ add(peer.sessionInfo(), nlri, peer.vpnAdjacencyRib().linkTree().get(linkLsIdentifier));
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Selection process for local RIB prefix.
+ *
+ * @param nlri NLRI to update
+ * @param isVpnRib true if VPN local RIB, otherwise false
+ */
+ public void selectionProcessPrefix(BgpLSNlri nlri, boolean isVpnRib) {
+ BgpPeerImpl peer;
+ BgpSessionInfo sessionInfo;
+ int decisionResult;
+ boolean containsKey;
+
+ BgpPrefixLSIdentifier prefixIdentifier = ((BgpPrefixIPv4LSNlriVer4) nlri).getPrefixIdentifier();
+ if (prefixTree.containsKey(prefixIdentifier)) {
+ log.debug("Local RIB remove prefix: {}", prefixIdentifier.toString());
+ prefixTree.remove(prefixIdentifier);
+ }
+
+ for (BgpId bgpId : bgpController.connectedPeers().keySet()) {
+ peer = (BgpPeerImpl) (bgpController.getPeer(bgpId));
+
+ if (prefixTree.containsKey(prefixIdentifier)) {
+
+ containsKey = (!isVpnRib) ? (peer.adjacencyRib().prefixTree().containsKey(prefixIdentifier)) :
+ (peer.vpnAdjacencyRib().prefixTree().containsKey(prefixIdentifier));
+ if (!containsKey) {
+ continue;
+ }
+ sessionInfo = peer.sessionInfo();
+
+ PathAttrNlriDetailsLocalRib detailsLocRib = new PathAttrNlriDetailsLocalRib(
+ sessionInfo.remoteBgpId().ipAddress(),
+ sessionInfo.remoteBgpIdentifier(),
+ sessionInfo.remoteBgpASNum(),
+ sessionInfo.isIbgpSession(),
+ ((!isVpnRib) ?
+ (peer.adjacencyRib().prefixTree()
+ .get(prefixIdentifier)) :
+ (peer.vpnAdjacencyRib().prefixTree()
+ .get(prefixIdentifier))));
+
+ BgpSelectionAlgo selectionAlgo = new BgpSelectionAlgo();
+ decisionResult = selectionAlgo.compare(prefixTree.get(prefixIdentifier), detailsLocRib);
+ if (decisionResult < 0) {
+ prefixTree.replace(prefixIdentifier, detailsLocRib);
+ log.debug("local RIB prefix updated: {}", detailsLocRib.toString());
+ }
+ } else {
+ if (!isVpnRib) {
+ if (peer.adjacencyRib().prefixTree().containsKey(prefixIdentifier)) {
+ add(peer.sessionInfo(), nlri, peer.adjacencyRib().prefixTree().get(prefixIdentifier));
+ } else {
+ if (peer.vpnAdjacencyRib().prefixTree().containsKey(prefixIdentifier)) {
+ add(peer.sessionInfo(), nlri, peer.vpnAdjacencyRib().prefixTree().get(prefixIdentifier));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public void add(BgpSessionInfo sessionInfo, BgpLSNlri nlri, PathAttrNlriDetails details,
+ RouteDistinguisher routeDistinguisher) {
+ add(sessionInfo, 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);
+ }
+ }
+ }
+
+ @Override
+ public void delete(BgpLSNlri nlri, RouteDistinguisher routeDistinguisher) {
+ // Update local RIB
+ decisionProcess(nlri, routeDistinguisher);
+ }
+
+ /**
+ * Update local RIB node based on avaliable peer adjacency RIB.
+ *
+ * @param o adjacency-in/VPN adjacency-in
+ */
+ public void localRIBUpdateNode(Object o) {
+
+ if (o instanceof AdjRibIn) {
+ AdjRibIn adjRib = (AdjRibIn) o;
+ log.debug("Update local RIB node.");
+
+ Set<BgpNodeLSIdentifier> nodeKeys = adjRib.nodeTree().keySet();
+ for (BgpNodeLSIdentifier key : nodeKeys) {
+ PathAttrNlriDetails pathAttrNlri = adjRib.nodeTree().get(key);
+
+ BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(pathAttrNlri.identifier(), pathAttrNlri
+ .protocolID().getType(), key, false, null);
+ decisionProcess(nodeNlri);
+ }
+ }
+
+ if (o instanceof VpnAdjRibIn) {
+ VpnAdjRibIn vpnAdjRib = (VpnAdjRibIn) o;
+ log.debug("Update local RIB VPN node.");
+ Set<RouteDistinguisher> nodeKeysVpn = vpnAdjRib.vpnNodeTree().keySet();
+ Map<BgpNodeLSIdentifier, PathAttrNlriDetails> node;
+ for (RouteDistinguisher keyVpnNode : nodeKeysVpn) {
+ node = vpnAdjRib.vpnNodeTree().get(keyVpnNode);
+
+ Set<BgpNodeLSIdentifier> vpnNodeKeys = node.keySet();
+ for (BgpNodeLSIdentifier key : vpnNodeKeys) {
+ PathAttrNlriDetails pathAttrNlri = vpnAdjRib.nodeTree().get(key);
+ BgpNodeLSNlriVer4 nodeNlri = new BgpNodeLSNlriVer4(pathAttrNlri.identifier(),
+ pathAttrNlri.protocolID().getType(),
+ key, true, keyVpnNode);
+ decisionProcess(nodeNlri, keyVpnNode);
+ }
+ }
+ }
+ }
+
+ /**
+ * Update localRIB link based on avaliable peer adjacency RIB.
+ *
+ * @param o adjacency-in/VPN adjacency-in
+ */
+ public void localRIBUpdateLink(Object o) {
+
+ if (o instanceof AdjRibIn) {
+ AdjRibIn adjRib = (AdjRibIn) o;
+ log.debug("Update local RIB link.");
+
+ Set<BgpLinkLSIdentifier> linkKeys = adjRib.linkTree().keySet();
+ for (BgpLinkLSIdentifier key : linkKeys) {
+ PathAttrNlriDetails pathAttrNlri = adjRib.linkTree().get(key);
+ BgpLinkLsNlriVer4 linkNlri = new BgpLinkLsNlriVer4(pathAttrNlri.protocolID().getType(),
+ pathAttrNlri.identifier(), key, null, false);
+ decisionProcess(linkNlri);
+ }
+ }
+
+ if (o instanceof VpnAdjRibIn) {
+ VpnAdjRibIn vpnAdjRib = (VpnAdjRibIn) o;
+ log.debug("Update local RIB VPN link");
+
+ Set<RouteDistinguisher> linkKeysVpn = vpnAdjRib.vpnLinkTree().keySet();
+ Map<BgpLinkLSIdentifier, PathAttrNlriDetails> link;
+ for (RouteDistinguisher keyVpnLink : linkKeysVpn) {
+ link = vpnAdjRib.vpnLinkTree().get(keyVpnLink);
+
+ Set<BgpLinkLSIdentifier> vpnLinkKeys = link.keySet();
+ for (BgpLinkLSIdentifier key : vpnLinkKeys) {
+ PathAttrNlriDetails pathAttrNlri = vpnAdjRib.linkTree().get(key);
+ BgpLinkLsNlriVer4 linkNlri = new BgpLinkLsNlriVer4(pathAttrNlri.protocolID().getType(),
+ pathAttrNlri.identifier(), key, keyVpnLink,
+ true);
+ decisionProcess(linkNlri, keyVpnLink);
+ }
+ }
+ }
+ }
+
+ /**
+ * Update localRIB prefix based on avaliable peer adjacency RIB.
+ *
+ * @param o instance of adjacency-in/VPN adjacency-in
+ */
+ public void localRIBUpdatePrefix(Object o) {
+
+ if (o instanceof AdjRibIn) {
+ AdjRibIn adjRib = (AdjRibIn) o;
+ log.debug("Update local RIB prefix.");
+
+ Set<BgpPrefixLSIdentifier> prefixKeys = adjRib.prefixTree().keySet();
+ for (BgpPrefixLSIdentifier key : prefixKeys) {
+ PathAttrNlriDetails pathAttrNlri = adjRib.prefixTree().get(key);
+ BgpPrefixIPv4LSNlriVer4 prefixNlri = new BgpPrefixIPv4LSNlriVer4(
+ pathAttrNlri.identifier(),
+ pathAttrNlri.protocolID().getType(),
+ key, null, false);
+ decisionProcess(prefixNlri);
+ }
+ }
+
+ if (o instanceof VpnAdjRibIn) {
+ VpnAdjRibIn vpnAdjRib = (VpnAdjRibIn) o;
+ log.debug("Update local RIB VPN prefix.");
+
+ Set<RouteDistinguisher> prefixKeysVpn = vpnAdjRib.vpnPrefixTree().keySet();
+ Map<BgpPrefixLSIdentifier, PathAttrNlriDetails> prefix;
+ for (RouteDistinguisher keyVpnPrefix : prefixKeysVpn) {
+ prefix = vpnAdjRib.vpnPrefixTree().get(keyVpnPrefix);
+
+ Set<BgpPrefixLSIdentifier> vpnPrefixKeys = prefix.keySet();
+ for (BgpPrefixLSIdentifier key : vpnPrefixKeys) {
+ PathAttrNlriDetails pathAttrNlri = vpnAdjRib.prefixTree().get(key);
+ BgpPrefixIPv4LSNlriVer4 prefixNlri = new BgpPrefixIPv4LSNlriVer4(pathAttrNlri.identifier(),
+ pathAttrNlri.protocolID()
+ .getType(), key,
+ keyVpnPrefix, true);
+ decisionProcess(prefixNlri, keyVpnPrefix);
+ }
+ }
+ }
+ }
+
+ /**
+ * Update localRIB.
+ *
+ * @param adjRibIn adjacency RIB-in
+ */
+ public void localRIBUpdate(AdjRibIn adjRibIn) {
+ log.debug("Update local RIB.");
+
+ localRIBUpdateNode(adjRibIn);
+ localRIBUpdateLink(adjRibIn);
+ localRIBUpdatePrefix(adjRibIn);
+ }
+
+ /**
+ * Update localRIB.
+ *
+ * @param vpnAdjRibIn VPN adjacency RIB-in
+ */
+ public void localRIBUpdate(VpnAdjRibIn vpnAdjRibIn) {
+ log.debug("Update VPN local RIB.");
+
+ localRIBUpdateNode(vpnAdjRibIn);
+ localRIBUpdateLink(vpnAdjRibIn);
+ localRIBUpdatePrefix(vpnAdjRibIn);
+ }
+
+ @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();
+ }
+}
diff --git a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
index 57a924a..e3f09f3 100644
--- a/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
+++ b/bgp/ctl/src/main/java/org/onosproject/bgp/controller/impl/BgpPeerImpl.java
@@ -28,6 +28,7 @@
import org.onosproject.bgp.controller.BgpController;
import org.onosproject.bgp.controller.BgpPeer;
import org.onosproject.bgp.controller.BgpSessionInfo;
+import org.onosproject.bgp.controller.BgpLocalRib;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.protocol.BgpFactories;
import org.onosproject.bgpio.protocol.BgpFactory;
@@ -61,9 +62,28 @@
protected boolean isHandShakeComplete = false;
private BgpSessionInfo sessionInfo;
private BgpPacketStatsImpl pktStats;
+ private BgpLocalRib bgplocalRIB;
+ private BgpLocalRib bgplocalRIBVpn;
private AdjRibIn adjRib;
private VpnAdjRibIn vpnAdjRib;
+ /**
+ * Return the adjacency RIB-IN.
+ *
+ * @return adjRib the adjacency RIB-IN
+ */
+ public AdjRibIn adjacencyRib() {
+ return adjRib;
+ }
+
+ /**
+ * Return the adjacency RIB-IN with VPN.
+ *
+ * @return vpnAdjRib the adjacency RIB-IN with VPN
+ */
+ public VpnAdjRibIn vpnAdjacencyRib() {
+ return vpnAdjRib;
+ }
@Override
public BgpSessionInfo sessionInfo() {
@@ -81,6 +101,8 @@
this.bgpController = bgpController;
this.sessionInfo = sessionInfo;
this.pktStats = pktStats;
+ this.bgplocalRIB = bgpController.bgpLocalRib();
+ this.bgplocalRIBVpn = bgpController.bgpLocalRibVpn();
this.adjRib = new AdjRibIn();
this.vpnAdjRib = new VpnAdjRibIn();
}
@@ -119,22 +141,31 @@
PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
adjRib.add(nlriInfo, details);
+ bgplocalRIB.add(sessionInfo(), nlriInfo, details);
} else {
vpnAdjRib.addVpn(nlriInfo, details, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
+ bgplocalRIBVpn.add(sessionInfo(), nlriInfo, details,
+ ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
}
} else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
adjRib.add(nlriInfo, details);
+ bgplocalRIB.add(sessionInfo(), nlriInfo, details);
} else {
vpnAdjRib.addVpn(nlriInfo, details, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
+ bgplocalRIBVpn.add(sessionInfo(), nlriInfo, details,
+ ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
}
} else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
PathAttrNlriDetails details = setPathAttrDetails(nlriInfo, pathAttr);
if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
adjRib.add(nlriInfo, details);
+ bgplocalRIB.add(sessionInfo(), nlriInfo, details);
} else {
vpnAdjRib.addVpn(nlriInfo, details, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
+ bgplocalRIBVpn.add(sessionInfo(), nlriInfo, details,
+ ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
}
}
}
@@ -170,20 +201,26 @@
if (nlriInfo instanceof BgpNodeLSNlriVer4) {
if (!((BgpNodeLSNlriVer4) nlriInfo).isVpnPresent()) {
adjRib.remove(nlriInfo);
+ bgplocalRIB.delete(nlriInfo);
} else {
vpnAdjRib.removeVpn(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
+ bgplocalRIBVpn.delete(nlriInfo, ((BgpNodeLSNlriVer4) nlriInfo).getRouteDistinguisher());
}
} else if (nlriInfo instanceof BgpLinkLsNlriVer4) {
if (!((BgpLinkLsNlriVer4) nlriInfo).isVpnPresent()) {
adjRib.remove(nlriInfo);
+ bgplocalRIB.delete(nlriInfo);
} else {
vpnAdjRib.removeVpn(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
+ bgplocalRIBVpn.delete(nlriInfo, ((BgpLinkLsNlriVer4) nlriInfo).getRouteDistinguisher());
}
} else if (nlriInfo instanceof BgpPrefixIPv4LSNlriVer4) {
if (!((BgpPrefixIPv4LSNlriVer4) nlriInfo).isVpnPresent()) {
adjRib.remove(nlriInfo);
+ bgplocalRIB.delete(nlriInfo);
} else {
vpnAdjRib.removeVpn(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
+ bgplocalRIBVpn.delete(nlriInfo, ((BgpPrefixIPv4LSNlriVer4) nlriInfo).getRouteDistinguisher());
}
}
}
@@ -207,6 +244,18 @@
return vpnAdjRib;
}
+ /**
+ * Update localRIB on peer disconnect.
+ *
+ */
+ public void updateLocalRIBOnPeerDisconnect() {
+ BgpLocalRibImpl localRib = (BgpLocalRibImpl) bgplocalRIB;
+ BgpLocalRibImpl localRibVpn = (BgpLocalRibImpl) bgplocalRIBVpn;
+
+ localRib.localRIBUpdate(adjacencyRib());
+ localRibVpn.localRIBUpdate(vpnAdjacencyRib());
+ }
+
// ************************
// Channel related
// ************************
diff --git a/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java b/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
index 30bb447..37576e4 100755
--- a/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
+++ b/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
@@ -31,6 +31,7 @@
import org.onosproject.bgp.controller.BgpController;
import org.onosproject.bgp.controller.BgpId;
import org.onosproject.bgp.controller.BgpPeer;
+import org.onosproject.bgp.controller.BgpLocalRib;
import org.onosproject.bgp.controller.BgpNodeListener;
import org.onosproject.bgp.controller.BgpPeerManager;
import org.onosproject.bgpio.exceptions.BgpParseException;
@@ -208,6 +209,17 @@
return 0;
}
+ @Override
+ public BgpLocalRib bgpLocalRibVpn() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public BgpLocalRib bgpLocalRib() {
+ // TODO Auto-generated method stub
+ return null;
+ }
@Override
public BgpPeerManager peerManager() {