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, Long>> 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 || !bgpRouter.isBgpConnected()) {
415 LOG.warn("{}: configuration received when BGP is inactive", yangObj);
421 public class AsIdReactor
422 extends AsyncDataTreeChangeListenerBase<AsId, AsIdReactor>
423 implements AutoCloseable, ClusteredDataTreeChangeListener<AsId> {
425 private static final String YANG_OBJ = "as-id ";
427 public AsIdReactor() {
428 super(AsId.class, AsIdReactor.class);
432 protected synchronized void add(InstanceIdentifier<AsId> iid, AsId val) {
433 LOG.error("received bgp add asid {}", val);
434 if (ignoreClusterDcnEventForFollower()) {
437 LOG.debug("received add router config asNum {}", val.getLocalAs());
438 synchronized (BgpConfigurationManager.this) {
439 IpAddress routerId = val.getRouterId();
440 BgpRouter br = getClient(YANG_OBJ);
441 long asNum = val.getLocalAs();
443 LOG.error("{} Unable to process add for routerId {} asNum {}; {}", YANG_OBJ, routerId, asNum,
444 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
447 Boolean afb = val.isAnnounceFbit();
448 String rid = (routerId == null) ? "" : new String(routerId.getValue());
449 int stalepathTime = (int) getStalePathtime(RESTART_DEFAULT_GR, val);
450 boolean announceFbit = true;
452 br.startBgp(asNum, rid, stalepathTime, announceFbit);
453 if (getBgpCounters() == null) {
454 startBgpCountersTask();
456 if (getBgpAlarms() == null) {
457 startBgpAlarmsTask();
459 } catch (BgpRouterException bre) {
460 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
461 LOG.error(YANG_OBJ + "Add requested when BGP is already active");
463 LOG.error(YANG_OBJ + "Add received exception: \""
464 + bre + "\"; " + ADD_WARN);
466 } catch (TException e) {
467 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
473 protected AsIdReactor getDataTreeChangeListener() {
474 return AsIdReactor.this;
478 protected InstanceIdentifier<AsId> getWildCardPath() {
479 return InstanceIdentifier.create(Bgp.class).child(AsId.class);
483 protected synchronized void remove(InstanceIdentifier<AsId> iid, AsId val) {
484 LOG.error("received delete router config asNum {}", val.getLocalAs());
485 if (ignoreClusterDcnEventForFollower()) {
488 synchronized (BgpConfigurationManager.this) {
489 long asNum = val.getLocalAs();
490 BgpRouter br = getClient(YANG_OBJ);
492 LOG.error("{} Unable to process remove for asNum {}; {}", YANG_OBJ, asNum,
493 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
498 } catch (TException | BgpRouterException e) {
499 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
501 if (getBgpCounters() != null) {
502 stopBgpCountersTask();
504 if (getBgpAlarms() != null) {
511 protected void update(InstanceIdentifier<AsId> iid,
512 AsId oldval, AsId newval) {
513 if (ignoreClusterDcnEventForFollower()) {
516 LOG.error(YANG_OBJ + UPD_WARN);
520 public class GracefulRestartReactor
521 extends AsyncDataTreeChangeListenerBase<GracefulRestart, GracefulRestartReactor>
522 implements AutoCloseable, ClusteredDataTreeChangeListener<GracefulRestart> {
524 private static final String YANG_OBJ = "graceful-restart ";
526 public GracefulRestartReactor() {
527 super(GracefulRestart.class, GracefulRestartReactor.class);
531 protected synchronized void add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
532 if (ignoreClusterDcnEventForFollower()) {
535 synchronized (BgpConfigurationManager.this) {
536 int stalePathTime = val.getStalepathTime().intValue();
537 BgpRouter br = getClient(YANG_OBJ);
539 LOG.error("{} Unable to add stale-path time {}; {}", YANG_OBJ, stalePathTime,
540 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
544 br.addGracefulRestart(stalePathTime);
545 } catch (TException | BgpRouterException e) {
546 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
552 protected GracefulRestartReactor getDataTreeChangeListener() {
553 return GracefulRestartReactor.this;
557 protected InstanceIdentifier<GracefulRestart> getWildCardPath() {
558 return InstanceIdentifier.create(Bgp.class).child(GracefulRestart.class);
562 protected synchronized void remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
563 if (ignoreClusterDcnEventForFollower()) {
566 LOG.debug("received delete GracefulRestart config val {}", val.getStalepathTime().intValue());
567 synchronized (BgpConfigurationManager.this) {
568 BgpRouter br = getClient(YANG_OBJ);
570 LOG.error("{} Unable to delete stale-path time; {}", YANG_OBJ,
571 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
575 br.delGracefulRestart();
576 } catch (TException | BgpRouterException e) {
577 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
583 protected void update(InstanceIdentifier<GracefulRestart> iid,
584 GracefulRestart oldval, GracefulRestart newval) {
585 if (ignoreClusterDcnEventForFollower()) {
588 LOG.debug("received update GracefulRestart config val {}", newval.getStalepathTime().intValue());
589 synchronized (BgpConfigurationManager.this) {
590 int stalePathTime = newval.getStalepathTime().intValue();
591 BgpRouter br = getClient(YANG_OBJ);
593 LOG.error("{} Unable to update stale-path time to {}; {}", YANG_OBJ, stalePathTime,
594 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
598 br.addGracefulRestart(stalePathTime);
599 } catch (TException | BgpRouterException e) {
600 LOG.error("{} update received exception; {}", YANG_OBJ, ADD_WARN, e);
606 public class LoggingReactor
607 extends AsyncDataTreeChangeListenerBase<Logging, LoggingReactor>
608 implements AutoCloseable, ClusteredDataTreeChangeListener<Logging> {
610 private static final String YANG_OBJ = "logging ";
612 public LoggingReactor() {
613 super(Logging.class, LoggingReactor.class);
617 protected synchronized void add(InstanceIdentifier<Logging> iid, Logging val) {
618 if (ignoreClusterDcnEventForFollower()) {
621 synchronized (BgpConfigurationManager.this) {
622 BgpRouter br = getClient(YANG_OBJ);
624 LOG.error("{} Unable to add logging for qbgp; {}", YANG_OBJ,
625 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
629 br.setLogging(val.getFile(), val.getLevel());
630 } catch (TException | BgpRouterException e) {
631 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
637 protected LoggingReactor getDataTreeChangeListener() {
638 return LoggingReactor.this;
642 protected InstanceIdentifier<Logging> getWildCardPath() {
643 return InstanceIdentifier.create(Bgp.class).child(Logging.class);
647 protected synchronized void remove(InstanceIdentifier<Logging> iid, Logging val) {
648 if (ignoreClusterDcnEventForFollower()) {
651 LOG.debug("received remove Logging config val {}", val.getLevel());
652 synchronized (BgpConfigurationManager.this) {
653 BgpRouter br = getClient(YANG_OBJ);
655 LOG.error("{} Unable to remove logging for qbgp; {}", YANG_OBJ,
656 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
660 br.setLogging(DEF_LOGFILE, DEF_LOGLEVEL);
661 } catch (TException | BgpRouterException e) {
662 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
668 protected void update(InstanceIdentifier<Logging> iid,
669 Logging oldval, Logging newval) {
670 if (ignoreClusterDcnEventForFollower()) {
673 synchronized (BgpConfigurationManager.this) {
674 BgpRouter br = getClient(YANG_OBJ);
676 LOG.error("{} Unable to update logging for qbgp; {}", YANG_OBJ,
677 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
681 br.setLogging(newval.getFile(), newval.getLevel());
682 } catch (TException | BgpRouterException e) {
683 LOG.error("{} newval received exception; {}", YANG_OBJ, ADD_WARN, e);
689 public class NeighborsReactor
690 extends AsyncDataTreeChangeListenerBase<Neighbors, NeighborsReactor>
691 implements AutoCloseable, ClusteredDataTreeChangeListener<Neighbors> {
693 private static final String YANG_OBJ = "neighbors ";
695 public NeighborsReactor() {
696 super(Neighbors.class, NeighborsReactor.class);
700 protected synchronized void add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
701 if (ignoreClusterDcnEventForFollower()) {
704 LOG.debug("received add Neighbors config val {}", val.getAddress().getValue());
705 synchronized (BgpConfigurationManager.this) {
706 String peerIp = val.getAddress().getValue();
707 long as = val.getRemoteAs();
708 BgpRouter br = getClient(YANG_OBJ);
710 LOG.error("{} Unable to process add for peer {} as {}; {}", YANG_OBJ, peerIp, as,
711 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
715 //itmProvider.buildTunnelsToDCGW(new IpAddress(peerIp.toCharArray()));
716 br.addNeighbor(peerIp, as);
718 } catch (TException | BgpRouterException e) {
719 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
725 protected NeighborsReactor getDataTreeChangeListener() {
726 return NeighborsReactor.this;
730 protected InstanceIdentifier<Neighbors> getWildCardPath() {
731 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class);
735 protected synchronized void remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
736 if (ignoreClusterDcnEventForFollower()) {
739 LOG.debug("received remove Neighbors config val {}", val.getAddress().getValue());
740 synchronized (BgpConfigurationManager.this) {
741 String peerIp = val.getAddress().getValue();
742 BgpRouter br = getClient(YANG_OBJ);
744 LOG.error("{} Unable to process remove for peer {}; {}", YANG_OBJ, peerIp,
745 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
749 //itmProvider.deleteTunnelsToDCGW(new IpAddress(val.getAddress().getValue().toCharArray()));
750 br.delNeighbor(peerIp);
751 } catch (TException | BgpRouterException e) {
752 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
758 protected void update(InstanceIdentifier<Neighbors> iid,
759 Neighbors oldval, Neighbors newval) {
760 if (ignoreClusterDcnEventForFollower()) {
763 //purposefully nothing to do.
767 public class EbgpMultihopReactor
768 extends AsyncDataTreeChangeListenerBase<EbgpMultihop, EbgpMultihopReactor>
769 implements AutoCloseable, ClusteredDataTreeChangeListener<EbgpMultihop> {
771 private static final String YANG_OBJ = "ebgp-multihop ";
773 public EbgpMultihopReactor() {
774 super(EbgpMultihop.class, EbgpMultihopReactor.class);
778 protected synchronized void add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
779 if (ignoreClusterDcnEventForFollower()) {
782 LOG.debug("received add EbgpMultihop config val {}", val.getPeerIp().getValue());
783 synchronized (BgpConfigurationManager.this) {
784 String peerIp = val.getPeerIp().getValue();
785 BgpRouter br = getClient(YANG_OBJ);
787 LOG.error("{} Unable to process add for peer {}; {}", YANG_OBJ, peerIp,
788 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
792 br.addEbgpMultihop(peerIp, val.getNhops().intValue());
793 } catch (TException | BgpRouterException e) {
794 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
800 protected EbgpMultihopReactor getDataTreeChangeListener() {
801 return EbgpMultihopReactor.this;
805 protected InstanceIdentifier<EbgpMultihop> getWildCardPath() {
806 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(EbgpMultihop.class);
810 protected synchronized void remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
811 if (ignoreClusterDcnEventForFollower()) {
814 LOG.debug("received remove EbgpMultihop config val {}", val.getPeerIp().getValue());
815 synchronized (BgpConfigurationManager.this) {
816 String peerIp = val.getPeerIp().getValue();
817 BgpRouter br = getClient(YANG_OBJ);
819 LOG.error("{} Unable to process remove for peer {}; {}", YANG_OBJ, peerIp,
820 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
824 br.delEbgpMultihop(peerIp);
825 } catch (TException | BgpRouterException e) {
826 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
832 protected void update(InstanceIdentifier<EbgpMultihop> iid,
833 EbgpMultihop oldval, EbgpMultihop newval) {
834 if (ignoreClusterDcnEventForFollower()) {
837 LOG.error(YANG_OBJ + UPD_WARN);
841 public class UpdateSourceReactor
842 extends AsyncDataTreeChangeListenerBase<UpdateSource, UpdateSourceReactor>
843 implements AutoCloseable, ClusteredDataTreeChangeListener<UpdateSource> {
845 private static final String YANG_OBJ = "update-source ";
847 public UpdateSourceReactor() {
848 super(UpdateSource.class, UpdateSourceReactor.class);
852 protected synchronized void add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
853 if (ignoreClusterDcnEventForFollower()) {
856 LOG.debug("received add UpdateSource config val {}", val.getSourceIp().getValue());
857 synchronized (BgpConfigurationManager.this) {
858 String peerIp = val.getPeerIp().getValue();
859 BgpRouter br = getClient(YANG_OBJ);
861 LOG.error("{} Unable to process add for peer {}; {}", YANG_OBJ, peerIp,
862 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
866 br.addUpdateSource(peerIp, val.getSourceIp().getValue());
867 } catch (TException | BgpRouterException e) {
868 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
874 protected UpdateSourceReactor getDataTreeChangeListener() {
875 return UpdateSourceReactor.this;
879 protected InstanceIdentifier<UpdateSource> getWildCardPath() {
880 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(UpdateSource.class);
884 protected synchronized void remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
885 if (ignoreClusterDcnEventForFollower()) {
888 LOG.debug("received remove UpdateSource config val {}", val.getSourceIp().getValue());
889 synchronized (BgpConfigurationManager.this) {
890 String peerIp = val.getPeerIp().getValue();
891 BgpRouter br = getClient(YANG_OBJ);
893 LOG.error("{} Unable to process remove for peer {}; {}", YANG_OBJ, peerIp,
894 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
898 br.delUpdateSource(peerIp);
899 } catch (TException | BgpRouterException e) {
900 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
906 protected void update(InstanceIdentifier<UpdateSource> iid,
907 UpdateSource oldval, UpdateSource newval) {
908 if (ignoreClusterDcnEventForFollower()) {
911 LOG.error(YANG_OBJ + UPD_WARN);
915 public class AddressFamiliesReactor
916 extends AsyncDataTreeChangeListenerBase<AddressFamilies, AddressFamiliesReactor>
917 implements AutoCloseable, ClusteredDataTreeChangeListener<AddressFamilies> {
919 private static final String YANG_OBJ = "address-families ";
921 public AddressFamiliesReactor() {
922 super(AddressFamilies.class, AddressFamiliesReactor.class);
926 protected synchronized void add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
927 if (ignoreClusterDcnEventForFollower()) {
930 LOG.debug("received add AddressFamilies config val {}", val.getPeerIp().getValue());
931 synchronized (BgpConfigurationManager.this) {
932 String peerIp = val.getPeerIp().getValue();
933 BgpRouter br = getClient(YANG_OBJ);
935 LOG.error("{} Unable to process add for peer {}; {}", YANG_OBJ, peerIp,
936 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
939 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
940 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
942 br.addAddressFamily(peerIp, afi, safi);
943 } catch (TException | BgpRouterException e) {
944 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
950 protected AddressFamiliesReactor getDataTreeChangeListener() {
951 return AddressFamiliesReactor.this;
955 protected InstanceIdentifier<AddressFamilies> getWildCardPath() {
956 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(AddressFamilies.class);
960 protected synchronized void remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
961 if (ignoreClusterDcnEventForFollower()) {
964 LOG.debug("received remove AddressFamilies config val {}", val.getPeerIp().getValue());
965 synchronized (BgpConfigurationManager.this) {
966 String peerIp = val.getPeerIp().getValue();
967 BgpRouter br = getClient(YANG_OBJ);
969 LOG.error("{} Unable to process remove for peer {}; {}", YANG_OBJ, peerIp,
970 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
973 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
974 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
976 br.delAddressFamily(peerIp, afi, safi);
977 } catch (TException | BgpRouterException e) {
978 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
984 protected void update(InstanceIdentifier<AddressFamilies> iid,
985 AddressFamilies oldval, AddressFamilies newval) {
986 if (ignoreClusterDcnEventForFollower()) {
989 LOG.error(YANG_OBJ + UPD_WARN);
993 public class NetworksReactor
994 extends AsyncDataTreeChangeListenerBase<Networks, NetworksReactor>
995 implements AutoCloseable, ClusteredDataTreeChangeListener<Networks> {
997 private static final String YANG_OBJ = "networks ";
999 public NetworksReactor() {
1000 super(Networks.class, NetworksReactor.class);
1004 public NetworksReactor getDataTreeChangeListener() {
1005 return NetworksReactor.this;
1009 protected synchronized void add(InstanceIdentifier<Networks> iid, Networks val) {
1010 if (ignoreClusterDcnEventForFollower()) {
1013 LOG.debug("received add Networks config val {}", val.getPrefixLen());
1014 synchronized (BgpConfigurationManager.this) {
1015 String rd = val.getRd();
1016 String pfxlen = val.getPrefixLen();
1017 String nh = val.getNexthop().getValue();
1018 BgpRouter br = getClient(YANG_OBJ);
1020 LOG.error("{} Unable to process add for rd {} prefix {} nexthop {}; {}", YANG_OBJ, rd, pfxlen, nh,
1021 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1024 Long label = val.getLabel();
1025 int lbl = (label == null) ? qbgpConstants.LBL_NO_LABEL
1027 int l3vni = (val.getL3vni() == null) ? qbgpConstants.LBL_NO_LABEL
1028 : val.getL3vni().intValue();
1030 BgpControlPlaneType protocolType = val.getBgpControlPlaneType();
1031 int ethernetTag = val.getEthtag().intValue();
1032 String esi = val.getEsi();
1033 String macaddress = val.getMacaddress();
1034 EncapType encapType = val.getEncapType();
1035 String routerMac = val.getRoutermac();
1038 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, BgpUtil.convertToThriftProtocolType(protocolType),
1039 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
1040 } catch (TException | BgpRouterException e) {
1041 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1047 protected InstanceIdentifier<Networks> getWildCardPath() {
1048 return InstanceIdentifier.create(Bgp.class).child(Networks.class);
1052 protected synchronized void remove(InstanceIdentifier<Networks> iid, Networks val) {
1053 if (ignoreClusterDcnEventForFollower()) {
1056 LOG.debug("received remove Networks config val {}", val.getPrefixLen());
1057 synchronized (BgpConfigurationManager.this) {
1058 String rd = val.getRd();
1059 String pfxlen = val.getPrefixLen();
1060 BgpRouter br = getClient(YANG_OBJ);
1062 LOG.error("{} Unable to process remove for rd {} prefix {}; {}", YANG_OBJ, rd, pfxlen,
1063 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1066 Long label = val.getLabel();
1067 int lbl = (label == null) ? 0 : label.intValue();
1068 if (rd == null && lbl > 0) {
1069 //LU prefix is being deleted.
1070 rd = Integer.toString(lbl);
1073 br.delPrefix(rd, pfxlen);
1074 } catch (TException | BgpRouterException e) {
1075 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1081 protected void update(final InstanceIdentifier<Networks> iid,
1082 final Networks oldval, final Networks newval) {
1083 if (ignoreClusterDcnEventForFollower()) {
1086 if (oldval.equals(newval)) {
1087 //Update: OLD and New values are same, no need to trigger remove/add.
1088 LOG.debug("received Updated for the same OLD and New values. RD: {}, Prefix: {}, Label: {}, NH: {}",
1089 oldval.getRd(), oldval.getPrefixLen(), oldval.getLabel(), oldval.getNexthop());
1092 LOG.debug("received update networks config val {}", newval.getPrefixLen());
1093 remove(iid, oldval);
1094 timer.schedule(new TimerTask() {
1099 }, Integer.getInteger("bgp.nexthop.update.delay.in.secs", 5) * 1000);
1103 static Timer timer = new Timer();
1105 public class VrfsReactor
1106 extends AsyncDataTreeChangeListenerBase<Vrfs, VrfsReactor>
1107 implements AutoCloseable, ClusteredDataTreeChangeListener<Vrfs> {
1109 private static final String YANG_OBJ = "vrfs ";
1111 public VrfsReactor() {
1112 super(Vrfs.class, VrfsReactor.class);
1116 protected synchronized void add(InstanceIdentifier<Vrfs> iid, Vrfs val) {
1117 if (ignoreClusterDcnEventForFollower()) {
1120 LOG.debug("received add Vrfs config val {}", val.getRd());
1121 synchronized (BgpConfigurationManager.this) {
1122 String rd = val.getRd();
1123 BgpRouter br = getClient(YANG_OBJ);
1125 LOG.error("{} Unable to process add for rd {}; {}", YANG_OBJ, rd,
1126 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1130 br.addVrf(val.getLayerType(), rd, val.getImportRts(),
1131 val.getExportRts());
1132 } catch (TException | BgpRouterException e) {
1133 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1139 protected VrfsReactor getDataTreeChangeListener() {
1140 return VrfsReactor.this;
1144 protected InstanceIdentifier<Vrfs> getWildCardPath() {
1145 return InstanceIdentifier.create(Bgp.class).child(Vrfs.class);
1149 protected synchronized void remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
1150 if (ignoreClusterDcnEventForFollower()) {
1153 LOG.debug("received remove Vrfs config val {}", val.getRd());
1154 synchronized (BgpConfigurationManager.this) {
1155 String rd = val.getRd();
1156 BgpRouter br = getClient(YANG_OBJ);
1158 LOG.error("{} Unable to process remove for rd {}; {}", YANG_OBJ, rd,
1159 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1164 } catch (TException | BgpRouterException e) {
1165 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1171 protected void update(InstanceIdentifier<Vrfs> iid,
1172 Vrfs oldval, Vrfs newval) {
1173 if (ignoreClusterDcnEventForFollower()) {
1176 LOG.debug("VRFS: Update getting triggered for VRFS rd {}", oldval.getRd());
1177 LOG.error(YANG_OBJ + UPD_WARN);
1181 Future lastCleanupJob;
1182 Future lastReplayJobFt = null;
1184 protected void activateMIP() {
1186 LOG.trace("BgpReactor: Executing MIP Activate command");
1187 Process processBgp = Runtime.getRuntime().exec("cluster ip -a sdnc_bgp_mip");
1188 Process processOs = Runtime.getRuntime().exec("cluster ip -a sdnc_os_mip");
1189 LOG.trace("bgpMIP Activated");
1191 } catch (IOException io) {
1192 LOG.error("IO Exception got while activating mip: {}", io.getMessage());
1196 AtomicBoolean started = new AtomicBoolean(false);
1198 public class BgpReactor
1199 extends AsyncDataTreeChangeListenerBase<Bgp, BgpReactor>
1200 implements AutoCloseable, ClusteredDataTreeChangeListener<Bgp> {
1202 private static final String YANG_OBJ = "Bgp ";
1204 public BgpReactor() {
1205 super(Bgp.class, BgpReactor.class);
1210 protected synchronized void add(InstanceIdentifier<Bgp> iid, Bgp val) {
1211 LOG.error("received add Bgp config replaying the config");
1215 } catch (InterruptedException e) {
1218 synchronized (BgpConfigurationManager.this) {
1220 if (ignoreClusterDcnEventForFollower()) {
1224 if (isIpAvailable(odlThriftIp)) {
1227 IP_ACTIVATION_CHECK_TIMER.scheduleAtFixedRate(new TimerTask() {
1230 if (isIpAvailable(odlThriftIp)) {
1232 IP_ACTIVATION_CHECK_TIMER.cancel();
1234 LOG.trace("waiting for odlThriftIP: {} to be present", odlThriftIp);
1243 protected BgpReactor getDataTreeChangeListener() {
1244 return BgpReactor.this;
1248 protected InstanceIdentifier<Bgp> getWildCardPath() {
1249 return InstanceIdentifier.create(Bgp.class);
1253 protected synchronized void remove(InstanceIdentifier<Bgp> iid, Bgp val) {
1254 if (ignoreClusterDcnEventForFollower()) {
1257 LOG.debug("received remove Bgp config");
1258 synchronized (BgpConfigurationManager.this) {
1264 protected void update(InstanceIdentifier<Bgp> iid,
1265 Bgp oldval, Bgp newval) {
1266 if (ignoreClusterDcnEventForFollower()) {
1269 synchronized (BgpConfigurationManager.this) {
1275 public String readThriftIpForCommunication(String mipAddr) {
1276 File file = new File(CLUSTER_CONF_FILE);
1277 if (!file.exists()) {
1281 try (BufferedReader br = new BufferedReader(new FileReader(file))) {
1283 while ((line = br.readLine()) != null) {
1284 if (line.contains(mipAddr)) {
1286 return line.substring(line.lastIndexOf(" ") + 1);
1289 } catch (FileNotFoundException e) {
1291 } catch (IOException e) {
1292 LOG.error("Error reading {}", CLUSTER_CONF_FILE, e);
1297 public boolean isIpAvailable(String odlip) {
1300 if (odlip != null) {
1301 if ("127.0.0.1".equals(odlip)) {
1304 Enumeration networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces();
1305 while (networkInterfaceEnumeration.hasMoreElements()) {
1306 NetworkInterface networkInterface = (NetworkInterface) networkInterfaceEnumeration.nextElement();
1307 Enumeration inetAddressEnumeration = networkInterface.getInetAddresses();
1308 while (inetAddressEnumeration.hasMoreElements()) {
1309 InetAddress inetAddress = (InetAddress) inetAddressEnumeration.nextElement();
1310 if (odlip.equals(inetAddress.getHostAddress())) {
1316 } catch (SocketException e) {
1322 public static long getStalePathtime(int defValue, AsId asId) {
1325 spt = getConfig().getGracefulRestart().getStalepathTime();
1326 } catch (NullPointerException e) {
1328 spt = asId.getStalepathTime();
1329 LOG.trace("BGP config/Stale-path time is not set using graceful");
1330 } catch (NullPointerException ignore) {
1331 LOG.trace("BGP AS id is not set using graceful");
1336 LOG.trace("BGP config/Stale-path time is not set using graceful/start-bgp");
1342 public synchronized void bgpRestarted() {
1344 * If there a thread which in the process of stale cleanup, cancel it
1345 * and start a new thread (to avoid processing same again).
1347 if (previousReplayJobInProgress()) {
1348 cancelPreviousReplayJob();
1350 Runnable task = () -> {
1352 LOG.info("running bgp replay task ");
1353 if (get() == null) {
1354 String host = getConfigHost();
1355 int port = getConfigPort();
1356 LOG.info("connecting to bgp host {} ", host);
1358 boolean res = bgpRouter.connect(host, port);
1359 LOG.info("no config to push in bgp replay task ");
1362 setStaleStartTime(System.currentTimeMillis());
1363 LOG.info("started creating stale fibDSWriter map ");
1364 createStaleFibMap();
1365 setStaleEndTime(System.currentTimeMillis());
1366 LOG.info("took {} msecs for stale fibDSWriter map creation ", getStaleEndTime() - getStaleStartTime());
1367 LOG.info("started bgp config replay ");
1368 setCfgReplayStartTime(System.currentTimeMillis());
1371 } catch (TimeoutException | ExecutionException e) {
1372 LOG.error("Error while replaying routes. {}", e);
1374 setCfgReplayEndTime(System.currentTimeMillis());
1375 LOG.info("took {} msecs for bgp replay ", getCfgReplayEndTime() - getCfgReplayStartTime());
1376 long routeSyncTime = getStalePathtime(BGP_RESTART_ROUTE_SYNC_SEC, config.getAsId());
1377 Thread.sleep(routeSyncTime * 1000L);
1378 setStaleCleanupTime(routeSyncTime);
1379 new RouteCleanup().call();
1380 } catch (InterruptedException eCancel) {
1381 LOG.error("Stale Cleanup Task Cancelled", eCancel);
1384 lastReplayJobFt = executor.submit(task);
1387 private boolean previousReplayJobInProgress() {
1388 return lastReplayJobFt != null && !lastReplayJobFt.isDone();
1391 private void cancelPreviousReplayJob() {
1393 LOG.error("cancelling already running bgp replay task");
1394 lastReplayJobFt.cancel(true);
1395 lastReplayJobFt = null;
1397 } catch (InterruptedException e) {
1398 LOG.error("Failed to cancel previous replay job ", e);
1402 private static void doRouteSync() throws InterruptedException, TimeoutException, ExecutionException {
1403 BgpSyncHandle bsh = BgpSyncHandle.getInstance();
1404 LOG.error("Starting BGP route sync");
1406 bgpRouter.initRibSync(bsh);
1407 } catch (TException | BgpRouterException e) {
1408 LOG.error("Route sync aborted, exception when initializing", e);
1411 while (bsh.getState() != bsh.DONE) {
1412 Routes routes = null;
1414 routes = bgpRouter.doRibSync(bsh);
1415 } catch (TException | BgpRouterException e) {
1416 LOG.error("Route sync aborted, exception when syncing", e);
1419 Iterator<Update> updates = routes.getUpdatesIterator();
1420 while (updates.hasNext()) {
1421 Update update = updates.next();
1422 Map<String, Map<String, Long>> staleFibRdMap = BgpConfigurationManager.getStaledFibEntriesMap();
1423 String rd = update.getRd();
1424 String nexthop = update.getNexthop();
1426 // TODO: decide correct label here
1427 int label = update.getL3label();
1429 String prefix = update.getPrefix();
1430 int plen = update.getPrefixlen();
1433 // TODO: protocol type will not be available in "update"
1434 // use "rd" to query vrf table and obtain the protocol_type. Currently using PROTOCOL_EVPN as default.
1436 protocol_type.PROTOCOL_EVPN,
1443 update.getMacaddress(),
1445 update.getRoutermac()
1450 LOG.error("Ending BGP route-sync");
1451 bgpRouter.endRibSync(bsh);
1452 } catch (TException | BgpRouterException e) {
1457 /* onUpdatePushRoute
1458 * Get Stale fibDSWriter map, and compare current route/fibDSWriter entry.
1459 * - Entry compare shall include NextHop, Label.
1460 * - If entry matches: delete from STALE Map. NO Change to FIB Config DS.
1461 * - If entry not found, add to FIB Config DS.
1462 * - If entry found, but either Label/NextHop doesn't match.
1463 * - Update FIB Config DS with modified values.
1464 * - delete from Stale Map.
1467 public static void onUpdatePushRoute(protocol_type protocolType,
1477 throws InterruptedException, ExecutionException, TimeoutException {
1478 boolean addroute = false;
1480 VrfEntry.EncapType encapType = VrfEntry.EncapType.Mplsgre;
1481 if (protocolType.equals(protocol_type.PROTOCOL_EVPN)) {
1482 encapType = VrfEntry.EncapType.Vxlan;
1483 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = BgpUtil.getVpnInstanceOpData(dataBroker, rd);
1484 if (vpnInstanceOpDataEntry != null) {
1485 l3vni = vpnInstanceOpDataEntry.getL3vni();
1487 LOG.error("No corresponding vpn instance found for rd {}. Aborting.", rd);
1491 if (!staledFibEntriesMap.isEmpty()) {
1492 // restart Scenario, as MAP is not empty.
1493 Map<String, Long> map = staledFibEntriesMap.get(rd);
1495 String prefixNextHop = appendNextHopToPrefix(prefix + "/" + plen, nextHop);
1496 Long labelInStaleMap = map.get(prefixNextHop);
1497 if (null == labelInStaleMap) {
1498 // New Entry, which happened to be added during restart.
1501 map.remove(prefixNextHop);
1502 if (isRouteModified(label, labelInStaleMap)) {
1503 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
1504 // Existing entry, where in Label got modified during restart
1510 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
1514 LOG.info("ADD: Adding Fib entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, label);
1515 // TODO: modify addFibEntryToDS signature
1516 fibDSWriter.addFibEntryToDS(rd, macaddress, prefix + "/" + plen, Collections.singletonList(nextHop),
1517 encapType, label, l3vni, routermac, RouteOrigin.BGP);
1518 LOG.info("ADD: Added Fib entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, label);
1522 private static boolean isRouteModified(int label, Long labelInStaleMap) {
1523 return labelInStaleMap != null && !labelInStaleMap.equals(label);
1526 private static void replayNbrConfig(List<Neighbors> neighbors, BgpRouter br) {
1527 for (Neighbors nbr : neighbors) {
1529 br.addNeighbor(nbr.getAddress().getValue(),
1531 //itmProvider.buildTunnelsToDCGW(new IpAddress(nbr.getAddress().getValue().toCharArray()));
1532 } catch (TException | BgpRouterException e) {
1533 LOG.error("Replay:addNbr() received exception", e);
1536 EbgpMultihop en = nbr.getEbgpMultihop();
1539 br.addEbgpMultihop(en.getPeerIp().getValue(),
1540 en.getNhops().intValue());
1541 } catch (TException | BgpRouterException e) {
1542 LOG.error("Replay:addEBgp() received exception", e);
1545 UpdateSource us = nbr.getUpdateSource();
1548 br.addUpdateSource(us.getPeerIp().getValue(),
1549 us.getSourceIp().getValue());
1550 } catch (TException | BgpRouterException e) {
1551 LOG.error("Replay:addUS() received exception", e);
1554 List<AddressFamilies> afs = nbr.getAddressFamilies();
1556 for (AddressFamilies af : afs) {
1557 af_afi afi = af_afi.findByValue(af.getAfi().intValue());
1558 af_safi safi = af_safi.findByValue(af.getSafi().intValue());
1560 br.addAddressFamily(af.getPeerIp().getValue(), afi, safi);
1561 } catch (TException | BgpRouterException e) {
1562 LOG.error("Replay:addAf() received exception", e);
1569 public static String getConfigHost() {
1570 if (config == null) {
1571 return cHostStartup;
1573 ConfigServer ts = config.getConfigServer();
1574 return (ts == null ? cHostStartup : ts.getHost().getValue());
1577 public static int getConfigPort() {
1578 if (config == null) {
1579 return Integer.parseInt(cPortStartup);
1581 ConfigServer ts = config.getConfigServer();
1582 return (ts == null ? Integer.parseInt(cPortStartup) :
1583 ts.getPort().intValue());
1586 public static Bgp getConfig() {
1587 AtomicInteger bgpDSretryCount = new AtomicInteger(DS_RETRY_COOUNT);
1588 while (0 != bgpDSretryCount.decrementAndGet()) {
1590 return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
1591 InstanceIdentifier.create(Bgp.class)).orNull();
1592 } catch (ReadFailedException e) {
1593 //Config DS may not be up, so sleep for 1 second and retry
1594 LOG.debug("failed to get bgp config, may be DS is yet in consistent state(?)", e);
1596 Thread.sleep(WAIT_TIME_BETWEEN_EACH_TRY_MILLIS);
1597 } catch (InterruptedException timerEx) {
1598 LOG.debug("WAIT_TIME_BETWEEN_EACH_TRY_MILLIS, Timer got interrupted while waiting for"
1599 + "config DS availability", timerEx);
1603 LOG.error("failed to get bgp config");
1607 @SuppressWarnings("checkstyle:IllegalCatch")
1608 public synchronized void replay() throws InterruptedException, TimeoutException, ExecutionException {
1609 synchronized (bgpConfigurationManager) {
1610 String host = getConfigHost();
1611 int port = getConfigPort();
1612 LOG.error("connecting to bgp host {} ", host);
1614 boolean res = bgpRouter.connect(host, port);
1616 String msg = "Cannot connect to BGP config server at " + host + ":" + port;
1617 if (config != null) {
1618 msg += "; Configuration Replay aborted";
1623 config = getConfig();
1624 if (config == null) {
1625 LOG.error("bgp config is empty nothing to push to bgp");
1628 BgpRouter br = bgpRouter;
1629 AsId asId = config.getAsId();
1633 long asNum = asId.getLocalAs();
1634 IpAddress routerId = asId.getRouterId();
1635 Long spt = asId.getStalepathTime();
1636 Boolean afb = asId.isAnnounceFbit();
1637 String rid = (routerId == null) ? "" : new String(routerId.getValue());
1638 int stalepathTime = (int) getStalePathtime(0, config.getAsId());
1639 boolean announceFbit = true;
1641 br.startBgp(asNum, rid, stalepathTime, announceFbit);
1642 } catch (BgpRouterException bre) {
1643 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
1646 LOG.error("Replay: startBgp() received exception: \""
1647 + bre + "\"; " + ADD_WARN);
1649 } catch (TException e) {
1650 //not unusual. We may have restarted & BGP is already on
1651 LOG.error("Replay:startBgp() received exception: \"" + e + "\"");
1654 if (getBgpCounters() == null) {
1655 startBgpCountersTask();
1658 if (getBgpAlarms() == null) {
1659 startBgpAlarmsTask();
1662 Logging logging = config.getLogging();
1663 if (logging != null) {
1665 br.setLogging(logging.getFile(), logging.getLevel());
1666 } catch (TException | BgpRouterException e) {
1667 LOG.error("Replay:setLogging() received exception", e);
1671 GracefulRestart gracefulRestart = config.getGracefulRestart();
1672 if (gracefulRestart != null) {
1674 br.addGracefulRestart(gracefulRestart.getStalepathTime().intValue());
1675 } catch (TException | BgpRouterException e) {
1676 LOG.error("Replay:addGr() received exception", e);
1680 List<Vrfs> vrfs = config.getVrfs();
1682 for (Vrfs vrf : vrfs) {
1684 br.addVrf(vrf.getLayerType(), vrf.getRd(), vrf.getImportRts(),
1685 vrf.getExportRts());
1686 } catch (TException | BgpRouterException e) {
1687 LOG.error("Replay:addVrf() received exception", e);
1692 List<Networks> ln = config.getNetworks();
1694 for (Networks net : ln) {
1695 String rd = net.getRd();
1696 String pfxlen = net.getPrefixLen();
1697 String nh = net.getNexthop().getValue();
1698 Long label = net.getLabel();
1699 int lbl = (label == null) ? 0 : label.intValue();
1700 int l3vni = (net.getL3vni() == null) ? 0 : net.getL3vni().intValue();
1701 if (rd == null && lbl > 0) {
1702 //LU prefix is being deleted.
1703 rd = Integer.toString(lbl);
1706 BgpControlPlaneType protocolType = net.getBgpControlPlaneType();
1707 int ethernetTag = net.getEthtag().intValue();
1708 String esi = net.getEsi();
1709 String macaddress = net.getMacaddress();
1710 EncapType encapType = net.getEncapType();
1711 String routerMac = net.getRoutermac();
1714 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, BgpUtil.convertToThriftProtocolType(protocolType),
1715 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
1716 } catch (Exception e) {
1717 LOG.error("Replay:addPfx() received exception", e);
1721 List<Neighbors> neighbors = config.getNeighbors();
1722 if (neighbors != null) {
1723 LOG.error("configuring existing Neighbors present for replay total neighbors {}", neighbors.size());
1724 replayNbrConfig(neighbors, br);
1726 LOG.error("no Neighbors present for replay config ");
1731 private <T extends DataObject> void update(InstanceIdentifier<T> iid, T dto) {
1732 BgpUtil.update(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1735 private <T extends DataObject> void asyncWrite(InstanceIdentifier<T> iid, T dto) {
1736 BgpUtil.write(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1739 private <T extends DataObject> void delete(InstanceIdentifier<T> iid) {
1740 BgpUtil.delete(dataBroker, LogicalDatastoreType.CONFIGURATION, iid);
1743 public synchronized void startConfig(String bgpHost, int thriftPort) {
1744 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1745 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1746 InstanceIdentifier<ConfigServer> iid = iib.build();
1747 Ipv4Address ipAddr = new Ipv4Address(bgpHost);
1748 ConfigServer dto = new ConfigServerBuilder().setHost(ipAddr)
1749 .setPort((long) thriftPort).build();
1753 public synchronized void startBgp(long as, String routerId, int spt, boolean fbit) {
1754 IpAddress rid = (routerId == null) ? null : new IpAddress(routerId.toCharArray());
1755 Long staleTime = (long) spt;
1756 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1757 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1758 InstanceIdentifier<AsId> iid = iib.build();
1759 AsId dto = new AsIdBuilder().setLocalAs(as)
1761 .setStalepathTime(staleTime)
1762 .setAnnounceFbit(fbit).build();
1766 public synchronized void addLogging(String fileName, String logLevel) {
1767 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1768 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1769 InstanceIdentifier<Logging> iid = iib.build();
1770 Logging dto = new LoggingBuilder().setFile(fileName)
1771 .setLevel(logLevel).build();
1775 public synchronized void addGracefulRestart(int staleTime) {
1776 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1777 InstanceIdentifier.builder(Bgp.class).child(GracefulRestart.class);
1778 InstanceIdentifier<GracefulRestart> iid = iib.build();
1779 GracefulRestart dto = new GracefulRestartBuilder()
1780 .setStalepathTime((long) staleTime).build();
1784 public synchronized void addNeighbor(String nbrIp, long remoteAs) {
1785 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1786 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1787 InstanceIdentifier.builder(Bgp.class)
1788 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1789 InstanceIdentifier<Neighbors> iid = iib.build();
1790 Neighbors dto = new NeighborsBuilder().setAddress(nbrAddr)
1791 .setRemoteAs(remoteAs).build();
1795 public synchronized void addUpdateSource(String nbrIp, String srcIp) {
1796 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1797 Ipv4Address srcAddr = new Ipv4Address(srcIp);
1798 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1799 InstanceIdentifier.builder(Bgp.class)
1800 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1801 .child(UpdateSource.class);
1802 InstanceIdentifier<UpdateSource> iid = iib.build();
1803 UpdateSource dto = new UpdateSourceBuilder().setPeerIp(nbrAddr)
1804 .setSourceIp(srcAddr).build();
1808 public synchronized void addEbgpMultihop(String nbrIp, int hops) {
1809 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1810 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1811 InstanceIdentifier.builder(Bgp.class)
1812 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1813 .child(EbgpMultihop.class);
1814 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1815 EbgpMultihop dto = new EbgpMultihopBuilder().setPeerIp(nbrAddr)
1816 .setNhops((long) hops).build();
1820 public synchronized void addAddressFamily(String nbrIp, int afi, int safi) {
1821 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1822 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1823 InstanceIdentifier.builder(Bgp.class)
1824 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1825 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
1826 InstanceIdentifier<AddressFamilies> iid = iib.build();
1827 AddressFamilies dto = new AddressFamiliesBuilder().setPeerIp(nbrAddr)
1828 .setAfi((long) afi).setSafi((long) safi).build();
1832 public synchronized void addPrefix(String rd, String macAddress, String pfx, List<String> nhList,
1833 VrfEntry.EncapType encapType, int lbl, long l3vni, String gatewayMac, int addressFamily) {
1834 for (String nh : nhList) {
1835 Ipv4Address nexthop = nh != null ? new Ipv4Address(nh) : null;
1836 Long label = (long) lbl;
1837 Long afi = (long) addressFamily;
1838 InstanceIdentifier<Networks> iid = InstanceIdentifier.builder(Bgp.class)
1839 .child(Networks.class, new NetworksKey(pfx, rd)).build();
1840 NetworksBuilder networksBuilder = new NetworksBuilder().setRd(rd).setPrefixLen(pfx).setNexthop(nexthop)
1841 .setLabel(label).setEthtag(BgpConstants.DEFAULT_ETH_TAG)
1843 buildVpnEncapSpecificInfo(networksBuilder, encapType, label, l3vni, macAddress, gatewayMac);
1844 update(iid, networksBuilder.build());
1848 private static void buildVpnEncapSpecificInfo(NetworksBuilder builder, VrfEntry.EncapType encapType, long label,
1849 long l3vni, String macAddress, String gatewayMac) {
1850 if (encapType.equals(VrfEntry.EncapType.Mplsgre)) {
1851 builder.setLabel(label).setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLL3VPN)
1852 .setEncapType(EncapType.GRE);
1854 builder.setL3vni(l3vni).setMacaddress(macAddress).setRoutermac(gatewayMac)
1855 .setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLEVPN).setEncapType(EncapType.VXLAN);
1859 // TODO: add LayerType as arg - supports command
1860 public synchronized void addVrf(String rd, List<String> irts, List<String> erts, LayerType layerType) {
1861 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1862 InstanceIdentifier.builder(Bgp.class)
1863 .child(Vrfs.class, new VrfsKey(rd));
1864 InstanceIdentifier<Vrfs> iid = iib.build();
1865 Vrfs dto = new VrfsBuilder().setRd(rd).setImportRts(irts)
1866 .setExportRts(erts).setLayerType(layerType).build();
1868 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1869 } catch (TransactionCommitFailedException e) {
1870 LOG.error("Error adding VRF to datastore", e);
1871 throw new RuntimeException(e);
1875 public synchronized void stopConfig() {
1876 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1877 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1878 InstanceIdentifier<ConfigServer> iid = iib.build();
1882 public synchronized void stopBgp() {
1883 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1884 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1885 InstanceIdentifier<AsId> iid = iib.build();
1889 public synchronized void delLogging() {
1890 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1891 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1892 InstanceIdentifier<Logging> iid = iib.build();
1896 public synchronized void delGracefulRestart() {
1897 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1898 InstanceIdentifier.builder(Bgp.class)
1899 .child(GracefulRestart.class);
1900 InstanceIdentifier<GracefulRestart> iid = iib.build();
1904 public synchronized void delNeighbor(String nbrIp) {
1905 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1906 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1907 InstanceIdentifier.builder(Bgp.class)
1908 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1909 InstanceIdentifier<Neighbors> iid = iib.build();
1913 public synchronized void delUpdateSource(String nbrIp) {
1914 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1915 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1916 InstanceIdentifier.builder(Bgp.class)
1917 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1918 .child(UpdateSource.class);
1919 InstanceIdentifier<UpdateSource> iid = iib.build();
1923 public synchronized void delEbgpMultihop(String nbrIp) {
1924 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1925 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1926 InstanceIdentifier.builder(Bgp.class)
1927 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1928 .child(EbgpMultihop.class);
1929 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1933 public synchronized void delAddressFamily(String nbrIp, int afi, int safi) {
1934 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1935 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1936 InstanceIdentifier.builder(Bgp.class)
1937 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1938 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
1939 InstanceIdentifier<AddressFamilies> iid = iib.build();
1943 public synchronized void delPrefix(String rd, String pfx, int afi) {
1944 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
1945 InstanceIdentifier.builder(Bgp.class)
1946 .child(Networks.class, new NetworksKey(pfx, rd));
1947 InstanceIdentifier<Networks> iid = iib.build();
1951 public synchronized void delVrf(String rd) {
1952 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1953 InstanceIdentifier.builder(Bgp.class)
1954 .child(Vrfs.class, new VrfsKey(rd));
1955 InstanceIdentifier<Vrfs> iid = iib.build();
1959 static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
1962 * Remove Stale Marked Routes after timer expiry.
1964 class RouteCleanup implements Callable<Integer> {
1967 public Integer call() {
1970 if (staledFibEntriesMap.isEmpty()) {
1971 LOG.info("BGP: RouteCleanup timertask tirggered but STALED FIB MAP is EMPTY");
1973 for (String rd : staledFibEntriesMap.keySet()) {
1974 if (Thread.interrupted()) {
1977 Map<String, Long> map = staledFibEntriesMap.get(rd);
1979 for (String key : map.keySet()) {
1980 if (Thread.interrupted()) {
1983 String prefix = extractPrefix(key);
1984 String nextHop = extractNextHop(key);
1986 LOG.debug("BGP: RouteCleanup deletePrefix called for : rd:{}, prefix{}, nextHop:{}",
1987 rd, prefix, nextHop);
1988 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix, nextHop);
1994 staledFibEntriesMap.clear();
1996 LOG.error("cleared {} stale routes after bgp restart", totalCleared);
2002 * BGP restart scenario, ODL-BGP manager was/is running.
2003 * On re-sync notification, Get a copy of FIB database.
2005 public static void createStaleFibMap() {
2006 totalStaledCount = 0;
2009 * at the time Stale FIB creation, Wait till all PENDING write transaction
2010 * to complete (or)wait for max timeout value of STALE_FIB_WAIT Seconds.
2012 int retry = STALE_FIB_WAIT;
2013 while ((BgpUtil.getGetPendingWrTransaction() != 0) && (retry > 0)) {
2017 LOG.error("TimeOut occured {} seconds, in waiting stale fibDSWriter create", STALE_FIB_WAIT);
2020 staledFibEntriesMap.clear();
2021 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
2022 DataBroker db = BgpUtil.getBroker();
2024 LOG.error("Couldn't find BgpUtil dataBroker while creating createStaleFibMap");
2028 Optional<FibEntries> fibEntries = SingleTransactionDataBroker.syncReadOptional(BgpUtil.getBroker(),
2029 LogicalDatastoreType.CONFIGURATION, id);
2030 if (fibEntries.isPresent()) {
2031 List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
2032 for (VrfTables vrfTable : staleVrfTables) {
2033 Map<String, Long> staleFibEntMap = new HashMap<>();
2034 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
2035 if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
2036 //Stale marking and cleanup is only meant for the routes learned through BGP.
2039 if (Thread.interrupted()) {
2043 //Create MAP from staleVrfTables.
2044 vrfEntry.getRoutePaths()
2046 routePath -> staleFibEntMap.put(
2047 appendNextHopToPrefix(vrfEntry.getDestPrefix(),
2048 routePath.getNexthopAddress()), routePath.getLabel()));
2050 staledFibEntriesMap.put(vrfTable.getRouteDistinguisher(), staleFibEntMap);
2053 LOG.error("createStaleFibMap:: FIBentries.class is not present");
2055 } catch (InterruptedException | ReadFailedException e) {
2056 LOG.error("createStaleFibMap:: error ", e);
2058 LOG.error("created {} staled entries ", totalStaledCount);
2061 //map<rd, map<prefix/len:nexthop, label>>
2062 public static Map<String, Map<String, Long>> getStaledFibEntriesMap() {
2063 return staledFibEntriesMap;
2066 //TODO: below function is for testing purpose with cli
2067 public static void onUpdateWithdrawRoute(String rd, String prefix, int plen, String nexthop) {
2068 LOG.debug("Route del ** {} ** {}/{} ", rd, prefix, plen);
2069 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix + "/" + plen, nexthop);
2072 public boolean isBgpConnected() {
2073 return bgpRouter.isBgpConnected();
2076 public long getLastConnectedTS() {
2077 return bgpRouter.getLastConnectedTS();
2080 public long getConnectTS() {
2081 return bgpRouter.getConnectTS();
2084 public long getStartTS() {
2085 return bgpRouter.getStartTS();
2088 public static int getTotalStaledCount() {
2089 return totalStaledCount;
2092 public static int getTotalCleared() {
2093 return totalCleared;
2096 public Timer getBgpCountersTimer() {
2097 return bgpCountersTimer;
2100 public BgpCounters getBgpCounters() {
2104 public void setBgpCountersTimer(Timer timer) {
2105 bgpCountersTimer = timer;
2108 public void setBgpAlarmsTimer(Timer timer) {
2109 bgpAlarmsTimer = timer;
2112 public void startBgpCountersTask() {
2113 if (getBgpCounters() == null) {
2114 bgpCounters = new BgpCounters(bgpConfigurationManager.getBgpSdncMipIp());
2115 setBgpCountersTimer(new Timer(true));
2116 getBgpCountersTimer().scheduleAtFixedRate(bgpCounters, 0, 120 * 1000);
2117 LOG.info("Bgp Counters task scheduled for every two minutes.");
2119 bgpManager.setQbgpLog(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
2123 public void stopBgpCountersTask() {
2124 Timer timer = getBgpCountersTimer();
2125 if (getBgpCounters() != null) {
2127 setBgpCountersTimer(null);
2132 public void startBgpAlarmsTask() {
2133 if (getBgpAlarms() == null) {
2134 bgpAlarms = new BgpAlarms(this);
2135 setBgpAlarmsTimer(new Timer(true));
2136 getBgpAlarmsTimer().scheduleAtFixedRate(bgpAlarms, 0, 60 * 1000);
2137 LOG.info("Bgp Alarms task scheduled for every minute.");
2141 public void stopBgpAlarmsTask() {
2142 Timer timer = getBgpAlarmsTimer();
2143 if (getBgpAlarms() != null) {
2145 setBgpAlarmsTimer(null);
2150 public Timer getBgpAlarmsTimer() {
2151 return bgpAlarmsTimer;
2154 public BgpAlarms getBgpAlarms() {
2158 private static String appendNextHopToPrefix(String prefix, String nextHop) {
2159 return prefix + ":" + nextHop;
2162 private static String extractPrefix(String prefixNextHop) {
2163 return prefixNextHop.split(":")[0];
2166 private static String extractNextHop(String prefixNextHop) {
2167 return prefixNextHop.split(":")[1];