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.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
33 public class BgpManager implements BindingAwareProvider, AutoCloseable, IBgpManager {
35 private static final Logger s_logger = LoggerFactory.getLogger(BgpManager.class);
36 private BgpConfigurationManager bgpConfigurationMgr;
37 private BgpConfiguration bgpConfiguration = new BgpConfiguration();
38 private BgpRouter bgpThriftClient;
39 private BgpThriftService bgpThriftService;
40 private String bgpHost;
43 private void initializeBGPCommunication() {
44 //start our side of thrift server
45 bgpThriftService = new BgpThriftService();
46 bgpThriftService.start();
48 //start bgp thrift client connection
49 bgpThriftClient = new BgpRouter();
51 //get bgp server, port from config.ini and connect
52 bgpHost = System.getProperty(BgpConstants.BGP_SPEAKER_HOST_NAME, BgpConstants.DEFAULT_BGP_HOST_NAME);
53 bgpPort = Integer.getInteger(BgpConstants.BGP_SPEAKER_THRIFT_PORT, BgpConstants.DEFAULT_BGP_THRIFT_PORT);
55 configureBgpServer(bgpHost, bgpPort);
57 connectToServer(bgpHost, bgpPort);
58 } catch (Exception e) {
59 //nothing to be done here, the logs have already been printed by the Exception handlers of "connectToServer"
61 /* read bgp router and peer info from DS
62 for the case when the BGP module came down but the DataStore was still up
65 configureBgp(101, "10.10.10.10");
67 // Now try start bgp - if bgp is already Active, it will tell us, nothing to do then
69 bgpThriftClient.startBgp((int)bgpConfiguration.getAsNum(), bgpConfiguration.getRouterId());
70 s_logger.info("Started BGP with AS number " + (int)bgpConfiguration.getAsNum() + " and router id " + bgpConfiguration.getRouterId());
71 } catch (BgpRouterException be) {
72 if(be.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
73 s_logger.info("bgp server already active");
77 s_logger.error("application error while starting bgp server " + be.getErrorCode());
81 } catch (TException t) {
82 s_logger.error("Transport error while starting bgp server ", t);
84 } catch (Exception e) {
85 s_logger.error("Error while starting bgp server", e);
88 //For testing - remove later
89 addNeighbor("169.144.42.168", 102);
94 public void onSessionInitiated(ProviderContext session) {
95 s_logger.info("BgpManager Session Initiated");
97 final DataBroker dataBroker = session.getSALService(DataBroker.class);
98 bgpConfigurationMgr = new BgpConfigurationManager(dataBroker);
99 } catch (Exception e) {
100 s_logger.error("Error initializing services", e);
103 initializeBGPCommunication();
108 public void close() throws Exception {
109 s_logger.info("BgpManager Closed");
112 private void setBgpServerDetails() {
113 if(bgpThriftClient != null)
114 bgpThriftClient.setBgpServer(bgpHost, bgpPort);
117 private void configureBgpServer(String bgpServer, int bgpPort) {
118 bgpConfiguration.setBgpServer(bgpServer);
119 bgpConfiguration.setBgpPort(bgpPort);
120 setBgpServerDetails();
123 private void addNeighbor(String ipAddress, int asNum) {
124 if(bgpThriftClient == null) {
125 s_logger.info("Add BGP Neighbor - bgpThriftClient is null. Unable to add BGP Neighbor.");
128 bgpConfiguration.setNeighbourIp(ipAddress);
129 bgpConfiguration.setNeighbourAsNum(asNum);
130 //updateBgpConfiguration(bgpConfiguration);
132 bgpThriftClient.addNeighbor(ipAddress, asNum);
133 } catch (BgpRouterException b) {
134 s_logger.error("Failed to add BGP neighbor " + ipAddress + "due to BgpRouter Exception number " + b.getErrorCode());
135 s_logger.error("BgpRouterException trace ", b);
136 } catch (TException t) {
137 s_logger.error(String.format("Failed adding neighbor %s due to Transport error", ipAddress));
139 } catch (Exception e) {
140 s_logger.error(String.format("Failed adding neighbor %s", ipAddress));
145 private void deleteNeighbor(String ipAddress) {
146 if(bgpThriftClient == null) {
147 s_logger.info("Delete BGP Neighbor - bgpThriftClient is null. Unable to delete BGP Neighbor.");
150 bgpConfiguration.setNeighbourIp("");
152 bgpThriftClient.delNeighbor(ipAddress);
153 } catch (BgpRouterException b) {
154 s_logger.error("Failed to delete BGP neighbor " + ipAddress + "due to BgpRouter Exception number " + b.getErrorCode());
155 s_logger.error("BgpRouterException trace ", b);
156 }catch (TException t) {
157 s_logger.error(String.format("Failed deleting neighbor %s due to Transport error", ipAddress));
159 } catch (Exception e) {
160 s_logger.error(String.format("Failed deleting neighbor %s", ipAddress));
166 public void addVrf(String rd, Collection<String> importRts, Collection<String> exportRts) {
167 if(bgpThriftClient == null) {
168 s_logger.info("Add BGP vrf - bgpThriftClient is null. Unable to add BGP vrf.");
172 bgpThriftClient.addVrf(rd, new ArrayList<>(importRts), new ArrayList<>(exportRts));
173 } catch (BgpRouterException b) {
174 s_logger.error("Failed to add BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
175 s_logger.error("BgpRouterException trace ", b);
176 } catch (TException t) {
177 s_logger.error(String.format("Failed adding vrf %s due to Transport error", rd));
179 } catch (Exception e) {
180 s_logger.error(String.format("Failed adding vrf %s", rd));
185 public void deleteVrf(String rd) {
186 if(bgpThriftClient == null) {
187 s_logger.info("Delete BGP vrf - bgpThriftClient is null. Unable to delete BGP vrf.");
191 bgpThriftClient.delVrf(rd);
192 } catch (BgpRouterException b) {
193 s_logger.error("Failed to delete BGP vrf " + rd + "due to BgpRouter Exception number " + b.getErrorCode());
194 s_logger.error("BgpRouterException trace ", b);
195 } catch (TException t) {
196 s_logger.error(String.format("Failed deleting vrf %s due to Transport error", rd));
198 } catch (Exception e) {
199 s_logger.error(String.format("Failed deleting vrf %s", rd));
204 public void addPrefix(String rd, String prefix, String nextHop, int vpnLabel) {
205 if(bgpThriftClient == null) {
206 s_logger.info("Add BGP prefix - bgpThriftClient is null. Unable to add BGP prefix.");
210 bgpThriftClient.addPrefix(rd, prefix, nextHop, vpnLabel);
211 } catch (BgpRouterException b) {
212 s_logger.error("Failed to add BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
213 s_logger.error("BgpRouterException trace ", b);
214 } catch (TException t) {
215 s_logger.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d due to Transport error",
216 rd, prefix, nextHop, vpnLabel));
218 } catch (Exception e) {
219 s_logger.error(String.format("Failed adding prefix entry <vrf:prefix:nexthop:vpnlabel> %s:%s:%s:%d",
220 rd, prefix, nextHop, vpnLabel));
226 public void deletePrefix(String rd, String prefix) {
227 if(bgpThriftClient == null) {
228 s_logger.info("Delete BGP prefix - bgpThriftClient is null. Unable to delete BGP prefix.");
232 bgpThriftClient.delPrefix(rd, prefix);
233 } catch (BgpRouterException b) {
234 s_logger.error("Failed to delete BGP prefix " + prefix + "due to BgpRouter Exception number " + b.getErrorCode());
235 s_logger.error("BgpRouterException trace ", b);
236 } catch (TException t) {
237 s_logger.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s due to Transport error",
240 } catch (Exception e) {
241 s_logger.error(String.format("Failed deleting prefix entry <vrf:prefix> %s:%s",
246 private void connectToServer(String host, int port) throws Exception {
251 if(bgpThriftClient == null) {
252 s_logger.error("Failed to connect to BGP server since Bgp Thrift Client is not initialized yet.");
256 bgpThriftClient.connect(host, port);
257 s_logger.info("Connected to BGP server " + host + " on port " + port);
258 } catch (BgpRouterException b) {
259 s_logger.error("Failed to connect to BGP server " + host + " on port " + port + " due to BgpRouter Exception number " + b.getErrorCode());
260 s_logger.error("BgpRouterException trace ", b);
262 } catch (TException t) {
263 s_logger.error("Failed to initialize BGP Connection due to Transport error ", t);
266 catch (Exception e) {
267 s_logger.error("Failed to initialize BGP Connection ", e);
272 public void configureBgp(long asNum, String routerId) {
274 bgpConfiguration.setAsNum(asNum);
275 bgpConfiguration.setRouterId(routerId);
276 } catch(Throwable e) {
277 s_logger.error("failed configuring bgp ",e);
281 public void reInitConn() {
284 bgpThriftClient.reInit();
285 s_logger.info("Reinitialized connection to BGP Server " + bgpHost);
286 } catch (BgpRouterException b) {
287 s_logger.error("Failed to reinitialize connection to BGP server " + bgpHost + " on port " + bgpPort + " due to BgpRouter Exception number " + b.getErrorCode());
288 s_logger.error("BgpRouterException trace ", b);
289 } catch (TException t) {
290 s_logger.error("Failed to reinitialize BGP Connection due to Transport error.", t);
292 catch (Exception e) {
293 s_logger.error("Failed to reinitialize BGP Connection.", e);
297 /*public synchronized void startBgpSync() {
298 boolean getRoutes = true;
299 readBgpConfiguration();
301 pushConfigurationToBgp();
303 } catch (BgpRouterException b) {
304 s_logger.error("Failed to push configuration to BGP due to BgpRouter Exception number " + b.getErrorCode());
305 s_logger.error("BgpRouterException trace ", b);
306 if(b.getErrorCode() == BgpRouterException.BGP_ERR_INACTIVE)
308 } catch (Exception e) {
309 s_logger.error("Failed to push configuration to bgp ", e);
311 if(getRoutes == true)
312 pullConfigurationFromBgp();
313 //controllerResyncLatch.countDown();
316 /*public void waitForControllerBgpResync() {
318 controllerResyncLatch.await();
319 } catch (InterruptedException e) {
323 /*private void pullConfigurationFromBgp() {
324 //get routes from bgp server
325 s_logger.info("Starting bgp route sync");
327 bgpThriftClient.doRouteSync();
328 } catch (BgpRouterException b) {
329 s_logger.error("Failed BGP Route sync due to BgpRouter Exception number " + b.getErrorCode());
330 s_logger.error("BgpRouterException trace ", b);
331 } catch (Exception e) {
332 s_logger.error("Failed to pull configuration from bgp ", e);
336 /*private BgpConfiguration readBgpConfiguration() {
338 bgpConfiguration = cache.get("bgpConfiguration");
339 if (bgpConfiguration == null) {
340 s_logger.info("Created bgp configuration cache");
341 bgpConfiguration = new BgpConfiguration();
342 cache.put("bgpConfiguration", bgpConfiguration);
344 s_logger.info("Using bgp configuration cache");
347 return bgpConfiguration;
350 /*public synchronized void pushConfigurationToBgp() throws Exception {
351 if (bgpConfiguration.getAsNum() == 0) {
352 s_logger.error("No as num configured, Skipping the push configuration to bgp ");
353 throw new BgpRouterException(BgpRouterException.BGP_ERR_INACTIVE);
356 if(bgpThriftClient == null) {
357 s_logger.error("bgpThriftClient is null. Skipping the push configuration to bgp.");
358 throw new BgpRouterException(BgpRouterException.BGP_ERR_INACTIVE);
363 bgpThriftClient.startBgp((int)bgpConfiguration.getAsNum(), bgpConfiguration.getRouterId());
364 s_logger.info("Started BGP with AS number " + (int)bgpConfiguration.getAsNum() + " and router id " + bgpConfiguration.getRouterId());
365 } catch (BgpRouterException be) {
366 if(be.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
367 s_logger.info("bgp server already active");
368 return; //the assumption here is that bgp server is configured already with neighbor, vrfs and routes as well
369 } if(be.getErrorCode() == BgpRouterException.BGP_ERR_INACTIVE) {
370 s_logger.info("bgp server inactive");
375 s_logger.error("application error while starting bgp server %d", be.getErrorCode());
379 } catch (SocketTimeoutException to) {
380 s_logger.error("Socket Timeout error while starting bgp server", to);
382 } catch (TException t) {
383 s_logger.error("Transport error while starting bgp server ", t);
385 } catch (Exception e) {
386 s_logger.error("Error while starting bgp server", e);
389 if (bgpConfiguration.getNeighbourIp().trim().length() > 0) {
391 bgpThriftClient.addNeighbor(bgpConfiguration.getNeighbourIp(), bgpConfiguration.getNeighbourAsNum());
392 } catch (TException t) {
393 s_logger.error("Failed to push vrf to bgp due to Transport error" );
396 addNeighbor(bgpConfiguration.getNeighbourIp(), bgpConfiguration.getNeighbourAsNum());
397 } catch (Exception e) {
398 s_logger.error("Error while starting bgp server", e);
404 tenant = tenantManager.getTenant("NEUTRON");
405 } catch (TenantNotFoundException e) {
406 s_logger.error("Tenant not found. Skipping push configuration to bgp.");
409 if (tenant != null) {
410 int tenantId = tenant.getTenantId();
412 Set<VpnInstanceInfo> vpnInfos = l3Manager.getVpnInstanceManager().getVpnsForTenant(tenantId);
413 s_logger.info("Number of vpns to configure is "+vpnInfos.size());
414 for (VpnInstanceInfo vpnInfo: vpnInfos) {
416 bgpThriftClient.addVrf(vpnInfo.getRouteDistinguisher(),
417 new ArrayList<>(vpnInfo.getRtImportList()),
418 new ArrayList<>(vpnInfo.getRtExportList()));
419 } catch (TException t) {
420 s_logger.error("Failed to push vrf to bgp due to Transport error" );
423 addVrf(vpnInfo.getRouteDistinguisher(), new ArrayList<>(vpnInfo.getRtImportList()),
424 new ArrayList<>(vpnInfo.getRtExportList()));
425 } catch (Exception e) {
426 s_logger.error("Failed to push vrf to bgp ", e);
429 for (VpnInstanceInfo vpnInfo: vpnInfos) {
430 ConcurrentMap<FibInfo, Object> fibInfos = l3Manager.getVpnInstanceManager().
431 getLocalFibInfosForRdCache(vpnInfo.getRouteDistinguisher());
432 s_logger.info("Number of fib infos to configure is "+fibInfos.size());
433 for (FibInfo fibInfo : fibInfos.keySet()) {
435 bgpThriftClient.addPrefix(vpnInfo.getRouteDistinguisher(), fibInfo.getDestinationPrefix(),
436 fibInfo.getNextHopPrefix(), (int) fibInfo.getLabel());
437 } catch (TException t) {
438 s_logger.error("Failed to push route to bgp due to Transport error" );
440 addPrefix(vpnInfo.getRouteDistinguisher(), fibInfo.getDestinationPrefix(),
441 fibInfo.getNextHopPrefix(), (int) fibInfo.getLabel());
442 } catch (Exception e) {
443 s_logger.error("Failed to push route to bgp ", e);
452 /* public void disconnect() {
453 bgpThriftClient.disconnect();
456 public void setRoute(Route r) {
457 s_logger.info("Setting route in VPN Manager");
458 //l3Manager.getVpnInstanceManager().addRoute(r.getRd(), r.getPrefix(), r.getNexthop(), r.getLabel());
461 /* For testing purposes */
462 /*public String ribGet() {
463 String family = "ipv4";
464 String format = "json";
467 List<Route> routeList = bgpThriftClient.getRoutes();
468 Iterator<Route> iter = routeList.iterator();
469 while(iter.hasNext()) {
470 Route r = iter.next();
471 System.out.println("Route:: vrf:" + r.getRd() + " Prefix: " + r.getPrefix() + " Nexthop: " + r.getNexthop() + "Label: " + r.getLabel());
473 } catch (Exception e) {
474 s_logger.error("Failed getting bgp routes ", e);