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.netvirt.bgpmanager.thrift.client.BgpRouter;
31 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouterException;
32 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpSyncHandle;
33 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Routes;
34 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Update;
35 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
36 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
37 import org.opendaylight.netvirt.bgpmanager.thrift.gen.qbgpConstants;
38 import org.opendaylight.netvirt.bgpmanager.thrift.server.BgpThriftService;
39 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.*;
40 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.*;
41 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.*;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.*;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
46 import org.opendaylight.yangtools.concepts.ListenerRegistration;
47 import org.opendaylight.yangtools.yang.binding.DataObject;
48 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
49 import org.osgi.framework.Bundle;
50 import org.osgi.framework.BundleContext;
51 import org.osgi.framework.FrameworkUtil;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 public class BgpConfigurationManager {
56 private static final Logger LOG =
57 LoggerFactory.getLogger(BgpConfigurationManager.class);
58 private static DataBroker broker;
59 private static FibDSWriter fib;
60 private boolean restarting = false;
61 private static Bgp config;
62 private static BgpRouter bgpRouter;
63 private static BgpThriftService updateServer;
65 private static final String DEF_LOGFILE = "/var/log/bgp_debug.log";
66 private static final String DEF_LOGLEVEL = "errors";
67 private static final String UPDATE_PORT = "bgp.thrift.service.port";
68 private static final String CONFIG_HOST = "vpnservice.bgpspeaker.host.name";
69 private static final String CONFIG_PORT = "vpnservice.bgpspeaker.thrift.port";
70 private static final String DEF_UPORT = "7744";
71 private static final String DEF_CHOST = "127.0.0.1";
72 private static final String DEF_CPORT = "7644";
73 private static final String SDNC_BGP_MIP = "sdnc_bgp_mip";
74 private static final String CLUSTER_CONF_FILE = "/cluster/etc/cluster.conf";
75 private static final Timer ipActivationCheckTimer = new Timer();
77 // to have stale FIB map (RD, Prefix)
78 // number of seconds wait for route sync-up between ODL and BGP.
79 private static final int BGP_RESTART_ROUTE_SYNC_SEC = 360;
81 static String odlThriftIp = "127.0.0.1";
82 private static String cHostStartup;
83 private static String cPortStartup;
84 private static CountDownLatch initer = new CountDownLatch(1);
85 //static IITMProvider itmProvider;
86 public static BgpManager bgpManager;
87 //map<rd, map<prefix/len, nexthop/label>>
88 private static Map<String, Map<String, String>> staledFibEntriesMap = new ConcurrentHashMap<>();
90 private static final Class[] reactors =
92 ConfigServerReactor.class, AsIdReactor.class,
93 GracefulRestartReactor.class, LoggingReactor.class,
94 NeighborsReactor.class, UpdateSourceReactor.class,
95 EbgpMultihopReactor.class, AddressFamiliesReactor.class,
96 NetworksReactor.class, VrfsReactor.class, BgpReactor.class
99 private ListenerRegistration<DataChangeListener>[] registrations;
101 private Object createListener(Class<?> cls) {
106 ctor= cls.getConstructor(BgpConfigurationManager.class);
107 obj = ctor.newInstance(this);
108 } catch (Exception e) {
109 LOG.error("Failed to create listener object", e);
114 private void registerCallbacks() {
115 String emsg = "Failed to register listener";
116 registrations = (ListenerRegistration<DataChangeListener>[])
117 new ListenerRegistration[reactors.length];
118 InstanceIdentifier<?> iid = InstanceIdentifier.create(Bgp.class);
119 for (int i = 0; i < reactors.length; i++) {
120 DataChangeListener dcl =
121 (DataChangeListener) createListener(reactors[i]);
122 String dclName = dcl.getClass().getName();
124 registrations[i] = broker.registerDataChangeListener(
125 LogicalDatastoreType.CONFIGURATION,
126 iid, dcl, DataChangeScope.SUBTREE);
127 } catch (Exception e) {
129 throw new IllegalStateException(emsg+" "+dclName, e);
134 public void close() {
135 if (updateServer != null) {
140 private boolean configExists() {
141 InstanceIdentifier.InstanceIdentifierBuilder<Bgp> iib =
142 InstanceIdentifier.builder(Bgp.class);
143 InstanceIdentifier<Bgp> iid = iib.build();
144 Optional<Bgp> b = BgpUtil.read(broker,
145 LogicalDatastoreType.CONFIGURATION, iid);
146 return b.isPresent();
149 private String getProperty(String var, String def) {
150 Bundle b = FrameworkUtil.getBundle(BgpManager.class);
154 BundleContext context = b.getBundleContext();
155 if (context == null) {
158 String s = context.getProperty(var);
159 return (s == null ? def : s);
162 public BgpConfigurationManager(BgpManager bgpMgr) {
163 broker = bgpMgr.getBroker();
164 fib = bgpMgr.getFibWriter();
165 //itmProvider = bgpMgr.getItmProvider();
166 // there must be a good way to detect that we're restarting.
167 // but for now infer it from the existance of config
168 restarting = configExists();
170 bgpRouter = BgpRouter.getInstance();
171 String uPort = getProperty(UPDATE_PORT, DEF_UPORT);
172 cHostStartup = getProperty(CONFIG_HOST, DEF_CHOST);
173 cPortStartup = getProperty(CONFIG_PORT, DEF_CPORT);
174 VtyshCli.setHostAddr(cHostStartup);
175 ClearBgpCli.setHostAddr(cHostStartup);
176 LOG.info("UpdateServer at localhost:"+uPort+" ConfigServer at "
177 +cHostStartup+":"+cPortStartup);
178 updateServer = new BgpThriftService(Integer.parseInt(uPort), bgpMgr);
179 updateServer.start();
180 readOdlThriftIpForBgpCommunication();
183 // this shouldn't be done. config client must connect in
184 // response to config; but connecting at startup to a default
185 // host is legacy behavior.
187 bgpRouter.connect(cHostStartup, Integer.parseInt(cPortStartup));
189 LOG.info("BGP Configuration manager initialized");
197 private static final String addWarn =
198 "Config store updated; undo with Delete if needed.";
199 private static final String delWarn =
200 "Config store updated; undo with Add if needed.";
201 private static final String updWarn =
202 "Update operation not supported; Config store updated;"
203 +" restore with another Update if needed.";
205 public class ConfigServerReactor
206 extends AbstractDataChangeListener<ConfigServer>
207 implements AutoCloseable {
208 private static final String yangObj = "config-server ";
209 public ConfigServerReactor() {
210 super(ConfigServer.class);
213 protected synchronized void
214 add(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
215 LOG.debug("received bgp connect config host {}", val.getHost().getValue());
218 } catch (Exception e) {
220 LOG.debug("issueing bgp router connect to host {}", val.getHost().getValue());
221 synchronized(BgpConfigurationManager.this) {
222 boolean res = bgpRouter.connect(val.getHost().getValue(),
223 val.getPort().intValue());
225 LOG.error(yangObj + "Add failed; "+addWarn);
230 protected synchronized void
231 remove(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
232 LOG.debug("received bgp disconnect");
233 synchronized(BgpConfigurationManager.this) {
234 bgpRouter.disconnect();
238 protected void update(InstanceIdentifier<ConfigServer> iid,
239 ConfigServer oldval, ConfigServer newval) {
240 LOG.error(yangObj + updWarn);
243 public void close() {
245 for (i=0 ; i < reactors.length ; i++) {
246 if (reactors[i] == ConfigServerReactor.class) {
250 registrations[i].close();
254 private BgpRouter getClient(String yangObj) {
255 if (bgpRouter == null) {
256 LOG.warn(yangObj+": configuration received when BGP is inactive");
261 public class AsIdReactor
262 extends AbstractDataChangeListener<AsId>
263 implements AutoCloseable {
265 private static final String yangObj = "as-id ";
267 public AsIdReactor() {
271 protected synchronized void
272 add(InstanceIdentifier<AsId> iid, AsId val) {
273 LOG.debug("received add router config asNum {}", val.getLocalAs().intValue());
274 synchronized(BgpConfigurationManager.this) {
275 BgpRouter br = getClient(yangObj);
279 int asNum = val.getLocalAs().intValue();
280 Ipv4Address routerId = val.getRouterId();
281 Long spt = val.getStalepathTime();
282 Boolean afb = val.isAnnounceFbit();
283 String rid = (routerId == null) ? "" : routerId.getValue();
284 int stalepathTime = (spt == null) ? 90 : spt.intValue();
285 boolean announceFbit = (afb == null) ? false : afb.booleanValue();
287 br.startBgp(asNum, rid, stalepathTime, announceFbit);
288 if (bgpManager.getBgpCounters() == null) {
289 bgpManager.startBgpCountersTask();
291 } catch (BgpRouterException bre) {
292 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
293 LOG.error(yangObj+"Add requested when BGP is already active");
295 LOG.error(yangObj+"Add received exception: \""
296 +bre+"\"; "+addWarn);
298 } catch (Exception e) {
299 LOG.error(yangObj+"Add received exception: \""+e+"\"; "+addWarn);
304 protected synchronized void
305 remove(InstanceIdentifier<AsId> iid, AsId val) {
306 LOG.debug("received delete router config asNum {}", val.getLocalAs().intValue());
307 synchronized(BgpConfigurationManager.this) {
308 BgpRouter br = getClient(yangObj);
312 int asNum = val.getLocalAs().intValue();
315 } catch (Exception e) {
316 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "+delWarn);
318 if (bgpManager.getBgpCounters() != null) {
319 bgpManager.stopBgpCountersTask();
324 protected void update(InstanceIdentifier<AsId> iid,
325 AsId oldval, AsId newval) {
326 LOG.error(yangObj + updWarn);
329 public void close() {
331 for (i=0 ; i < reactors.length ; i++) {
332 if (reactors[i] == AsIdReactor.class) {
336 registrations[i].close();
340 public class GracefulRestartReactor
341 extends AbstractDataChangeListener<GracefulRestart>
342 implements AutoCloseable {
344 private static final String yangObj = "graceful-restart ";
346 public GracefulRestartReactor() {
347 super(GracefulRestart.class);
350 protected synchronized void
351 add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
352 synchronized(BgpConfigurationManager.this) {
353 BgpRouter br = getClient(yangObj);
358 br.addGracefulRestart(val.getStalepathTime().intValue());
359 } catch (Exception e) {
360 LOG.error(yangObj+"Add received exception: \""+e+"\"; "+addWarn);
365 protected synchronized void
366 remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
367 LOG.debug("received delete GracefulRestart config val {}", val.getStalepathTime().intValue());
368 synchronized(BgpConfigurationManager.this) {
369 BgpRouter br = getClient(yangObj);
374 br.delGracefulRestart();
375 } catch (Exception e) {
376 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
382 protected void update(InstanceIdentifier<GracefulRestart> iid,
383 GracefulRestart oldval, GracefulRestart newval) {
384 LOG.debug("received update GracefulRestart config val {}", newval.getStalepathTime().intValue());
385 synchronized(BgpConfigurationManager.this) {
386 BgpRouter br = getClient(yangObj);
391 br.addGracefulRestart(newval.getStalepathTime().intValue());
392 } catch (Exception e) {
393 LOG.error(yangObj+"update received exception: \""+e+"\"; "+addWarn);
398 public void close() {
400 for (i=0 ; i < reactors.length ; i++) {
401 if (reactors[i] == GracefulRestartReactor.class) {
405 registrations[i].close();
409 public class LoggingReactor
410 extends AbstractDataChangeListener<Logging>
411 implements AutoCloseable {
413 private static final String yangObj = "logging ";
415 public LoggingReactor() {
416 super(Logging.class);
419 protected synchronized void
420 add(InstanceIdentifier<Logging> iid, Logging val) {
421 synchronized(BgpConfigurationManager.this) {
422 BgpRouter br = getClient(yangObj);
427 br.setLogging(val.getFile(),val.getLevel());
428 } catch (Exception e) {
429 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
435 protected synchronized void
436 remove(InstanceIdentifier<Logging> iid, Logging val) {
437 LOG.debug("received remove Logging config val {}", val.getLevel());
438 synchronized(BgpConfigurationManager.this) {
439 BgpRouter br = getClient(yangObj);
444 br.setLogging(DEF_LOGFILE, DEF_LOGLEVEL);
445 } catch (Exception e) {
446 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
452 protected void update(InstanceIdentifier<Logging> iid,
453 Logging oldval, Logging newval) {
454 synchronized(BgpConfigurationManager.this) {
455 BgpRouter br = getClient(yangObj);
460 br.setLogging(newval.getFile(),newval.getLevel());
461 } catch (Exception e) {
462 LOG.error(yangObj+"newval received exception: \""+e+"\"; "
468 public void close() {
470 for (i=0 ; i < reactors.length ; i++) {
471 if (reactors[i] == LoggingReactor.class) {
475 registrations[i].close();
479 public class NeighborsReactor
480 extends AbstractDataChangeListener<Neighbors>
481 implements AutoCloseable {
483 private static final String yangObj = "neighbors ";
485 public NeighborsReactor() {
486 super(Neighbors.class);
489 protected synchronized void
490 add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
491 LOG.debug("received add Neighbors config val {}", val.getAddress().getValue());
492 synchronized(BgpConfigurationManager.this) {
493 BgpRouter br = getClient(yangObj);
497 String peerIp = val.getAddress().getValue();
498 int as = val.getRemoteAs().intValue();
500 //itmProvider.buildTunnelsToDCGW(new IpAddress(peerIp.toCharArray()));
501 br.addNeighbor(peerIp, as);
503 } catch (Exception e) {
504 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
510 protected synchronized void
511 remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
512 LOG.debug("received remove Neighbors config val {}", val.getAddress().getValue());
513 synchronized(BgpConfigurationManager.this) {
514 BgpRouter br = getClient(yangObj);
518 String peerIp = val.getAddress().getValue();
520 //itmProvider.deleteTunnelsToDCGW(new IpAddress(val.getAddress().getValue().toCharArray()));
521 br.delNeighbor(peerIp);
522 } catch (Exception e) {
523 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
529 protected void update(InstanceIdentifier<Neighbors> iid,
530 Neighbors oldval, Neighbors newval) {
531 //purposefully nothing to do.
534 public void close() {
536 for (i=0 ; i < reactors.length ; i++) {
537 if (reactors[i] == NeighborsReactor.class) {
541 registrations[i].close();
545 public class EbgpMultihopReactor
546 extends AbstractDataChangeListener<EbgpMultihop>
547 implements AutoCloseable {
549 private static final String yangObj = "ebgp-multihop ";
551 public EbgpMultihopReactor() {
552 super(EbgpMultihop.class);
555 protected synchronized void
556 add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
557 LOG.debug("received add EbgpMultihop config val {}", val.getPeerIp().getValue());
558 synchronized(BgpConfigurationManager.this) {
559 BgpRouter br = getClient(yangObj);
563 String peerIp = val.getPeerIp().getValue();
565 br.addEbgpMultihop(peerIp, val.getNhops().intValue());
566 } catch (Exception e) {
567 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
573 protected synchronized void
574 remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
575 LOG.debug("received remove EbgpMultihop config val {}", val.getPeerIp().getValue());
576 synchronized(BgpConfigurationManager.this) {
577 BgpRouter br = getClient(yangObj);
581 String peerIp = val.getPeerIp().getValue();
583 br.delEbgpMultihop(peerIp);
584 } catch (Exception e) {
585 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
591 protected void update(InstanceIdentifier<EbgpMultihop> iid,
592 EbgpMultihop oldval, EbgpMultihop newval) {
593 LOG.error(yangObj + updWarn);
596 public void close() {
598 for (i=0 ; i < reactors.length ; i++) {
599 if (reactors[i] == EbgpMultihopReactor.class) {
603 registrations[i].close();
607 public class UpdateSourceReactor
608 extends AbstractDataChangeListener<UpdateSource>
609 implements AutoCloseable {
611 private static final String yangObj = "update-source ";
613 public UpdateSourceReactor() {
614 super(UpdateSource.class);
617 protected synchronized void
618 add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
619 LOG.debug("received add UpdateSource config val {}", val.getSourceIp().getValue());
620 synchronized(BgpConfigurationManager.this) {
621 BgpRouter br = getClient(yangObj);
625 String peerIp = val.getPeerIp().getValue();
627 br.addUpdateSource(peerIp, val.getSourceIp().getValue());
628 } catch (Exception e) {
629 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
635 protected synchronized void
636 remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
637 LOG.debug("received remove UpdateSource config val {}", val.getSourceIp().getValue());
638 synchronized(BgpConfigurationManager.this) {
639 BgpRouter br = getClient(yangObj);
643 String peerIp = val.getPeerIp().getValue();
645 br.delUpdateSource(peerIp);
646 } catch (Exception e) {
647 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
653 protected void update(InstanceIdentifier<UpdateSource> iid,
654 UpdateSource oldval, UpdateSource newval) {
655 LOG.error(yangObj + updWarn);
658 public void close() {
660 for (i=0 ; i < reactors.length ; i++) {
661 if (reactors[i] == UpdateSourceReactor.class) {
665 registrations[i].close();
669 public class AddressFamiliesReactor
670 extends AbstractDataChangeListener<AddressFamilies>
671 implements AutoCloseable {
673 private static final String yangObj = "address-families ";
675 public AddressFamiliesReactor() {
676 super(AddressFamilies.class);
679 protected synchronized void
680 add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
681 LOG.debug("received add AddressFamilies config val {}", val.getPeerIp().getValue());
682 synchronized(BgpConfigurationManager.this) {
683 BgpRouter br = getClient(yangObj);
687 String peerIp = val.getPeerIp().getValue();
688 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
689 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
691 br.addAddressFamily(peerIp, afi, safi);
692 } catch (Exception e) {
693 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
699 protected synchronized void
700 remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
701 LOG.debug("received remove AddressFamilies config val {}", val.getPeerIp().getValue());
702 synchronized(BgpConfigurationManager.this) {
703 BgpRouter br = getClient(yangObj);
707 String peerIp = val.getPeerIp().getValue();
708 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
709 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
711 br.delAddressFamily(peerIp, afi, safi);
712 } catch (Exception e) {
713 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
719 protected void update(InstanceIdentifier<AddressFamilies> iid,
720 AddressFamilies oldval, AddressFamilies newval) {
721 LOG.error(yangObj + updWarn);
724 public void close() {
726 for (i=0 ; i < reactors.length ; i++) {
727 if (reactors[i] == AddressFamiliesReactor.class) {
731 registrations[i].close();
735 public class NetworksReactor
736 extends AbstractDataChangeListener<Networks>
737 implements AutoCloseable {
739 private static final String yangObj = "networks ";
741 public NetworksReactor() {
742 super(Networks.class);
745 protected synchronized void
746 add(InstanceIdentifier<Networks> iid, Networks val) {
747 LOG.debug("received add Networks config val {}", val.getPrefixLen());
748 synchronized(BgpConfigurationManager.this) {
749 BgpRouter br = getClient(yangObj);
753 String rd = val.getRd();
754 String pfxlen = val.getPrefixLen();
755 String nh = val.getNexthop().getValue();
756 Long label = val.getLabel();
757 int lbl = (label == null) ? qbgpConstants.LBL_NO_LABEL
760 br.addPrefix(rd, pfxlen, nh, lbl);
761 } catch (Exception e) {
762 LOG.error(yangObj+"Add received exception: \""+e+"\"; "+addWarn);
767 protected synchronized void
768 remove(InstanceIdentifier<Networks> iid, Networks val) {
769 LOG.debug("received remove Networks config val {}", val.getPrefixLen());
770 synchronized(BgpConfigurationManager.this) {
771 BgpRouter br = getClient(yangObj);
775 String rd = val.getRd();
776 String pfxlen = val.getPrefixLen();
777 Long label = val.getLabel();
778 int lbl = (label == null) ? 0 : label.intValue();
779 if (rd == null && lbl > 0) {
780 //LU prefix is being deleted.
781 rd = Integer.toString(lbl);
784 br.delPrefix(rd, pfxlen);
785 } catch (Exception e) {
786 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
792 protected void update(InstanceIdentifier<Networks> iid,
793 Networks oldval, Networks newval) {
794 LOG.error(yangObj + updWarn);
797 public void close() {
799 for (i=0 ; i < reactors.length ; i++) {
800 if (reactors[i] == NetworksReactor.class) {
804 registrations[i].close();
808 public class VrfsReactor
809 extends AbstractDataChangeListener<Vrfs>
810 implements AutoCloseable {
812 private static final String yangObj = "vrfs ";
814 public VrfsReactor() {
818 protected synchronized void
819 add(InstanceIdentifier<Vrfs> iid, Vrfs val) {
820 LOG.debug("received add Vrfs config val {}", val.getRd());
821 synchronized(BgpConfigurationManager.this) {
822 BgpRouter br = getClient(yangObj);
827 br.addVrf(val.getRd(), val.getImportRts(),
829 } catch (Exception e) {
830 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
836 protected synchronized void
837 remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
838 LOG.debug("received remove Vrfs config val {}", val.getRd());
839 synchronized(BgpConfigurationManager.this) {
840 BgpRouter br = getClient(yangObj);
845 br.delVrf(val.getRd());
846 } catch (Exception e) {
847 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
853 protected void update(InstanceIdentifier<Vrfs> iid,
854 Vrfs oldval, Vrfs newval) {
855 LOG.error(yangObj + updWarn);
858 public void close() {
860 for (i=0 ; i < reactors.length ; i++) {
861 if (reactors[i] == VrfsReactor.class) {
865 registrations[i].close();
869 Future lastCleanupJob;
870 AtomicReference<Future> lastCleanupJobReference = new AtomicReference<>();
872 AtomicBoolean started = new AtomicBoolean(false);
873 public class BgpReactor
874 extends AbstractDataChangeListener<Bgp>
875 implements AutoCloseable {
877 private static final String yangObj = "Bgp ";
879 public BgpReactor() {
883 protected synchronized void
884 add(InstanceIdentifier<Bgp> iid, Bgp val) {
885 LOG.debug("received add Bgp config replaying the config");
888 } catch (Exception e) {
890 synchronized(BgpConfigurationManager.this) {
893 if (isIpAvailable(odlThriftIp)) {
896 ipActivationCheckTimer.scheduleAtFixedRate(new TimerTask() {
898 if (isIpAvailable(odlThriftIp)) {
900 ipActivationCheckTimer.cancel();
909 protected synchronized void
910 remove(InstanceIdentifier<Bgp> iid, Bgp val) {
911 LOG.debug("received remove Bgp config");
912 synchronized(BgpConfigurationManager.this) {
917 protected void update(InstanceIdentifier<Bgp> iid,
918 Bgp oldval, Bgp newval) {
919 synchronized(BgpConfigurationManager.this) {
924 public void close() {
926 for (i=0 ; i < reactors.length ; i++) {
927 if (reactors[i] == BgpReactor.class) {
931 registrations[i].close();
935 public void readOdlThriftIpForBgpCommunication() {
936 File f = new File(CLUSTER_CONF_FILE);
938 odlThriftIp = "127.0.0.1";
941 BufferedReader br = null;
943 br = new BufferedReader(new InputStreamReader(
944 new FileInputStream(f)));
945 String line = br.readLine();
946 while (line != null) {
947 if (line.contains(SDNC_BGP_MIP)) {
949 odlThriftIp = line.substring(line.lastIndexOf(" ")+1);
952 line = br.readLine();
954 } catch (Exception e) {
956 try {br.close();} catch (Exception ignore){}
960 public boolean isIpAvailable(String odlip) {
964 if ("127.0.0.1".equals(odlip)) {
967 Enumeration e = NetworkInterface.getNetworkInterfaces();
968 while(e.hasMoreElements())
970 NetworkInterface n = (NetworkInterface) e.nextElement();
971 Enumeration ee = n.getInetAddresses();
972 while (ee.hasMoreElements())
974 InetAddress i = (InetAddress) ee.nextElement();
975 if (odlip.equals(i.getHostAddress())) {
981 } catch (Exception e) {
986 public void bgpRestarted() {
988 * If there a thread which in the process of stale cleanup, cancel it
989 * and start a new thread (to avoid processing same again).
991 if (lastCleanupJobReference.get() != null) {
992 lastCleanupJobReference.get().cancel(true);
993 lastCleanupJobReference.set(null);
995 Runnable task = new Runnable() {
999 long startTime = System.currentTimeMillis();
1000 LOG.error("started creating stale fib map ");
1001 createStaleFibMap();
1002 long endTime = System.currentTimeMillis();
1003 LOG.error("took {} msecs for stale fib map creation ", endTime - startTime);
1004 LOG.error("started bgp config replay ");
1005 startTime = endTime;
1007 endTime = System.currentTimeMillis();
1008 LOG.error("took {} msecs for bgp replay ", endTime - startTime);
1009 long route_sync_time = BGP_RESTART_ROUTE_SYNC_SEC;
1011 route_sync_time = bgpManager.getConfig().getGracefulRestart().getStalepathTime();
1012 } catch (Exception e) {
1013 LOG.error("BGP config/Stale-path time is not set");
1015 Thread.sleep(route_sync_time * 1000L);
1016 new RouteCleanup().call();
1018 } catch (Exception eCancel) {
1019 LOG.error("Stale Cleanup Task Cancelled", eCancel);
1023 lastCleanupJob = executor.submit(task);
1024 lastCleanupJobReference.set(lastCleanupJob);
1027 private static void doRouteSync() {
1028 BgpSyncHandle bsh = BgpSyncHandle.getInstance();
1029 LOG.debug("Starting BGP route sync");
1031 bgpRouter.initRibSync(bsh);
1032 } catch (Exception e) {
1033 LOG.error("Route sync aborted, exception when initialzing: "+e);
1036 while (bsh.getState() != bsh.DONE) {
1037 Routes routes = null;
1039 routes = bgpRouter.doRibSync(bsh);
1040 } catch (Exception e) {
1041 LOG.error("Route sync aborted, exception when syncing: "+e);
1044 Iterator<Update> updates = routes.getUpdatesIterator();
1045 while (updates.hasNext()) {
1046 Update u = updates.next();
1047 Map<String, Map<String, String>> stale_fib_rd_map = BgpConfigurationManager.getStaledFibEntriesMap();
1048 String rd = u.getRd();
1049 String nexthop = u.getNexthop();
1050 int label = u.getLabel();
1051 String prefix = u.getPrefix();
1052 int plen = u.getPrefixlen();
1053 onUpdatePushRoute(rd, prefix, plen, nexthop, label);
1057 LOG.debug("Ending BGP route-sync");
1058 bgpRouter.endRibSync(bsh);
1059 } catch (Exception e) {
1063 /* onUpdatePushRoute
1064 * Get Stale fib map, and compare current route/fib entry.
1065 * - Entry compare shall include NextHop, Label.
1066 * - If entry matches: delete from STALE Map. NO Change to FIB Config DS.
1067 * - If entry nor found, add to FIB Config DS.
1068 * - If entry found, but either Label/NextHop doesnt match.
1069 * - Update FIB Config DS with modified values.
1070 * - delete from Stale Map.
1072 public static void onUpdatePushRoute(String rd, String prefix, int plen,
1073 String nexthop, int label) {
1074 Map<String, Map<String, String>> stale_fib_rd_map = BgpConfigurationManager.getStaledFibEntriesMap();
1075 boolean addroute = false;
1076 if (!stale_fib_rd_map.isEmpty()) {
1077 // restart Scenario, as MAP is not empty.
1078 Map<String, String> map = stale_fib_rd_map.get(rd);
1080 String nexthoplabel = map.get(prefix + "/" + plen);
1081 if (null == nexthoplabel) {
1082 // New Entry, which happend to be added during restart.
1085 map.remove(prefix + "/" + plen);
1086 if (isRouteModified(nexthop, label, nexthoplabel)) {
1087 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix,
1088 plen, nexthop, label);
1089 // Existing entry, where in Nexthop/Label got modified during restart
1095 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix,
1096 plen, nexthop, label);
1100 fib.addFibEntryToDS(rd, prefix + "/" + plen,
1105 private static boolean isRouteModified(String nexthop, int label, String nexthoplabel) {
1106 return !nexthoplabel.isEmpty() && !nexthoplabel.equals(nexthop+"/"+label);
1109 static private void replayNbrConfig(List<Neighbors> n, BgpRouter br) {
1110 for (Neighbors nbr : n) {
1112 br.addNeighbor(nbr.getAddress().getValue(),
1113 nbr.getRemoteAs().intValue());
1114 //itmProvider.buildTunnelsToDCGW(new IpAddress(nbr.getAddress().getValue().toCharArray()));
1115 } catch (Exception e) {
1116 LOG.error("Replay:addNbr() received exception: \""+e+"\"");
1119 EbgpMultihop en = nbr.getEbgpMultihop();
1122 br.addEbgpMultihop(en.getPeerIp().getValue(),
1123 en.getNhops().intValue());
1124 } catch (Exception e) {
1125 LOG.error("Replay:addEBgp() received exception: \""+e+"\"");
1128 UpdateSource us = nbr.getUpdateSource();
1131 br.addUpdateSource(us.getPeerIp().getValue(),
1132 us.getSourceIp().getValue());
1133 } catch (Exception e) {
1134 LOG.error("Replay:addUS() received exception: \""+e+"\"");
1137 List<AddressFamilies> afs = nbr.getAddressFamilies();
1139 for (AddressFamilies af : afs) {
1140 af_afi afi = af_afi.findByValue(af.getAfi().intValue());
1141 af_safi safi = af_safi.findByValue(af.getSafi().intValue());
1143 br.addAddressFamily(af.getPeerIp().getValue(), afi, safi);
1144 } catch (Exception e) {
1145 LOG.error("Replay:addAf() received exception: \""+e+"\"");
1152 public static String getConfigHost() {
1153 if (config == null) {
1154 return cHostStartup;
1156 ConfigServer ts = config.getConfigServer();
1157 return (ts == null ? cHostStartup : ts.getHost().getValue());
1160 public static int getConfigPort() {
1161 if (config == null) {
1162 return Integer.parseInt(cPortStartup);
1164 ConfigServer ts = config.getConfigServer();
1165 return (ts == null ? Integer.parseInt(cPortStartup) :
1166 ts.getPort().intValue());
1169 public static synchronized void replay() {
1170 String host = getConfigHost();
1171 int port = getConfigPort();
1172 boolean res = bgpRouter.connect(host, port);
1174 String msg = "Cannot connect to BGP config server at "+host+":"+port;
1175 if (config != null) {
1176 msg += "; Configuration Replay aborted";
1181 if (config == null) {
1184 BgpRouter br = bgpRouter;
1185 AsId a = config.getAsId();
1189 int asNum = a.getLocalAs().intValue();
1190 Ipv4Address routerId = a.getRouterId();
1191 Long spt = a.getStalepathTime();
1192 Boolean afb = a.isAnnounceFbit();
1193 String rid = (routerId == null) ? "" : routerId.getValue();
1194 int stalepathTime = (spt == null) ? 90 : spt.intValue();
1195 boolean announceFbit = (afb == null) ? false : afb.booleanValue();
1197 br.startBgp(asNum, rid, stalepathTime, announceFbit);
1198 } catch (BgpRouterException bre) {
1199 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
1202 LOG.error("Replay: startBgp() received exception: \""
1203 +bre+"\"; "+addWarn);
1205 } catch (Exception e) {
1206 //not unusual. We may have restarted & BGP is already on
1207 LOG.error("Replay:startBgp() received exception: \""+e+"\"");
1210 if (bgpManager.getBgpCounters() == null) {
1211 bgpManager.startBgpCountersTask();
1214 Logging l = config.getLogging();
1217 br.setLogging(l.getFile(), l.getLevel());
1218 } catch (Exception e) {
1219 LOG.error("Replay:setLogging() received exception: \""+e+"\"");
1223 GracefulRestart g = config.getGracefulRestart();
1226 br.addGracefulRestart(g.getStalepathTime().intValue());
1227 } catch (Exception e) {
1228 LOG.error("Replay:addGr() received exception: \""+e+"\"");
1232 List<Neighbors> n = config.getNeighbors();
1234 replayNbrConfig(n, br);
1237 List<Vrfs> v = config.getVrfs();
1239 for (Vrfs vrf : v) {
1241 br.addVrf(vrf.getRd(), vrf.getImportRts(),
1242 vrf.getExportRts());
1243 } catch (Exception e) {
1244 LOG.error("Replay:addVrf() received exception: \""+e+"\"");
1249 List<Networks> ln = config.getNetworks();
1251 for (Networks net : ln) {
1252 String rd = net.getRd();
1253 String pfxlen = net.getPrefixLen();
1254 String nh = net.getNexthop().getValue();
1255 Long label = net.getLabel();
1256 int lbl = (label == null) ? 0 : label.intValue();
1257 if (rd == null && lbl > 0) {
1258 //LU prefix is being deleted.
1259 rd = Integer.toString(lbl);
1262 br.addPrefix(rd, pfxlen, nh, lbl);
1263 } catch (Exception e) {
1264 LOG.error("Replay:addPfx() received exception: \""+e+"\"");
1270 private <T extends DataObject> void update(InstanceIdentifier<T> iid, T dto) {
1271 BgpUtil.update(broker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1274 private <T extends DataObject> void asyncWrite(InstanceIdentifier<T> iid, T dto) {
1275 BgpUtil.write(broker,LogicalDatastoreType.CONFIGURATION,iid,dto);
1278 private <T extends DataObject> void delete(InstanceIdentifier<T> iid) {
1279 BgpUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, iid);
1282 public synchronized void
1283 startConfig(String bgpHost, int thriftPort) {
1284 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1285 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1286 InstanceIdentifier<ConfigServer> iid = iib.build();
1287 Ipv4Address ipAddr = new Ipv4Address(bgpHost);
1288 ConfigServer dto = new ConfigServerBuilder().setHost(ipAddr)
1289 .setPort((long) thriftPort).build();
1293 public synchronized void
1294 startBgp(int as, String routerId, int spt, boolean fbit) {
1295 Long localAs = (long) as;
1296 Ipv4Address rid = (routerId == null) ?
1297 null : new Ipv4Address(routerId);
1298 Long staleTime = (long) spt;
1299 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1300 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1301 InstanceIdentifier<AsId> iid = iib.build();
1302 AsId dto = new AsIdBuilder().setLocalAs(localAs)
1304 .setStalepathTime(staleTime)
1305 .setAnnounceFbit(fbit).build();
1309 public synchronized void
1310 addLogging(String fileName, String logLevel) {
1311 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1312 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1313 InstanceIdentifier<Logging> iid = iib.build();
1314 Logging dto = new LoggingBuilder().setFile(fileName)
1315 .setLevel(logLevel).build();
1319 public synchronized void
1320 addGracefulRestart(int staleTime) {
1321 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1322 InstanceIdentifier.builder(Bgp.class).child(GracefulRestart.class);
1323 InstanceIdentifier<GracefulRestart> iid = iib.build();
1324 GracefulRestart dto = new GracefulRestartBuilder()
1325 .setStalepathTime((long)staleTime).build();
1329 public synchronized void
1330 addNeighbor(String nbrIp, int remoteAs) {
1331 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1332 Long rAs = (long) remoteAs;
1333 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1334 InstanceIdentifier.builder(Bgp.class)
1335 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1336 InstanceIdentifier<Neighbors> iid = iib.build();
1337 Neighbors dto = new NeighborsBuilder().setAddress(nbrAddr)
1338 .setRemoteAs(rAs).build();
1342 public synchronized void
1343 addUpdateSource(String nbrIp, String srcIp) {
1344 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1345 Ipv4Address srcAddr = new Ipv4Address(srcIp);
1346 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1347 InstanceIdentifier.builder(Bgp.class)
1348 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1349 .child(UpdateSource.class);
1350 InstanceIdentifier<UpdateSource> iid = iib.build();
1351 UpdateSource dto = new UpdateSourceBuilder().setPeerIp(nbrAddr)
1352 .setSourceIp(srcAddr).build();
1356 public synchronized void
1357 addEbgpMultihop(String nbrIp, int nHops) {
1358 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1359 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1360 InstanceIdentifier.builder(Bgp.class)
1361 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1362 .child(EbgpMultihop.class);
1363 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1364 EbgpMultihop dto = new EbgpMultihopBuilder().setPeerIp(nbrAddr)
1365 .setNhops((long)nHops).build();
1369 public synchronized void
1370 addAddressFamily(String nbrIp, int afi, int safi) {
1371 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1372 Long a = (long) afi;
1373 Long sa = (long) safi;
1374 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1375 InstanceIdentifier.builder(Bgp.class)
1376 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1377 .child(AddressFamilies.class, new AddressFamiliesKey(a, sa));
1378 InstanceIdentifier<AddressFamilies> iid = iib.build();
1379 AddressFamilies dto = new AddressFamiliesBuilder().setPeerIp(nbrAddr)
1380 .setAfi(a).setSafi(sa).build();
1384 public synchronized void
1385 addPrefix(String rd, String pfx, String nh, int lbl) {
1386 Ipv4Address nexthop = new Ipv4Address(nh);
1387 Long label = (long) lbl;
1388 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
1389 InstanceIdentifier.builder(Bgp.class)
1390 .child(Networks.class, new NetworksKey(pfx, rd));
1391 InstanceIdentifier<Networks> iid = iib.build();
1392 Networks dto = new NetworksBuilder().setRd(rd)
1394 .setNexthop(nexthop)
1395 .setLabel(label).build();
1399 public synchronized void
1400 addVrf(String rd, List<String> irts, List<String> erts) {
1401 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1402 InstanceIdentifier.builder(Bgp.class)
1403 .child(Vrfs.class, new VrfsKey(rd));
1404 InstanceIdentifier<Vrfs> iid = iib.build();
1405 Vrfs dto = new VrfsBuilder().setRd(rd)
1407 .setExportRts(erts).build();
1409 asyncWrite(iid, dto);
1412 public synchronized void stopConfig() {
1413 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1414 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1415 InstanceIdentifier<ConfigServer> iid = iib.build();
1419 public synchronized void stopBgp() {
1420 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1421 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1422 InstanceIdentifier<AsId> iid = iib.build();
1426 public synchronized void delLogging() {
1427 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1428 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1429 InstanceIdentifier<Logging> iid = iib.build();
1433 public synchronized void delGracefulRestart() {
1434 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1435 InstanceIdentifier.builder(Bgp.class)
1436 .child(GracefulRestart.class);
1437 InstanceIdentifier<GracefulRestart> iid = iib.build();
1441 public synchronized void delNeighbor(String nbrIp) {
1442 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1443 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1444 InstanceIdentifier.builder(Bgp.class)
1445 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1446 InstanceIdentifier<Neighbors> iid = iib.build();
1450 public synchronized void delUpdateSource(String nbrIp) {
1451 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1452 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1453 InstanceIdentifier.builder(Bgp.class)
1454 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1455 .child(UpdateSource.class);
1456 InstanceIdentifier<UpdateSource> iid = iib.build();
1460 public synchronized void delEbgpMultihop(String nbrIp) {
1461 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1462 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1463 InstanceIdentifier.builder(Bgp.class)
1464 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1465 .child(EbgpMultihop.class);
1466 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1470 public synchronized void
1471 delAddressFamily(String nbrIp, int afi, int safi) {
1472 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1473 Long a = (long) afi;
1474 Long sa = (long) safi;
1475 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1476 InstanceIdentifier.builder(Bgp.class)
1477 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1478 .child(AddressFamilies.class, new AddressFamiliesKey(a, sa));
1479 InstanceIdentifier<AddressFamilies> iid = iib.build();
1483 public synchronized void delPrefix(String rd, String pfx) {
1484 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
1485 InstanceIdentifier.builder(Bgp.class)
1486 .child(Networks.class, new NetworksKey(pfx, rd));
1487 InstanceIdentifier<Networks> iid = iib.build();
1491 public synchronized void delVrf(String rd) {
1492 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1493 InstanceIdentifier.builder(Bgp.class)
1494 .child(Vrfs.class, new VrfsKey(rd));
1495 InstanceIdentifier<Vrfs> iid = iib.build();
1499 static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
1501 * Remove Stale Marked Routes after timer expiry.
1503 class RouteCleanup implements Callable<Integer> {
1505 public Integer call () {
1506 int totalCleared = 0;
1508 if (staledFibEntriesMap.isEmpty()) {
1509 LOG.info("BGP: RouteCleanup timertask tirggered but STALED FIB MAP is EMPTY");
1511 for (String rd : staledFibEntriesMap.keySet()) {
1512 if (Thread.interrupted()) {
1515 Map<String, String> map = staledFibEntriesMap.get(rd);
1517 for (String prefix : map.keySet()) {
1518 if (Thread.interrupted()) {
1523 bgpManager.deletePrefix(rd, prefix);
1524 } catch (Exception e) {
1525 LOG.error("BGP: RouteCleanup deletePrefix failed rd:{}, prefix{}" + rd.toString() + prefix);
1531 } catch(Exception e) {
1532 LOG.error("Cleanup Thread Got interrupted, Failed to cleanup stale routes ", e);
1534 staledFibEntriesMap.clear();
1536 LOG.error("cleared {} stale routes after bgp restart", totalCleared);
1542 * BGP restart scenario, ODL-BGP manager was/is running.
1543 * On re-sync notification, Get a copy of FIB database.
1545 public static void createStaleFibMap() {
1546 int totalStaledCount = 0;
1548 staledFibEntriesMap.clear();
1549 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
1550 DataBroker db = BgpUtil.getBroker();
1552 LOG.error("Couldn't find BgpUtil broker while creating createStaleFibMap");
1556 Optional<FibEntries> fibEntries = BgpUtil.read(BgpUtil.getBroker(),
1557 LogicalDatastoreType.CONFIGURATION, id);
1558 if (fibEntries.isPresent()) {
1559 List<VrfTables> stale_vrfTables = fibEntries.get().getVrfTables();
1560 for (VrfTables vrfTable : stale_vrfTables) {
1561 Map<String, String> stale_fib_ent_map = new HashMap<>();
1562 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
1563 if (Thread.interrupted()) {
1567 //Create MAP from stale_vrfTables.
1568 stale_fib_ent_map.put(vrfEntry.getDestPrefix(), vrfEntry.getNextHopAddress() + "/" + vrfEntry.getLabel());
1570 staledFibEntriesMap.put(vrfTable.getRouteDistinguisher(), stale_fib_ent_map);
1573 LOG.error("createStaleFibMap:: FIBentries.class is not present");
1575 } catch (Exception e) {
1576 LOG.error("createStaleFibMap:: erorr ", e);
1578 LOG.error("created {} staled entries ", totalStaledCount);
1581 //map<rd, map<prefix/len, nexthop/label>>
1582 public static Map<String, Map<String, String>> getStaledFibEntriesMap() {
1583 return staledFibEntriesMap;