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.netvirt.bgpmanager;
10 import com.google.common.base.Optional;
11 import io.netty.util.concurrent.GlobalEventExecutor;
12 import java.io.BufferedReader;
14 import java.io.FileInputStream;
15 import java.io.IOException;
16 import java.io.InputStreamReader;
17 import java.lang.reflect.Constructor;
18 import java.net.InetAddress;
19 import java.net.NetworkInterface;
20 import java.util.Arrays;
21 import java.util.Enumeration;
22 import java.util.HashMap;
23 import java.util.Iterator;
24 import java.util.List;
26 import java.util.Timer;
27 import java.util.TimerTask;
28 import java.util.concurrent.Callable;
29 import java.util.concurrent.ConcurrentHashMap;
30 import java.util.concurrent.CountDownLatch;
31 import java.util.concurrent.ExecutionException;
32 import java.util.concurrent.Executors;
33 import java.util.concurrent.Future;
34 import java.util.concurrent.ScheduledExecutorService;
35 import java.util.concurrent.TimeoutException;
36 import java.util.concurrent.atomic.AtomicBoolean;
37 import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
38 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
39 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
40 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
41 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
42 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
43 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
44 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
45 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
46 import org.opendaylight.genius.utils.clustering.EntityOwnerUtils;
47 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
48 import org.opendaylight.netvirt.bgpmanager.commands.ClearBgpCli;
49 import org.opendaylight.netvirt.bgpmanager.oam.BgpAlarms;
50 import org.opendaylight.netvirt.bgpmanager.oam.BgpConstants;
51 import org.opendaylight.netvirt.bgpmanager.oam.BgpCounters;
52 import org.opendaylight.netvirt.bgpmanager.oam.BgpAlarms;
53 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouter;
54 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouterException;
55 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpSyncHandle;
56 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Routes;
57 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Update;
58 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
59 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
60 import org.opendaylight.netvirt.bgpmanager.thrift.gen.qbgpConstants;
61 import org.opendaylight.netvirt.bgpmanager.thrift.server.BgpThriftService;
62 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
63 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
64 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsId;
65 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsIdBuilder;
66 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServer;
67 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServerBuilder;
68 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestart;
69 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestartBuilder;
70 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Logging;
71 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.LoggingBuilder;
72 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Neighbors;
73 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsBuilder;
74 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsKey;
75 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Networks;
76 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksBuilder;
77 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksKey;
78 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Vrfs;
79 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsBuilder;
80 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsKey;
81 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamilies;
82 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesBuilder;
83 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesKey;
84 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihop;
85 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihopBuilder;
86 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSource;
87 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSourceBuilder;
88 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
89 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
93 import org.opendaylight.yangtools.concepts.ListenerRegistration;
94 import org.opendaylight.yangtools.yang.binding.DataObject;
95 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
96 import org.opendaylight.genius.utils.batching.DefaultBatchHandler;
97 import org.osgi.framework.BundleContext;
98 import org.slf4j.Logger;
99 import org.slf4j.LoggerFactory;
100 import java.util.concurrent.atomic.AtomicInteger;
101 import org.opendaylight.yangtools.yang.binding.DataObject;
103 public class BgpConfigurationManager {
104 private static final Logger LOG = LoggerFactory.getLogger(BgpConfigurationManager.class);
105 private static DataBroker dataBroker;
106 private static FibDSWriter fibDSWriter;
107 public static IBgpManager bgpManager;
108 private final BundleContext bundleContext;
109 private static Bgp config;
110 private static BgpRouter bgpRouter;
111 private static BgpThriftService updateServer;
112 private BgpCounters bgpCounters;
113 private BgpAlarms bgpAlarms;
114 private Timer bgpCountersTimer;
115 private Timer bgpAlarmsTimer;
116 private static final String DEF_LOGFILE = "/var/log/bgp_debug.log";
117 private static final String DEF_LOGLEVEL = "errors";
118 private static final String UPDATE_PORT = "bgp.thrift.service.port";
119 private static final String CONFIG_HOST = "vpnservice.bgpspeaker.host.name";
120 private static final String CONFIG_PORT = "vpnservice.bgpspeaker.thrift.port";
121 private static final String DEF_UPORT = "6644";
122 private static final String DEF_CHOST = "127.0.0.1";
123 private static final String DEF_CPORT = "7644";
124 private static final String SDNC_BGP_MIP = "sdnc_bgp_mip";
125 private static final String BGP_SDNC_MIP = "bgp_sdnc_mip";
126 private static final String CLUSTER_CONF_FILE = "/cluster/etc/cluster.conf";
127 private static final Timer ipActivationCheckTimer = new Timer();
128 private static final int STALE_FIB_WAIT = 60;
129 private static final int RESTART_DEFAULT_GR = 90;
130 private long StaleStartTime = 0;
131 private long StaleEndTime = 0;
132 private long CfgReplayStartTime = 0;
133 private long CfgReplayEndTime = 0;
134 private long StaleCleanupTime = 0;
135 private static final int dsRetryCoount = 100; //100 retries, each after waitTimeBetweenEachTryMillis seconds
136 private static final long waitTimeBetweenEachTryMillis = 1000L; //one second sleep after every retry
138 public String getBgpSdncMipIp() { return readThriftIpForCommunication(BGP_SDNC_MIP);}
139 public long getStaleCleanupTime() {
140 return StaleCleanupTime;
143 public void setStaleCleanupTime(long staleCleanupTime) {
144 StaleCleanupTime = staleCleanupTime;
147 public long getCfgReplayEndTime() {
148 return CfgReplayEndTime;
151 public void setCfgReplayEndTime(long cfgReplayEndTime) {
152 CfgReplayEndTime = cfgReplayEndTime;
155 public long getCfgReplayStartTime() {
156 return CfgReplayStartTime;
159 public void setCfgReplayStartTime(long cfgReplayStartTime) {
160 CfgReplayStartTime = cfgReplayStartTime;
163 public long getStaleEndTime() {
167 public void setStaleEndTime(long staleEndTime) {
168 StaleEndTime = staleEndTime;
171 public long getStaleStartTime() {
172 return StaleStartTime;
175 public void setStaleStartTime(long staleStartTime) {
176 StaleStartTime = staleStartTime;
180 // to have stale FIB map (RD, Prefix)
181 // number of seconds wait for route sync-up between ODL and BGP.
182 private static final int BGP_RESTART_ROUTE_SYNC_SEC = 600;
184 static String odlThriftIp = "127.0.0.1";
185 static String bgpThriftIp = "127.0.0.1";
186 private static String cHostStartup;
187 private static String cPortStartup;
188 private static CountDownLatch initer = new CountDownLatch(1);
189 //static IITMProvider itmProvider;
190 //map<rd, map<prefix/len, nexthop/label>>
191 private static Map<String, Map<String, String>> staledFibEntriesMap = new ConcurrentHashMap<>();
193 static final String BGP_ENTITY_TYPE_FOR_OWNERSHIP = "bgp";
194 static final String BGP_ENTITY_NAME = "bgp";
196 static int totalStaledCount = 0;
197 static int totalCleared = 0;
199 private static final Class[] reactors = {
200 ConfigServerReactor.class, AsIdReactor.class,
201 GracefulRestartReactor.class, LoggingReactor.class,
202 NeighborsReactor.class, UpdateSourceReactor.class,
203 EbgpMultihopReactor.class, AddressFamiliesReactor.class,
204 NetworksReactor.class, VrfsReactor.class, BgpReactor.class
207 private ListenerRegistration<DataChangeListener>[] registrations;
209 final BgpConfigurationManager bgpConfigurationManager;
211 public BgpConfigurationManager(final DataBroker dataBroker,
212 final EntityOwnershipService entityOwnershipService,
213 final FibDSWriter fibDSWriter,
214 final BundleContext bundleContext)
215 throws InterruptedException, ExecutionException, TimeoutException {
216 BgpConfigurationManager.dataBroker = dataBroker;
217 BgpConfigurationManager.fibDSWriter = fibDSWriter;
218 this.bundleContext = bundleContext;
219 String uPort = getProperty(UPDATE_PORT, DEF_UPORT);
220 cHostStartup = getProperty(CONFIG_HOST, DEF_CHOST);
221 cPortStartup = getProperty(CONFIG_PORT, DEF_CPORT);
222 LOG.info("UpdateServer at localhost:" + uPort + " ConfigServer at "
223 + cHostStartup + ":" + cPortStartup);
224 VtyshCli.setHostAddr(cHostStartup);
225 ClearBgpCli.setHostAddr(cHostStartup);
226 setEntityOwnershipService(entityOwnershipService);
227 bgpRouter = BgpRouter.getInstance();
228 odlThriftIp = readThriftIpForCommunication(SDNC_BGP_MIP);
229 bgpThriftIp = readThriftIpForCommunication(BGP_SDNC_MIP);
232 LOG.info("BGP Configuration manager initialized");
235 bgpConfigurationManager = this;
236 BgpUtil.batchSize = BgpUtil.BATCH_SIZE;
237 if (Integer.getInteger("batch.size") != null) {
238 BgpUtil.batchSize = Integer.getInteger("batch.size");
240 BgpUtil.batchInterval = BgpUtil.PERIODICITY;
241 if (Integer.getInteger("batch.wait.time") != null) {
242 BgpUtil.batchInterval = Integer.getInteger("batch.wait.time");
244 BgpUtil.registerWithBatchManager(new DefaultBatchHandler(dataBroker, LogicalDatastoreType.CONFIGURATION, BgpUtil.batchSize, BgpUtil.batchInterval));
246 GlobalEventExecutor.INSTANCE.execute(new Runnable() {
249 final WaitingServiceTracker<IBgpManager> tracker = WaitingServiceTracker.create(
250 IBgpManager.class, bundleContext);
251 bgpManager = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
252 updateServer = new BgpThriftService(Integer.parseInt(uPort), bgpManager, fibDSWriter);
253 updateServer.start();
254 LOG.info("BgpConfigurationManager initialized. IBgpManager={}", bgpManager);
259 private Object createListener(Class<?> cls) {
264 ctor = cls.getConstructor(BgpConfigurationManager.class);
265 obj = ctor.newInstance(this);
266 } catch (Exception e) {
267 LOG.error("Failed to create listener object", e);
272 private void registerCallbacks() {
273 String emsg = "Failed to register listener";
274 registrations = new ListenerRegistration[reactors.length];
275 InstanceIdentifier<?> iid = InstanceIdentifier.create(Bgp.class);
276 for (Class reactor : reactors) {
277 Object obj = createListener(reactor);
278 String dclName = obj.getClass().getName();
280 AsyncDataTreeChangeListenerBase dcl = (AsyncDataTreeChangeListenerBase) obj;
281 dcl.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
282 } catch (Exception e) {
284 throw new IllegalStateException(emsg + " " + dclName, e);
289 public void close() {
290 if (updateServer != null) {
293 LOG.info("{} close", getClass().getSimpleName());
296 private boolean configExists() throws InterruptedException, ExecutionException, TimeoutException {
297 InstanceIdentifier.InstanceIdentifierBuilder<Bgp> iib =
298 InstanceIdentifier.builder(Bgp.class);
299 InstanceIdentifier<Bgp> iid = iib.build();
300 Optional<Bgp> b = BgpUtil.read(dataBroker,
301 LogicalDatastoreType.CONFIGURATION, iid);
302 return b.isPresent();
305 private String getProperty(String var, String def) {
306 String s = bundleContext.getProperty(var);
307 return (s == null ? def : s);
310 boolean ignoreClusterDcnEventForFollower() {
311 return !EntityOwnerUtils.amIEntityOwner(BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME);
315 config = getConfig();
319 public void setEntityOwnershipService(final EntityOwnershipService entityOwnershipService) {
321 EntityOwnerUtils.registerEntityCandidateForOwnerShip(entityOwnershipService,
322 BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME, new EntityOwnershipListener() {
324 public void ownershipChanged(EntityOwnershipChange ownershipChange) {
325 LOG.trace("entity owner change event fired");
326 if (ownershipChange.hasOwner() && ownershipChange.isOwner()) {
327 LOG.trace("This PL is the Owner");
331 LOG.info("Not owner: hasOwner: {}, isOwner: {}",ownershipChange.hasOwner(),
332 ownershipChange.isOwner() );
336 } catch (Exception e) {
337 LOG.error("failed to register bgp entity", e);
341 private static final String addWarn =
342 "Config store updated; undo with Delete if needed.";
343 private static final String delWarn =
344 "Config store updated; undo with Add if needed.";
345 private static final String updWarn =
346 "Update operation not supported; Config store updated;"
347 + " restore with another Update if needed.";
349 public class ConfigServerReactor
350 extends AsyncDataTreeChangeListenerBase<ConfigServer, ConfigServerReactor>
351 implements AutoCloseable, ClusteredDataTreeChangeListener <ConfigServer> {
352 private static final String yangObj = "config-server ";
354 public ConfigServerReactor() {
355 super(ConfigServer.class, ConfigServerReactor.class);
359 protected synchronized void
360 add(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
361 LOG.trace("received bgp connect config host {}", val.getHost().getValue());
362 if (ignoreClusterDcnEventForFollower()) {
368 } catch (Exception e) {
370 LOG.debug("issueing bgp router connect to host {}", val.getHost().getValue());
371 synchronized (BgpConfigurationManager.this) {
372 boolean res = bgpRouter.connect(val.getHost().getValue(),
373 val.getPort().intValue());
375 LOG.error(yangObj + "Add failed; " + addWarn);
381 protected ConfigServerReactor getDataTreeChangeListener() {
382 return ConfigServerReactor.this;
386 protected InstanceIdentifier<ConfigServer> getWildCardPath() {
387 return InstanceIdentifier.create(Bgp.class).child(ConfigServer.class);
391 protected synchronized void
392 remove(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
393 LOG.trace("received bgp disconnect");
394 if (ignoreClusterDcnEventForFollower()) {
397 synchronized (BgpConfigurationManager.this) {
398 bgpRouter.disconnect();
403 protected void update(InstanceIdentifier<ConfigServer> iid,
404 ConfigServer oldval, ConfigServer newval) {
405 LOG.trace("received bgp Connection update");
406 if (ignoreClusterDcnEventForFollower()) {
409 LOG.error(yangObj + updWarn);
413 public void close() {
416 } catch (Exception e) {
417 LOG.error("ConfigServerReactor failed to close: ", e);
422 private BgpRouter getClient(String yangObj) {
423 if (bgpRouter == null) {
424 LOG.warn("{}: configuration received when BGP is inactive", yangObj);
429 public class AsIdReactor
430 extends AsyncDataTreeChangeListenerBase<AsId, AsIdReactor>
431 implements AutoCloseable, ClusteredDataTreeChangeListener<AsId> {
433 private static final String yangObj = "as-id ";
435 public AsIdReactor() {
436 super(AsId.class, AsIdReactor.class);
440 protected synchronized void
441 add(InstanceIdentifier<AsId> iid, AsId val) {
442 LOG.error("received bgp add asid {}",val);
443 if (ignoreClusterDcnEventForFollower()) {
446 LOG.debug("received add router config asNum {}", val.getLocalAs().longValue());
447 synchronized (BgpConfigurationManager.this) {
448 BgpRouter br = getClient(yangObj);
450 LOG.error("no bgp router client found exiting asid add");
453 long asNum = val.getLocalAs().longValue();
454 IpAddress routerId = val.getRouterId();
455 Boolean afb = val.isAnnounceFbit();
456 String rid = (routerId == null) ? "" : new String(routerId.getValue());
457 int stalepathTime = (int) getStalePathtime(RESTART_DEFAULT_GR, val);
458 boolean announceFbit = true;
460 br.startBgp(asNum, rid, stalepathTime, announceFbit);
461 if (getBgpCounters() == null) {
462 startBgpCountersTask();
464 if (getBgpAlarms() == null) {
465 startBgpAlarmsTask();
467 } catch (BgpRouterException bre) {
468 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
469 LOG.error(yangObj + "Add requested when BGP is already active");
471 LOG.error(yangObj + "Add received exception: \""
472 + bre + "\"; " + addWarn);
474 } catch (Exception e) {
475 LOG.error(yangObj + "Add received exception: \"" + e + "\"; " + addWarn);
481 protected AsIdReactor getDataTreeChangeListener() {
482 return AsIdReactor.this;
486 protected InstanceIdentifier<AsId> getWildCardPath() {
487 return InstanceIdentifier.create(Bgp.class).child(AsId.class);
491 protected synchronized void
492 remove(InstanceIdentifier<AsId> iid, AsId val) {
493 LOG.error("received delete router config asNum {}", val.getLocalAs().longValue());
494 if (ignoreClusterDcnEventForFollower()) {
497 synchronized (BgpConfigurationManager.this) {
498 BgpRouter br = getClient(yangObj);
502 long asNum = val.getLocalAs().longValue();
505 } catch (Exception e) {
506 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; " + delWarn);
508 if (getBgpCounters() != null) {
509 stopBgpCountersTask();
511 if (getBgpAlarms() != null) {
518 protected void update(InstanceIdentifier<AsId> iid,
519 AsId oldval, AsId newval) {
520 if (ignoreClusterDcnEventForFollower()) {
523 LOG.error(yangObj + updWarn);
527 public void close() {
530 } catch (Exception e) {
536 public class GracefulRestartReactor
537 extends AsyncDataTreeChangeListenerBase<GracefulRestart, GracefulRestartReactor>
538 implements AutoCloseable, ClusteredDataTreeChangeListener<GracefulRestart> {
540 private static final String yangObj = "graceful-restart ";
542 public GracefulRestartReactor() {
543 super(GracefulRestart.class, GracefulRestartReactor.class);
547 protected synchronized void
548 add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
549 if (ignoreClusterDcnEventForFollower()) {
552 synchronized (BgpConfigurationManager.this) {
553 BgpRouter br = getClient(yangObj);
558 br.addGracefulRestart(val.getStalepathTime().intValue());
559 } catch (Exception e) {
560 LOG.error(yangObj + "Add received exception: \"" + e + "\"; " + addWarn);
566 protected GracefulRestartReactor getDataTreeChangeListener() {
567 return GracefulRestartReactor.this;
571 protected InstanceIdentifier<GracefulRestart> getWildCardPath() {
572 return InstanceIdentifier.create(Bgp.class).child(GracefulRestart.class);
576 protected synchronized void
577 remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
578 if (ignoreClusterDcnEventForFollower()) {
581 LOG.debug("received delete GracefulRestart config val {}", val.getStalepathTime().intValue());
582 synchronized (BgpConfigurationManager.this) {
583 BgpRouter br = getClient(yangObj);
588 br.delGracefulRestart();
589 } catch (Exception e) {
590 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
597 protected void update(InstanceIdentifier<GracefulRestart> iid,
598 GracefulRestart oldval, GracefulRestart newval) {
599 if (ignoreClusterDcnEventForFollower()) {
602 LOG.debug("received update GracefulRestart config val {}", newval.getStalepathTime().intValue());
603 synchronized (BgpConfigurationManager.this) {
604 BgpRouter br = getClient(yangObj);
609 br.addGracefulRestart(newval.getStalepathTime().intValue());
610 } catch (Exception e) {
611 LOG.error(yangObj + "update received exception: \"" + e + "\"; " + addWarn);
617 public void close() {
620 } catch (Exception e) {
626 public class LoggingReactor
627 extends AsyncDataTreeChangeListenerBase<Logging, LoggingReactor>
628 implements AutoCloseable, ClusteredDataTreeChangeListener<Logging> {
630 private static final String yangObj = "logging ";
632 public LoggingReactor() {
633 super(Logging.class, LoggingReactor.class);
637 protected synchronized void
638 add(InstanceIdentifier<Logging> iid, Logging val) {
639 if (ignoreClusterDcnEventForFollower()) {
642 synchronized (BgpConfigurationManager.this) {
643 BgpRouter br = getClient(yangObj);
648 br.setLogging(val.getFile(), val.getLevel());
649 } catch (Exception e) {
650 LOG.error(yangObj + "Add received exception: \"" + e + "\"; "
657 protected LoggingReactor getDataTreeChangeListener() {
658 return LoggingReactor.this;
662 protected InstanceIdentifier<Logging> getWildCardPath() {
663 return InstanceIdentifier.create(Bgp.class).child(Logging.class);
667 protected synchronized void
668 remove(InstanceIdentifier<Logging> iid, Logging val) {
669 if (ignoreClusterDcnEventForFollower()) {
672 LOG.debug("received remove Logging config val {}", val.getLevel());
673 synchronized (BgpConfigurationManager.this) {
674 BgpRouter br = getClient(yangObj);
679 br.setLogging(DEF_LOGFILE, DEF_LOGLEVEL);
680 } catch (Exception e) {
681 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
688 protected void update(InstanceIdentifier<Logging> iid,
689 Logging oldval, Logging newval) {
690 if (ignoreClusterDcnEventForFollower()) {
693 synchronized (BgpConfigurationManager.this) {
694 BgpRouter br = getClient(yangObj);
699 br.setLogging(newval.getFile(), newval.getLevel());
700 } catch (Exception e) {
701 LOG.error(yangObj + "newval received exception: \"" + e + "\"; "
708 public void close() {
711 } catch (Exception e) {
717 public class NeighborsReactor
718 extends AsyncDataTreeChangeListenerBase<Neighbors, NeighborsReactor>
719 implements AutoCloseable, ClusteredDataTreeChangeListener<Neighbors> {
721 private static final String yangObj = "neighbors ";
723 public NeighborsReactor() {
724 super(Neighbors.class, NeighborsReactor.class);
728 protected synchronized void
729 add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
730 if (ignoreClusterDcnEventForFollower()) {
733 LOG.debug("received add Neighbors config val {}", val.getAddress().getValue());
734 synchronized (BgpConfigurationManager.this) {
735 BgpRouter br = getClient(yangObj);
739 String peerIp = val.getAddress().getValue();
740 long as = val.getRemoteAs().longValue();
742 //itmProvider.buildTunnelsToDCGW(new IpAddress(peerIp.toCharArray()));
743 br.addNeighbor(peerIp, as);
745 } catch (Exception e) {
746 LOG.error(yangObj + "Add received exception: \"" + e + "\"; "
753 protected NeighborsReactor getDataTreeChangeListener() {
754 return NeighborsReactor.this;
758 protected InstanceIdentifier<Neighbors> getWildCardPath() {
759 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class);
763 protected synchronized void
764 remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
765 if (ignoreClusterDcnEventForFollower()) {
768 LOG.debug("received remove Neighbors config val {}", val.getAddress().getValue());
769 synchronized (BgpConfigurationManager.this) {
770 BgpRouter br = getClient(yangObj);
774 String peerIp = val.getAddress().getValue();
776 //itmProvider.deleteTunnelsToDCGW(new IpAddress(val.getAddress().getValue().toCharArray()));
777 br.delNeighbor(peerIp);
778 } catch (Exception e) {
779 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
786 protected void update(InstanceIdentifier<Neighbors> iid,
787 Neighbors oldval, Neighbors newval) {
788 if (ignoreClusterDcnEventForFollower()) {
791 //purposefully nothing to do.
795 public void close() {
798 } catch (Exception e) {
804 public class EbgpMultihopReactor
805 extends AsyncDataTreeChangeListenerBase<EbgpMultihop, EbgpMultihopReactor>
806 implements AutoCloseable, ClusteredDataTreeChangeListener<EbgpMultihop> {
808 private static final String yangObj = "ebgp-multihop ";
810 public EbgpMultihopReactor() {
811 super(EbgpMultihop.class, EbgpMultihopReactor.class);
815 protected synchronized void
816 add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
817 if (ignoreClusterDcnEventForFollower()) {
820 LOG.debug("received add EbgpMultihop config val {}", val.getPeerIp().getValue());
821 synchronized (BgpConfigurationManager.this) {
822 BgpRouter br = getClient(yangObj);
826 String peerIp = val.getPeerIp().getValue();
828 br.addEbgpMultihop(peerIp, val.getNhops().intValue());
829 } catch (Exception e) {
830 LOG.error(yangObj + "Add received exception: \"" + e + "\"; "
837 protected EbgpMultihopReactor getDataTreeChangeListener() {
838 return EbgpMultihopReactor.this;
842 protected InstanceIdentifier<EbgpMultihop> getWildCardPath() {
843 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(EbgpMultihop.class);
847 protected synchronized void
848 remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
849 if (ignoreClusterDcnEventForFollower()) {
852 LOG.debug("received remove EbgpMultihop config val {}", val.getPeerIp().getValue());
853 synchronized (BgpConfigurationManager.this) {
854 BgpRouter br = getClient(yangObj);
858 String peerIp = val.getPeerIp().getValue();
860 br.delEbgpMultihop(peerIp);
861 } catch (Exception e) {
862 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
869 protected void update(InstanceIdentifier<EbgpMultihop> iid,
870 EbgpMultihop oldval, EbgpMultihop newval) {
871 if (ignoreClusterDcnEventForFollower()) {
874 LOG.error(yangObj + updWarn);
878 public void close() {
881 } catch (Exception e) {
887 public class UpdateSourceReactor
888 extends AsyncDataTreeChangeListenerBase<UpdateSource, UpdateSourceReactor>
889 implements AutoCloseable, ClusteredDataTreeChangeListener<UpdateSource> {
891 private static final String yangObj = "update-source ";
893 public UpdateSourceReactor() {
894 super(UpdateSource.class, UpdateSourceReactor.class);
898 protected synchronized void
899 add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
900 if (ignoreClusterDcnEventForFollower()) {
903 LOG.debug("received add UpdateSource config val {}", val.getSourceIp().getValue());
904 synchronized (BgpConfigurationManager.this) {
905 BgpRouter br = getClient(yangObj);
909 String peerIp = val.getPeerIp().getValue();
911 br.addUpdateSource(peerIp, val.getSourceIp().getValue());
912 } catch (Exception e) {
913 LOG.error(yangObj + "Add received exception: \"" + e + "\"; "
920 protected UpdateSourceReactor getDataTreeChangeListener() {
921 return UpdateSourceReactor.this;
925 protected InstanceIdentifier<UpdateSource> getWildCardPath() {
926 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(UpdateSource.class);
930 protected synchronized void
931 remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
932 if (ignoreClusterDcnEventForFollower()) {
935 LOG.debug("received remove UpdateSource config val {}", val.getSourceIp().getValue());
936 synchronized (BgpConfigurationManager.this) {
937 BgpRouter br = getClient(yangObj);
941 String peerIp = val.getPeerIp().getValue();
943 br.delUpdateSource(peerIp);
944 } catch (Exception e) {
945 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
952 protected void update(InstanceIdentifier<UpdateSource> iid,
953 UpdateSource oldval, UpdateSource newval) {
954 if (ignoreClusterDcnEventForFollower()) {
957 LOG.error(yangObj + updWarn);
961 public void close() {
964 } catch (Exception e) {
970 public class AddressFamiliesReactor
971 extends AsyncDataTreeChangeListenerBase<AddressFamilies, AddressFamiliesReactor>
972 implements AutoCloseable, ClusteredDataTreeChangeListener<AddressFamilies> {
974 private static final String yangObj = "address-families ";
976 public AddressFamiliesReactor() {
977 super(AddressFamilies.class, AddressFamiliesReactor.class);
981 protected synchronized void
982 add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
983 if (ignoreClusterDcnEventForFollower()) {
986 LOG.debug("received add AddressFamilies config val {}", val.getPeerIp().getValue());
987 synchronized (BgpConfigurationManager.this) {
988 BgpRouter br = getClient(yangObj);
992 String peerIp = val.getPeerIp().getValue();
993 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
994 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
996 br.addAddressFamily(peerIp, afi, safi);
997 } catch (Exception e) {
998 LOG.error(yangObj + "Add received exception: \"" + e + "\"; "
1005 protected AddressFamiliesReactor getDataTreeChangeListener() {
1006 return AddressFamiliesReactor.this;
1010 protected InstanceIdentifier<AddressFamilies> getWildCardPath() {
1011 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(AddressFamilies.class);
1015 protected synchronized void
1016 remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
1017 if (ignoreClusterDcnEventForFollower()) {
1020 LOG.debug("received remove AddressFamilies config val {}", val.getPeerIp().getValue());
1021 synchronized (BgpConfigurationManager.this) {
1022 BgpRouter br = getClient(yangObj);
1026 String peerIp = val.getPeerIp().getValue();
1027 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
1028 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
1030 br.delAddressFamily(peerIp, afi, safi);
1031 } catch (Exception e) {
1032 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
1039 protected void update(InstanceIdentifier<AddressFamilies> iid,
1040 AddressFamilies oldval, AddressFamilies newval) {
1041 if (ignoreClusterDcnEventForFollower()) {
1044 LOG.error(yangObj + updWarn);
1048 public void close() {
1051 } catch (Exception e) {
1052 e.printStackTrace();
1057 public class NetworksReactor
1058 extends AsyncDataTreeChangeListenerBase<Networks, NetworksReactor>
1059 implements AutoCloseable, ClusteredDataTreeChangeListener<Networks> {
1061 private static final String yangObj = "networks ";
1063 public NetworksReactor() {
1064 super(Networks.class, NetworksReactor.class);
1067 public NetworksReactor getDataTreeChangeListener() {
1068 return NetworksReactor.this;
1072 protected synchronized void
1073 add(InstanceIdentifier<Networks> iid, Networks val) {
1074 if (ignoreClusterDcnEventForFollower()) {
1077 LOG.debug("received add Networks config val {}", val.getPrefixLen());
1078 synchronized (BgpConfigurationManager.this) {
1079 BgpRouter br = getClient(yangObj);
1083 String rd = val.getRd();
1084 String pfxlen = val.getPrefixLen();
1085 String nh = val.getNexthop().getValue();
1086 Long label = val.getLabel();
1087 int lbl = (label == null) ? qbgpConstants.LBL_NO_LABEL
1090 br.addPrefix(rd, pfxlen, nh, lbl);
1091 } catch (Exception e) {
1092 LOG.error(yangObj + "Add received exception: \"" + e + "\"; " + addWarn);
1098 protected InstanceIdentifier<Networks> getWildCardPath() {
1099 return InstanceIdentifier.create(Bgp.class).child(Networks.class);
1103 protected synchronized void
1104 remove(InstanceIdentifier<Networks> iid, Networks val) {
1105 if (ignoreClusterDcnEventForFollower()) {
1108 LOG.debug("received remove Networks config val {}", val.getPrefixLen());
1109 synchronized (BgpConfigurationManager.this) {
1110 BgpRouter br = getClient(yangObj);
1114 String rd = val.getRd();
1115 String pfxlen = val.getPrefixLen();
1116 Long label = val.getLabel();
1117 int lbl = (label == null) ? 0 : label.intValue();
1118 if (rd == null && lbl > 0) {
1119 //LU prefix is being deleted.
1120 rd = Integer.toString(lbl);
1123 br.delPrefix(rd, pfxlen);
1124 } catch (Exception e) {
1125 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
1132 protected void update(final InstanceIdentifier<Networks> iid,
1133 final Networks oldval, final Networks newval) {
1134 if (ignoreClusterDcnEventForFollower()) {
1137 if(oldval.equals(newval)){
1138 //Update: OLD and New values are same, no need to trigger remove/add.
1139 LOG.debug("received Updated for the same OLD and New values. RD: {}, Prefix: {}, Label: {}, NH: {}",
1140 oldval.getRd(), oldval.getPrefixLen(), oldval.getLabel(), oldval.getNexthop());
1143 LOG.debug("received update networks config val {}", newval.getPrefixLen());
1144 remove(iid, oldval);
1145 timer.schedule(new TimerTask() {
1150 }, Integer.getInteger("bgp.nexthop.update.delay.in.secs", 5) * 1000);
1154 public void close() {
1157 } catch (Exception e) {
1158 e.printStackTrace();
1163 static Timer timer = new Timer();
1165 public class VrfsReactor
1166 extends AsyncDataTreeChangeListenerBase<Vrfs, VrfsReactor>
1167 implements AutoCloseable, ClusteredDataTreeChangeListener<Vrfs> {
1169 private static final String yangObj = "vrfs ";
1171 public VrfsReactor() {
1172 super(Vrfs.class, VrfsReactor.class);
1176 protected synchronized void
1177 add(InstanceIdentifier<Vrfs> iid, Vrfs val) {
1178 if (ignoreClusterDcnEventForFollower()) {
1181 LOG.debug("received add Vrfs config val {}", val.getRd());
1182 synchronized (BgpConfigurationManager.this) {
1183 BgpRouter br = getClient(yangObj);
1188 br.addVrf(val.getRd(), val.getImportRts(),
1189 val.getExportRts());
1190 } catch (Exception e) {
1191 LOG.error(yangObj + "Add received exception: \"" + e + "\"; "
1198 protected VrfsReactor getDataTreeChangeListener() {
1199 return VrfsReactor.this;
1203 protected InstanceIdentifier<Vrfs> getWildCardPath() {
1204 return InstanceIdentifier.create(Bgp.class).child(Vrfs.class);
1208 protected synchronized void
1209 remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
1210 if (ignoreClusterDcnEventForFollower()) {
1213 LOG.debug("received remove Vrfs config val {}", val.getRd());
1214 synchronized (BgpConfigurationManager.this) {
1215 BgpRouter br = getClient(yangObj);
1220 br.delVrf(val.getRd());
1221 } catch (Exception e) {
1222 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
1229 protected void update(InstanceIdentifier<Vrfs> iid,
1230 Vrfs oldval, Vrfs newval) {
1231 if (ignoreClusterDcnEventForFollower()) {
1234 LOG.debug("VRFS: Update getting triggered for VRFS rd {}", oldval.getRd());
1235 LOG.error(yangObj + updWarn);
1239 public void close() {
1242 } catch (Exception e) {
1243 e.printStackTrace();
1248 Future lastCleanupJob;
1249 Future lastReplayJobFt = null;
1250 protected void activateMIP() {
1252 LOG.trace("BgpReactor: Executing MIP Activate command");
1253 Process process_bgp = Runtime.getRuntime().exec("cluster ip -a sdnc_bgp_mip");
1254 Process process_os = Runtime.getRuntime().exec("cluster ip -a sdnc_os_mip");
1255 LOG.trace("bgpMIP Activated");
1257 } catch (IOException io) {
1258 //LOG.error("IO Exception got while activating mip: ", io);
1259 } catch (Exception e) {
1260 //LOG.error("Exception got while activating mip: ", e);
1264 AtomicBoolean started = new AtomicBoolean(false);
1266 public class BgpReactor
1267 extends AsyncDataTreeChangeListenerBase<Bgp, BgpReactor>
1268 implements AutoCloseable, ClusteredDataTreeChangeListener<Bgp> {
1270 private static final String yangObj = "Bgp ";
1272 public BgpReactor() {
1273 super(Bgp.class, BgpReactor.class);
1278 protected synchronized void
1279 add(InstanceIdentifier<Bgp> iid, Bgp val) {
1280 LOG.error("received add Bgp config replaying the config");
1284 } catch (Exception e) {
1286 synchronized (BgpConfigurationManager.this) {
1288 if (ignoreClusterDcnEventForFollower()) {
1292 if (isIpAvailable(odlThriftIp)) {
1295 ipActivationCheckTimer.scheduleAtFixedRate(new TimerTask() {
1298 if (isIpAvailable(odlThriftIp)) {
1300 ipActivationCheckTimer.cancel();
1302 LOG.trace("waiting for odlThriftIP: {} to be present", odlThriftIp);
1311 protected BgpReactor getDataTreeChangeListener() {
1312 return BgpReactor.this;
1316 protected InstanceIdentifier<Bgp> getWildCardPath() {
1317 return InstanceIdentifier.create(Bgp.class);
1321 protected synchronized void
1322 remove(InstanceIdentifier<Bgp> iid, Bgp val) {
1323 if (ignoreClusterDcnEventForFollower()) {
1326 LOG.debug("received remove Bgp config");
1327 synchronized (BgpConfigurationManager.this) {
1333 protected void update(InstanceIdentifier<Bgp> iid,
1334 Bgp oldval, Bgp newval) {
1335 if (ignoreClusterDcnEventForFollower()) {
1338 synchronized (BgpConfigurationManager.this) {
1344 public void close() {
1347 } catch (Exception e) {
1348 e.printStackTrace();
1353 public String readThriftIpForCommunication( String mipAddr) {
1354 File f = new File(CLUSTER_CONF_FILE);
1358 BufferedReader br = null;
1360 br = new BufferedReader(new InputStreamReader(
1361 new FileInputStream(f)));
1362 String line = br.readLine();
1363 while (line != null) {
1364 if (line.contains(mipAddr)) {
1366 return line.substring(line.lastIndexOf(" ") + 1);
1368 line = br.readLine();
1370 } catch (Exception e) {
1374 } catch (Exception ignore) {
1380 public boolean isIpAvailable(String odlip) {
1383 if (odlip != null) {
1384 if ("127.0.0.1".equals(odlip)) {
1387 Enumeration e = NetworkInterface.getNetworkInterfaces();
1388 while (e.hasMoreElements()) {
1389 NetworkInterface n = (NetworkInterface) e.nextElement();
1390 Enumeration ee = n.getInetAddresses();
1391 while (ee.hasMoreElements()) {
1392 InetAddress i = (InetAddress) ee.nextElement();
1393 if (odlip.equals(i.getHostAddress())) {
1400 } catch (Exception e) {
1405 public static long getStalePathtime(int defValue, AsId as_num) {
1408 spt = getConfig().getGracefulRestart().getStalepathTime();
1409 } catch (Exception e) {
1411 spt = as_num.getStalepathTime();
1412 LOG.trace("BGP config/Stale-path time is not set using graceful");
1413 } catch (Exception ignore) {
1414 LOG.trace("BGP AS id is not set using graceful");
1419 LOG.trace("BGP config/Stale-path time is not set using graceful/start-bgp");
1425 public synchronized void bgpRestarted() {
1427 * If there a thread which in the process of stale cleanup, cancel it
1428 * and start a new thread (to avoid processing same again).
1430 if (previousReplayJobInProgress()) {
1431 cancelPreviousReplayJob();
1433 Runnable task = new Runnable() {
1437 LOG.info("running bgp replay task ");
1438 if (get() == null) {
1439 String host = getConfigHost();
1440 int port = getConfigPort();
1441 LOG.info("connecting to bgp host {} ", host);
1443 boolean res = bgpRouter.connect(host, port);
1444 LOG.info("no config to push in bgp replay task ");
1447 setStaleStartTime(System.currentTimeMillis());
1448 LOG.info("started creating stale fibDSWriter map ");
1449 createStaleFibMap();
1450 setStaleEndTime(System.currentTimeMillis());
1451 LOG.info("took {} msecs for stale fibDSWriter map creation ", getStaleEndTime()- getStaleStartTime());
1452 LOG.info("started bgp config replay ");
1453 setCfgReplayStartTime(System.currentTimeMillis());
1455 setCfgReplayEndTime(System.currentTimeMillis());
1456 LOG.info("took {} msecs for bgp replay ", getCfgReplayEndTime() - getCfgReplayStartTime());
1457 long route_sync_time = getStalePathtime(BGP_RESTART_ROUTE_SYNC_SEC, config.getAsId());
1458 Thread.sleep(route_sync_time * 1000L);
1459 setStaleCleanupTime(route_sync_time);
1460 new RouteCleanup().call();
1461 } catch (Exception eCancel) {
1462 LOG.error("Stale Cleanup Task Cancelled", eCancel);
1466 lastReplayJobFt = executor.submit(task);
1469 private boolean previousReplayJobInProgress() {
1470 return lastReplayJobFt != null && !lastReplayJobFt.isDone();
1473 private void cancelPreviousReplayJob() {
1475 LOG.error("cancelling already running bgp replay task");
1476 lastReplayJobFt.cancel(true);
1477 lastReplayJobFt = null;
1479 } catch (Throwable e) {
1480 LOG.error("Failed to cancel previous replay job ",e);
1484 private static void doRouteSync() {
1485 BgpSyncHandle bsh = BgpSyncHandle.getInstance();
1486 LOG.error("Starting BGP route sync");
1488 bgpRouter.initRibSync(bsh);
1489 } catch (Exception e) {
1490 LOG.error("Route sync aborted, exception when initializing: " + e);
1493 while (bsh.getState() != bsh.DONE) {
1494 Routes routes = null;
1496 routes = bgpRouter.doRibSync(bsh);
1497 } catch (Exception e) {
1498 LOG.error("Route sync aborted, exception when syncing: " + e);
1501 Iterator<Update> updates = routes.getUpdatesIterator();
1502 while (updates.hasNext()) {
1503 Update u = updates.next();
1504 Map<String, Map<String, String>> stale_fib_rd_map = BgpConfigurationManager.getStaledFibEntriesMap();
1505 String rd = u.getRd();
1506 String nexthop = u.getNexthop();
1507 int label = u.getLabel();
1508 String prefix = u.getPrefix();
1509 int plen = u.getPrefixlen();
1510 onUpdatePushRoute(rd, prefix, plen, nexthop, label);
1514 LOG.error("Ending BGP route-sync");
1515 bgpRouter.endRibSync(bsh);
1516 } catch (Exception e) {
1520 /* onUpdatePushRoute
1521 * Get Stale fibDSWriter map, and compare current route/fibDSWriter entry.
1522 * - Entry compare shall include NextHop, Label.
1523 * - If entry matches: delete from STALE Map. NO Change to FIB Config DS.
1524 * - If entry not found, add to FIB Config DS.
1525 * - If entry found, but either Label/NextHop doesn't match.
1526 * - Update FIB Config DS with modified values.
1527 * - delete from Stale Map.
1529 public static void onUpdatePushRoute(String rd, String prefix, int plen, String nextHop, int label) {
1530 Map<String, Map<String, String>> stale_fib_rd_map = BgpConfigurationManager.getStaledFibEntriesMap();
1531 boolean addroute = false;
1532 if (!stale_fib_rd_map.isEmpty()) {
1533 // restart Scenario, as MAP is not empty.
1534 Map<String, String> map = stale_fib_rd_map.get(rd);
1536 String nexthoplabel = map.get(prefix + "/" + plen);
1537 if (null == nexthoplabel) {
1538 // New Entry, which happened to be added during restart.
1541 map.remove(prefix + "/" + plen);
1542 if (isRouteModified(nextHop, label, nexthoplabel)) {
1543 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
1544 // Existing entry, where in Nexthop/Label got modified during restart
1550 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
1554 LOG.info("ADD: Adding Fib entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, label);
1555 fibDSWriter.addFibEntryToDS(rd, prefix + "/" + plen, Arrays.asList(nextHop), label, RouteOrigin.BGP);
1556 LOG.info("ADD: Added Fib entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, label);
1560 private static boolean isRouteModified(String nexthop, int label, String nexthoplabel) {
1561 return !nexthoplabel.isEmpty() && !nexthoplabel.equals(nexthop + "/" + label);
1564 static private void replayNbrConfig(List<Neighbors> n, BgpRouter br) {
1565 for (Neighbors nbr : n) {
1567 br.addNeighbor(nbr.getAddress().getValue(),
1568 nbr.getRemoteAs().longValue());
1569 //itmProvider.buildTunnelsToDCGW(new IpAddress(nbr.getAddress().getValue().toCharArray()));
1570 } catch (Exception e) {
1571 LOG.error("Replay:addNbr() received exception: \"" + e + "\"");
1574 EbgpMultihop en = nbr.getEbgpMultihop();
1577 br.addEbgpMultihop(en.getPeerIp().getValue(),
1578 en.getNhops().intValue());
1579 } catch (Exception e) {
1580 LOG.error("Replay:addEBgp() received exception: \"" + e + "\"");
1583 UpdateSource us = nbr.getUpdateSource();
1586 br.addUpdateSource(us.getPeerIp().getValue(),
1587 us.getSourceIp().getValue());
1588 } catch (Exception e) {
1589 LOG.error("Replay:addUS() received exception: \"" + e + "\"");
1592 List<AddressFamilies> afs = nbr.getAddressFamilies();
1594 for (AddressFamilies af : afs) {
1595 af_afi afi = af_afi.findByValue(af.getAfi().intValue());
1596 af_safi safi = af_safi.findByValue(af.getSafi().intValue());
1598 br.addAddressFamily(af.getPeerIp().getValue(), afi, safi);
1599 } catch (Exception e) {
1600 LOG.error("Replay:addAf() received exception: \"" + e + "\"");
1607 public static String getConfigHost() {
1608 if (config == null) {
1609 return cHostStartup;
1611 ConfigServer ts = config.getConfigServer();
1612 return (ts == null ? cHostStartup : ts.getHost().getValue());
1615 public static int getConfigPort() {
1616 if (config == null) {
1617 return Integer.parseInt(cPortStartup);
1619 ConfigServer ts = config.getConfigServer();
1620 return (ts == null ? Integer.parseInt(cPortStartup) :
1621 ts.getPort().intValue());
1624 public static Bgp getConfig() {
1625 AtomicInteger bgpDSretryCount = new AtomicInteger(dsRetryCoount);
1626 while (0 != bgpDSretryCount.decrementAndGet()) {
1628 return BgpUtil.read(dataBroker, LogicalDatastoreType.CONFIGURATION,
1629 InstanceIdentifier.create(Bgp.class)).orNull();
1630 } catch (Exception e) {
1631 //Config DS may not be up, so sleep for 1 second and retry
1632 LOG.debug("failed to get bgp config, may be DS is yet in consistent state(?)", e);
1634 Thread.sleep(waitTimeBetweenEachTryMillis);
1635 }catch (Exception timerEx){
1636 LOG.debug("waitTimeBetweenEachTryMillis, Timer got interrupted while waiting for" +
1637 "config DS availability", timerEx);
1641 LOG.error("failed to get bgp config");
1645 public synchronized void replay() {
1646 synchronized (bgpConfigurationManager) {
1647 String host = getConfigHost();
1648 int port = getConfigPort();
1649 LOG.error("connecting to bgp host {} ", host);
1651 boolean res = bgpRouter.connect(host, port);
1653 String msg = "Cannot connect to BGP config server at " + host + ":" + port;
1654 if (config != null) {
1655 msg += "; Configuration Replay aborted";
1660 config = getConfig();
1661 if (config == null) {
1662 LOG.error("bgp config is empty nothing to push to bgp");
1665 BgpRouter br = bgpRouter;
1666 AsId a = config.getAsId();
1670 long asNum = a.getLocalAs().longValue();
1671 IpAddress routerId = a.getRouterId();
1672 Long spt = a.getStalepathTime();
1673 Boolean afb = a.isAnnounceFbit();
1674 String rid = (routerId == null) ? "" : new String(routerId.getValue());
1675 int stalepathTime = (int) getStalePathtime(0, config.getAsId());
1676 boolean announceFbit = true;
1678 br.startBgp(asNum, rid, stalepathTime, announceFbit);
1679 } catch (BgpRouterException bre) {
1680 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
1683 LOG.error("Replay: startBgp() received exception: \""
1684 + bre + "\"; " + addWarn);
1686 } catch (Exception e) {
1687 //not unusual. We may have restarted & BGP is already on
1688 LOG.error("Replay:startBgp() received exception: \"" + e + "\"");
1691 if (getBgpCounters() == null) {
1692 startBgpCountersTask();
1695 if (getBgpAlarms() == null) {
1696 startBgpAlarmsTask();
1699 Logging l = config.getLogging();
1702 br.setLogging(l.getFile(), l.getLevel());
1703 } catch (Exception e) {
1704 LOG.error("Replay:setLogging() received exception: \"" + e + "\"");
1708 GracefulRestart g = config.getGracefulRestart();
1711 br.addGracefulRestart(g.getStalepathTime().intValue());
1712 } catch (Exception e) {
1713 LOG.error("Replay:addGr() received exception: \"" + e + "\"");
1717 List<Vrfs> v = config.getVrfs();
1719 for (Vrfs vrf : v) {
1721 br.addVrf(vrf.getRd(), vrf.getImportRts(),
1722 vrf.getExportRts());
1723 } catch (Exception e) {
1724 LOG.error("Replay:addVrf() received exception: \"" + e + "\"");
1729 List<Networks> ln = config.getNetworks();
1731 for (Networks net : ln) {
1732 String rd = net.getRd();
1733 String pfxlen = net.getPrefixLen();
1734 String nh = net.getNexthop().getValue();
1735 Long label = net.getLabel();
1736 int lbl = (label == null) ? 0 : label.intValue();
1737 if (rd == null && lbl > 0) {
1738 //LU prefix is being deleted.
1739 rd = Integer.toString(lbl);
1742 br.addPrefix(rd, pfxlen, nh, lbl);
1743 } catch (Exception e) {
1744 LOG.error("Replay:addPfx() received exception: \"" + e + "\"");
1748 List<Neighbors> n = config.getNeighbors();
1750 LOG.error("configuring existing Neighbors present for replay total neighbors {}", n.size());
1751 replayNbrConfig(n, br);
1753 LOG.error("no Neighbors present for replay config ");
1758 private <T extends DataObject> void update(InstanceIdentifier<T> iid, T dto) {
1759 BgpUtil.update(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1762 private <T extends DataObject> void asyncWrite(InstanceIdentifier<T> iid, T dto) {
1763 BgpUtil.write(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1766 private <T extends DataObject> void delete(InstanceIdentifier<T> iid) {
1767 BgpUtil.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, iid);
1770 public synchronized void
1771 startConfig(String bgpHost, int thriftPort) {
1772 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1773 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1774 InstanceIdentifier<ConfigServer> iid = iib.build();
1775 Ipv4Address ipAddr = new Ipv4Address(bgpHost);
1776 ConfigServer dto = new ConfigServerBuilder().setHost(ipAddr)
1777 .setPort((long) thriftPort).build();
1781 public synchronized void
1782 startBgp(long as, String routerId, int spt, boolean fbit) {
1783 IpAddress rid = (routerId == null) ?
1784 null : new IpAddress(routerId.toCharArray());
1785 Long staleTime = (long) spt;
1786 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1787 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1788 InstanceIdentifier<AsId> iid = iib.build();
1789 AsId dto = new AsIdBuilder().setLocalAs(as)
1791 .setStalepathTime(staleTime)
1792 .setAnnounceFbit(fbit).build();
1796 public synchronized void
1797 addLogging(String fileName, String logLevel) {
1798 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1799 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1800 InstanceIdentifier<Logging> iid = iib.build();
1801 Logging dto = new LoggingBuilder().setFile(fileName)
1802 .setLevel(logLevel).build();
1806 public synchronized void
1807 addGracefulRestart(int staleTime) {
1808 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1809 InstanceIdentifier.builder(Bgp.class).child(GracefulRestart.class);
1810 InstanceIdentifier<GracefulRestart> iid = iib.build();
1811 GracefulRestart dto = new GracefulRestartBuilder()
1812 .setStalepathTime((long) staleTime).build();
1816 public synchronized void
1817 addNeighbor(String nbrIp, long remoteAs) {
1818 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1819 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1820 InstanceIdentifier.builder(Bgp.class)
1821 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1822 InstanceIdentifier<Neighbors> iid = iib.build();
1823 Neighbors dto = new NeighborsBuilder().setAddress(nbrAddr)
1824 .setRemoteAs(remoteAs).build();
1828 public synchronized void
1829 addUpdateSource(String nbrIp, String srcIp) {
1830 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1831 Ipv4Address srcAddr = new Ipv4Address(srcIp);
1832 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1833 InstanceIdentifier.builder(Bgp.class)
1834 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1835 .child(UpdateSource.class);
1836 InstanceIdentifier<UpdateSource> iid = iib.build();
1837 UpdateSource dto = new UpdateSourceBuilder().setPeerIp(nbrAddr)
1838 .setSourceIp(srcAddr).build();
1842 public synchronized void
1843 addEbgpMultihop(String nbrIp, int nHops) {
1844 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1845 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1846 InstanceIdentifier.builder(Bgp.class)
1847 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1848 .child(EbgpMultihop.class);
1849 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1850 EbgpMultihop dto = new EbgpMultihopBuilder().setPeerIp(nbrAddr)
1851 .setNhops((long) nHops).build();
1855 public synchronized void
1856 addAddressFamily(String nbrIp, int afi, int safi) {
1857 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1858 Long a = (long) afi;
1859 Long sa = (long) safi;
1860 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1861 InstanceIdentifier.builder(Bgp.class)
1862 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1863 .child(AddressFamilies.class, new AddressFamiliesKey(a, sa));
1864 InstanceIdentifier<AddressFamilies> iid = iib.build();
1865 AddressFamilies dto = new AddressFamiliesBuilder().setPeerIp(nbrAddr)
1866 .setAfi(a).setSafi(sa).build();
1870 public synchronized void
1871 addPrefix(String rd, String pfx, List<String> nhList, int lbl) {
1872 for (String nh : nhList) {
1873 Ipv4Address nexthop = new Ipv4Address(nh);
1874 Long label = (long) lbl;
1875 InstanceIdentifier<Networks> iid = InstanceIdentifier.builder(Bgp.class)
1876 .child(Networks.class, new NetworksKey(pfx, rd)).build();
1877 Networks dto = new NetworksBuilder().setRd(rd).setPrefixLen(pfx).setNexthop(nexthop)
1878 .setLabel(label).build();
1883 public synchronized void
1884 addVrf(String rd, List<String> irts, List<String> erts) {
1885 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1886 InstanceIdentifier.builder(Bgp.class)
1887 .child(Vrfs.class, new VrfsKey(rd));
1888 InstanceIdentifier<Vrfs> iid = iib.build();
1889 Vrfs dto = new VrfsBuilder().setRd(rd)
1891 .setExportRts(erts).build();
1892 BgpUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1895 public synchronized void stopConfig() {
1896 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1897 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1898 InstanceIdentifier<ConfigServer> iid = iib.build();
1902 public synchronized void stopBgp() {
1903 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1904 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1905 InstanceIdentifier<AsId> iid = iib.build();
1909 public synchronized void delLogging() {
1910 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1911 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1912 InstanceIdentifier<Logging> iid = iib.build();
1916 public synchronized void delGracefulRestart() {
1917 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1918 InstanceIdentifier.builder(Bgp.class)
1919 .child(GracefulRestart.class);
1920 InstanceIdentifier<GracefulRestart> iid = iib.build();
1924 public synchronized void delNeighbor(String nbrIp) {
1925 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1926 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1927 InstanceIdentifier.builder(Bgp.class)
1928 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1929 InstanceIdentifier<Neighbors> iid = iib.build();
1933 public synchronized void delUpdateSource(String nbrIp) {
1934 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1935 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1936 InstanceIdentifier.builder(Bgp.class)
1937 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1938 .child(UpdateSource.class);
1939 InstanceIdentifier<UpdateSource> iid = iib.build();
1943 public synchronized void delEbgpMultihop(String nbrIp) {
1944 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1945 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1946 InstanceIdentifier.builder(Bgp.class)
1947 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1948 .child(EbgpMultihop.class);
1949 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1953 public synchronized void
1954 delAddressFamily(String nbrIp, int afi, int safi) {
1955 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1956 Long a = (long) afi;
1957 Long sa = (long) safi;
1958 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1959 InstanceIdentifier.builder(Bgp.class)
1960 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1961 .child(AddressFamilies.class, new AddressFamiliesKey(a, sa));
1962 InstanceIdentifier<AddressFamilies> iid = iib.build();
1966 public synchronized void delPrefix(String rd, String pfx) {
1967 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
1968 InstanceIdentifier.builder(Bgp.class)
1969 .child(Networks.class, new NetworksKey(pfx, rd));
1970 InstanceIdentifier<Networks> iid = iib.build();
1974 public synchronized void delVrf(String rd) {
1975 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1976 InstanceIdentifier.builder(Bgp.class)
1977 .child(Vrfs.class, new VrfsKey(rd));
1978 InstanceIdentifier<Vrfs> iid = iib.build();
1982 static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
1985 * Remove Stale Marked Routes after timer expiry.
1987 class RouteCleanup implements Callable<Integer> {
1990 public Integer call() {
1993 if (staledFibEntriesMap.isEmpty()) {
1994 LOG.info("BGP: RouteCleanup timertask tirggered but STALED FIB MAP is EMPTY");
1996 for (String rd : staledFibEntriesMap.keySet()) {
1997 if (Thread.interrupted()) {
2000 Map<String, String> map = staledFibEntriesMap.get(rd);
2002 for (String prefix : map.keySet()) {
2003 if (Thread.interrupted()) {
2008 LOG.debug("BGP: RouteCleanup deletePrefix called for : rd:{}, prefix{}" + rd.toString() + prefix);
2009 fibDSWriter.removeFibEntryFromDS(rd, prefix);
2010 } catch (Exception e) {
2011 LOG.error("BGP: RouteCleanup deletePrefix failed rd:{}, prefix{}" + rd.toString() + prefix);
2017 } catch (Exception e) {
2018 LOG.error("Cleanup Thread Got interrupted, Failed to cleanup stale routes ", e);
2020 staledFibEntriesMap.clear();
2022 LOG.error("cleared {} stale routes after bgp restart", totalCleared);
2028 * BGP restart scenario, ODL-BGP manager was/is running.
2029 * On re-sync notification, Get a copy of FIB database.
2031 public static void createStaleFibMap() {
2032 totalStaledCount = 0;
2035 * at the time Stale FIB creation, Wait till all PENDING write transaction
2036 * to complete (or)wait for max timeout value of STALE_FIB_WAIT Seconds.
2038 int retry = STALE_FIB_WAIT;
2039 while ((BgpUtil.getGetPendingWrTransaction() != 0) && (retry > 0)) {
2043 LOG.error("TimeOut occured {} seconds, in waiting stale fibDSWriter create", STALE_FIB_WAIT);
2046 staledFibEntriesMap.clear();
2047 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
2048 DataBroker db = BgpUtil.getBroker();
2050 LOG.error("Couldn't find BgpUtil dataBroker while creating createStaleFibMap");
2054 Optional<FibEntries> fibEntries = BgpUtil.read(BgpUtil.getBroker(),
2055 LogicalDatastoreType.CONFIGURATION, id);
2056 if (fibEntries.isPresent()) {
2057 List<VrfTables> stale_vrfTables = fibEntries.get().getVrfTables();
2058 for (VrfTables vrfTable : stale_vrfTables) {
2059 Map<String, String> stale_fib_ent_map = new HashMap<>();
2060 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
2061 if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
2062 //Stale marking and cleanup is only meant for the routes learned through BGP.
2065 if (Thread.interrupted()) {
2069 //Create MAP from stale_vrfTables.
2070 for (String nextHop : vrfEntry.getNextHopAddressList()) {
2071 stale_fib_ent_map.put(vrfEntry.getDestPrefix(), nextHop + "/" + vrfEntry.getLabel());
2074 staledFibEntriesMap.put(vrfTable.getRouteDistinguisher(), stale_fib_ent_map);
2077 LOG.error("createStaleFibMap:: FIBentries.class is not present");
2079 } catch (Exception e) {
2080 LOG.error("createStaleFibMap:: error ", e);
2082 LOG.error("created {} staled entries ", totalStaledCount);
2085 //map<rd, map<prefix/len, nexthop/label>>
2086 public static Map<String, Map<String, String>> getStaledFibEntriesMap() {
2087 return staledFibEntriesMap;
2090 //TODO: below function is for testing purpose with cli
2091 public static void onUpdateWithdrawRoute(String rd, String prefix, int plen, String nexthop) {
2092 LOG.debug("Route del ** {} ** {}/{} ", rd, prefix, plen);
2094 fibDSWriter.removeFibEntryFromDS(rd, prefix + "/" + plen);
2095 } catch (Throwable e) {
2096 LOG.error("failed to handle withdraw route ", e);
2099 public boolean isBgpConnected(){
2100 return bgpRouter.isBgpConnected();
2102 public long getLastConnectedTS() {
2103 return bgpRouter.getLastConnectedTS();
2105 public long getConnectTS() {
2106 return bgpRouter.getConnectTS();
2108 public long getStartTS() {
2109 return bgpRouter.getStartTS();
2111 public static int getTotalStaledCount() {return totalStaledCount;}
2112 public static int getTotalCleared() { return totalCleared;}
2114 public Timer getBgpCountersTimer() {
2115 return bgpCountersTimer;
2118 public BgpCounters getBgpCounters() {
2122 public void setBgpCountersTimer (Timer t) {
2123 bgpCountersTimer = t;
2125 public void setBgpAlarmsTimer (Timer t) {
2129 public void startBgpCountersTask() {
2130 if (getBgpCounters() == null) {
2133 bgpCounters = new BgpCounters(bgpConfigurationManager.getBgpSdncMipIp());
2134 setBgpCountersTimer(new Timer(true));
2135 getBgpCountersTimer().scheduleAtFixedRate(bgpCounters, 0, 120 * 1000);
2138 LOG.info("Bgp Counters task scheduled for every two minutes.");
2139 } catch (Exception e) {
2140 System.out.println("Could not start the timertask for Bgp Counters.");
2141 e.printStackTrace();
2145 bgpManager.setQbgpLog(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
2146 } catch (Exception e) {
2147 System.out.println("Could not set the default options for logging");
2152 public void stopBgpCountersTask() {
2153 Timer t = getBgpCountersTimer();
2154 if (getBgpCounters() != null) {
2156 setBgpCountersTimer(null);
2160 public void startBgpAlarmsTask() {
2161 if (getBgpAlarms() == null) {
2163 bgpAlarms = new BgpAlarms(this);
2164 setBgpAlarmsTimer(new Timer(true));
2165 getBgpAlarmsTimer().scheduleAtFixedRate(bgpAlarms, 0, 60 * 1000);
2166 LOG.info("Bgp Alarms task scheduled for every minute.");
2167 } catch (Exception e) {
2168 System.out.println("Could not start the timertask for Bgp Alarms.");
2169 e.printStackTrace();
2174 public void stopBgpAlarmsTask() {
2175 Timer t = getBgpAlarmsTimer();
2176 if (getBgpAlarms() != null) {
2178 setBgpAlarmsTimer(null);
2182 public Timer getBgpAlarmsTimer() {
2183 return bgpAlarmsTimer;
2186 public BgpAlarms getBgpAlarms() {