2 * Copyright © 2015, 2017 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.FileNotFoundException;
15 import java.io.FileReader;
16 import java.io.IOException;
17 import java.lang.reflect.Constructor;
18 import java.lang.reflect.InvocationTargetException;
19 import java.net.InetAddress;
20 import java.net.NetworkInterface;
21 import java.net.SocketException;
22 import java.util.Collections;
23 import java.util.Enumeration;
24 import java.util.HashMap;
25 import java.util.Iterator;
26 import java.util.List;
28 import java.util.Timer;
29 import java.util.TimerTask;
30 import java.util.concurrent.Callable;
31 import java.util.concurrent.ConcurrentHashMap;
32 import java.util.concurrent.CountDownLatch;
33 import java.util.concurrent.ExecutionException;
34 import java.util.concurrent.Executors;
35 import java.util.concurrent.Future;
36 import java.util.concurrent.ScheduledExecutorService;
37 import java.util.concurrent.TimeoutException;
38 import java.util.concurrent.atomic.AtomicBoolean;
39 import java.util.concurrent.atomic.AtomicInteger;
40 import org.apache.thrift.TException;
41 import org.opendaylight.controller.config.api.osgi.WaitingServiceTracker;
42 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
43 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
44 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
45 import org.opendaylight.controller.md.sal.common.api.clustering.CandidateAlreadyRegisteredException;
46 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
47 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
48 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
49 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
50 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
51 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
52 import org.opendaylight.genius.utils.batching.DefaultBatchHandler;
53 import org.opendaylight.genius.utils.clustering.EntityOwnerUtils;
54 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
55 import org.opendaylight.netvirt.bgpmanager.commands.ClearBgpCli;
56 import org.opendaylight.netvirt.bgpmanager.oam.BgpAlarms;
57 import org.opendaylight.netvirt.bgpmanager.oam.BgpConstants;
58 import org.opendaylight.netvirt.bgpmanager.oam.BgpCounters;
59 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouter;
60 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouterException;
61 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpSyncHandle;
62 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Routes;
63 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Update;
64 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
65 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
66 import org.opendaylight.netvirt.bgpmanager.thrift.gen.protocol_type;
67 import org.opendaylight.netvirt.bgpmanager.thrift.gen.qbgpConstants;
68 import org.opendaylight.netvirt.bgpmanager.thrift.server.BgpThriftService;
69 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
70 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
71 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.BgpControlPlaneType;
72 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.EncapType;
73 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.LayerType;
74 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsId;
75 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsIdBuilder;
76 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServer;
77 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServerBuilder;
78 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestart;
79 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestartBuilder;
80 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Logging;
81 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.LoggingBuilder;
82 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Neighbors;
83 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsBuilder;
84 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsKey;
85 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Networks;
86 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksBuilder;
87 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksKey;
88 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Vrfs;
89 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsBuilder;
90 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsKey;
91 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamilies;
92 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesBuilder;
93 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesKey;
94 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihop;
95 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihopBuilder;
96 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSource;
97 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSourceBuilder;
98 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
99 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
104 import org.opendaylight.yangtools.concepts.ListenerRegistration;
105 import org.opendaylight.yangtools.yang.binding.DataObject;
106 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
107 import org.osgi.framework.BundleContext;
108 import org.slf4j.Logger;
109 import org.slf4j.LoggerFactory;
111 public class BgpConfigurationManager {
112 private static final Logger LOG = LoggerFactory.getLogger(BgpConfigurationManager.class);
113 private static DataBroker dataBroker;
114 private static FibDSWriter fibDSWriter;
115 public static IBgpManager bgpManager;
116 private final BundleContext bundleContext;
117 private static Bgp config;
118 private static BgpRouter bgpRouter;
119 private static BgpThriftService updateServer;
120 private BgpCounters bgpCounters;
121 private BgpAlarms bgpAlarms;
122 private Timer bgpCountersTimer;
123 private Timer bgpAlarmsTimer;
124 private static final String DEF_LOGFILE = "/var/log/bgp_debug.log";
125 private static final String DEF_LOGLEVEL = "errors";
126 private static final String UPDATE_PORT = "bgp.thrift.service.port";
127 private static final String CONFIG_HOST = "vpnservice.bgpspeaker.host.name";
128 private static final String CONFIG_PORT = "vpnservice.bgpspeaker.thrift.port";
129 private static final String DEF_UPORT = "6644";
130 private static final String DEF_CHOST = "127.0.0.1";
131 private static final String DEF_CPORT = "7644";
132 private static final String SDNC_BGP_MIP = "sdnc_bgp_mip";
133 private static final String BGP_SDNC_MIP = "bgp_sdnc_mip";
134 private static final String CLUSTER_CONF_FILE = "/cluster/etc/cluster.conf";
135 private static final Timer IP_ACTIVATION_CHECK_TIMER = new Timer();
136 private static final int STALE_FIB_WAIT = 60;
137 private static final int RESTART_DEFAULT_GR = 90;
138 private long staleStartTime = 0;
139 private long staleEndTime = 0;
140 private long cfgReplayStartTime = 0;
141 private long cfgReplayEndTime = 0;
142 private long staleCleanupTime = 0;
143 private static final int DS_RETRY_COOUNT = 100; //100 retries, each after WAIT_TIME_BETWEEN_EACH_TRY_MILLIS seconds
144 private static final long WAIT_TIME_BETWEEN_EACH_TRY_MILLIS = 1000L; //one second sleep after every retry
146 public String getBgpSdncMipIp() {
147 return readThriftIpForCommunication(BGP_SDNC_MIP);
150 public long getStaleCleanupTime() {
151 return staleCleanupTime;
154 public void setStaleCleanupTime(long staleCleanupTime) {
155 this.staleCleanupTime = staleCleanupTime;
158 public long getCfgReplayEndTime() {
159 return cfgReplayEndTime;
162 public void setCfgReplayEndTime(long cfgReplayEndTime) {
163 this.cfgReplayEndTime = cfgReplayEndTime;
166 public long getCfgReplayStartTime() {
167 return cfgReplayStartTime;
170 public void setCfgReplayStartTime(long cfgReplayStartTime) {
171 this.cfgReplayStartTime = cfgReplayStartTime;
174 public long getStaleEndTime() {
178 public void setStaleEndTime(long staleEndTime) {
179 this.staleEndTime = staleEndTime;
182 public long getStaleStartTime() {
183 return staleStartTime;
186 public void setStaleStartTime(long staleStartTime) {
187 this.staleStartTime = staleStartTime;
191 // to have stale FIB map (RD, Prefix)
192 // number of seconds wait for route sync-up between ODL and BGP
193 private static final int BGP_RESTART_ROUTE_SYNC_SEC = 600;
195 static String odlThriftIp = "127.0.0.1";
196 static String bgpThriftIp = "127.0.0.1";
197 private static String cHostStartup;
198 private static String cPortStartup;
199 private static CountDownLatch initer = new CountDownLatch(1);
200 //static IITMProvider itmProvider;
201 //map<rd, map<prefix/len, nexthop/label>>
202 private static Map<String, Map<String, String>> staledFibEntriesMap = new ConcurrentHashMap<>();
204 static final String BGP_ENTITY_TYPE_FOR_OWNERSHIP = "bgp";
205 static final String BGP_ENTITY_NAME = "bgp";
207 static int totalStaledCount = 0;
208 static int totalCleared = 0;
210 private static final Class[] REACTORS = {
211 ConfigServerReactor.class, AsIdReactor.class,
212 GracefulRestartReactor.class, LoggingReactor.class,
213 NeighborsReactor.class, UpdateSourceReactor.class,
214 EbgpMultihopReactor.class, AddressFamiliesReactor.class,
215 NetworksReactor.class, VrfsReactor.class, BgpReactor.class
218 private ListenerRegistration<DataChangeListener>[] registrations;
220 final BgpConfigurationManager bgpConfigurationManager;
222 public BgpConfigurationManager(final DataBroker dataBroker,
223 final EntityOwnershipService entityOwnershipService,
224 final FibDSWriter fibDSWriter,
225 final BundleContext bundleContext)
226 throws InterruptedException, ExecutionException, TimeoutException {
227 BgpConfigurationManager.dataBroker = dataBroker;
228 BgpConfigurationManager.fibDSWriter = fibDSWriter;
229 this.bundleContext = bundleContext;
230 String updatePort = getProperty(UPDATE_PORT, DEF_UPORT);
231 cHostStartup = getProperty(CONFIG_HOST, DEF_CHOST);
232 cPortStartup = getProperty(CONFIG_PORT, DEF_CPORT);
233 LOG.info("UpdateServer at localhost:" + updatePort + " ConfigServer at "
234 + cHostStartup + ":" + cPortStartup);
235 VtyshCli.setHostAddr(cHostStartup);
236 ClearBgpCli.setHostAddr(cHostStartup);
237 setEntityOwnershipService(entityOwnershipService);
238 bgpRouter = BgpRouter.getInstance();
239 odlThriftIp = readThriftIpForCommunication(SDNC_BGP_MIP);
240 bgpThriftIp = readThriftIpForCommunication(BGP_SDNC_MIP);
243 LOG.info("BGP Configuration manager initialized");
246 bgpConfigurationManager = this;
247 BgpUtil.batchSize = BgpUtil.BATCH_SIZE;
248 if (Integer.getInteger("batch.size") != null) {
249 BgpUtil.batchSize = Integer.getInteger("batch.size");
251 BgpUtil.batchInterval = BgpUtil.PERIODICITY;
252 if (Integer.getInteger("batch.wait.time") != null) {
253 BgpUtil.batchInterval = Integer.getInteger("batch.wait.time");
255 BgpUtil.registerWithBatchManager(
256 new DefaultBatchHandler(dataBroker, LogicalDatastoreType.CONFIGURATION, BgpUtil.batchSize,
257 BgpUtil.batchInterval));
259 GlobalEventExecutor.INSTANCE.execute(() -> {
260 final WaitingServiceTracker<IBgpManager> tracker = WaitingServiceTracker.create(
261 IBgpManager.class, bundleContext);
262 bgpManager = tracker.waitForService(WaitingServiceTracker.FIVE_MINUTES);
263 updateServer = new BgpThriftService(Integer.parseInt(updatePort), bgpManager, fibDSWriter);
264 updateServer.start();
265 LOG.info("BgpConfigurationManager initialized. IBgpManager={}", bgpManager);
269 private Object createListener(Class<?> cls) {
274 ctor = cls.getConstructor(BgpConfigurationManager.class);
275 obj = ctor.newInstance(this);
276 } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException
278 LOG.error("Failed to create listener object", e);
283 private void registerCallbacks() {
284 String emsg = "Failed to register listener";
285 registrations = new ListenerRegistration[REACTORS.length];
286 InstanceIdentifier<?> iid = InstanceIdentifier.create(Bgp.class);
287 for (Class reactor : REACTORS) {
288 Object obj = createListener(reactor);
289 AsyncDataTreeChangeListenerBase dcl = (AsyncDataTreeChangeListenerBase) obj;
290 dcl.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
294 public void close() {
295 if (updateServer != null) {
298 LOG.info("{} close", getClass().getSimpleName());
301 private boolean configExists() throws ReadFailedException {
302 InstanceIdentifier.InstanceIdentifierBuilder<Bgp> iib =
303 InstanceIdentifier.builder(Bgp.class);
304 InstanceIdentifier<Bgp> iid = iib.build();
305 return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
309 private String getProperty(String var, String def) {
310 String property = bundleContext.getProperty(var);
311 return (property == null ? def : property);
314 boolean ignoreClusterDcnEventForFollower() {
315 return !EntityOwnerUtils.amIEntityOwner(BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME);
319 config = getConfig();
323 public void setEntityOwnershipService(final EntityOwnershipService entityOwnershipService) {
325 EntityOwnerUtils.registerEntityCandidateForOwnerShip(entityOwnershipService,
326 BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME, ownershipChange -> {
327 LOG.trace("entity owner change event fired");
328 if (ownershipChange.hasOwner() && ownershipChange.isOwner()) {
329 LOG.trace("This PL is the Owner");
333 LOG.info("Not owner: hasOwner: {}, isOwner: {}", ownershipChange.hasOwner(),
334 ownershipChange.isOwner());
337 } catch (CandidateAlreadyRegisteredException e) {
338 LOG.error("failed to register bgp entity", e);
342 private static final String ADD_WARN =
343 "Config store updated; undo with Delete if needed.";
344 private static final String DEL_WARN =
345 "Config store updated; undo with Add if needed.";
346 private static final String UPD_WARN =
347 "Update operation not supported; Config store updated;"
348 + " restore with another Update if needed.";
350 public class ConfigServerReactor
351 extends AsyncDataTreeChangeListenerBase<ConfigServer, ConfigServerReactor>
352 implements AutoCloseable, ClusteredDataTreeChangeListener<ConfigServer> {
353 private static final String YANG_OBJ = "config-server ";
355 public ConfigServerReactor() {
356 super(ConfigServer.class, ConfigServerReactor.class);
360 protected synchronized void add(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
361 LOG.trace("received bgp connect config host {}", val.getHost().getValue());
362 if (ignoreClusterDcnEventForFollower()) {
368 } catch (InterruptedException e) {
371 LOG.debug("issueing bgp router connect to host {}", val.getHost().getValue());
372 synchronized (BgpConfigurationManager.this) {
373 boolean res = bgpRouter.connect(val.getHost().getValue(),
374 val.getPort().intValue());
376 LOG.error(YANG_OBJ + "Add failed; " + ADD_WARN);
382 protected ConfigServerReactor getDataTreeChangeListener() {
383 return ConfigServerReactor.this;
387 protected InstanceIdentifier<ConfigServer> getWildCardPath() {
388 return InstanceIdentifier.create(Bgp.class).child(ConfigServer.class);
392 protected synchronized void 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(YANG_OBJ + UPD_WARN);
413 private BgpRouter getClient(String yangObj) {
414 if (bgpRouter == null) {
415 LOG.warn("{}: configuration received when BGP is inactive", yangObj);
420 public class AsIdReactor
421 extends AsyncDataTreeChangeListenerBase<AsId, AsIdReactor>
422 implements AutoCloseable, ClusteredDataTreeChangeListener<AsId> {
424 private static final String YANG_OBJ = "as-id ";
426 public AsIdReactor() {
427 super(AsId.class, AsIdReactor.class);
431 protected synchronized void add(InstanceIdentifier<AsId> iid, AsId val) {
432 LOG.error("received bgp add asid {}", val);
433 if (ignoreClusterDcnEventForFollower()) {
436 LOG.debug("received add router config asNum {}", val.getLocalAs());
437 synchronized (BgpConfigurationManager.this) {
438 BgpRouter br = getClient(YANG_OBJ);
440 LOG.error("no bgp router client found exiting asid add");
443 long asNum = val.getLocalAs();
444 IpAddress routerId = val.getRouterId();
445 Boolean afb = val.isAnnounceFbit();
446 String rid = (routerId == null) ? "" : new String(routerId.getValue());
447 int stalepathTime = (int) getStalePathtime(RESTART_DEFAULT_GR, val);
448 boolean announceFbit = true;
450 br.startBgp(asNum, rid, stalepathTime, announceFbit);
451 if (getBgpCounters() == null) {
452 startBgpCountersTask();
454 if (getBgpAlarms() == null) {
455 startBgpAlarmsTask();
457 } catch (BgpRouterException bre) {
458 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
459 LOG.error(YANG_OBJ + "Add requested when BGP is already active");
461 LOG.error(YANG_OBJ + "Add received exception: \""
462 + bre + "\"; " + ADD_WARN);
464 } catch (TException e) {
465 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
471 protected AsIdReactor getDataTreeChangeListener() {
472 return AsIdReactor.this;
476 protected InstanceIdentifier<AsId> getWildCardPath() {
477 return InstanceIdentifier.create(Bgp.class).child(AsId.class);
481 protected synchronized void remove(InstanceIdentifier<AsId> iid, AsId val) {
482 LOG.error("received delete router config asNum {}", val.getLocalAs());
483 if (ignoreClusterDcnEventForFollower()) {
486 synchronized (BgpConfigurationManager.this) {
487 BgpRouter br = getClient(YANG_OBJ);
491 long asNum = val.getLocalAs();
494 } catch (TException | BgpRouterException e) {
495 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
497 if (getBgpCounters() != null) {
498 stopBgpCountersTask();
500 if (getBgpAlarms() != null) {
507 protected void update(InstanceIdentifier<AsId> iid,
508 AsId oldval, AsId newval) {
509 if (ignoreClusterDcnEventForFollower()) {
512 LOG.error(YANG_OBJ + UPD_WARN);
516 public class GracefulRestartReactor
517 extends AsyncDataTreeChangeListenerBase<GracefulRestart, GracefulRestartReactor>
518 implements AutoCloseable, ClusteredDataTreeChangeListener<GracefulRestart> {
520 private static final String YANG_OBJ = "graceful-restart ";
522 public GracefulRestartReactor() {
523 super(GracefulRestart.class, GracefulRestartReactor.class);
527 protected synchronized void add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
528 if (ignoreClusterDcnEventForFollower()) {
531 synchronized (BgpConfigurationManager.this) {
532 BgpRouter br = getClient(YANG_OBJ);
537 br.addGracefulRestart(val.getStalepathTime().intValue());
538 } catch (TException | BgpRouterException e) {
539 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
545 protected GracefulRestartReactor getDataTreeChangeListener() {
546 return GracefulRestartReactor.this;
550 protected InstanceIdentifier<GracefulRestart> getWildCardPath() {
551 return InstanceIdentifier.create(Bgp.class).child(GracefulRestart.class);
555 protected synchronized void remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
556 if (ignoreClusterDcnEventForFollower()) {
559 LOG.debug("received delete GracefulRestart config val {}", val.getStalepathTime().intValue());
560 synchronized (BgpConfigurationManager.this) {
561 BgpRouter br = getClient(YANG_OBJ);
566 br.delGracefulRestart();
567 } catch (TException | BgpRouterException e) {
568 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
574 protected void update(InstanceIdentifier<GracefulRestart> iid,
575 GracefulRestart oldval, GracefulRestart newval) {
576 if (ignoreClusterDcnEventForFollower()) {
579 LOG.debug("received update GracefulRestart config val {}", newval.getStalepathTime().intValue());
580 synchronized (BgpConfigurationManager.this) {
581 BgpRouter br = getClient(YANG_OBJ);
586 br.addGracefulRestart(newval.getStalepathTime().intValue());
587 } catch (TException | BgpRouterException e) {
588 LOG.error("{} update received exception; {}", YANG_OBJ, ADD_WARN, e);
594 public class LoggingReactor
595 extends AsyncDataTreeChangeListenerBase<Logging, LoggingReactor>
596 implements AutoCloseable, ClusteredDataTreeChangeListener<Logging> {
598 private static final String YANG_OBJ = "logging ";
600 public LoggingReactor() {
601 super(Logging.class, LoggingReactor.class);
605 protected synchronized void add(InstanceIdentifier<Logging> iid, Logging val) {
606 if (ignoreClusterDcnEventForFollower()) {
609 synchronized (BgpConfigurationManager.this) {
610 BgpRouter br = getClient(YANG_OBJ);
615 br.setLogging(val.getFile(), val.getLevel());
616 } catch (TException | BgpRouterException e) {
617 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
623 protected LoggingReactor getDataTreeChangeListener() {
624 return LoggingReactor.this;
628 protected InstanceIdentifier<Logging> getWildCardPath() {
629 return InstanceIdentifier.create(Bgp.class).child(Logging.class);
633 protected synchronized void remove(InstanceIdentifier<Logging> iid, Logging val) {
634 if (ignoreClusterDcnEventForFollower()) {
637 LOG.debug("received remove Logging config val {}", val.getLevel());
638 synchronized (BgpConfigurationManager.this) {
639 BgpRouter br = getClient(YANG_OBJ);
644 br.setLogging(DEF_LOGFILE, DEF_LOGLEVEL);
645 } catch (TException | BgpRouterException e) {
646 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
652 protected void update(InstanceIdentifier<Logging> iid,
653 Logging oldval, Logging newval) {
654 if (ignoreClusterDcnEventForFollower()) {
657 synchronized (BgpConfigurationManager.this) {
658 BgpRouter br = getClient(YANG_OBJ);
663 br.setLogging(newval.getFile(), newval.getLevel());
664 } catch (TException | BgpRouterException e) {
665 LOG.error("{} newval received exception; {}", YANG_OBJ, ADD_WARN, e);
671 public class NeighborsReactor
672 extends AsyncDataTreeChangeListenerBase<Neighbors, NeighborsReactor>
673 implements AutoCloseable, ClusteredDataTreeChangeListener<Neighbors> {
675 private static final String YANG_OBJ = "neighbors ";
677 public NeighborsReactor() {
678 super(Neighbors.class, NeighborsReactor.class);
682 protected synchronized void add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
683 if (ignoreClusterDcnEventForFollower()) {
686 LOG.debug("received add Neighbors config val {}", val.getAddress().getValue());
687 synchronized (BgpConfigurationManager.this) {
688 BgpRouter br = getClient(YANG_OBJ);
692 String peerIp = val.getAddress().getValue();
693 long as = val.getRemoteAs();
695 //itmProvider.buildTunnelsToDCGW(new IpAddress(peerIp.toCharArray()));
696 br.addNeighbor(peerIp, as);
698 } catch (TException | BgpRouterException e) {
699 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
705 protected NeighborsReactor getDataTreeChangeListener() {
706 return NeighborsReactor.this;
710 protected InstanceIdentifier<Neighbors> getWildCardPath() {
711 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class);
715 protected synchronized void remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
716 if (ignoreClusterDcnEventForFollower()) {
719 LOG.debug("received remove Neighbors config val {}", val.getAddress().getValue());
720 synchronized (BgpConfigurationManager.this) {
721 BgpRouter br = getClient(YANG_OBJ);
725 String peerIp = val.getAddress().getValue();
727 //itmProvider.deleteTunnelsToDCGW(new IpAddress(val.getAddress().getValue().toCharArray()));
728 br.delNeighbor(peerIp);
729 } catch (TException | BgpRouterException e) {
730 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
736 protected void update(InstanceIdentifier<Neighbors> iid,
737 Neighbors oldval, Neighbors newval) {
738 if (ignoreClusterDcnEventForFollower()) {
741 //purposefully nothing to do.
745 public class EbgpMultihopReactor
746 extends AsyncDataTreeChangeListenerBase<EbgpMultihop, EbgpMultihopReactor>
747 implements AutoCloseable, ClusteredDataTreeChangeListener<EbgpMultihop> {
749 private static final String YANG_OBJ = "ebgp-multihop ";
751 public EbgpMultihopReactor() {
752 super(EbgpMultihop.class, EbgpMultihopReactor.class);
756 protected synchronized void add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
757 if (ignoreClusterDcnEventForFollower()) {
760 LOG.debug("received add EbgpMultihop config val {}", val.getPeerIp().getValue());
761 synchronized (BgpConfigurationManager.this) {
762 BgpRouter br = getClient(YANG_OBJ);
766 String peerIp = val.getPeerIp().getValue();
768 br.addEbgpMultihop(peerIp, val.getNhops().intValue());
769 } catch (TException | BgpRouterException e) {
770 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
776 protected EbgpMultihopReactor getDataTreeChangeListener() {
777 return EbgpMultihopReactor.this;
781 protected InstanceIdentifier<EbgpMultihop> getWildCardPath() {
782 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(EbgpMultihop.class);
786 protected synchronized void remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
787 if (ignoreClusterDcnEventForFollower()) {
790 LOG.debug("received remove EbgpMultihop config val {}", val.getPeerIp().getValue());
791 synchronized (BgpConfigurationManager.this) {
792 BgpRouter br = getClient(YANG_OBJ);
796 String peerIp = val.getPeerIp().getValue();
798 br.delEbgpMultihop(peerIp);
799 } catch (TException | BgpRouterException e) {
800 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
806 protected void update(InstanceIdentifier<EbgpMultihop> iid,
807 EbgpMultihop oldval, EbgpMultihop newval) {
808 if (ignoreClusterDcnEventForFollower()) {
811 LOG.error(YANG_OBJ + UPD_WARN);
815 public class UpdateSourceReactor
816 extends AsyncDataTreeChangeListenerBase<UpdateSource, UpdateSourceReactor>
817 implements AutoCloseable, ClusteredDataTreeChangeListener<UpdateSource> {
819 private static final String YANG_OBJ = "update-source ";
821 public UpdateSourceReactor() {
822 super(UpdateSource.class, UpdateSourceReactor.class);
826 protected synchronized void add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
827 if (ignoreClusterDcnEventForFollower()) {
830 LOG.debug("received add UpdateSource config val {}", val.getSourceIp().getValue());
831 synchronized (BgpConfigurationManager.this) {
832 BgpRouter br = getClient(YANG_OBJ);
836 String peerIp = val.getPeerIp().getValue();
838 br.addUpdateSource(peerIp, val.getSourceIp().getValue());
839 } catch (TException | BgpRouterException e) {
840 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
846 protected UpdateSourceReactor getDataTreeChangeListener() {
847 return UpdateSourceReactor.this;
851 protected InstanceIdentifier<UpdateSource> getWildCardPath() {
852 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(UpdateSource.class);
856 protected synchronized void remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
857 if (ignoreClusterDcnEventForFollower()) {
860 LOG.debug("received remove UpdateSource config val {}", val.getSourceIp().getValue());
861 synchronized (BgpConfigurationManager.this) {
862 BgpRouter br = getClient(YANG_OBJ);
866 String peerIp = val.getPeerIp().getValue();
868 br.delUpdateSource(peerIp);
869 } catch (TException | BgpRouterException e) {
870 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
876 protected void update(InstanceIdentifier<UpdateSource> iid,
877 UpdateSource oldval, UpdateSource newval) {
878 if (ignoreClusterDcnEventForFollower()) {
881 LOG.error(YANG_OBJ + UPD_WARN);
885 public class AddressFamiliesReactor
886 extends AsyncDataTreeChangeListenerBase<AddressFamilies, AddressFamiliesReactor>
887 implements AutoCloseable, ClusteredDataTreeChangeListener<AddressFamilies> {
889 private static final String YANG_OBJ = "address-families ";
891 public AddressFamiliesReactor() {
892 super(AddressFamilies.class, AddressFamiliesReactor.class);
896 protected synchronized void add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
897 if (ignoreClusterDcnEventForFollower()) {
900 LOG.debug("received add AddressFamilies config val {}", val.getPeerIp().getValue());
901 synchronized (BgpConfigurationManager.this) {
902 BgpRouter br = getClient(YANG_OBJ);
906 String peerIp = val.getPeerIp().getValue();
907 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
908 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
910 br.addAddressFamily(peerIp, afi, safi);
911 } catch (TException | BgpRouterException e) {
912 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
918 protected AddressFamiliesReactor getDataTreeChangeListener() {
919 return AddressFamiliesReactor.this;
923 protected InstanceIdentifier<AddressFamilies> getWildCardPath() {
924 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(AddressFamilies.class);
928 protected synchronized void remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
929 if (ignoreClusterDcnEventForFollower()) {
932 LOG.debug("received remove AddressFamilies config val {}", val.getPeerIp().getValue());
933 synchronized (BgpConfigurationManager.this) {
934 BgpRouter br = getClient(YANG_OBJ);
938 String peerIp = val.getPeerIp().getValue();
939 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
940 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
942 br.delAddressFamily(peerIp, afi, safi);
943 } catch (TException | BgpRouterException e) {
944 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
950 protected void update(InstanceIdentifier<AddressFamilies> iid,
951 AddressFamilies oldval, AddressFamilies newval) {
952 if (ignoreClusterDcnEventForFollower()) {
955 LOG.error(YANG_OBJ + UPD_WARN);
959 public class NetworksReactor
960 extends AsyncDataTreeChangeListenerBase<Networks, NetworksReactor>
961 implements AutoCloseable, ClusteredDataTreeChangeListener<Networks> {
963 private static final String YANG_OBJ = "networks ";
965 public NetworksReactor() {
966 super(Networks.class, NetworksReactor.class);
970 public NetworksReactor getDataTreeChangeListener() {
971 return NetworksReactor.this;
975 protected synchronized void add(InstanceIdentifier<Networks> iid, Networks val) {
976 if (ignoreClusterDcnEventForFollower()) {
979 LOG.debug("received add Networks config val {}", val.getPrefixLen());
980 synchronized (BgpConfigurationManager.this) {
981 BgpRouter br = getClient(YANG_OBJ);
985 String rd = val.getRd();
986 String pfxlen = val.getPrefixLen();
987 String nh = val.getNexthop().getValue();
988 Long label = val.getLabel();
989 int lbl = (label == null) ? qbgpConstants.LBL_NO_LABEL
991 int l3vni = (val.getL3vni() == null) ? qbgpConstants.LBL_NO_LABEL
992 : val.getL3vni().intValue();
994 BgpControlPlaneType protocolType = val.getBgpControlPlaneType();
995 int ethernetTag = val.getEthtag().intValue();
996 String esi = val.getEsi();
997 String macaddress = val.getMacaddress();
998 EncapType encapType = val.getEncapType();
999 String routerMac = val.getRoutermac();
1002 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, BgpUtil.convertToThriftProtocolType(protocolType),
1003 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
1004 } catch (TException | BgpRouterException e) {
1005 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1011 protected InstanceIdentifier<Networks> getWildCardPath() {
1012 return InstanceIdentifier.create(Bgp.class).child(Networks.class);
1016 protected synchronized void remove(InstanceIdentifier<Networks> iid, Networks val) {
1017 if (ignoreClusterDcnEventForFollower()) {
1020 LOG.debug("received remove Networks config val {}", val.getPrefixLen());
1021 synchronized (BgpConfigurationManager.this) {
1022 BgpRouter br = getClient(YANG_OBJ);
1026 String rd = val.getRd();
1027 String pfxlen = val.getPrefixLen();
1028 Long label = val.getLabel();
1029 int lbl = (label == null) ? 0 : label.intValue();
1030 if (rd == null && lbl > 0) {
1031 //LU prefix is being deleted.
1032 rd = Integer.toString(lbl);
1035 br.delPrefix(rd, pfxlen);
1036 } catch (TException | BgpRouterException e) {
1037 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1043 protected void update(final InstanceIdentifier<Networks> iid,
1044 final Networks oldval, final Networks newval) {
1045 if (ignoreClusterDcnEventForFollower()) {
1048 if (oldval.equals(newval)) {
1049 //Update: OLD and New values are same, no need to trigger remove/add.
1050 LOG.debug("received Updated for the same OLD and New values. RD: {}, Prefix: {}, Label: {}, NH: {}",
1051 oldval.getRd(), oldval.getPrefixLen(), oldval.getLabel(), oldval.getNexthop());
1054 LOG.debug("received update networks config val {}", newval.getPrefixLen());
1055 remove(iid, oldval);
1056 timer.schedule(new TimerTask() {
1061 }, Integer.getInteger("bgp.nexthop.update.delay.in.secs", 5) * 1000);
1065 static Timer timer = new Timer();
1067 public class VrfsReactor
1068 extends AsyncDataTreeChangeListenerBase<Vrfs, VrfsReactor>
1069 implements AutoCloseable, ClusteredDataTreeChangeListener<Vrfs> {
1071 private static final String YANG_OBJ = "vrfs ";
1073 public VrfsReactor() {
1074 super(Vrfs.class, VrfsReactor.class);
1078 protected synchronized void add(InstanceIdentifier<Vrfs> iid, Vrfs val) {
1079 if (ignoreClusterDcnEventForFollower()) {
1082 LOG.debug("received add Vrfs config val {}", val.getRd());
1083 synchronized (BgpConfigurationManager.this) {
1084 BgpRouter br = getClient(YANG_OBJ);
1089 br.addVrf(val.getLayerType(), val.getRd(), val.getImportRts(),
1090 val.getExportRts());
1091 } catch (TException | BgpRouterException e) {
1092 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1098 protected VrfsReactor getDataTreeChangeListener() {
1099 return VrfsReactor.this;
1103 protected InstanceIdentifier<Vrfs> getWildCardPath() {
1104 return InstanceIdentifier.create(Bgp.class).child(Vrfs.class);
1108 protected synchronized void remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
1109 if (ignoreClusterDcnEventForFollower()) {
1112 LOG.debug("received remove Vrfs config val {}", val.getRd());
1113 synchronized (BgpConfigurationManager.this) {
1114 BgpRouter br = getClient(YANG_OBJ);
1119 br.delVrf(val.getRd());
1120 } catch (TException | BgpRouterException e) {
1121 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1127 protected void update(InstanceIdentifier<Vrfs> iid,
1128 Vrfs oldval, Vrfs newval) {
1129 if (ignoreClusterDcnEventForFollower()) {
1132 LOG.debug("VRFS: Update getting triggered for VRFS rd {}", oldval.getRd());
1133 LOG.error(YANG_OBJ + UPD_WARN);
1137 Future lastCleanupJob;
1138 Future lastReplayJobFt = null;
1140 protected void activateMIP() {
1142 LOG.trace("BgpReactor: Executing MIP Activate command");
1143 Process processBgp = Runtime.getRuntime().exec("cluster ip -a sdnc_bgp_mip");
1144 Process processOs = Runtime.getRuntime().exec("cluster ip -a sdnc_os_mip");
1145 LOG.trace("bgpMIP Activated");
1147 } catch (IOException io) {
1148 LOG.error("IO Exception got while activating mip: ", io);
1152 AtomicBoolean started = new AtomicBoolean(false);
1154 public class BgpReactor
1155 extends AsyncDataTreeChangeListenerBase<Bgp, BgpReactor>
1156 implements AutoCloseable, ClusteredDataTreeChangeListener<Bgp> {
1158 private static final String YANG_OBJ = "Bgp ";
1160 public BgpReactor() {
1161 super(Bgp.class, BgpReactor.class);
1166 protected synchronized void add(InstanceIdentifier<Bgp> iid, Bgp val) {
1167 LOG.error("received add Bgp config replaying the config");
1171 } catch (InterruptedException e) {
1174 synchronized (BgpConfigurationManager.this) {
1176 if (ignoreClusterDcnEventForFollower()) {
1180 if (isIpAvailable(odlThriftIp)) {
1183 IP_ACTIVATION_CHECK_TIMER.scheduleAtFixedRate(new TimerTask() {
1186 if (isIpAvailable(odlThriftIp)) {
1188 IP_ACTIVATION_CHECK_TIMER.cancel();
1190 LOG.trace("waiting for odlThriftIP: {} to be present", odlThriftIp);
1199 protected BgpReactor getDataTreeChangeListener() {
1200 return BgpReactor.this;
1204 protected InstanceIdentifier<Bgp> getWildCardPath() {
1205 return InstanceIdentifier.create(Bgp.class);
1209 protected synchronized void remove(InstanceIdentifier<Bgp> iid, Bgp val) {
1210 if (ignoreClusterDcnEventForFollower()) {
1213 LOG.debug("received remove Bgp config");
1214 synchronized (BgpConfigurationManager.this) {
1220 protected void update(InstanceIdentifier<Bgp> iid,
1221 Bgp oldval, Bgp newval) {
1222 if (ignoreClusterDcnEventForFollower()) {
1225 synchronized (BgpConfigurationManager.this) {
1231 public String readThriftIpForCommunication(String mipAddr) {
1232 File file = new File(CLUSTER_CONF_FILE);
1233 if (!file.exists()) {
1237 try (BufferedReader br = new BufferedReader(new FileReader(file))) {
1239 while ((line = br.readLine()) != null) {
1240 if (line.contains(mipAddr)) {
1242 return line.substring(line.lastIndexOf(" ") + 1);
1245 } catch (FileNotFoundException e) {
1247 } catch (IOException e) {
1248 LOG.error("Error reading {}", CLUSTER_CONF_FILE, e);
1253 public boolean isIpAvailable(String odlip) {
1256 if (odlip != null) {
1257 if ("127.0.0.1".equals(odlip)) {
1260 Enumeration networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces();
1261 while (networkInterfaceEnumeration.hasMoreElements()) {
1262 NetworkInterface networkInterface = (NetworkInterface) networkInterfaceEnumeration.nextElement();
1263 Enumeration inetAddressEnumeration = networkInterface.getInetAddresses();
1264 while (inetAddressEnumeration.hasMoreElements()) {
1265 InetAddress inetAddress = (InetAddress) inetAddressEnumeration.nextElement();
1266 if (odlip.equals(inetAddress.getHostAddress())) {
1272 } catch (SocketException e) {
1278 public static long getStalePathtime(int defValue, AsId asId) {
1281 spt = getConfig().getGracefulRestart().getStalepathTime();
1282 } catch (NullPointerException e) {
1284 spt = asId.getStalepathTime();
1285 LOG.trace("BGP config/Stale-path time is not set using graceful");
1286 } catch (NullPointerException ignore) {
1287 LOG.trace("BGP AS id is not set using graceful");
1292 LOG.trace("BGP config/Stale-path time is not set using graceful/start-bgp");
1298 public synchronized void bgpRestarted() {
1300 * If there a thread which in the process of stale cleanup, cancel it
1301 * and start a new thread (to avoid processing same again).
1303 if (previousReplayJobInProgress()) {
1304 cancelPreviousReplayJob();
1306 Runnable task = () -> {
1308 LOG.info("running bgp replay task ");
1309 if (get() == null) {
1310 String host = getConfigHost();
1311 int port = getConfigPort();
1312 LOG.info("connecting to bgp host {} ", host);
1314 boolean res = bgpRouter.connect(host, port);
1315 LOG.info("no config to push in bgp replay task ");
1318 setStaleStartTime(System.currentTimeMillis());
1319 LOG.info("started creating stale fibDSWriter map ");
1320 createStaleFibMap();
1321 setStaleEndTime(System.currentTimeMillis());
1322 LOG.info("took {} msecs for stale fibDSWriter map creation ", getStaleEndTime() - getStaleStartTime());
1323 LOG.info("started bgp config replay ");
1324 setCfgReplayStartTime(System.currentTimeMillis());
1327 } catch (TimeoutException | ExecutionException e) {
1328 LOG.error("Error while replaying routes. {}", e);
1330 setCfgReplayEndTime(System.currentTimeMillis());
1331 LOG.info("took {} msecs for bgp replay ", getCfgReplayEndTime() - getCfgReplayStartTime());
1332 long routeSyncTime = getStalePathtime(BGP_RESTART_ROUTE_SYNC_SEC, config.getAsId());
1333 Thread.sleep(routeSyncTime * 1000L);
1334 setStaleCleanupTime(routeSyncTime);
1335 new RouteCleanup().call();
1336 } catch (InterruptedException eCancel) {
1337 LOG.error("Stale Cleanup Task Cancelled", eCancel);
1340 lastReplayJobFt = executor.submit(task);
1343 private boolean previousReplayJobInProgress() {
1344 return lastReplayJobFt != null && !lastReplayJobFt.isDone();
1347 private void cancelPreviousReplayJob() {
1349 LOG.error("cancelling already running bgp replay task");
1350 lastReplayJobFt.cancel(true);
1351 lastReplayJobFt = null;
1353 } catch (InterruptedException e) {
1354 LOG.error("Failed to cancel previous replay job ", e);
1358 private static void doRouteSync() throws InterruptedException, TimeoutException, ExecutionException {
1359 BgpSyncHandle bsh = BgpSyncHandle.getInstance();
1360 LOG.error("Starting BGP route sync");
1362 bgpRouter.initRibSync(bsh);
1363 } catch (TException | BgpRouterException e) {
1364 LOG.error("Route sync aborted, exception when initializing", e);
1367 while (bsh.getState() != bsh.DONE) {
1368 Routes routes = null;
1370 routes = bgpRouter.doRibSync(bsh);
1371 } catch (TException | BgpRouterException e) {
1372 LOG.error("Route sync aborted, exception when syncing", e);
1375 Iterator<Update> updates = routes.getUpdatesIterator();
1376 while (updates.hasNext()) {
1377 Update update = updates.next();
1378 Map<String, Map<String, String>> staleFibRdMap = BgpConfigurationManager.getStaledFibEntriesMap();
1379 String rd = update.getRd();
1380 String nexthop = update.getNexthop();
1382 // TODO: decide correct label here
1383 int label = update.getL3label();
1385 String prefix = update.getPrefix();
1386 int plen = update.getPrefixlen();
1389 // TODO: protocol type will not be available in "update"
1390 // use "rd" to query vrf table and obtain the protocol_type. Currently using PROTOCOL_EVPN as default.
1392 protocol_type.PROTOCOL_EVPN,
1399 update.getMacaddress(),
1401 update.getRoutermac()
1406 LOG.error("Ending BGP route-sync");
1407 bgpRouter.endRibSync(bsh);
1408 } catch (TException | BgpRouterException e) {
1413 /* onUpdatePushRoute
1414 * Get Stale fibDSWriter map, and compare current route/fibDSWriter entry.
1415 * - Entry compare shall include NextHop, Label.
1416 * - If entry matches: delete from STALE Map. NO Change to FIB Config DS.
1417 * - If entry not found, add to FIB Config DS.
1418 * - If entry found, but either Label/NextHop doesn't match.
1419 * - Update FIB Config DS with modified values.
1420 * - delete from Stale Map.
1423 public static void onUpdatePushRoute(protocol_type protocolType,
1433 throws InterruptedException, ExecutionException, TimeoutException {
1434 Map<String, Map<String, String>> staleFibRdMap = BgpConfigurationManager.getStaledFibEntriesMap();
1435 boolean addroute = false;
1437 VrfEntry.EncapType encapType = VrfEntry.EncapType.Mplsgre;
1438 if (protocolType.equals(protocol_type.PROTOCOL_EVPN)) {
1439 encapType = VrfEntry.EncapType.Vxlan;
1440 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = BgpUtil.getVpnInstanceOpData(dataBroker, rd);
1441 if (vpnInstanceOpDataEntry != null) {
1442 l3vni = vpnInstanceOpDataEntry.getL3vni();
1444 LOG.error("No corresponding vpn instance found for rd {}. Aborting.", rd);
1448 if (!staledFibEntriesMap.isEmpty()) {
1449 // restart Scenario, as MAP is not empty.
1450 Map<String, String> map = staledFibEntriesMap.get(rd);
1452 String nexthoplabel = map.get(prefix + "/" + plen);
1453 if (null == nexthoplabel) {
1454 // New Entry, which happened to be added during restart.
1457 map.remove(prefix + "/" + plen);
1458 if (isRouteModified(nextHop, label, nexthoplabel)) {
1459 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
1460 // Existing entry, where in Nexthop/Label got modified during restart
1466 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
1470 LOG.info("ADD: Adding Fib entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, label);
1471 // TODO: modify addFibEntryToDS signature
1472 fibDSWriter.addFibEntryToDS(rd, macaddress, prefix + "/" + plen, Collections.singletonList(nextHop),
1473 encapType, label, l3vni, routermac, RouteOrigin.BGP);
1474 LOG.info("ADD: Added Fib entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, label);
1478 private static boolean isRouteModified(String nexthop, int label, String nexthoplabel) {
1479 return !nexthoplabel.isEmpty() && !nexthoplabel.equals(nexthop + "/" + label);
1482 private static void replayNbrConfig(List<Neighbors> neighbors, BgpRouter br) {
1483 for (Neighbors nbr : neighbors) {
1485 br.addNeighbor(nbr.getAddress().getValue(),
1487 //itmProvider.buildTunnelsToDCGW(new IpAddress(nbr.getAddress().getValue().toCharArray()));
1488 } catch (TException | BgpRouterException e) {
1489 LOG.error("Replay:addNbr() received exception", e);
1492 EbgpMultihop en = nbr.getEbgpMultihop();
1495 br.addEbgpMultihop(en.getPeerIp().getValue(),
1496 en.getNhops().intValue());
1497 } catch (TException | BgpRouterException e) {
1498 LOG.error("Replay:addEBgp() received exception", e);
1501 UpdateSource us = nbr.getUpdateSource();
1504 br.addUpdateSource(us.getPeerIp().getValue(),
1505 us.getSourceIp().getValue());
1506 } catch (TException | BgpRouterException e) {
1507 LOG.error("Replay:addUS() received exception", e);
1510 List<AddressFamilies> afs = nbr.getAddressFamilies();
1512 for (AddressFamilies af : afs) {
1513 af_afi afi = af_afi.findByValue(af.getAfi().intValue());
1514 af_safi safi = af_safi.findByValue(af.getSafi().intValue());
1516 br.addAddressFamily(af.getPeerIp().getValue(), afi, safi);
1517 } catch (TException | BgpRouterException e) {
1518 LOG.error("Replay:addAf() received exception", e);
1525 public static String getConfigHost() {
1526 if (config == null) {
1527 return cHostStartup;
1529 ConfigServer ts = config.getConfigServer();
1530 return (ts == null ? cHostStartup : ts.getHost().getValue());
1533 public static int getConfigPort() {
1534 if (config == null) {
1535 return Integer.parseInt(cPortStartup);
1537 ConfigServer ts = config.getConfigServer();
1538 return (ts == null ? Integer.parseInt(cPortStartup) :
1539 ts.getPort().intValue());
1542 public static Bgp getConfig() {
1543 AtomicInteger bgpDSretryCount = new AtomicInteger(DS_RETRY_COOUNT);
1544 while (0 != bgpDSretryCount.decrementAndGet()) {
1546 return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
1547 InstanceIdentifier.create(Bgp.class)).orNull();
1548 } catch (ReadFailedException e) {
1549 //Config DS may not be up, so sleep for 1 second and retry
1550 LOG.debug("failed to get bgp config, may be DS is yet in consistent state(?)", e);
1552 Thread.sleep(WAIT_TIME_BETWEEN_EACH_TRY_MILLIS);
1553 } catch (InterruptedException timerEx) {
1554 LOG.debug("WAIT_TIME_BETWEEN_EACH_TRY_MILLIS, Timer got interrupted while waiting for"
1555 + "config DS availability", timerEx);
1559 LOG.error("failed to get bgp config");
1563 @SuppressWarnings("checkstyle:IllegalCatch")
1564 public synchronized void replay() throws InterruptedException, TimeoutException, ExecutionException {
1565 synchronized (bgpConfigurationManager) {
1566 String host = getConfigHost();
1567 int port = getConfigPort();
1568 LOG.error("connecting to bgp host {} ", host);
1570 boolean res = bgpRouter.connect(host, port);
1572 String msg = "Cannot connect to BGP config server at " + host + ":" + port;
1573 if (config != null) {
1574 msg += "; Configuration Replay aborted";
1579 config = getConfig();
1580 if (config == null) {
1581 LOG.error("bgp config is empty nothing to push to bgp");
1584 BgpRouter br = bgpRouter;
1585 AsId asId = config.getAsId();
1589 long asNum = asId.getLocalAs();
1590 IpAddress routerId = asId.getRouterId();
1591 Long spt = asId.getStalepathTime();
1592 Boolean afb = asId.isAnnounceFbit();
1593 String rid = (routerId == null) ? "" : new String(routerId.getValue());
1594 int stalepathTime = (int) getStalePathtime(0, config.getAsId());
1595 boolean announceFbit = true;
1597 br.startBgp(asNum, rid, stalepathTime, announceFbit);
1598 } catch (BgpRouterException bre) {
1599 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
1602 LOG.error("Replay: startBgp() received exception: \""
1603 + bre + "\"; " + ADD_WARN);
1605 } catch (TException e) {
1606 //not unusual. We may have restarted & BGP is already on
1607 LOG.error("Replay:startBgp() received exception: \"" + e + "\"");
1610 if (getBgpCounters() == null) {
1611 startBgpCountersTask();
1614 if (getBgpAlarms() == null) {
1615 startBgpAlarmsTask();
1618 Logging logging = config.getLogging();
1619 if (logging != null) {
1621 br.setLogging(logging.getFile(), logging.getLevel());
1622 } catch (TException | BgpRouterException e) {
1623 LOG.error("Replay:setLogging() received exception", e);
1627 GracefulRestart gracefulRestart = config.getGracefulRestart();
1628 if (gracefulRestart != null) {
1630 br.addGracefulRestart(gracefulRestart.getStalepathTime().intValue());
1631 } catch (TException | BgpRouterException e) {
1632 LOG.error("Replay:addGr() received exception", e);
1636 List<Vrfs> vrfs = config.getVrfs();
1638 for (Vrfs vrf : vrfs) {
1640 br.addVrf(vrf.getLayerType(), vrf.getRd(), vrf.getImportRts(),
1641 vrf.getExportRts());
1642 } catch (TException | BgpRouterException e) {
1643 LOG.error("Replay:addVrf() received exception", e);
1648 List<Networks> ln = config.getNetworks();
1650 for (Networks net : ln) {
1651 String rd = net.getRd();
1652 String pfxlen = net.getPrefixLen();
1653 String nh = net.getNexthop().getValue();
1654 Long label = net.getLabel();
1655 int lbl = (label == null) ? 0 : label.intValue();
1656 int l3vni = (net.getL3vni() == null) ? 0 : net.getL3vni().intValue();
1657 if (rd == null && lbl > 0) {
1658 //LU prefix is being deleted.
1659 rd = Integer.toString(lbl);
1662 BgpControlPlaneType protocolType = net.getBgpControlPlaneType();
1663 int ethernetTag = net.getEthtag().intValue();
1664 String esi = net.getEsi();
1665 String macaddress = net.getMacaddress();
1666 EncapType encapType = net.getEncapType();
1667 String routerMac = net.getRoutermac();
1670 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, BgpUtil.convertToThriftProtocolType(protocolType),
1671 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
1672 } catch (Exception e) {
1673 LOG.error("Replay:addPfx() received exception", e);
1677 List<Neighbors> neighbors = config.getNeighbors();
1678 if (neighbors != null) {
1679 LOG.error("configuring existing Neighbors present for replay total neighbors {}", neighbors.size());
1680 replayNbrConfig(neighbors, br);
1682 LOG.error("no Neighbors present for replay config ");
1687 private <T extends DataObject> void update(InstanceIdentifier<T> iid, T dto) {
1688 BgpUtil.update(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1691 private <T extends DataObject> void asyncWrite(InstanceIdentifier<T> iid, T dto) {
1692 BgpUtil.write(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1695 private <T extends DataObject> void delete(InstanceIdentifier<T> iid) {
1696 BgpUtil.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, iid);
1699 public synchronized void startConfig(String bgpHost, int thriftPort) {
1700 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1701 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1702 InstanceIdentifier<ConfigServer> iid = iib.build();
1703 Ipv4Address ipAddr = new Ipv4Address(bgpHost);
1704 ConfigServer dto = new ConfigServerBuilder().setHost(ipAddr)
1705 .setPort((long) thriftPort).build();
1709 public synchronized void startBgp(long as, String routerId, int spt, boolean fbit) {
1710 IpAddress rid = (routerId == null) ? null : new IpAddress(routerId.toCharArray());
1711 Long staleTime = (long) spt;
1712 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1713 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1714 InstanceIdentifier<AsId> iid = iib.build();
1715 AsId dto = new AsIdBuilder().setLocalAs(as)
1717 .setStalepathTime(staleTime)
1718 .setAnnounceFbit(fbit).build();
1722 public synchronized void addLogging(String fileName, String logLevel) {
1723 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1724 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1725 InstanceIdentifier<Logging> iid = iib.build();
1726 Logging dto = new LoggingBuilder().setFile(fileName)
1727 .setLevel(logLevel).build();
1731 public synchronized void addGracefulRestart(int staleTime) {
1732 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1733 InstanceIdentifier.builder(Bgp.class).child(GracefulRestart.class);
1734 InstanceIdentifier<GracefulRestart> iid = iib.build();
1735 GracefulRestart dto = new GracefulRestartBuilder()
1736 .setStalepathTime((long) staleTime).build();
1740 public synchronized void addNeighbor(String nbrIp, long remoteAs) {
1741 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1742 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1743 InstanceIdentifier.builder(Bgp.class)
1744 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1745 InstanceIdentifier<Neighbors> iid = iib.build();
1746 Neighbors dto = new NeighborsBuilder().setAddress(nbrAddr)
1747 .setRemoteAs(remoteAs).build();
1751 public synchronized void addUpdateSource(String nbrIp, String srcIp) {
1752 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1753 Ipv4Address srcAddr = new Ipv4Address(srcIp);
1754 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1755 InstanceIdentifier.builder(Bgp.class)
1756 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1757 .child(UpdateSource.class);
1758 InstanceIdentifier<UpdateSource> iid = iib.build();
1759 UpdateSource dto = new UpdateSourceBuilder().setPeerIp(nbrAddr)
1760 .setSourceIp(srcAddr).build();
1764 public synchronized void addEbgpMultihop(String nbrIp, int hops) {
1765 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1766 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1767 InstanceIdentifier.builder(Bgp.class)
1768 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1769 .child(EbgpMultihop.class);
1770 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1771 EbgpMultihop dto = new EbgpMultihopBuilder().setPeerIp(nbrAddr)
1772 .setNhops((long) hops).build();
1776 public synchronized void addAddressFamily(String nbrIp, int afi, int safi) {
1777 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1778 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1779 InstanceIdentifier.builder(Bgp.class)
1780 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1781 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
1782 InstanceIdentifier<AddressFamilies> iid = iib.build();
1783 AddressFamilies dto = new AddressFamiliesBuilder().setPeerIp(nbrAddr)
1784 .setAfi((long) afi).setSafi((long) safi).build();
1788 public synchronized void addPrefix(String rd, String macAddress, String pfx, List<String> nhList,
1789 VrfEntry.EncapType encapType, int lbl, long l3vni, String gatewayMac) {
1790 for (String nh : nhList) {
1791 Ipv4Address nexthop = nh != null ? new Ipv4Address(nh) : null;
1792 Long label = (long) lbl;
1793 InstanceIdentifier<Networks> iid = InstanceIdentifier.builder(Bgp.class)
1794 .child(Networks.class, new NetworksKey(pfx, rd)).build();
1795 NetworksBuilder networksBuilder = new NetworksBuilder().setRd(rd).setPrefixLen(pfx).setNexthop(nexthop)
1796 .setLabel(label).setEthtag(BgpConstants.DEFAULT_ETH_TAG);
1797 buildVpnEncapSpecificInfo(networksBuilder, encapType, label, l3vni, macAddress, gatewayMac);
1798 update(iid, networksBuilder.build());
1802 private static void buildVpnEncapSpecificInfo(NetworksBuilder builder, VrfEntry.EncapType encapType, long label,
1803 long l3vni, String macAddress, String gatewayMac) {
1804 if (encapType.equals(VrfEntry.EncapType.Mplsgre)) {
1805 builder.setLabel(label).setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLL3VPN)
1806 .setEncapType(EncapType.GRE);
1808 builder.setL3vni(l3vni).setMacaddress(macAddress).setRoutermac(gatewayMac)
1809 .setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLEVPN).setEncapType(EncapType.VXLAN);
1813 // TODO: add LayerType as arg - supports command
1814 public synchronized void addVrf(String rd, List<String> irts, List<String> erts, LayerType layerType) {
1815 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1816 InstanceIdentifier.builder(Bgp.class)
1817 .child(Vrfs.class, new VrfsKey(rd));
1818 InstanceIdentifier<Vrfs> iid = iib.build();
1819 Vrfs dto = new VrfsBuilder().setRd(rd).setImportRts(irts)
1820 .setExportRts(erts).setLayerType(layerType).build();
1822 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1823 } catch (TransactionCommitFailedException e) {
1824 LOG.error("Error adding VRF to datastore", e);
1825 throw new RuntimeException(e);
1829 public synchronized void stopConfig() {
1830 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1831 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1832 InstanceIdentifier<ConfigServer> iid = iib.build();
1836 public synchronized void stopBgp() {
1837 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1838 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1839 InstanceIdentifier<AsId> iid = iib.build();
1843 public synchronized void delLogging() {
1844 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1845 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1846 InstanceIdentifier<Logging> iid = iib.build();
1850 public synchronized void delGracefulRestart() {
1851 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1852 InstanceIdentifier.builder(Bgp.class)
1853 .child(GracefulRestart.class);
1854 InstanceIdentifier<GracefulRestart> iid = iib.build();
1858 public synchronized void delNeighbor(String nbrIp) {
1859 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1860 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1861 InstanceIdentifier.builder(Bgp.class)
1862 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1863 InstanceIdentifier<Neighbors> iid = iib.build();
1867 public synchronized void delUpdateSource(String nbrIp) {
1868 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1869 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1870 InstanceIdentifier.builder(Bgp.class)
1871 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1872 .child(UpdateSource.class);
1873 InstanceIdentifier<UpdateSource> iid = iib.build();
1877 public synchronized void delEbgpMultihop(String nbrIp) {
1878 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1879 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1880 InstanceIdentifier.builder(Bgp.class)
1881 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1882 .child(EbgpMultihop.class);
1883 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1887 public synchronized void delAddressFamily(String nbrIp, int afi, int safi) {
1888 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1889 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1890 InstanceIdentifier.builder(Bgp.class)
1891 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1892 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
1893 InstanceIdentifier<AddressFamilies> iid = iib.build();
1897 public synchronized void delPrefix(String rd, String pfx) {
1898 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
1899 InstanceIdentifier.builder(Bgp.class)
1900 .child(Networks.class, new NetworksKey(pfx, rd));
1901 InstanceIdentifier<Networks> iid = iib.build();
1905 public synchronized void delVrf(String rd) {
1906 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1907 InstanceIdentifier.builder(Bgp.class)
1908 .child(Vrfs.class, new VrfsKey(rd));
1909 InstanceIdentifier<Vrfs> iid = iib.build();
1913 static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
1916 * Remove Stale Marked Routes after timer expiry.
1918 class RouteCleanup implements Callable<Integer> {
1921 public Integer call() {
1924 if (staledFibEntriesMap.isEmpty()) {
1925 LOG.info("BGP: RouteCleanup timertask tirggered but STALED FIB MAP is EMPTY");
1927 for (String rd : staledFibEntriesMap.keySet()) {
1928 if (Thread.interrupted()) {
1931 Map<String, String> map = staledFibEntriesMap.get(rd);
1933 for (String prefix : map.keySet()) {
1934 if (Thread.interrupted()) {
1938 LOG.debug("BGP: RouteCleanup deletePrefix called for : rd:{}, prefix{}", rd, prefix);
1939 fibDSWriter.removeFibEntryFromDS(rd, prefix);
1945 staledFibEntriesMap.clear();
1947 LOG.error("cleared {} stale routes after bgp restart", totalCleared);
1953 * BGP restart scenario, ODL-BGP manager was/is running.
1954 * On re-sync notification, Get a copy of FIB database.
1956 public static void createStaleFibMap() {
1957 totalStaledCount = 0;
1960 * at the time Stale FIB creation, Wait till all PENDING write transaction
1961 * to complete (or)wait for max timeout value of STALE_FIB_WAIT Seconds.
1963 int retry = STALE_FIB_WAIT;
1964 while ((BgpUtil.getGetPendingWrTransaction() != 0) && (retry > 0)) {
1968 LOG.error("TimeOut occured {} seconds, in waiting stale fibDSWriter create", STALE_FIB_WAIT);
1971 staledFibEntriesMap.clear();
1972 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
1973 DataBroker db = BgpUtil.getBroker();
1975 LOG.error("Couldn't find BgpUtil dataBroker while creating createStaleFibMap");
1979 Optional<FibEntries> fibEntries = SingleTransactionDataBroker.syncReadOptional(BgpUtil.getBroker(),
1980 LogicalDatastoreType.CONFIGURATION, id);
1981 if (fibEntries.isPresent()) {
1982 List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
1983 for (VrfTables vrfTable : staleVrfTables) {
1984 Map<String, String> staleFibEntMap = new HashMap<>();
1985 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
1986 if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
1987 //Stale marking and cleanup is only meant for the routes learned through BGP.
1990 if (Thread.interrupted()) {
1994 //Create MAP from staleVrfTables.
1995 for (String nextHop : vrfEntry.getNextHopAddressList()) {
1996 staleFibEntMap.put(vrfEntry.getDestPrefix(), nextHop + "/" + vrfEntry.getLabel());
1999 staledFibEntriesMap.put(vrfTable.getRouteDistinguisher(), staleFibEntMap);
2002 LOG.error("createStaleFibMap:: FIBentries.class is not present");
2004 } catch (InterruptedException | ReadFailedException e) {
2005 LOG.error("createStaleFibMap:: error ", e);
2007 LOG.error("created {} staled entries ", totalStaledCount);
2010 //map<rd, map<prefix/len, nexthop/label>>
2011 public static Map<String, Map<String, String>> getStaledFibEntriesMap() {
2012 return staledFibEntriesMap;
2015 //TODO: below function is for testing purpose with cli
2016 public static void onUpdateWithdrawRoute(String rd, String prefix, int plen, String nexthop) {
2017 LOG.debug("Route del ** {} ** {}/{} ", rd, prefix, plen);
2018 fibDSWriter.removeFibEntryFromDS(rd, prefix + "/" + plen);
2021 public boolean isBgpConnected() {
2022 return bgpRouter.isBgpConnected();
2025 public long getLastConnectedTS() {
2026 return bgpRouter.getLastConnectedTS();
2029 public long getConnectTS() {
2030 return bgpRouter.getConnectTS();
2033 public long getStartTS() {
2034 return bgpRouter.getStartTS();
2037 public static int getTotalStaledCount() {
2038 return totalStaledCount;
2041 public static int getTotalCleared() {
2042 return totalCleared;
2045 public Timer getBgpCountersTimer() {
2046 return bgpCountersTimer;
2049 public BgpCounters getBgpCounters() {
2053 public void setBgpCountersTimer(Timer timer) {
2054 bgpCountersTimer = timer;
2057 public void setBgpAlarmsTimer(Timer timer) {
2058 bgpAlarmsTimer = timer;
2061 public void startBgpCountersTask() {
2062 if (getBgpCounters() == null) {
2063 bgpCounters = new BgpCounters(bgpConfigurationManager.getBgpSdncMipIp());
2064 setBgpCountersTimer(new Timer(true));
2065 getBgpCountersTimer().scheduleAtFixedRate(bgpCounters, 0, 120 * 1000);
2066 LOG.info("Bgp Counters task scheduled for every two minutes.");
2068 bgpManager.setQbgpLog(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
2072 public void stopBgpCountersTask() {
2073 Timer timer = getBgpCountersTimer();
2074 if (getBgpCounters() != null) {
2076 setBgpCountersTimer(null);
2081 public void startBgpAlarmsTask() {
2082 if (getBgpAlarms() == null) {
2083 bgpAlarms = new BgpAlarms(this);
2084 setBgpAlarmsTimer(new Timer(true));
2085 getBgpAlarmsTimer().scheduleAtFixedRate(bgpAlarms, 0, 60 * 1000);
2086 LOG.info("Bgp Alarms task scheduled for every minute.");
2090 public void stopBgpAlarmsTask() {
2091 Timer timer = getBgpAlarmsTimer();
2092 if (getBgpAlarms() != null) {
2094 setBgpAlarmsTimer(null);
2099 public Timer getBgpAlarmsTimer() {
2100 return bgpAlarmsTimer;
2103 public BgpAlarms getBgpAlarms() {