From 99ab6f0692202e46d82c7b705d10419277143bf6 Mon Sep 17 00:00:00 2001 From: Manisha Malla Date: Tue, 21 Apr 2015 12:28:41 +0530 Subject: [PATCH 1/1] BgpManager commit for: - Bgp Router/Neighbor Listener logic - Bgp FIB DS Writes - Bgp API Provider Signed-off-by: Manisha Malla Change-Id: I9229f92e018b64c8175e15bbef1e7b476a35b66f --- .../IBgpManager.java | 8 +- .../src/main/yang/bgpmanager-api.yang | 20 ++ bgpmanager/bgpmanager-impl/pom.xml | 9 +- .../src/main/config/default-config.xml | 10 + .../bgpmanager/BgpConfigurationManager.java | 229 +++++++++++++++++- .../opendaylight/bgpmanager/BgpManager.java | 131 +++++++--- .../opendaylight/bgpmanager/FibDSWriter.java | 129 ++++++++++ .../bgpmanager/globals/BgpConfiguration.java | 18 +- .../bgpmanager/globals/BgpConstants.java | 4 +- .../client/implementation/BgpRouter.java | 12 +- .../implementation/BgpThriftService.java | 11 +- .../implementation/BgpUpdateHandler.java | 26 +- .../src/main/yang/bgpmanager-impl.yang | 2 + features/src/main/features/features.xml | 3 +- 14 files changed, 539 insertions(+), 73 deletions(-) create mode 100644 bgpmanager/bgpmanager-api/src/main/yang/bgpmanager-api.yang create mode 100644 bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/FibDSWriter.java diff --git a/bgpmanager/bgpmanager-api/src/main/java/org.opendaylight.bgpmanager.api/IBgpManager.java b/bgpmanager/bgpmanager-api/src/main/java/org.opendaylight.bgpmanager.api/IBgpManager.java index 36a2cff5..bf7153e1 100644 --- a/bgpmanager/bgpmanager-api/src/main/java/org.opendaylight.bgpmanager.api/IBgpManager.java +++ b/bgpmanager/bgpmanager-api/src/main/java/org.opendaylight.bgpmanager.api/IBgpManager.java @@ -10,13 +10,13 @@ public interface IBgpManager { * @param importRts * @param exportRts */ - public void addVrf(String rd, Collection importRts, Collection exportRts); + public void addVrf(String rd, Collection importRts, Collection exportRts) throws Exception; /** * * @param rd */ - public void deleteVrf(String rd); + public void deleteVrf(String rd) throws Exception; /** * @@ -25,13 +25,13 @@ public interface IBgpManager { * @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 diff --git a/bgpmanager/bgpmanager-api/src/main/yang/bgpmanager-api.yang b/bgpmanager/bgpmanager-api/src/main/yang/bgpmanager-api.yang new file mode 100644 index 00000000..be066c3c --- /dev/null +++ b/bgpmanager/bgpmanager-api/src/main/yang/bgpmanager-api.yang @@ -0,0 +1,20 @@ +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 diff --git a/bgpmanager/bgpmanager-impl/pom.xml b/bgpmanager/bgpmanager-impl/pom.xml index 11e14fff..7ad9092f 100644 --- a/bgpmanager/bgpmanager-impl/pom.xml +++ b/bgpmanager/bgpmanager-impl/pom.xml @@ -32,13 +32,12 @@ and is available at http://www.eclipse.org/legal/epl-v10.html model-bgp 2013.07.15.7-SNAPSHOT - + org.apache.thrift libthrift diff --git a/bgpmanager/bgpmanager-impl/src/main/config/default-config.xml b/bgpmanager/bgpmanager-impl/src/main/config/default-config.xml index e629fa03..d1a5ce52 100644 --- a/bgpmanager/bgpmanager-impl/src/main/config/default-config.xml +++ b/bgpmanager/bgpmanager-impl/src/main/config/default-config.xml @@ -9,6 +9,7 @@ and is available at http://www.eclipse.org/legal/epl-v10.html --> + urn:opendaylight:params:xml:ns:yang:bgpmanager:api?module=bgpmanager-api&revision=2015-04-20 urn:opendaylight:params:xml:ns:yang:bgpmanager:impl?module=bgpmanager-impl&revision=2015-03-26 urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding?module=opendaylight-md-sal-binding&revision=2013-10-28 @@ -25,6 +26,15 @@ and is available at http://www.eclipse.org/legal/epl-v10.html + + + prefix:bgpmanager-api + + bgpmanager + /modules/module[type='bgpmanager-impl'][name='bgpmanager-default'] + + + diff --git a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/BgpConfigurationManager.java b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/BgpConfigurationManager.java index dfa061b2..b12f9278 100644 --- a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/BgpConfigurationManager.java +++ b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/BgpConfigurationManager.java @@ -11,30 +11,42 @@ import java.util.Collections; 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 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 implements AutoCloseable { @@ -54,23 +66,98 @@ public class BgpConfigurationManager { } } + private synchronized void removeBgpRouter(BgpRouter del) + { + + } + @Override protected void remove(InstanceIdentifier 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 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 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 getWildCardPath() { @@ -108,23 +195,149 @@ public class BgpConfigurationManager { } } + private synchronized void removeBgpNeighbors(BgpNeighbors del) { + List 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 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 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 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 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 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() { diff --git a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/BgpManager.java b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/BgpManager.java index 14cd1aab..d4fa53cc 100644 --- a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/BgpManager.java +++ b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/BgpManager.java @@ -27,6 +27,9 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; 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; @@ -34,35 +37,68 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana 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 { @@ -73,20 +109,27 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana 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; } @@ -95,7 +138,8 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana 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); } @@ -107,7 +151,14 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana @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) @@ -120,34 +171,33 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana 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) { @@ -156,6 +206,7 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana }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)); } @@ -163,7 +214,7 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana @Override - public void addVrf(String rd, Collection importRts, Collection exportRts) { + public void addVrf(String rd, Collection importRts, Collection exportRts) throws Exception { if(bgpThriftClient == null) { s_logger.info("Add BGP vrf - bgpThriftClient is null. Unable to add BGP vrf."); return; @@ -173,16 +224,19 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana } 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; @@ -192,54 +246,69 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana } 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 %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 %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 %s:%s due to Transport error", rd, prefix)); reInitConn(); + throw t; } catch (Exception e) { s_logger.error(String.format("Failed deleting prefix entry %s:%s", rd, prefix)); + throw e; } } @@ -278,7 +347,7 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana } } - public void reInitConn() { + public synchronized void reInitConn() { try { bgpThriftClient.reInit(); @@ -287,7 +356,7 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana 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); @@ -449,10 +518,10 @@ public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpMana } */ -/* 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()); diff --git a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/FibDSWriter.java b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/FibDSWriter.java new file mode 100644 index 00000000..6737385a --- /dev/null +++ b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/FibDSWriter.java @@ -0,0 +1,129 @@ +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 idBuilder = + InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)); + + logger.info("Created idBuilder for VrfTables"); + + InstanceIdentifier vrfTableId = idBuilder.build(); + Optional vrfTable = read(LogicalDatastoreType.CONFIGURATION, vrfTableId); + if (vrfTable.isPresent()) { + List vrfEntryListExisting = vrfTable.get().getVrfEntry(); + vrfEntryListExisting.add(vrfEntry); + + + VrfTables vrfTableUpdate = new VrfTablesBuilder().setRouteDistinguisher(rd). + setVrfEntry(vrfEntryListExisting).build(); + write(LogicalDatastoreType.CONFIGURATION, vrfTableId, vrfTableUpdate); + } + else { + List vrfEntryList = new ArrayList(); + 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 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 idBuilder = + InstanceIdentifier.builder(FibEntries.class).child(VrfTables.class, new VrfTablesKey(rd)); + InstanceIdentifier vrfTableId = idBuilder.build(); + Optional vrfTable = read(LogicalDatastoreType.CONFIGURATION, vrfTableId); + if (vrfTable.isPresent()) { + String searchPfx = prefix; + + List vrfEntryListExisting = vrfTable.get().getVrfEntry(); + for (Iterator 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 Optional read(LogicalDatastoreType datastoreType, + InstanceIdentifier path) { + + ReadOnlyTransaction tx = broker.newReadOnlyTransaction(); + + Optional result = Optional.absent(); + try { + result = tx.read(datastoreType, path).get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + + return result; + } + + private void write(LogicalDatastoreType datastoreType, + InstanceIdentifier path, T data) { + WriteTransaction tx = broker.newWriteOnlyTransaction(); + tx.put(datastoreType, path, data, true); + tx.submit(); + } +} diff --git a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/globals/BgpConfiguration.java b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/globals/BgpConfiguration.java index e1d19502..ae8bfb4b 100644 --- a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/globals/BgpConfiguration.java +++ b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/globals/BgpConfiguration.java @@ -7,18 +7,16 @@ */ 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() { } @@ -63,14 +61,20 @@ public class BgpConfiguration implements Serializable { 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{" + diff --git a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/globals/BgpConstants.java b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/globals/BgpConstants.java index 5ffca0a9..396ed8b7 100644 --- a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/globals/BgpConstants.java +++ b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/globals/BgpConstants.java @@ -3,8 +3,8 @@ package org.opendaylight.bgpmanager.globals; 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; diff --git a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/client/implementation/BgpRouter.java b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/client/implementation/BgpRouter.java index c10bb303..82ac98d8 100644 --- a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/client/implementation/BgpRouter.java +++ b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/client/implementation/BgpRouter.java @@ -145,7 +145,7 @@ public class BgpRouter { 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; @@ -154,7 +154,7 @@ public class BgpRouter { dispatch(bop); } - public void delNeighbor(String nbrIp) + public synchronized void delNeighbor(String nbrIp) throws TException, BgpRouterException { bop.type = DEL_NBR; bop.nbrIp = nbrIp; @@ -162,7 +162,7 @@ public class BgpRouter { dispatch(bop); } - public void addVrf(String rd, List irts, List erts) + public synchronized void addVrf(String rd, List irts, List erts) throws TException, BgpRouterException { bop.type = ADD_VRF; bop.rd = rd; @@ -172,7 +172,7 @@ public class BgpRouter { dispatch(bop); } - public void delVrf(String rd) + public synchronized void delVrf(String rd) throws TException, BgpRouterException { bop.type = DEL_VRF; bop.rd = rd; @@ -180,7 +180,7 @@ public class BgpRouter { 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; @@ -191,7 +191,7 @@ public class BgpRouter { 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; diff --git a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/server/implementation/BgpThriftService.java b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/server/implementation/BgpThriftService.java index 06c353e6..c6d01195 100644 --- a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/server/implementation/BgpThriftService.java +++ b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/server/implementation/BgpThriftService.java @@ -5,6 +5,8 @@ import org.apache.thrift.server.TServer; 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; @@ -22,9 +24,12 @@ public class BgpThriftService { //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; } @@ -81,7 +86,7 @@ public class BgpThriftService { private class ThriftRunnable implements Runnable { @Override public void run() { - notificationHandler = new BgpUpdateHandler(); + //notificationHandler = new BgpUpdateHandler(bgpManager); try { serverTransport = new TServerSocket(port); diff --git a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/server/implementation/BgpUpdateHandler.java b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/server/implementation/BgpUpdateHandler.java index 86880709..d0825d9d 100644 --- a/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/server/implementation/BgpUpdateHandler.java +++ b/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/bgpmanager/thrift/server/implementation/BgpUpdateHandler.java @@ -1,35 +1,49 @@ 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(); } } diff --git a/bgpmanager/bgpmanager-impl/src/main/yang/bgpmanager-impl.yang b/bgpmanager/bgpmanager-impl/src/main/yang/bgpmanager-impl.yang index 60c87850..e4006364 100644 --- a/bgpmanager/bgpmanager-impl/src/main/yang/bgpmanager-impl.yang +++ b/bgpmanager/bgpmanager-impl/src/main/yang/bgpmanager-impl.yang @@ -5,6 +5,7 @@ module bgpmanager-impl { 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"; @@ -16,6 +17,7 @@ module bgpmanager-impl { identity bgpmanager-impl { base config:module-type; + config:provided-service bgpmgr-api:bgpmanager-api; config:java-name-prefix BgpManagerImpl; } diff --git a/features/src/main/features/features.xml b/features/src/main/features/features.xml index 65cd4382..7147f6de 100644 --- a/features/src/main/features/features.xml +++ b/features/src/main/features/features.xml @@ -23,11 +23,12 @@ and is available at http://www.eclipse.org/legal/epl-v10.html mvn:org.opendaylight.vpnservice/nexthopmgr-api/${nexthopmgr.version} mvn:org.opendaylight.vpnservice/idmanager-api/${idmanager.version} mvn:org.opendaylight.vpnservice/fibmanager-api/${fibmanager.version} - mvn:org.opendaylight.vpnservice/bgpmanager-api/${project.version} + odl-mdsal-broker odl-vpnservice-api + mvn:org.opendaylight.vpnservice/bgpmanager-api/${project.version} mvn:org.opendaylight.vpnservice/vpnmanager-impl/${vpnmanager.version} mvn:org.opendaylight.vpnservice/interfacemgr-impl/${interfacemgr.version} mvn:org.opendaylight.vpnservice/nexthopmgr-impl/${nexthopmgr.version} -- 2.36.6