2 * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.bgpmanager;
11 import java.net.SocketTimeoutException;
13 import java.util.concurrent.ConcurrentMap;
14 import java.util.concurrent.CountDownLatch;
16 import org.apache.thrift.TException;
17 import org.opendaylight.bgpmanager.thrift.client.globals.Route;
18 import org.opendaylight.bgpmanager.thrift.client.implementation.BgpRouter;
19 import org.opendaylight.bgpmanager.thrift.server.implementation.BgpThriftService;
20 import org.opendaylight.bgpmanager.thrift.exceptions.BgpRouterException;
21 import org.opendaylight.bgpmanager.api.IBgpManager;
22 import org.opendaylight.bgpmanager.globals.BgpConfiguration;
23 import org.opendaylight.bgpmanager.globals.BgpConstants;
25 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
26 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
27 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
28 import org.opendaylight.controller.sal.binding.api.BindingAwareProvider;
30 import org.osgi.framework.Bundle;
31 import org.osgi.framework.BundleContext;
32 import org.osgi.framework.FrameworkUtil;
33 import org.slf4j.Logger;
34 import org.slf4j.LoggerFactory;
36 public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpManager {
38 private static final Logger LOGGER = LoggerFactory.getLogger(BgpManager.class);
39 private BgpConfigurationManager bgpConfigurationMgr;
40 private FibDSWriter fibDSWriter;
41 private BgpConfiguration bgpConfiguration = new BgpConfiguration();
42 private BgpRouter bgpThriftClient;
43 private BgpThriftService bgpThriftService;
44 private boolean isBgpInitialized = false;
45 private boolean hasBgpServiceStarted = false;
46 private String bgpHost;
50 private String getCustomConfig(String var, String def) {
51 Bundle b = FrameworkUtil.getBundle(this.getClass());
52 BundleContext context = null;
54 context = b.getBundleContext();
57 return context.getProperty(var);
63 private void initializeBGPCommunication() {
64 //start our side of thrift server
65 bgpThriftService = new BgpThriftService(this, fibDSWriter);
66 bgpThriftService.start();
68 //start bgp thrift client connection
69 bgpThriftClient = new BgpRouter();
71 bgpHost = getCustomConfig(BgpConstants.BGP_SPEAKER_HOST_NAME, BgpConstants.DEFAULT_BGP_HOST_NAME);
72 bgpPort = BgpConstants.DEFAULT_BGP_THRIFT_PORT;
74 configureBgpServer(bgpHost, bgpPort);
76 connectToServer(bgpHost, bgpPort);
77 } catch (Exception e) {
81 isBgpInitialized = true;
82 //notify(); //notify all threads waiting for bgp init
86 public synchronized void waitForBgpInit() {
87 if(!isBgpInitialized) {
90 } catch (InterruptedException e) {
91 LOGGER.error("InterruptedException while waiting for Bgp connection to initialize");
97 public void startBgpService() throws TException {
98 if(bgpThriftClient == null) {
99 LOGGER.info("Start Bgp Service - bgpThriftClient is null. Unable to start BGP service.");
103 // Now try start bgp - if bgp is already Active, it will tell us, nothing to do then
105 bgpThriftClient.startBgp((int)bgpConfiguration.getAsNum(), bgpConfiguration.getRouterId());
106 LOGGER.info("Started BGP with AS number " + (int)bgpConfiguration.getAsNum() + " and router id " + bgpConfiguration.getRouterId());
107 } catch (BgpRouterException be) {
108 if(be.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
109 LOGGER.info("bgp server already active");
112 else if(be.getErrorCode() == BgpRouterException.BGP_ERR_NOT_INITED) {
113 LOGGER.error("bgp server connection not initialized.");
118 LOGGER.error("application error while starting bgp server " + be.getErrorCode());
122 } catch (TException t) {
123 LOGGER.error("Could not set up thrift connection with bgp server");
124 //LOGGER.trace("Transport error while starting bgp server ", t);
127 } catch (Exception e) {
128 LOGGER.error("Error while starting bgp server");
129 //LOGGER.trace("Bgp Service not started due to exception", e);
133 hasBgpServiceStarted = true;
138 public void onSessionInitiated(ProviderContext session) {
139 LOGGER.info("BgpManager Session Initiated");
141 final DataBroker dataBroker = session.getSALService(DataBroker.class);
142 bgpConfigurationMgr = new BgpConfigurationManager(dataBroker, bgpConfiguration, this);
143 fibDSWriter = new FibDSWriter(dataBroker);
144 } catch (Exception e) {
145 LOGGER.error("Error initializing services", e);
148 initializeBGPCommunication();
153 public void close() throws Exception {
154 LOGGER.info("BgpManager Closed");
156 //close the client and server ends of the thrift communication
157 if(bgpThriftClient != null)
158 bgpThriftClient.disconnect();
159 bgpThriftService.stop();
164 private void setBgpServerDetails() {
165 if(bgpThriftClient != null)
166 bgpThriftClient.setBgpServer(bgpHost, bgpPort);
169 private void configureBgpServer(String bgpServer, int bgpPort) {
170 bgpConfiguration.setBgpServer(bgpServer);
171 bgpConfiguration.setBgpPort(bgpPort);
172 setBgpServerDetails();
175 protected void addNeighbor(String ipAddress, long asNum) throws TException {
176 if(bgpThriftClient == null) {
177 LOGGER.info("Add BGP Neighbor - bgpThriftClient is null. Unable to add BGP Neighbor.");
182 bgpThriftClient.addNeighbor(ipAddress, (int) asNum);
183 } catch (BgpRouterException b) {
184 LOGGER.error("Failed to add BGP neighbor " + ipAddress + "due to BgpRouter Exception number " + b.getErrorCode());
185 LOGGER.error("BgpRouterException trace ", b);
186 } catch (TException t) {
187 LOGGER.error(String.format("Failed adding neighbor %s due to Transport error", ipAddress));
190 } catch (Exception e) {
191 LOGGER.error(String.format("Failed adding neighbor %s", ipAddress));
196 protected void deleteNeighbor(String ipAddress) throws TException {
197 if(bgpThriftClient == null) {
198 LOGGER.info("Delete BGP Neighbor - bgpThriftClient is null. Unable to delete BGP Neighbor.");
203 bgpThriftClient.delNeighbor(ipAddress);
204 } catch (BgpRouterException b) {
205 LOGGER.error("Failed to delete BGP neighbor " + ipAddress + "due to BgpRouter Exception number " + b.getErrorCode());
206 LOGGER.error("BgpRouterException trace ", b);
207 }catch (TException t) {
208 LOGGER.error(String.format("Failed deleting neighbor %s due to Transport error", ipAddress));
211 } catch (Exception e) {
212 LOGGER.error(String.format("Failed deleting neighbor %s", ipAddress));
218 public void addVrf(String rd, Collection<String> importRts, Collection<String> exportRts) throws Exception {
219 if(bgpThriftClient == null) {
220 LOGGER.info("Add BGP vrf - bgpThriftClient is null. Unable to add BGP vrf.");
224 bgpThriftClient.addVrf(rd, new ArrayList<>(importRts), new ArrayList<>(exportRts));
225 } catch (BgpRouterException b) {
226 LOGGER.error("Failed to add BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
227 LOGGER.error("BgpRouterException trace ", b);
229 } catch (TException t) {
230 LOGGER.error(String.format("Failed adding vrf %s due to Transport error", rd));
233 } catch (Exception e) {
234 LOGGER.error(String.format("Failed adding vrf %s", rd));
240 public void deleteVrf(String rd) throws Exception {
241 if(bgpThriftClient == null) {
242 LOGGER.info("Delete BGP vrf - bgpThriftClient is null. Unable to delete BGP vrf.");
246 bgpThriftClient.delVrf(rd);
247 } catch (BgpRouterException b) {
248 LOGGER.error("Failed to delete BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
249 LOGGER.error("BgpRouterException trace ", b);
251 } catch (TException t) {
252 LOGGER.error(String.format("Failed deleting vrf %s due to Transport error", rd));
255 } catch (Exception e) {
256 LOGGER.error(String.format("Failed deleting vrf %s", rd));
262 public void addPrefix(String rd, String prefix, String nextHop, int vpnLabel) throws Exception {
264 if(bgpThriftClient == null || !hasBgpServiceStarted) {
265 fibDSWriter.addFibEntryToDS(rd, prefix, nextHop, vpnLabel);
270 bgpThriftClient.addPrefix(rd, prefix, nextHop, vpnLabel);
271 } catch (BgpRouterException b) {
272 LOGGER.error("Failed to add BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
273 LOGGER.error("BgpRouterException trace ", b);
275 } catch (TException t) {
276 LOGGER.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d due to Transport error",
277 rd, prefix, nextHop, vpnLabel));
280 } catch (Exception e) {
281 LOGGER.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d",
282 rd, prefix, nextHop, vpnLabel));
289 public void deletePrefix(String rd, String prefix) throws Exception {
290 if(bgpThriftClient == null || !hasBgpServiceStarted) {
291 fibDSWriter.removeFibEntryFromDS(rd, prefix);
296 bgpThriftClient.delPrefix(rd, prefix);
297 } catch (BgpRouterException b) {
298 LOGGER.error("Failed to delete BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
299 LOGGER.error("BgpRouterException trace ", b);
301 } catch (TException t) {
302 LOGGER.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s due to Transport error",
306 } catch (Exception e) {
307 LOGGER.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s",
313 private void connectToServer(String host, int port) throws Exception {
318 if(bgpThriftClient == null) {
319 LOGGER.error("Failed to connect to BGP server since Bgp Thrift Client is not initialized yet.");
323 bgpThriftClient.connect(host, port);
324 LOGGER.info("Connected to BGP server " + host + " on port " + port);
325 } catch (BgpRouterException b) {
326 LOGGER.error("Failed to connect to BGP server " + host + " on port " + port + " due to BgpRouter Exception number " + b.getErrorCode());
327 //_logger.error("BgpRouterException trace ", b);
329 } catch (TException t) {
330 LOGGER.error("Failed to initialize BGP Connection due to Transport error ");
333 catch (Exception e) {
334 LOGGER.error("Failed to initialize BGP Connection ");
339 public void configureBgp(long asNum, String routerId) {
341 bgpConfiguration.setAsNum(asNum);
342 bgpConfiguration.setRouterId(routerId);
343 } catch(Exception e) {
344 LOGGER.error("failed configuring bgp ",e);
348 public synchronized void reInitConn() {
351 bgpThriftClient.reInit();
352 LOGGER.info("Reinitialized connection to BGP Server " + bgpHost);
353 } catch (BgpRouterException b) {
354 LOGGER.error("Failed to reinitialize connection to BGP server " + bgpHost + " on port " + bgpPort + " due to BgpRouter Exception number " + b.getErrorCode());
355 LOGGER.error("BgpRouterException trace ", b);
356 } catch (TException t) {
357 LOGGER.error("Failed to reinitialize BGP Connection due to Transport error.");
359 catch (Exception e) {
360 LOGGER.error("Failed to reinitialize BGP Connection.", e);
364 public void disconnect() {
365 bgpThriftClient.disconnect();