2 * Copyright (c) 2015 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.netvirt.bgpmanager;
11 import com.google.common.base.Optional;
14 import java.io.BufferedReader;
16 import java.io.FileInputStream;
17 import java.io.InputStreamReader;
18 import java.lang.reflect.*;
19 import java.net.InetAddress;
20 import java.net.NetworkInterface;
21 import java.util.concurrent.*;
22 import java.util.concurrent.atomic.AtomicBoolean;
23 import java.util.concurrent.atomic.AtomicReference;
25 import org.opendaylight.netvirt.bgpmanager.commands.ClearBgpCli;
26 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
27 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
28 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
29 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
30 //import org.opendaylight.vpnservice.itm.api.IITMProvider;
31 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouter;
32 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouterException;
33 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpSyncHandle;
34 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Routes;
35 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Update;
36 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
37 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
38 import org.opendaylight.netvirt.bgpmanager.thrift.gen.qbgpConstants;
39 import org.opendaylight.netvirt.bgpmanager.thrift.server.BgpThriftService;
40 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.*;
41 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.*;
42 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.*;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.*;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
47 import org.opendaylight.yangtools.concepts.ListenerRegistration;
48 import org.opendaylight.yangtools.yang.binding.DataObject;
49 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
50 import org.osgi.framework.Bundle;
51 import org.osgi.framework.BundleContext;
52 import org.osgi.framework.FrameworkUtil;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
56 public class BgpConfigurationManager {
57 private static final Logger LOG =
58 LoggerFactory.getLogger(BgpConfigurationManager.class);
59 private static DataBroker broker;
60 private static FibDSWriter fib;
61 private boolean restarting = false;
62 private static Bgp config;
63 private static BgpRouter bgpRouter;
64 private static BgpThriftService updateServer;
66 private static final String DEF_LOGFILE = "/var/log/bgp_debug.log";
67 private static final String DEF_LOGLEVEL = "errors";
68 private static final String UPDATE_PORT = "bgp.thrift.service.port";
69 private static final String CONFIG_HOST = "vpnservice.bgpspeaker.host.name";
70 private static final String CONFIG_PORT = "vpnservice.bgpspeaker.thrift.port";
71 private static final String DEF_UPORT = "6644";
72 private static final String DEF_CHOST = "127.0.0.1";
73 private static final String DEF_CPORT = "7644";
74 private static final String SDNC_BGP_MIP = "sdnc_bgp_mip";
75 private static final String CLUSTER_CONF_FILE = "/cluster/etc/cluster.conf";
76 private static final Timer ipActivationCheckTimer = new Timer();
78 // to have stale FIB map (RD, Prefix)
79 // number of seconds wait for route sync-up between ODL and BGP.
80 private static final int BGP_RESTART_ROUTE_SYNC_SEC = 360;
82 static String odlThriftIp = "127.0.0.1";
83 private static String cHostStartup;
84 private static String cPortStartup;
85 private static CountDownLatch initer = new CountDownLatch(1);
86 //static IITMProvider itmProvider;
87 public static BgpManager bgpManager;
88 //map<rd, map<prefix/len, nexthop/label>>
89 private static Map<String, Map<String, String>> staledFibEntriesMap = new ConcurrentHashMap<>();
91 private static final Class[] reactors =
93 ConfigServerReactor.class, AsIdReactor.class,
94 GracefulRestartReactor.class, LoggingReactor.class,
95 NeighborsReactor.class, UpdateSourceReactor.class,
96 EbgpMultihopReactor.class, AddressFamiliesReactor.class,
97 NetworksReactor.class, VrfsReactor.class, BgpReactor.class
100 private ListenerRegistration<DataChangeListener>[] registrations;
102 private Object createListener(Class<?> cls) {
107 ctor= cls.getConstructor(BgpConfigurationManager.class);
108 obj = ctor.newInstance(this);
109 } catch (Exception e) {
110 LOG.error("Failed to create listener object", e);
115 private void registerCallbacks() {
116 String emsg = "Failed to register listener";
117 registrations = (ListenerRegistration<DataChangeListener>[])
118 new ListenerRegistration[reactors.length];
119 InstanceIdentifier<?> iid = InstanceIdentifier.create(Bgp.class);
120 for (int i = 0; i < reactors.length; i++) {
121 DataChangeListener dcl =
122 (DataChangeListener) createListener(reactors[i]);
123 String dclName = dcl.getClass().getName();
125 registrations[i] = broker.registerDataChangeListener(
126 LogicalDatastoreType.CONFIGURATION,
127 iid, dcl, DataChangeScope.SUBTREE);
128 } catch (Exception e) {
130 throw new IllegalStateException(emsg+" "+dclName, e);
135 public void close() {
136 if (updateServer != null) {
141 private boolean configExists() {
142 InstanceIdentifier.InstanceIdentifierBuilder<Bgp> iib =
143 InstanceIdentifier.builder(Bgp.class);
144 InstanceIdentifier<Bgp> iid = iib.build();
145 Optional<Bgp> b = BgpUtil.read(broker,
146 LogicalDatastoreType.CONFIGURATION, iid);
147 return b.isPresent();
150 private String getProperty(String var, String def) {
151 Bundle b = FrameworkUtil.getBundle(BgpManager.class);
155 BundleContext context = b.getBundleContext();
156 if (context == null) {
159 String s = context.getProperty(var);
160 return (s == null ? def : s);
163 public BgpConfigurationManager(BgpManager bgpMgr) {
164 broker = bgpMgr.getBroker();
165 fib = bgpMgr.getFibWriter();
166 //itmProvider = bgpMgr.getItmProvider();
167 // there must be a good way to detect that we're restarting.
168 // but for now infer it from the existance of config
169 restarting = configExists();
171 bgpRouter = BgpRouter.getInstance();
172 String uPort = getProperty(UPDATE_PORT, DEF_UPORT);
173 cHostStartup = getProperty(CONFIG_HOST, DEF_CHOST);
174 cPortStartup = getProperty(CONFIG_PORT, DEF_CPORT);
175 VtyshCli.setHostAddr(cHostStartup);
176 ClearBgpCli.setHostAddr(cHostStartup);
177 LOG.info("UpdateServer at localhost:"+uPort+" ConfigServer at "
178 +cHostStartup+":"+cPortStartup);
179 updateServer = new BgpThriftService(Integer.parseInt(uPort), bgpMgr);
180 updateServer.start();
181 readOdlThriftIpForBgpCommunication();
184 // this shouldn't be done. config client must connect in
185 // response to config; but connecting at startup to a default
186 // host is legacy behavior.
188 bgpRouter.connect(cHostStartup, Integer.parseInt(cPortStartup));
190 LOG.info("BGP Configuration manager initialized");
198 private static final String addWarn =
199 "Config store updated; undo with Delete if needed.";
200 private static final String delWarn =
201 "Config store updated; undo with Add if needed.";
202 private static final String updWarn =
203 "Update operation not supported; Config store updated;"
204 +" restore with another Update if needed.";
206 public class ConfigServerReactor
207 extends AbstractDataChangeListener<ConfigServer>
208 implements AutoCloseable {
209 private static final String yangObj = "config-server ";
210 public ConfigServerReactor() {
211 super(ConfigServer.class);
214 protected synchronized void
215 add(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
216 LOG.debug("received bgp connect config host {}", val.getHost().getValue());
219 } catch (Exception e) {
221 LOG.debug("issueing bgp router connect to host {}", val.getHost().getValue());
222 synchronized(BgpConfigurationManager.this) {
223 boolean res = bgpRouter.connect(val.getHost().getValue(),
224 val.getPort().intValue());
226 LOG.error(yangObj + "Add failed; "+addWarn);
231 protected synchronized void
232 remove(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
233 LOG.debug("received bgp disconnect");
234 synchronized(BgpConfigurationManager.this) {
235 bgpRouter.disconnect();
239 protected void update(InstanceIdentifier<ConfigServer> iid,
240 ConfigServer oldval, ConfigServer newval) {
241 LOG.error(yangObj + updWarn);
244 public void close() {
246 for (i=0 ; i < reactors.length ; i++) {
247 if (reactors[i] == ConfigServerReactor.class) {
251 registrations[i].close();
255 private BgpRouter getClient(String yangObj) {
256 if (bgpRouter == null) {
257 LOG.warn(yangObj+": configuration received when BGP is inactive");
262 public class AsIdReactor
263 extends AbstractDataChangeListener<AsId>
264 implements AutoCloseable {
266 private static final String yangObj = "as-id ";
268 public AsIdReactor() {
272 protected synchronized void
273 add(InstanceIdentifier<AsId> iid, AsId val) {
274 LOG.debug("received add router config asNum {}", val.getLocalAs().intValue());
275 synchronized(BgpConfigurationManager.this) {
276 BgpRouter br = getClient(yangObj);
280 int asNum = val.getLocalAs().intValue();
281 Ipv4Address routerId = val.getRouterId();
282 Long spt = val.getStalepathTime();
283 Boolean afb = val.isAnnounceFbit();
284 String rid = (routerId == null) ? "" : routerId.getValue();
285 int stalepathTime = (spt == null) ? 90 : spt.intValue();
286 boolean announceFbit = (afb == null) ? false : afb.booleanValue();
288 br.startBgp(asNum, rid, stalepathTime, announceFbit);
289 if (bgpManager.getBgpCounters() == null) {
290 bgpManager.startBgpCountersTask();
292 } catch (BgpRouterException bre) {
293 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
294 LOG.error(yangObj+"Add requested when BGP is already active");
296 LOG.error(yangObj+"Add received exception: \""
297 +bre+"\"; "+addWarn);
299 } catch (Exception e) {
300 LOG.error(yangObj+"Add received exception: \""+e+"\"; "+addWarn);
305 protected synchronized void
306 remove(InstanceIdentifier<AsId> iid, AsId val) {
307 LOG.debug("received delete router config asNum {}", val.getLocalAs().intValue());
308 synchronized(BgpConfigurationManager.this) {
309 BgpRouter br = getClient(yangObj);
313 int asNum = val.getLocalAs().intValue();
316 } catch (Exception e) {
317 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "+delWarn);
319 if (bgpManager.getBgpCounters() != null) {
320 bgpManager.stopBgpCountersTask();
325 protected void update(InstanceIdentifier<AsId> iid,
326 AsId oldval, AsId newval) {
327 LOG.error(yangObj + updWarn);
330 public void close() {
332 for (i=0 ; i < reactors.length ; i++) {
333 if (reactors[i] == AsIdReactor.class) {
337 registrations[i].close();
341 public class GracefulRestartReactor
342 extends AbstractDataChangeListener<GracefulRestart>
343 implements AutoCloseable {
345 private static final String yangObj = "graceful-restart ";
347 public GracefulRestartReactor() {
348 super(GracefulRestart.class);
351 protected synchronized void
352 add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
353 synchronized(BgpConfigurationManager.this) {
354 BgpRouter br = getClient(yangObj);
359 br.addGracefulRestart(val.getStalepathTime().intValue());
360 } catch (Exception e) {
361 LOG.error(yangObj+"Add received exception: \""+e+"\"; "+addWarn);
366 protected synchronized void
367 remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
368 LOG.debug("received delete GracefulRestart config val {}", val.getStalepathTime().intValue());
369 synchronized(BgpConfigurationManager.this) {
370 BgpRouter br = getClient(yangObj);
375 br.delGracefulRestart();
376 } catch (Exception e) {
377 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
383 protected void update(InstanceIdentifier<GracefulRestart> iid,
384 GracefulRestart oldval, GracefulRestart newval) {
385 LOG.debug("received update GracefulRestart config val {}", newval.getStalepathTime().intValue());
386 synchronized(BgpConfigurationManager.this) {
387 BgpRouter br = getClient(yangObj);
392 br.addGracefulRestart(newval.getStalepathTime().intValue());
393 } catch (Exception e) {
394 LOG.error(yangObj+"update received exception: \""+e+"\"; "+addWarn);
399 public void close() {
401 for (i=0 ; i < reactors.length ; i++) {
402 if (reactors[i] == GracefulRestartReactor.class) {
406 registrations[i].close();
410 public class LoggingReactor
411 extends AbstractDataChangeListener<Logging>
412 implements AutoCloseable {
414 private static final String yangObj = "logging ";
416 public LoggingReactor() {
417 super(Logging.class);
420 protected synchronized void
421 add(InstanceIdentifier<Logging> iid, Logging val) {
422 synchronized(BgpConfigurationManager.this) {
423 BgpRouter br = getClient(yangObj);
428 br.setLogging(val.getFile(),val.getLevel());
429 } catch (Exception e) {
430 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
436 protected synchronized void
437 remove(InstanceIdentifier<Logging> iid, Logging val) {
438 LOG.debug("received remove Logging config val {}", val.getLevel());
439 synchronized(BgpConfigurationManager.this) {
440 BgpRouter br = getClient(yangObj);
445 br.setLogging(DEF_LOGFILE, DEF_LOGLEVEL);
446 } catch (Exception e) {
447 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
453 protected void update(InstanceIdentifier<Logging> iid,
454 Logging oldval, Logging newval) {
455 synchronized(BgpConfigurationManager.this) {
456 BgpRouter br = getClient(yangObj);
461 br.setLogging(newval.getFile(),newval.getLevel());
462 } catch (Exception e) {
463 LOG.error(yangObj+"newval received exception: \""+e+"\"; "
469 public void close() {
471 for (i=0 ; i < reactors.length ; i++) {
472 if (reactors[i] == LoggingReactor.class) {
476 registrations[i].close();
480 public class NeighborsReactor
481 extends AbstractDataChangeListener<Neighbors>
482 implements AutoCloseable {
484 private static final String yangObj = "neighbors ";
486 public NeighborsReactor() {
487 super(Neighbors.class);
490 protected synchronized void
491 add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
492 LOG.debug("received add Neighbors config val {}", val.getAddress().getValue());
493 synchronized(BgpConfigurationManager.this) {
494 BgpRouter br = getClient(yangObj);
498 String peerIp = val.getAddress().getValue();
499 int as = val.getRemoteAs().intValue();
501 //itmProvider.buildTunnelsToDCGW(new IpAddress(peerIp.toCharArray()));
502 br.addNeighbor(peerIp, as);
504 } catch (Exception e) {
505 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
511 protected synchronized void
512 remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
513 LOG.debug("received remove Neighbors config val {}", val.getAddress().getValue());
514 synchronized(BgpConfigurationManager.this) {
515 BgpRouter br = getClient(yangObj);
519 String peerIp = val.getAddress().getValue();
521 //itmProvider.deleteTunnelsToDCGW(new IpAddress(val.getAddress().getValue().toCharArray()));
522 br.delNeighbor(peerIp);
523 } catch (Exception e) {
524 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
530 protected void update(InstanceIdentifier<Neighbors> iid,
531 Neighbors oldval, Neighbors newval) {
532 //purposefully nothing to do.
535 public void close() {
537 for (i=0 ; i < reactors.length ; i++) {
538 if (reactors[i] == NeighborsReactor.class) {
542 registrations[i].close();
546 public class EbgpMultihopReactor
547 extends AbstractDataChangeListener<EbgpMultihop>
548 implements AutoCloseable {
550 private static final String yangObj = "ebgp-multihop ";
552 public EbgpMultihopReactor() {
553 super(EbgpMultihop.class);
556 protected synchronized void
557 add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
558 LOG.debug("received add EbgpMultihop config val {}", val.getPeerIp().getValue());
559 synchronized(BgpConfigurationManager.this) {
560 BgpRouter br = getClient(yangObj);
564 String peerIp = val.getPeerIp().getValue();
566 br.addEbgpMultihop(peerIp, val.getNhops().intValue());
567 } catch (Exception e) {
568 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
574 protected synchronized void
575 remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
576 LOG.debug("received remove EbgpMultihop config val {}", val.getPeerIp().getValue());
577 synchronized(BgpConfigurationManager.this) {
578 BgpRouter br = getClient(yangObj);
582 String peerIp = val.getPeerIp().getValue();
584 br.delEbgpMultihop(peerIp);
585 } catch (Exception e) {
586 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
592 protected void update(InstanceIdentifier<EbgpMultihop> iid,
593 EbgpMultihop oldval, EbgpMultihop newval) {
594 LOG.error(yangObj + updWarn);
597 public void close() {
599 for (i=0 ; i < reactors.length ; i++) {
600 if (reactors[i] == EbgpMultihopReactor.class) {
604 registrations[i].close();
608 public class UpdateSourceReactor
609 extends AbstractDataChangeListener<UpdateSource>
610 implements AutoCloseable {
612 private static final String yangObj = "update-source ";
614 public UpdateSourceReactor() {
615 super(UpdateSource.class);
618 protected synchronized void
619 add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
620 LOG.debug("received add UpdateSource config val {}", val.getSourceIp().getValue());
621 synchronized(BgpConfigurationManager.this) {
622 BgpRouter br = getClient(yangObj);
626 String peerIp = val.getPeerIp().getValue();
628 br.addUpdateSource(peerIp, val.getSourceIp().getValue());
629 } catch (Exception e) {
630 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
636 protected synchronized void
637 remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
638 LOG.debug("received remove UpdateSource config val {}", val.getSourceIp().getValue());
639 synchronized(BgpConfigurationManager.this) {
640 BgpRouter br = getClient(yangObj);
644 String peerIp = val.getPeerIp().getValue();
646 br.delUpdateSource(peerIp);
647 } catch (Exception e) {
648 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
654 protected void update(InstanceIdentifier<UpdateSource> iid,
655 UpdateSource oldval, UpdateSource newval) {
656 LOG.error(yangObj + updWarn);
659 public void close() {
661 for (i=0 ; i < reactors.length ; i++) {
662 if (reactors[i] == UpdateSourceReactor.class) {
666 registrations[i].close();
670 public class AddressFamiliesReactor
671 extends AbstractDataChangeListener<AddressFamilies>
672 implements AutoCloseable {
674 private static final String yangObj = "address-families ";
676 public AddressFamiliesReactor() {
677 super(AddressFamilies.class);
680 protected synchronized void
681 add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
682 LOG.debug("received add AddressFamilies config val {}", val.getPeerIp().getValue());
683 synchronized(BgpConfigurationManager.this) {
684 BgpRouter br = getClient(yangObj);
688 String peerIp = val.getPeerIp().getValue();
689 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
690 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
692 br.addAddressFamily(peerIp, afi, safi);
693 } catch (Exception e) {
694 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
700 protected synchronized void
701 remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
702 LOG.debug("received remove AddressFamilies config val {}", val.getPeerIp().getValue());
703 synchronized(BgpConfigurationManager.this) {
704 BgpRouter br = getClient(yangObj);
708 String peerIp = val.getPeerIp().getValue();
709 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
710 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
712 br.delAddressFamily(peerIp, afi, safi);
713 } catch (Exception e) {
714 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
720 protected void update(InstanceIdentifier<AddressFamilies> iid,
721 AddressFamilies oldval, AddressFamilies newval) {
722 LOG.error(yangObj + updWarn);
725 public void close() {
727 for (i=0 ; i < reactors.length ; i++) {
728 if (reactors[i] == AddressFamiliesReactor.class) {
732 registrations[i].close();
736 public class NetworksReactor
737 extends AbstractDataChangeListener<Networks>
738 implements AutoCloseable {
740 private static final String yangObj = "networks ";
742 public NetworksReactor() {
743 super(Networks.class);
746 protected synchronized void
747 add(InstanceIdentifier<Networks> iid, Networks val) {
748 LOG.debug("received add Networks config val {}", val.getPrefixLen());
749 synchronized(BgpConfigurationManager.this) {
750 BgpRouter br = getClient(yangObj);
754 String rd = val.getRd();
755 String pfxlen = val.getPrefixLen();
756 String nh = val.getNexthop().getValue();
757 Long label = val.getLabel();
758 int lbl = (label == null) ? qbgpConstants.LBL_NO_LABEL
761 br.addPrefix(rd, pfxlen, nh, lbl);
762 } catch (Exception e) {
763 LOG.error(yangObj+"Add received exception: \""+e+"\"; "+addWarn);
768 protected synchronized void
769 remove(InstanceIdentifier<Networks> iid, Networks val) {
770 LOG.debug("received remove Networks config val {}", val.getPrefixLen());
771 synchronized(BgpConfigurationManager.this) {
772 BgpRouter br = getClient(yangObj);
776 String rd = val.getRd();
777 String pfxlen = val.getPrefixLen();
778 Long label = val.getLabel();
779 int lbl = (label == null) ? 0 : label.intValue();
780 if (rd == null && lbl > 0) {
781 //LU prefix is being deleted.
782 rd = Integer.toString(lbl);
785 br.delPrefix(rd, pfxlen);
786 } catch (Exception e) {
787 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
793 protected void update(InstanceIdentifier<Networks> iid,
794 Networks oldval, Networks newval) {
795 LOG.error(yangObj + updWarn);
798 public void close() {
800 for (i=0 ; i < reactors.length ; i++) {
801 if (reactors[i] == NetworksReactor.class) {
805 registrations[i].close();
809 public class VrfsReactor
810 extends AbstractDataChangeListener<Vrfs>
811 implements AutoCloseable {
813 private static final String yangObj = "vrfs ";
815 public VrfsReactor() {
819 protected synchronized void
820 add(InstanceIdentifier<Vrfs> iid, Vrfs val) {
821 LOG.debug("received add Vrfs config val {}", val.getRd());
822 synchronized(BgpConfigurationManager.this) {
823 BgpRouter br = getClient(yangObj);
828 br.addVrf(val.getRd(), val.getImportRts(),
830 } catch (Exception e) {
831 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
837 protected synchronized void
838 remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
839 LOG.debug("received remove Vrfs config val {}", val.getRd());
840 synchronized(BgpConfigurationManager.this) {
841 BgpRouter br = getClient(yangObj);
846 br.delVrf(val.getRd());
847 } catch (Exception e) {
848 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
854 protected void update(InstanceIdentifier<Vrfs> iid,
855 Vrfs oldval, Vrfs newval) {
856 LOG.error(yangObj + updWarn);
859 public void close() {
861 for (i=0 ; i < reactors.length ; i++) {
862 if (reactors[i] == VrfsReactor.class) {
866 registrations[i].close();
870 Future lastCleanupJob;
871 AtomicReference<Future> lastCleanupJobReference = new AtomicReference<>();
873 AtomicBoolean started = new AtomicBoolean(false);
874 public class BgpReactor
875 extends AbstractDataChangeListener<Bgp>
876 implements AutoCloseable {
878 private static final String yangObj = "Bgp ";
880 public BgpReactor() {
884 protected synchronized void
885 add(InstanceIdentifier<Bgp> iid, Bgp val) {
886 LOG.debug("received add Bgp config replaying the config");
889 } catch (Exception e) {
891 synchronized(BgpConfigurationManager.this) {
894 if (isIpAvailable(odlThriftIp)) {
897 ipActivationCheckTimer.scheduleAtFixedRate(new TimerTask() {
899 if (isIpAvailable(odlThriftIp)) {
901 ipActivationCheckTimer.cancel();
910 protected synchronized void
911 remove(InstanceIdentifier<Bgp> iid, Bgp val) {
912 LOG.debug("received remove Bgp config");
913 synchronized(BgpConfigurationManager.this) {
918 protected void update(InstanceIdentifier<Bgp> iid,
919 Bgp oldval, Bgp newval) {
920 synchronized(BgpConfigurationManager.this) {
925 public void close() {
927 for (i=0 ; i < reactors.length ; i++) {
928 if (reactors[i] == BgpReactor.class) {
932 registrations[i].close();
936 public void readOdlThriftIpForBgpCommunication() {
937 File f = new File(CLUSTER_CONF_FILE);
939 odlThriftIp = "127.0.0.1";
942 BufferedReader br = null;
944 br = new BufferedReader(new InputStreamReader(
945 new FileInputStream(f)));
946 String line = br.readLine();
947 while (line != null) {
948 if (line.contains(SDNC_BGP_MIP)) {
950 odlThriftIp = line.substring(line.lastIndexOf(" ")+1);
953 line = br.readLine();
955 } catch (Exception e) {
957 try {br.close();} catch (Exception ignore){}
961 public boolean isIpAvailable(String odlip) {
965 if ("127.0.0.1".equals(odlip)) {
968 Enumeration e = NetworkInterface.getNetworkInterfaces();
969 while(e.hasMoreElements())
971 NetworkInterface n = (NetworkInterface) e.nextElement();
972 Enumeration ee = n.getInetAddresses();
973 while (ee.hasMoreElements())
975 InetAddress i = (InetAddress) ee.nextElement();
976 if (odlip.equals(i.getHostAddress())) {
982 } catch (Exception e) {
987 public void bgpRestarted() {
989 * If there a thread which in the process of stale cleanup, cancel it
990 * and start a new thread (to avoid processing same again).
992 if (lastCleanupJobReference.get() != null) {
993 lastCleanupJobReference.get().cancel(true);
994 lastCleanupJobReference.set(null);
996 Runnable task = new Runnable() {
1000 long startTime = System.currentTimeMillis();
1001 LOG.error("started creating stale fib map ");
1002 createStaleFibMap();
1003 long endTime = System.currentTimeMillis();
1004 LOG.error("took {} msecs for stale fib map creation ", endTime - startTime);
1005 LOG.error("started bgp config replay ");
1006 startTime = endTime;
1008 endTime = System.currentTimeMillis();
1009 LOG.error("took {} msecs for bgp replay ", endTime - startTime);
1010 long route_sync_time = BGP_RESTART_ROUTE_SYNC_SEC;
1012 route_sync_time = bgpManager.getConfig().getGracefulRestart().getStalepathTime();
1013 } catch (Exception e) {
1014 LOG.error("BGP config/Stale-path time is not set");
1016 Thread.sleep(route_sync_time * 1000L);
1017 new RouteCleanup().call();
1019 } catch (Exception eCancel) {
1020 LOG.error("Stale Cleanup Task Cancelled", eCancel);
1024 lastCleanupJob = executor.submit(task);
1025 lastCleanupJobReference.set(lastCleanupJob);
1028 private static void doRouteSync() {
1029 BgpSyncHandle bsh = BgpSyncHandle.getInstance();
1030 LOG.debug("Starting BGP route sync");
1032 bgpRouter.initRibSync(bsh);
1033 } catch (Exception e) {
1034 LOG.error("Route sync aborted, exception when initialzing: "+e);
1037 while (bsh.getState() != bsh.DONE) {
1038 Routes routes = null;
1040 routes = bgpRouter.doRibSync(bsh);
1041 } catch (Exception e) {
1042 LOG.error("Route sync aborted, exception when syncing: "+e);
1045 Iterator<Update> updates = routes.getUpdatesIterator();
1046 while (updates.hasNext()) {
1047 Update u = updates.next();
1048 Map<String, Map<String, String>> stale_fib_rd_map = BgpConfigurationManager.getStaledFibEntriesMap();
1049 String rd = u.getRd();
1050 String nexthop = u.getNexthop();
1051 int label = u.getLabel();
1052 String prefix = u.getPrefix();
1053 int plen = u.getPrefixlen();
1054 onUpdatePushRoute(rd, prefix, plen, nexthop, label);
1058 LOG.debug("Ending BGP route-sync");
1059 bgpRouter.endRibSync(bsh);
1060 } catch (Exception e) {
1064 /* onUpdatePushRoute
1065 * Get Stale fib map, and compare current route/fib entry.
1066 * - Entry compare shall include NextHop, Label.
1067 * - If entry matches: delete from STALE Map. NO Change to FIB Config DS.
1068 * - If entry nor found, add to FIB Config DS.
1069 * - If entry found, but either Label/NextHop doesnt match.
1070 * - Update FIB Config DS with modified values.
1071 * - delete from Stale Map.
1073 public static void onUpdatePushRoute(String rd, String prefix, int plen,
1074 String nexthop, int label) {
1075 Map<String, Map<String, String>> stale_fib_rd_map = BgpConfigurationManager.getStaledFibEntriesMap();
1076 boolean addroute = false;
1077 if (!stale_fib_rd_map.isEmpty()) {
1078 // restart Scenario, as MAP is not empty.
1079 Map<String, String> map = stale_fib_rd_map.get(rd);
1081 String nexthoplabel = map.get(prefix + "/" + plen);
1082 if (null == nexthoplabel) {
1083 // New Entry, which happend to be added during restart.
1086 map.remove(prefix + "/" + plen);
1087 if (isRouteModified(nexthop, label, nexthoplabel)) {
1088 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix,
1089 plen, nexthop, label);
1090 // Existing entry, where in Nexthop/Label got modified during restart
1096 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix,
1097 plen, nexthop, label);
1101 fib.addFibEntryToDS(rd, prefix + "/" + plen,
1106 private static boolean isRouteModified(String nexthop, int label, String nexthoplabel) {
1107 return !nexthoplabel.isEmpty() && !nexthoplabel.equals(nexthop+"/"+label);
1110 static private void replayNbrConfig(List<Neighbors> n, BgpRouter br) {
1111 for (Neighbors nbr : n) {
1113 br.addNeighbor(nbr.getAddress().getValue(),
1114 nbr.getRemoteAs().intValue());
1115 //itmProvider.buildTunnelsToDCGW(new IpAddress(nbr.getAddress().getValue().toCharArray()));
1116 } catch (Exception e) {
1117 LOG.error("Replay:addNbr() received exception: \""+e+"\"");
1120 EbgpMultihop en = nbr.getEbgpMultihop();
1123 br.addEbgpMultihop(en.getPeerIp().getValue(),
1124 en.getNhops().intValue());
1125 } catch (Exception e) {
1126 LOG.error("Replay:addEBgp() received exception: \""+e+"\"");
1129 UpdateSource us = nbr.getUpdateSource();
1132 br.addUpdateSource(us.getPeerIp().getValue(),
1133 us.getSourceIp().getValue());
1134 } catch (Exception e) {
1135 LOG.error("Replay:addUS() received exception: \""+e+"\"");
1138 List<AddressFamilies> afs = nbr.getAddressFamilies();
1140 for (AddressFamilies af : afs) {
1141 af_afi afi = af_afi.findByValue(af.getAfi().intValue());
1142 af_safi safi = af_safi.findByValue(af.getSafi().intValue());
1144 br.addAddressFamily(af.getPeerIp().getValue(), afi, safi);
1145 } catch (Exception e) {
1146 LOG.error("Replay:addAf() received exception: \""+e+"\"");
1153 public static String getConfigHost() {
1154 if (config == null) {
1155 return cHostStartup;
1157 ConfigServer ts = config.getConfigServer();
1158 return (ts == null ? cHostStartup : ts.getHost().getValue());
1161 public static int getConfigPort() {
1162 if (config == null) {
1163 return Integer.parseInt(cPortStartup);
1165 ConfigServer ts = config.getConfigServer();
1166 return (ts == null ? Integer.parseInt(cPortStartup) :
1167 ts.getPort().intValue());
1170 public static synchronized void replay() {
1171 String host = getConfigHost();
1172 int port = getConfigPort();
1173 boolean res = bgpRouter.connect(host, port);
1175 String msg = "Cannot connect to BGP config server at "+host+":"+port;
1176 if (config != null) {
1177 msg += "; Configuration Replay aborted";
1182 if (config == null) {
1185 BgpRouter br = bgpRouter;
1186 AsId a = config.getAsId();
1190 int asNum = a.getLocalAs().intValue();
1191 Ipv4Address routerId = a.getRouterId();
1192 Long spt = a.getStalepathTime();
1193 Boolean afb = a.isAnnounceFbit();
1194 String rid = (routerId == null) ? "" : routerId.getValue();
1195 int stalepathTime = (spt == null) ? 90 : spt.intValue();
1196 boolean announceFbit = (afb == null) ? false : afb.booleanValue();
1198 br.startBgp(asNum, rid, stalepathTime, announceFbit);
1199 } catch (BgpRouterException bre) {
1200 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
1203 LOG.error("Replay: startBgp() received exception: \""
1204 +bre+"\"; "+addWarn);
1206 } catch (Exception e) {
1207 //not unusual. We may have restarted & BGP is already on
1208 LOG.error("Replay:startBgp() received exception: \""+e+"\"");
1211 if (bgpManager.getBgpCounters() == null) {
1212 bgpManager.startBgpCountersTask();
1215 Logging l = config.getLogging();
1218 br.setLogging(l.getFile(), l.getLevel());
1219 } catch (Exception e) {
1220 LOG.error("Replay:setLogging() received exception: \""+e+"\"");
1224 GracefulRestart g = config.getGracefulRestart();
1227 br.addGracefulRestart(g.getStalepathTime().intValue());
1228 } catch (Exception e) {
1229 LOG.error("Replay:addGr() received exception: \""+e+"\"");
1233 List<Neighbors> n = config.getNeighbors();
1235 replayNbrConfig(n, br);
1238 List<Vrfs> v = config.getVrfs();
1240 for (Vrfs vrf : v) {
1242 br.addVrf(vrf.getRd(), vrf.getImportRts(),
1243 vrf.getExportRts());
1244 } catch (Exception e) {
1245 LOG.error("Replay:addVrf() received exception: \""+e+"\"");
1250 List<Networks> ln = config.getNetworks();
1252 for (Networks net : ln) {
1253 String rd = net.getRd();
1254 String pfxlen = net.getPrefixLen();
1255 String nh = net.getNexthop().getValue();
1256 Long label = net.getLabel();
1257 int lbl = (label == null) ? 0 : label.intValue();
1258 if (rd == null && lbl > 0) {
1259 //LU prefix is being deleted.
1260 rd = Integer.toString(lbl);
1263 br.addPrefix(rd, pfxlen, nh, lbl);
1264 } catch (Exception e) {
1265 LOG.error("Replay:addPfx() received exception: \""+e+"\"");
1271 private <T extends DataObject> void update(InstanceIdentifier<T> iid, T dto) {
1272 BgpUtil.update(broker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1275 private <T extends DataObject> void asyncWrite(InstanceIdentifier<T> iid, T dto) {
1276 BgpUtil.write(broker,LogicalDatastoreType.CONFIGURATION,iid,dto);
1279 private <T extends DataObject> void delete(InstanceIdentifier<T> iid) {
1280 BgpUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, iid);
1283 public synchronized void
1284 startConfig(String bgpHost, int thriftPort) {
1285 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1286 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1287 InstanceIdentifier<ConfigServer> iid = iib.build();
1288 Ipv4Address ipAddr = new Ipv4Address(bgpHost);
1289 ConfigServer dto = new ConfigServerBuilder().setHost(ipAddr)
1290 .setPort((long) thriftPort).build();
1294 public synchronized void
1295 startBgp(int as, String routerId, int spt, boolean fbit) {
1296 Long localAs = (long) as;
1297 Ipv4Address rid = (routerId == null) ?
1298 null : new Ipv4Address(routerId);
1299 Long staleTime = (long) spt;
1300 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1301 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1302 InstanceIdentifier<AsId> iid = iib.build();
1303 AsId dto = new AsIdBuilder().setLocalAs(localAs)
1305 .setStalepathTime(staleTime)
1306 .setAnnounceFbit(fbit).build();
1310 public synchronized void
1311 addLogging(String fileName, String logLevel) {
1312 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1313 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1314 InstanceIdentifier<Logging> iid = iib.build();
1315 Logging dto = new LoggingBuilder().setFile(fileName)
1316 .setLevel(logLevel).build();
1320 public synchronized void
1321 addGracefulRestart(int staleTime) {
1322 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1323 InstanceIdentifier.builder(Bgp.class).child(GracefulRestart.class);
1324 InstanceIdentifier<GracefulRestart> iid = iib.build();
1325 GracefulRestart dto = new GracefulRestartBuilder()
1326 .setStalepathTime((long)staleTime).build();
1330 public synchronized void
1331 addNeighbor(String nbrIp, int remoteAs) {
1332 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1333 Long rAs = (long) remoteAs;
1334 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1335 InstanceIdentifier.builder(Bgp.class)
1336 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1337 InstanceIdentifier<Neighbors> iid = iib.build();
1338 Neighbors dto = new NeighborsBuilder().setAddress(nbrAddr)
1339 .setRemoteAs(rAs).build();
1343 public synchronized void
1344 addUpdateSource(String nbrIp, String srcIp) {
1345 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1346 Ipv4Address srcAddr = new Ipv4Address(srcIp);
1347 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1348 InstanceIdentifier.builder(Bgp.class)
1349 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1350 .child(UpdateSource.class);
1351 InstanceIdentifier<UpdateSource> iid = iib.build();
1352 UpdateSource dto = new UpdateSourceBuilder().setPeerIp(nbrAddr)
1353 .setSourceIp(srcAddr).build();
1357 public synchronized void
1358 addEbgpMultihop(String nbrIp, int nHops) {
1359 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1360 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1361 InstanceIdentifier.builder(Bgp.class)
1362 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1363 .child(EbgpMultihop.class);
1364 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1365 EbgpMultihop dto = new EbgpMultihopBuilder().setPeerIp(nbrAddr)
1366 .setNhops((long)nHops).build();
1370 public synchronized void
1371 addAddressFamily(String nbrIp, int afi, int safi) {
1372 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1373 Long a = (long) afi;
1374 Long sa = (long) safi;
1375 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1376 InstanceIdentifier.builder(Bgp.class)
1377 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1378 .child(AddressFamilies.class, new AddressFamiliesKey(a, sa));
1379 InstanceIdentifier<AddressFamilies> iid = iib.build();
1380 AddressFamilies dto = new AddressFamiliesBuilder().setPeerIp(nbrAddr)
1381 .setAfi(a).setSafi(sa).build();
1385 public synchronized void
1386 addPrefix(String rd, String pfx, String nh, int lbl) {
1387 Ipv4Address nexthop = new Ipv4Address(nh);
1388 Long label = (long) lbl;
1389 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
1390 InstanceIdentifier.builder(Bgp.class)
1391 .child(Networks.class, new NetworksKey(pfx, rd));
1392 InstanceIdentifier<Networks> iid = iib.build();
1393 Networks dto = new NetworksBuilder().setRd(rd)
1395 .setNexthop(nexthop)
1396 .setLabel(label).build();
1400 public synchronized void
1401 addVrf(String rd, List<String> irts, List<String> erts) {
1402 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1403 InstanceIdentifier.builder(Bgp.class)
1404 .child(Vrfs.class, new VrfsKey(rd));
1405 InstanceIdentifier<Vrfs> iid = iib.build();
1406 Vrfs dto = new VrfsBuilder().setRd(rd)
1408 .setExportRts(erts).build();
1410 asyncWrite(iid, dto);
1413 public synchronized void stopConfig() {
1414 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1415 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1416 InstanceIdentifier<ConfigServer> iid = iib.build();
1420 public synchronized void stopBgp() {
1421 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1422 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1423 InstanceIdentifier<AsId> iid = iib.build();
1427 public synchronized void delLogging() {
1428 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1429 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1430 InstanceIdentifier<Logging> iid = iib.build();
1434 public synchronized void delGracefulRestart() {
1435 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1436 InstanceIdentifier.builder(Bgp.class)
1437 .child(GracefulRestart.class);
1438 InstanceIdentifier<GracefulRestart> iid = iib.build();
1442 public synchronized void delNeighbor(String nbrIp) {
1443 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1444 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1445 InstanceIdentifier.builder(Bgp.class)
1446 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1447 InstanceIdentifier<Neighbors> iid = iib.build();
1451 public synchronized void delUpdateSource(String nbrIp) {
1452 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1453 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1454 InstanceIdentifier.builder(Bgp.class)
1455 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1456 .child(UpdateSource.class);
1457 InstanceIdentifier<UpdateSource> iid = iib.build();
1461 public synchronized void delEbgpMultihop(String nbrIp) {
1462 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1463 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1464 InstanceIdentifier.builder(Bgp.class)
1465 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1466 .child(EbgpMultihop.class);
1467 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1471 public synchronized void
1472 delAddressFamily(String nbrIp, int afi, int safi) {
1473 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1474 Long a = (long) afi;
1475 Long sa = (long) safi;
1476 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1477 InstanceIdentifier.builder(Bgp.class)
1478 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1479 .child(AddressFamilies.class, new AddressFamiliesKey(a, sa));
1480 InstanceIdentifier<AddressFamilies> iid = iib.build();
1484 public synchronized void delPrefix(String rd, String pfx) {
1485 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
1486 InstanceIdentifier.builder(Bgp.class)
1487 .child(Networks.class, new NetworksKey(pfx, rd));
1488 InstanceIdentifier<Networks> iid = iib.build();
1492 public synchronized void delVrf(String rd) {
1493 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1494 InstanceIdentifier.builder(Bgp.class)
1495 .child(Vrfs.class, new VrfsKey(rd));
1496 InstanceIdentifier<Vrfs> iid = iib.build();
1500 static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
1502 * Remove Stale Marked Routes after timer expiry.
1504 class RouteCleanup implements Callable<Integer> {
1506 public Integer call () {
1507 int totalCleared = 0;
1509 if (staledFibEntriesMap.isEmpty()) {
1510 LOG.info("BGP: RouteCleanup timertask tirggered but STALED FIB MAP is EMPTY");
1512 for (String rd : staledFibEntriesMap.keySet()) {
1513 if (Thread.interrupted()) {
1516 Map<String, String> map = staledFibEntriesMap.get(rd);
1518 for (String prefix : map.keySet()) {
1519 if (Thread.interrupted()) {
1524 bgpManager.deletePrefix(rd, prefix);
1525 } catch (Exception e) {
1526 LOG.error("BGP: RouteCleanup deletePrefix failed rd:{}, prefix{}" + rd.toString() + prefix);
1532 } catch(Exception e) {
1533 LOG.error("Cleanup Thread Got interrupted, Failed to cleanup stale routes ", e);
1535 staledFibEntriesMap.clear();
1537 LOG.error("cleared {} stale routes after bgp restart", totalCleared);
1543 * BGP restart scenario, ODL-BGP manager was/is running.
1544 * On re-sync notification, Get a copy of FIB database.
1546 public static void createStaleFibMap() {
1547 int totalStaledCount = 0;
1549 staledFibEntriesMap.clear();
1550 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
1551 DataBroker db = BgpUtil.getBroker();
1553 LOG.error("Couldn't find BgpUtil broker while creating createStaleFibMap");
1557 Optional<FibEntries> fibEntries = BgpUtil.read(BgpUtil.getBroker(),
1558 LogicalDatastoreType.CONFIGURATION, id);
1559 if (fibEntries.isPresent()) {
1560 List<VrfTables> stale_vrfTables = fibEntries.get().getVrfTables();
1561 for (VrfTables vrfTable : stale_vrfTables) {
1562 Map<String, String> stale_fib_ent_map = new HashMap<>();
1563 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
1564 if (Thread.interrupted()) {
1568 //Create MAP from stale_vrfTables.
1569 stale_fib_ent_map.put(vrfEntry.getDestPrefix(), vrfEntry.getNextHopAddress() + "/" + vrfEntry.getLabel());
1571 staledFibEntriesMap.put(vrfTable.getRouteDistinguisher(), stale_fib_ent_map);
1574 LOG.error("createStaleFibMap:: FIBentries.class is not present");
1576 } catch (Exception e) {
1577 LOG.error("createStaleFibMap:: erorr ", e);
1579 LOG.error("created {} staled entries ", totalStaledCount);
1582 //map<rd, map<prefix/len, nexthop/label>>
1583 public static Map<String, Map<String, String>> getStaledFibEntriesMap() {
1584 return staledFibEntriesMap;