* @param importRts
* @param exportRts
*/
- public void addVrf(String rd, Collection<String> importRts, Collection<String> exportRts);
+ public void addVrf(String rd, Collection<String> importRts, Collection<String> exportRts) throws Exception;
/**
*
* @param rd
*/
- public void deleteVrf(String rd);
+ public void deleteVrf(String rd) throws Exception;
/**
*
* @param nextHop
* @param vpnLabel
*/
- public void addPrefix(String rd, String prefix, String nextHop, int vpnLabel);
+ public void addPrefix(String rd, String prefix, String nextHop, int vpnLabel) throws Exception;
/**
*
* @param rd
* @param prefix
*/
- public void deletePrefix(String rd, String prefix);
+ public void deletePrefix(String rd, String prefix) throws Exception;
}
\ No newline at end of file
--- /dev/null
+module bgpmanager-api {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:bgpmanager:api";
+ prefix "bgpmgr-api";
+
+ import config { prefix config; revision-date 2013-04-05; }
+
+ description
+ "Service definition for bgpmanager project";
+
+ revision "2015-04-20" {
+ description
+ "Initial revision";
+ }
+
+ identity bgpmanager-api {
+ base "config:service-type";
+ config:java-class "org.opendaylight.bgpmanager.api.IBgpManager";
+ }
+}
\ No newline at end of file
<artifactId>model-bgp</artifactId>
<version>2013.07.15.7-SNAPSHOT</version>
</dependency>
- <!--
<dependency>
- <groupId>${project.groupId}.third-party</groupId>
- <artifactId>org.apache.thriftlib</artifactId>
- <version>1.0.1-SNAPSHOT</version>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>fibmanager-api</artifactId>
+ <version>0.0.1-SNAPSHOT</version>
</dependency>
- -->
+
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
-->
<snapshot>
<required-capabilities>
+ <capability>urn:opendaylight:params:xml:ns:yang:bgpmanager:api?module=bgpmanager-api&revision=2015-04-20</capability>
<capability>urn:opendaylight:params:xml:ns:yang:bgpmanager:impl?module=bgpmanager-impl&revision=2015-03-26</capability>
<capability>urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28</capability>
</required-capabilities>
</broker>
</module>
</modules>
+ <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <service>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:bgpmanager:api">prefix:bgpmanager-api</type>
+ <instance>
+ <name>bgpmanager</name>
+ <provider>/modules/module[type='bgpmanager-impl'][name='bgpmanager-default']</provider>
+ </instance>
+ </service>
+ </services>
</data>
</configuration>
</snapshot>
import java.util.Map;
import java.util.Set;
+import org.apache.thrift.TException;
+import org.opendaylight.bgpmanager.globals.BgpConfiguration;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.opendaylight.yangtools.concepts.ListenerRegistration;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.BgpRouter;
import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.BgpNeighbors;
+import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.BgpNeighbor;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.List;
+
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
public class BgpConfigurationManager {
private static final Logger LOG = LoggerFactory.getLogger(BgpConfigurationManager.class);
private ListenerRegistration<DataChangeListener> listenerRegistration;
+ private BgpConfiguration bgpConfiguration;
+ private BgpManager bgpManager;
private final DataBroker broker;
+ private static final int MAX_RETRIES_BGP_COMMUNICATION = 1;
- public BgpConfigurationManager(final DataBroker db) {
+ public BgpConfigurationManager(final DataBroker db, BgpConfiguration bgpCfg, BgpManager bgpMgr) {
broker = db;
- BgpRtrCfgManager rtrCfgManager = new BgpRtrCfgManager(db);
- BgpNghbrCfgManager nghbrCfgManager = new BgpNghbrCfgManager(db);
+ bgpConfiguration = bgpCfg;
+ bgpManager = bgpMgr;
+ BgpRtrCfgManager rtrCfgManager = new BgpRtrCfgManager(broker);
+ BgpNghbrCfgManager nghbrCfgManager = new BgpNghbrCfgManager(broker);
}
public class BgpRtrCfgManager extends AbstractDataChangeListener<BgpRouter> implements AutoCloseable {
}
}
+ private synchronized void removeBgpRouter(BgpRouter del)
+ {
+
+ }
+
@Override
protected void remove(InstanceIdentifier<BgpRouter> identifier,
BgpRouter del) {
- // TODO Auto-generated method stub
+
+ LOG.info("Bgp Router deleted in DS - " + "key: " + identifier + ", value=" + del);
+
+ removeBgpRouter(del);
+
+ }
+
+ private synchronized void updateBgpRouter(BgpRouter original, BgpRouter update)
+ {
+ if(bgpConfiguration.getAsNum() != update.getLocalAsNumber()) {
+ bgpConfiguration.setAsNum(update.getLocalAsNumber());
+ bgpConfiguration.setConfigUpdated();
+ }
+ if(bgpConfiguration.getRouterId() != update.getLocalAsIdentifier().getIpv4Address().getValue()) {
+ bgpConfiguration.setRouterId(update.getLocalAsIdentifier().getIpv4Address().getValue());
+ bgpConfiguration.setConfigUpdated();
+ }
+
+ if(bgpConfiguration.isConfigUpdated()) {
+ int retryCount = 0;
+ boolean retry = false;
+ do {
+ try {
+ if(retry)
+ LOG.info("Retrying BgpService start.." + "retry count:" + retryCount);
+ //bgpManager.waitForBgpInit();
+ bgpManager.startBgpService();
+ LOG.info("BgpService start done..");
+ retry = false;
+ } catch (TException t) {
+ LOG.info("BgpService start failed..");
+ retry = true;
+ retryCount++;
+ }
+ } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);
+
+ bgpConfiguration.unsetConfigUpdated();
+ }
+
}
@Override
protected void update(InstanceIdentifier<BgpRouter> identifier,
BgpRouter original, BgpRouter update) {
- // TODO Auto-generated method stub
+
+ LOG.info("Bgp Router Updated in DS - " + "key: " + identifier + ", original=" + original + ", update=" + update);
+
+ updateBgpRouter(original, update);
+ }
+
+ private synchronized void addBgpRouter(BgpRouter value){
+ if(value.getLocalAsNumber() != null) {
+ bgpConfiguration.setAsNum(value.getLocalAsNumber());
+ }
+ if(value.getLocalAsIdentifier() != null) {
+ bgpConfiguration.setRouterId(value.getLocalAsIdentifier().getIpv4Address().getValue());
+ }
+
+ if(value.getLocalAsNumber() == null || value.getLocalAsIdentifier() == null)
+ return;
+
+ int retryCount = 0;
+ boolean retry = false;
+
+ do {
+ try {
+ //bgpManager.waitForBgpInit();
+ bgpManager.startBgpService();
+ retry = false;
+ } catch (TException t) {
+ retry = true;
+ retryCount++;
+ }
+ } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);
}
@Override
protected void add(InstanceIdentifier<BgpRouter> identifier,
BgpRouter value) {
- LOG.info("key: " + identifier + ", value=" + value);
+ LOG.info("Bgp Router added in DS - " + "key: " + identifier + ", value=" + value);
+ LOG.info("Bgp Router localASNumber:" + value.getLocalAsNumber());
+ LOG.info("Bgp Router localASIdentifier:" + value.getLocalAsIdentifier());
+ addBgpRouter(value);
}
private InstanceIdentifier<BgpRouter> getWildCardPath() {
}
}
+ private synchronized void removeBgpNeighbors(BgpNeighbors del) {
+ List<BgpNeighbor> bgpNeighborList = del.getBgpNeighbor();
+ BgpNeighbor gateway = bgpNeighborList.get(0);
+
+ if(gateway != null) {
+ if ((gateway.getPeerAddressType() != null) && (gateway.getPeerAddressType() instanceof org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)) {
+ IpAddress neighborIPAddr = ((org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress) gateway.getPeerAddressType()).getIpAddress();
+ LOG.info("Bgp Neighbor IP Address " + neighborIPAddr.getIpv4Address().getValue());
+ bgpConfiguration.setNeighbourIp("");
+ bgpConfiguration.setNeighbourAsNum(0);
+
+ int retryCount = 0;
+ boolean retry = false;
+
+ do {
+ try {
+ bgpManager.deleteNeighbor(neighborIPAddr.getIpv4Address().getValue());
+ retry = false;
+ } catch (TException t) {
+ retry = true;
+ retryCount++;
+ }
+ } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);
+
+ }
+ }
+
+ }
+
@Override
protected void remove(InstanceIdentifier<BgpNeighbors> identifier,
BgpNeighbors del) {
- // TODO Auto-generated method stub
+
+ LOG.info("Bgp Neighbors deleted in DS - " + "key: " + identifier + ", value=" + del);
+ removeBgpNeighbors(del);
+ }
+
+ private synchronized void updateBgpNeighbors(BgpNeighbors original, BgpNeighbors update) {
+ List<BgpNeighbor> bgpNeighborList = update.getBgpNeighbor();
+
+ //We will always consider the first element of this list, since there can be just one DC Gateway
+ BgpNeighbor gateway = bgpNeighborList.get(0);
+
+ if(gateway != null) {
+ if(gateway.getAsNumber() != null) {
+ LOG.info("Bgp Neighbor AS number " + gateway.getAsNumber());
+ if(bgpConfiguration.getNeighbourAsNum() != gateway.getAsNumber()) {
+ bgpConfiguration.setNeighbourAsNum(gateway.getAsNumber());
+ bgpConfiguration.setConfigUpdated();
+ }
+ }
+ if((gateway.getPeerAddressType() != null) && (gateway.getPeerAddressType() instanceof org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)) {
+ IpAddress neighborIPAddr = ((org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)gateway.getPeerAddressType()).getIpAddress();
+ LOG.info("Bgp Neighbor IP Address " + neighborIPAddr.getIpv4Address().getValue());
+ if(bgpConfiguration.getNeighbourIp() != neighborIPAddr.getIpv4Address().getValue()) {
+ bgpConfiguration.setNeighbourIp(neighborIPAddr.getIpv4Address().getValue());
+ bgpConfiguration.setConfigUpdated();
+ }
+
+ }
+ }
+ if(bgpConfiguration.isConfigUpdated()) {
+ //delete old neighbor
+ BgpNeighbor old = original.getBgpNeighbor().get(0);
+ IpAddress oldIPAddr = ((org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)old.getPeerAddressType()).getIpAddress();
+ int retryCount = 0;
+ boolean retry = false;
+ do {
+ try {
+ bgpManager.deleteNeighbor(oldIPAddr.getIpv4Address().getValue());
+ retry = false;
+ } catch (TException t) {
+ retry = true;
+ retryCount++;
+ }
+ } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);
+
+ //add the newly configured neighbor
+ retryCount = 0;
+ retry = false;
+ do {
+ try {
+ bgpManager.addNeighbor(bgpConfiguration.getNeighbourIp(), bgpConfiguration.getNeighbourAsNum());
+ retry = false;
+ } catch (TException t) {
+ retry = true;
+ retryCount++;
+ }
+ } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);
+ }
}
@Override
protected void update(InstanceIdentifier<BgpNeighbors> identifier,
BgpNeighbors original, BgpNeighbors update) {
- // TODO Auto-generated method stub
+
+ LOG.info("Bgp Neighbors Updated in DS - " + "key: " + identifier + ", original=" + original + ", update=" + update);
+
+ updateBgpNeighbors(original, update);
+
+ }
+
+ private synchronized void addBgpNeighbors(BgpNeighbors value) {
+ List<BgpNeighbor> bgpNeighborList = value.getBgpNeighbor();
+
+ //We will always consider the first element of this list, since there can be just one DC Gateway
+ BgpNeighbor gateway = bgpNeighborList.get(0);
+
+ if(gateway != null) {
+ if(gateway.getAsNumber() != null) {
+ LOG.info("Bgp Neighbor AS number " + gateway.getAsNumber());
+ bgpConfiguration.setNeighbourAsNum(gateway.getAsNumber());
+ }
+ if((gateway.getPeerAddressType() != null) && (gateway.getPeerAddressType() instanceof org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)) {
+ IpAddress neighborIPAddr = ((org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.bgp.rev130715.bgp.neighbors.bgp.neighbor.peer.address.type.IpAddress)gateway.getPeerAddressType()).getIpAddress();
+ LOG.info("Bgp Neighbor IP Address " + neighborIPAddr.getIpv4Address().getValue());
+ bgpConfiguration.setNeighbourIp(neighborIPAddr.getIpv4Address().getValue());
+
+ }
+ if(bgpConfiguration.getNeighbourAsNum() != 0 && bgpConfiguration.getNeighbourIp() != null) {
+ int retryCount = 0;
+ boolean retry = false;
+ do {
+ try {
+ bgpManager.addNeighbor(bgpConfiguration.getNeighbourIp(), bgpConfiguration.getNeighbourAsNum());
+ retry = false;
+ } catch (TException t) {
+ retry = true;
+ retryCount++;
+ }
+ } while(retry && retryCount <= MAX_RETRIES_BGP_COMMUNICATION);
+ }
+ }
+
}
@Override
protected void add(InstanceIdentifier<BgpNeighbors> identifier,
BgpNeighbors value) {
LOG.info("key: " + identifier + ", value=" + value);
+ LOG.info("Bgp Neighbor added in DS - " + "key: " + identifier + ", value=" + value);
+ addBgpNeighbors(value);
}
private InstanceIdentifier<?> getWildCardPath() {
import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger s_logger = LoggerFactory.getLogger(BgpManager.class);
private BgpConfigurationManager bgpConfigurationMgr;
+ private FibDSWriter fibDSWriter;
private BgpConfiguration bgpConfiguration = new BgpConfiguration();
private BgpRouter bgpThriftClient;
private BgpThriftService bgpThriftService;
+ private boolean isBgpInitialized = false;
+ private boolean hasBgpServiceStarted = false;
private String bgpHost;
private int bgpPort;
+
+ private String getCustomConfig(String var, String def) {
+ Bundle b = FrameworkUtil.getBundle(this.getClass());
+ BundleContext context = null;
+ if (b != null) {
+ context = b.getBundleContext();
+ }
+ if (context != null)
+ return context.getProperty(var);
+ else
+ return def;
+
+ }
+
private void initializeBGPCommunication() {
//start our side of thrift server
- bgpThriftService = new BgpThriftService();
+ bgpThriftService = new BgpThriftService(this, fibDSWriter);
bgpThriftService.start();
//start bgp thrift client connection
bgpThriftClient = new BgpRouter();
- //get bgp server, port from config.ini and connect
- bgpHost = System.getProperty(BgpConstants.BGP_SPEAKER_HOST_NAME, BgpConstants.DEFAULT_BGP_HOST_NAME);
- bgpPort = Integer.getInteger(BgpConstants.BGP_SPEAKER_THRIFT_PORT, BgpConstants.DEFAULT_BGP_THRIFT_PORT);
+ bgpHost = getCustomConfig(BgpConstants.BGP_SPEAKER_HOST_NAME, BgpConstants.DEFAULT_BGP_HOST_NAME);
+ bgpPort = BgpConstants.DEFAULT_BGP_THRIFT_PORT;
configureBgpServer(bgpHost, bgpPort);
try {
connectToServer(bgpHost, bgpPort);
} catch (Exception e) {
- //nothing to be done here, the logs have already been printed by the Exception handlers of "connectToServer"
+ return;
+ }
+
+ isBgpInitialized = true;
+ //notify(); //notify all threads waiting for bgp init
+
+ }
+
+ public synchronized void waitForBgpInit() {
+ if(!isBgpInitialized) {
+ try {
+ wait();
+ } catch (InterruptedException e) {
+ s_logger.error("InterruptedException while waiting for Bgp connection to initialize");
+ return;
+ }
+ }
+ }
+
+ public void startBgpService() throws TException {
+ if(bgpThriftClient == null) {
+ s_logger.info("Start Bgp Service - bgpThriftClient is null. Unable to start BGP service.");
+ return;
}
- /* read bgp router and peer info from DS
- for the case when the BGP module came down but the DataStore was still up
- */
- //for testing
- configureBgp(101, "10.10.10.10");
// Now try start bgp - if bgp is already Active, it will tell us, nothing to do then
try {
s_logger.info("bgp server already active");
return;
}
+ else if(be.getErrorCode() == BgpRouterException.BGP_ERR_NOT_INITED) {
+ s_logger.error("bgp server connection not initialized.");
+ reInitConn();
+ return;
+ }
else {
s_logger.error("application error while starting bgp server " + be.getErrorCode());
return;
}
} catch (TException t) {
- s_logger.error("Transport error while starting bgp server ", t);
- return;
+ //s_logger.error("Transport error while starting bgp server ", t);
+ s_logger.error("Could not set up thrift connection with bgp server");
+ reInitConn();
+ throw t;
} catch (Exception e) {
s_logger.error("Error while starting bgp server", e);
+ return;
}
- //For testing - remove later
- addNeighbor("169.144.42.168", 102);
+ hasBgpServiceStarted = true;
}
s_logger.info("BgpManager Session Initiated");
try {
final DataBroker dataBroker = session.getSALService(DataBroker.class);
- bgpConfigurationMgr = new BgpConfigurationManager(dataBroker);
+ bgpConfigurationMgr = new BgpConfigurationManager(dataBroker, bgpConfiguration, this);
+ fibDSWriter = new FibDSWriter(dataBroker);
} catch (Exception e) {
s_logger.error("Error initializing services", e);
}
@Override
public void close() throws Exception {
s_logger.info("BgpManager Closed");
- }
+
+ //close the client and server ends of the thrift communication
+ if(bgpThriftClient != null)
+ bgpThriftClient.disconnect();
+ bgpThriftService.stop();
+
+
+ }
private void setBgpServerDetails() {
if(bgpThriftClient != null)
setBgpServerDetails();
}
- private void addNeighbor(String ipAddress, int asNum) {
+ protected void addNeighbor(String ipAddress, long asNum) throws TException {
if(bgpThriftClient == null) {
s_logger.info("Add BGP Neighbor - bgpThriftClient is null. Unable to add BGP Neighbor.");
return;
}
- bgpConfiguration.setNeighbourIp(ipAddress);
- bgpConfiguration.setNeighbourAsNum(asNum);
- //updateBgpConfiguration(bgpConfiguration);
+
try {
- bgpThriftClient.addNeighbor(ipAddress, asNum);
+ bgpThriftClient.addNeighbor(ipAddress, (int) asNum);
} catch (BgpRouterException b) {
s_logger.error("Failed to add BGP neighbor " + ipAddress + "due to BgpRouter Exception number " + b.getErrorCode());
s_logger.error("BgpRouterException trace ", b);
} catch (TException t) {
s_logger.error(String.format("Failed adding neighbor %s due to Transport error", ipAddress));
reInitConn();
+ throw t;
} catch (Exception e) {
s_logger.error(String.format("Failed adding neighbor %s", ipAddress));
}
}
- private void deleteNeighbor(String ipAddress) {
+ protected void deleteNeighbor(String ipAddress) throws TException {
if(bgpThriftClient == null) {
s_logger.info("Delete BGP Neighbor - bgpThriftClient is null. Unable to delete BGP Neighbor.");
return;
}
- bgpConfiguration.setNeighbourIp("");
+
try {
bgpThriftClient.delNeighbor(ipAddress);
} catch (BgpRouterException b) {
}catch (TException t) {
s_logger.error(String.format("Failed deleting neighbor %s due to Transport error", ipAddress));
reInitConn();
+ throw t;
} catch (Exception e) {
s_logger.error(String.format("Failed deleting neighbor %s", ipAddress));
}
@Override
- public void addVrf(String rd, Collection<String> importRts, Collection<String> exportRts) {
+ public void addVrf(String rd, Collection<String> importRts, Collection<String> exportRts) throws Exception {
if(bgpThriftClient == null) {
s_logger.info("Add BGP vrf - bgpThriftClient is null. Unable to add BGP vrf.");
return;
} catch (BgpRouterException b) {
s_logger.error("Failed to add BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
s_logger.error("BgpRouterException trace ", b);
+ throw b;
} catch (TException t) {
s_logger.error(String.format("Failed adding vrf %s due to Transport error", rd));
reInitConn();
+ throw t;
} catch (Exception e) {
s_logger.error(String.format("Failed adding vrf %s", rd));
+ throw e;
}
}
@Override
- public void deleteVrf(String rd) {
+ public void deleteVrf(String rd) throws Exception {
if(bgpThriftClient == null) {
s_logger.info("Delete BGP vrf - bgpThriftClient is null. Unable to delete BGP vrf.");
return;
} catch (BgpRouterException b) {
s_logger.error("Failed to delete BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
s_logger.error("BgpRouterException trace ", b);
+ throw b;
} catch (TException t) {
s_logger.error(String.format("Failed deleting vrf %s due to Transport error", rd));
reInitConn();
+ throw t;
} catch (Exception e) {
s_logger.error(String.format("Failed deleting vrf %s", rd));
+ throw e;
}
}
@Override
- public void addPrefix(String rd, String prefix, String nextHop, int vpnLabel) {
+ public void addPrefix(String rd, String prefix, String nextHop, int vpnLabel) throws Exception {
if(bgpThriftClient == null) {
s_logger.info("Add BGP prefix - bgpThriftClient is null. Unable to add BGP prefix.");
return;
}
+ if(!hasBgpServiceStarted) {
+ fibDSWriter.addFibEntryToDS(rd, prefix, nextHop, vpnLabel);
+ }
try {
bgpThriftClient.addPrefix(rd, prefix, nextHop, vpnLabel);
} catch (BgpRouterException b) {
s_logger.error("Failed to add BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
s_logger.error("BgpRouterException trace ", b);
+ throw b;
} catch (TException t) {
s_logger.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d due to Transport error",
rd, prefix, nextHop, vpnLabel));
reInitConn();
+ throw t;
} catch (Exception e) {
s_logger.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d",
rd, prefix, nextHop, vpnLabel));
+ throw e;
}
}
@Override
- public void deletePrefix(String rd, String prefix) {
+ public void deletePrefix(String rd, String prefix) throws Exception {
if(bgpThriftClient == null) {
s_logger.info("Delete BGP prefix - bgpThriftClient is null. Unable to delete BGP prefix.");
return;
}
+ if(!hasBgpServiceStarted) {
+ fibDSWriter.removeFibEntryFromDS(rd, prefix);
+ }
try {
bgpThriftClient.delPrefix(rd, prefix);
} catch (BgpRouterException b) {
s_logger.error("Failed to delete BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
s_logger.error("BgpRouterException trace ", b);
+ throw b;
} catch (TException t) {
s_logger.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s due to Transport error",
rd, prefix));
reInitConn();
+ throw t;
} catch (Exception e) {
s_logger.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s",
rd, prefix));
+ throw e;
}
}
}
}
- public void reInitConn() {
+ public synchronized void reInitConn() {
try {
bgpThriftClient.reInit();
s_logger.error("Failed to reinitialize connection to BGP server " + bgpHost + " on port " + bgpPort + " due to BgpRouter Exception number " + b.getErrorCode());
s_logger.error("BgpRouterException trace ", b);
} catch (TException t) {
- s_logger.error("Failed to reinitialize BGP Connection due to Transport error.", t);
+ s_logger.error("Failed to reinitialize BGP Connection due to Transport error.");
}
catch (Exception e) {
s_logger.error("Failed to reinitialize BGP Connection.", e);
}
*/
-/* public void disconnect() {
+ public void disconnect() {
bgpThriftClient.disconnect();
}
-
+/*
public void setRoute(Route r) {
s_logger.info("Setting route in VPN Manager");
//l3Manager.getVpnInstanceManager().addRoute(r.getRd(), r.getPrefix(), r.getNexthop(), r.getLabel());
--- /dev/null
+package org.opendaylight.bgpmanager;
+
+import com.google.common.util.concurrent.Futures;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.VrfEntries;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.vrfentries.VrfEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.vrfentries.VrfEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTablesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTablesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.FibEntries;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Iterator;
+
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.base.Optional;
+
+/**
+ * Created by emhamla on 4/14/2015.
+ */
+public class FibDSWriter {
+ private static final Logger logger = LoggerFactory.getLogger(FibDSWriter.class);
+ private final DataBroker broker;
+
+ public FibDSWriter(final DataBroker db) {
+ broker = db;
+ }
+
+ public synchronized void addFibEntryToDS(String rd, String prefix,
+ String nexthop, int label) {
+
+ VrfEntry vrfEntry = new VrfEntryBuilder().setDestPrefix(prefix).
+ setNextHopAddress(nexthop).setLabel((long)label).build();
+
+ logger.info("Created vrfEntry for " + prefix + " nexthop " + nexthop + " label " + label);
+ InstanceIdentifierBuilder<VrfTables> idBuilder =
+ InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd));
+
+ logger.info("Created idBuilder for VrfTables");
+
+ InstanceIdentifier<VrfTables> vrfTableId = idBuilder.build();
+ Optional<VrfTables> vrfTable = read(LogicalDatastoreType.CONFIGURATION, vrfTableId);
+ if (vrfTable.isPresent()) {
+ List<VrfEntry> vrfEntryListExisting = vrfTable.get().getVrfEntry();
+ vrfEntryListExisting.add(vrfEntry);
+
+
+ VrfTables vrfTableUpdate = new VrfTablesBuilder().setRouteDistinguisher(rd).
+ setVrfEntry(vrfEntryListExisting).build();
+ write(LogicalDatastoreType.CONFIGURATION, vrfTableId, vrfTableUpdate);
+ }
+ else {
+ List<VrfEntry> vrfEntryList = new ArrayList<VrfEntry>();
+ vrfEntryList.add(vrfEntry);
+
+ //add a new vrf table with this vrf entry
+ VrfTables vrfTableNew = new VrfTablesBuilder().setRouteDistinguisher(rd).
+ setVrfEntry(vrfEntryList).build();
+
+ logger.info("Created VrfTables");
+
+ InstanceIdentifier<VrfTables> vrfTableNewId = InstanceIdentifier.builder(FibEntries.class)
+ .child(VrfTables.class, new VrfTablesKey(rd)).build();
+ logger.info("Created idBuilder for new VrfTables");
+ write(LogicalDatastoreType.CONFIGURATION, vrfTableNewId, vrfTableNew);
+ }
+
+ }
+
+ public synchronized void removeFibEntryFromDS(String rd, String prefix) {
+
+ logger.debug("Removing fib entry with destination prefix " + prefix + " from vrf table for rd " + rd);
+
+ InstanceIdentifierBuilder<VrfTables> idBuilder =
+ InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd));
+ InstanceIdentifier<VrfTables> vrfTableId = idBuilder.build();
+ Optional<VrfTables> vrfTable = read(LogicalDatastoreType.CONFIGURATION, vrfTableId);
+ if (vrfTable.isPresent()) {
+ String searchPfx = prefix;
+
+ List<VrfEntry> vrfEntryListExisting = vrfTable.get().getVrfEntry();
+ for (Iterator<VrfEntry> it = vrfEntryListExisting.iterator(); it.hasNext(); ) {
+ VrfEntry elem = it.next();
+ if (elem.getDestPrefix().equals(searchPfx)) {
+ it.remove();
+ break;
+ }
+ }
+
+ VrfTables vrfTableUpdate = new VrfTablesBuilder().setRouteDistinguisher(rd).
+ setVrfEntry(vrfEntryListExisting).build();
+ write(LogicalDatastoreType.CONFIGURATION, vrfTableId, vrfTableUpdate);
+ }
+ }
+
+ private <T extends DataObject> Optional<T> read(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path) {
+
+ ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
+
+ Optional<T> result = Optional.absent();
+ try {
+ result = tx.read(datastoreType, path).get();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return result;
+ }
+
+ private <T extends DataObject> void write(LogicalDatastoreType datastoreType,
+ InstanceIdentifier<T> path, T data) {
+ WriteTransaction tx = broker.newWriteOnlyTransaction();
+ tx.put(datastoreType, path, data, true);
+ tx.submit();
+ }
+}
*/
package org.opendaylight.bgpmanager.globals;
-import java.io.Serializable;
-public class BgpConfiguration implements Serializable {
-
- private static final long serialVersionUID = 1L;
+public class BgpConfiguration {
long asNum;
String bgpServer = "";
int bgpPort;
String routerId = "";
String neighbourIp = "";
- int neighbourAsNum;
+ long neighbourAsNum = 0;
+ boolean configUpdated = false;
public BgpConfiguration() {
}
this.neighbourIp = neighbourIp;
}
- public int getNeighbourAsNum() {
+ public long getNeighbourAsNum() {
return neighbourAsNum;
}
- public void setNeighbourAsNum(int neighbourAsNum) {
+ public void setNeighbourAsNum(long neighbourAsNum) {
this.neighbourAsNum = neighbourAsNum;
}
+ public void setConfigUpdated() { this.configUpdated = true; }
+
+ public void unsetConfigUpdated() { this.configUpdated = false; }
+
+ public boolean isConfigUpdated() { return this.configUpdated; }
+
@Override
public String toString() {
return "BgpConfiguration{" +
public class BgpConstants {
- public static final String BGP_SPEAKER_HOST_NAME = "bpg.speaker.host.name";
- public static final String BGP_SPEAKER_THRIFT_PORT = "bgp.speaker.thrift.port";
+ public static final String BGP_SPEAKER_HOST_NAME = "vpnservice.bgpspeaker.host.name";
+ public static final String BGP_SPEAKER_THRIFT_PORT = "vpnservice.bgpspeaker.thrift.port";
public static final String DEFAULT_BGP_HOST_NAME = "localhost";
public static final int DEFAULT_BGP_THRIFT_PORT = 7644;
dispatch(bop);
}
- public void addNeighbor(String nbrIp, int nbrAsNum)
+ public synchronized void addNeighbor(String nbrIp, int nbrAsNum)
throws TException, BgpRouterException {
bop.type = ADD_NBR;
bop.nbrIp = nbrIp;
dispatch(bop);
}
- public void delNeighbor(String nbrIp)
+ public synchronized void delNeighbor(String nbrIp)
throws TException, BgpRouterException {
bop.type = DEL_NBR;
bop.nbrIp = nbrIp;
dispatch(bop);
}
- public void addVrf(String rd, List<String> irts, List<String> erts)
+ public synchronized void addVrf(String rd, List<String> irts, List<String> erts)
throws TException, BgpRouterException {
bop.type = ADD_VRF;
bop.rd = rd;
dispatch(bop);
}
- public void delVrf(String rd)
+ public synchronized void delVrf(String rd)
throws TException, BgpRouterException {
bop.type = DEL_VRF;
bop.rd = rd;
dispatch(bop);
}
- public void addPrefix(String rd, String prefix, String nexthop, int label)
+ public synchronized void addPrefix(String rd, String prefix, String nexthop, int label)
throws TException, BgpRouterException {
bop.type = ADD_PFX;
bop.rd = rd;
dispatch(bop);
}
- public void delPrefix(String rd, String prefix)
+ public synchronized void delPrefix(String rd, String prefix)
throws TException, BgpRouterException {
bop.type = DEL_PFX;
bop.rd = rd;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.*;
+import org.opendaylight.bgpmanager.BgpManager;
+import org.opendaylight.bgpmanager.FibDSWriter;
import org.opendaylight.bgpmanager.thrift.common.Constants;
import org.opendaylight.bgpmanager.thrift.gen.BgpUpdater;
import org.slf4j.Logger;
//private TNonblockingServerTransport serverTransport;
private TServer server;
private BgpUpdateHandler notificationHandler;
+ private BgpManager bgpManager;
- public BgpThriftService() {
-
+ public BgpThriftService(BgpManager bgpMgr, FibDSWriter dsWriter) {
+ bgpManager = bgpMgr;
+ notificationHandler = new BgpUpdateHandler(bgpManager, dsWriter);
+ //fibDSWriter = dsWriter;
}
private class ThriftRunnable implements Runnable {
@Override
public void run() {
- notificationHandler = new BgpUpdateHandler();
+ //notificationHandler = new BgpUpdateHandler(bgpManager);
try {
serverTransport = new TServerSocket(port);
package org.opendaylight.bgpmanager.thrift.server.implementation;
+import org.opendaylight.bgpmanager.BgpManager;
+import org.opendaylight.bgpmanager.FibDSWriter;
import org.opendaylight.bgpmanager.thrift.gen.BgpUpdater;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.*;
-
class BgpUpdateHandler implements BgpUpdater.Iface {
private static final Logger logger = LoggerFactory.getLogger(BgpUpdateHandler.class);
+ private BgpManager bgpManager;
+ private FibDSWriter fibDSWriter;
+
+ public BgpUpdateHandler(BgpManager bgpMgr, FibDSWriter dsWriter) {
+ bgpManager = bgpMgr;
+ fibDSWriter = dsWriter;
+
+ //Test
+ onUpdatePushRoute("5", "10.1.1.2", 32, "1.2.3.4", 200);
+ onUpdatePushRoute("5", "10.1.1.3", 32, "1.2.3.5", 400);
+ onUpdatePushRoute("10", "10.10.0.10", 32, "5.4.3.2", 600);
+ onUpdateWithdrawRoute("5", "10.1.1.3", 32);
- public BgpUpdateHandler() {}
+
+ }
public void onUpdatePushRoute(String rd, String prefix, int plen,
String nexthop, int label) {
+
logger.info("Route add ** " + rd + " ** " + prefix + "/" + plen
+ " ** " + nexthop + " ** " + label);
//Write to FIB in Data Store
+ fibDSWriter.addFibEntryToDS(rd, prefix + "/" + plen, nexthop, label);
}
public void onUpdateWithdrawRoute(String rd, String prefix, int plen) {
logger.info("Route del ** " + rd + " ** " + prefix + "/" + plen);
- //Write to FIB in Data Store
+ fibDSWriter.removeFibEntryFromDS(rd, prefix + "/" + plen);
}
public void onStartConfigResyncNotification() {
logger.info("BGP (re)started");
-
- //Reconfigure BGP
+ bgpManager.reInitConn();
}
}
import config { prefix config; revision-date 2013-04-05; }
import opendaylight-md-sal-binding { prefix md-sal-binding; revision-date 2013-10-28;}
+ import bgpmanager-api { prefix bgpmgr-api; revision-date 2015-04-20;}
description
"Service definition for bgpmanager project";
identity bgpmanager-impl {
base config:module-type;
+ config:provided-service bgpmgr-api:bgpmanager-api;
config:java-name-prefix BgpManagerImpl;
}
<bundle>mvn:org.opendaylight.vpnservice/nexthopmgr-api/${nexthopmgr.version}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/idmanager-api/${idmanager.version}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/fibmanager-api/${fibmanager.version}</bundle>
- <bundle>mvn:org.opendaylight.vpnservice/bgpmanager-api/${project.version}</bundle>
+
</feature>
<feature name='odl-vpnservice-impl' version='${project.version}' description='OpenDaylight :: vpnservice :: impl '>
<feature version='${mdsal.version}'>odl-mdsal-broker</feature>
<feature version='${project.version}'>odl-vpnservice-api</feature>
+ <bundle>mvn:org.opendaylight.vpnservice/bgpmanager-api/${project.version}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/interfacemgr-impl/${interfacemgr.version}</bundle>
<bundle>mvn:org.opendaylight.vpnservice/nexthopmgr-impl/${nexthopmgr.version}</bundle>