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.bgpmanager;
11 import com.google.common.base.Optional;
14 import java.io.BufferedReader;
16 import java.io.FileInputStream;
17 import java.io.FileOutputStream;
18 import java.io.InputStreamReader;
19 import java.lang.reflect.*;
20 import java.net.InetAddress;
21 import java.net.NetworkInterface;
22 import java.util.concurrent.*;
23 import java.util.concurrent.atomic.AtomicBoolean;
24 import java.util.concurrent.atomic.AtomicInteger;
25 import java.util.concurrent.atomic.AtomicReference;
26 import java.util.concurrent.locks.ReadWriteLock;
27 import java.util.concurrent.locks.ReentrantReadWriteLock;
29 import org.opendaylight.bgpmanager.commands.ClearBgpCli;
30 import org.opendaylight.bgpmanager.thrift.gen.*;
31 import org.opendaylight.bgpmanager.thrift.client.*;
32 import org.opendaylight.bgpmanager.thrift.server.*;
33 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
34 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
35 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
36 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
37 //import org.opendaylight.vpnservice.itm.api.IITMProvider;
38 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.*;
39 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.*;
40 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.*;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.*;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.FibEntries;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.fibentries.VrfTables;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.fibmanager.rev150330.vrfentries.VrfEntry;
45 import org.opendaylight.yangtools.concepts.ListenerRegistration;
46 import org.opendaylight.yangtools.yang.binding.DataObject;
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
48 import org.osgi.framework.Bundle;
49 import org.osgi.framework.BundleContext;
50 import org.osgi.framework.FrameworkUtil;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
54 public class BgpConfigurationManager {
55 private static final Logger LOG =
56 LoggerFactory.getLogger(BgpConfigurationManager.class);
57 private static DataBroker broker;
58 private static FibDSWriter fib;
59 private boolean restarting = false;
60 private static Bgp config;
61 private static BgpRouter bgpRouter;
62 private static BgpThriftService updateServer;
64 private static final String DEF_LOGFILE = "/var/log/bgp_debug.log";
65 private static final String DEF_LOGLEVEL = "errors";
66 private static final String UPDATE_PORT = "bgp.thrift.service.port";
67 private static final String CONFIG_HOST = "vpnservice.bgpspeaker.host.name";
68 private static final String CONFIG_PORT = "vpnservice.bgpspeaker.thrift.port";
69 private static final String DEF_UPORT = "6644";
70 private static final String DEF_CHOST = "127.0.0.1";
71 private static final String DEF_CPORT = "7644";
72 private static final String SDNC_BGP_MIP = "sdnc_bgp_mip";
73 private static final String CLUSTER_CONF_FILE = "/cluster/etc/cluster.conf";
74 private static final Timer ipActivationCheckTimer = new Timer();
76 // to have stale FIB map (RD, Prefix)
77 // number of seconds wait for route sync-up between ODL and BGP.
78 private static final int BGP_RESTART_ROUTE_SYNC_SEC = 360;
80 static String odlThriftIp = "127.0.0.1";
81 private static String cHostStartup;
82 private static String cPortStartup;
83 private static CountDownLatch initer = new CountDownLatch(1);
84 //static IITMProvider itmProvider;
85 public static BgpManager bgpManager;
86 //map<rd, map<prefix/len, nexthop/label>>
87 private static Map<String, Map<String, String>> staledFibEntriesMap = new ConcurrentHashMap<>();
89 private static final Class[] reactors =
91 ConfigServerReactor.class, AsIdReactor.class,
92 GracefulRestartReactor.class, LoggingReactor.class,
93 NeighborsReactor.class, UpdateSourceReactor.class,
94 EbgpMultihopReactor.class, AddressFamiliesReactor.class,
95 NetworksReactor.class, VrfsReactor.class, BgpReactor.class
98 private ListenerRegistration<DataChangeListener>[] registrations;
100 private Object createListener(Class<?> cls) {
105 ctor= cls.getConstructor(BgpConfigurationManager.class);
106 obj = ctor.newInstance(this);
107 } catch (Exception e) {
108 LOG.error("Failed to create listener object", e);
113 private void registerCallbacks() {
114 String emsg = "Failed to register listener";
115 registrations = (ListenerRegistration<DataChangeListener>[])
116 new ListenerRegistration[reactors.length];
117 InstanceIdentifier<?> iid = InstanceIdentifier.create(Bgp.class);
118 for (int i = 0; i < reactors.length; i++) {
119 DataChangeListener dcl =
120 (DataChangeListener) createListener(reactors[i]);
121 String dclName = dcl.getClass().getName();
123 registrations[i] = broker.registerDataChangeListener(
124 LogicalDatastoreType.CONFIGURATION,
125 iid, dcl, DataChangeScope.SUBTREE);
126 } catch (Exception e) {
128 throw new IllegalStateException(emsg+" "+dclName, e);
133 public void close() {
134 if (updateServer != null) {
139 private boolean configExists() {
140 InstanceIdentifier.InstanceIdentifierBuilder<Bgp> iib =
141 InstanceIdentifier.builder(Bgp.class);
142 InstanceIdentifier<Bgp> iid = iib.build();
143 Optional<Bgp> b = BgpUtil.read(broker,
144 LogicalDatastoreType.CONFIGURATION, iid);
145 return b.isPresent();
148 private String getProperty(String var, String def) {
149 Bundle b = FrameworkUtil.getBundle(BgpManager.class);
153 BundleContext context = b.getBundleContext();
154 if (context == null) {
157 String s = context.getProperty(var);
158 return (s == null ? def : s);
161 public BgpConfigurationManager(BgpManager bgpMgr) {
162 broker = bgpMgr.getBroker();
163 fib = bgpMgr.getFibWriter();
164 //itmProvider = bgpMgr.getItmProvider();
165 // there must be a good way to detect that we're restarting.
166 // but for now infer it from the existance of config
167 restarting = configExists();
169 bgpRouter = BgpRouter.getInstance();
170 String uPort = getProperty(UPDATE_PORT, DEF_UPORT);
171 cHostStartup = getProperty(CONFIG_HOST, DEF_CHOST);
172 cPortStartup = getProperty(CONFIG_PORT, DEF_CPORT);
173 VtyshCli.setHostAddr(cHostStartup);
174 ClearBgpCli.setHostAddr(cHostStartup);
175 LOG.info("UpdateServer at localhost:"+uPort+" ConfigServer at "
176 +cHostStartup+":"+cPortStartup);
177 updateServer = new BgpThriftService(Integer.parseInt(uPort), bgpMgr);
178 updateServer.start();
179 readOdlThriftIpForBgpCommunication();
182 // this shouldn't be done. config client must connect in
183 // response to config; but connecting at startup to a default
184 // host is legacy behavior.
186 bgpRouter.connect(cHostStartup, Integer.parseInt(cPortStartup));
188 LOG.info("BGP Configuration manager initialized");
196 private static final String addWarn =
197 "Config store updated; undo with Delete if needed.";
198 private static final String delWarn =
199 "Config store updated; undo with Add if needed.";
200 private static final String updWarn =
201 "Update operation not supported; Config store updated;"
202 +" restore with another Update if needed.";
204 public class ConfigServerReactor
205 extends AbstractDataChangeListener<ConfigServer>
206 implements AutoCloseable {
207 private static final String yangObj = "config-server ";
208 public ConfigServerReactor() {
209 super(ConfigServer.class);
212 protected synchronized void
213 add(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
214 LOG.debug("received bgp connect config host {}", val.getHost().getValue());
217 } catch (Exception e) {
219 LOG.debug("issueing bgp router connect to host {}", val.getHost().getValue());
220 synchronized(BgpConfigurationManager.this) {
221 boolean res = bgpRouter.connect(val.getHost().getValue(),
222 val.getPort().intValue());
224 LOG.error(yangObj + "Add failed; "+addWarn);
229 protected synchronized void
230 remove(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
231 LOG.debug("received bgp disconnect");
232 synchronized(BgpConfigurationManager.this) {
233 bgpRouter.disconnect();
237 protected void update(InstanceIdentifier<ConfigServer> iid,
238 ConfigServer oldval, ConfigServer newval) {
239 LOG.error(yangObj + updWarn);
242 public void close() {
244 for (i=0 ; i < reactors.length ; i++) {
245 if (reactors[i] == ConfigServerReactor.class) {
249 registrations[i].close();
253 private BgpRouter getClient(String yangObj) {
254 if (bgpRouter == null) {
255 LOG.warn(yangObj+": configuration received when BGP is inactive");
260 public class AsIdReactor
261 extends AbstractDataChangeListener<AsId>
262 implements AutoCloseable {
264 private static final String yangObj = "as-id ";
266 public AsIdReactor() {
270 protected synchronized void
271 add(InstanceIdentifier<AsId> iid, AsId val) {
272 LOG.debug("received add router config asNum {}", val.getLocalAs().intValue());
273 synchronized(BgpConfigurationManager.this) {
274 BgpRouter br = getClient(yangObj);
278 int asNum = val.getLocalAs().intValue();
279 Ipv4Address routerId = val.getRouterId();
280 Long spt = val.getStalepathTime();
281 Boolean afb = val.isAnnounceFbit();
282 String rid = (routerId == null) ? "" : routerId.getValue();
283 int stalepathTime = (spt == null) ? 90 : spt.intValue();
284 boolean announceFbit = (afb == null) ? false : afb.booleanValue();
286 br.startBgp(asNum, rid, stalepathTime, announceFbit);
287 if (bgpManager.getBgpCounters() == null) {
288 bgpManager.startBgpCountersTask();
290 } catch (BgpRouterException bre) {
291 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
292 LOG.error(yangObj+"Add requested when BGP is already active");
294 LOG.error(yangObj+"Add received exception: \""
295 +bre+"\"; "+addWarn);
297 } catch (Exception e) {
298 LOG.error(yangObj+"Add received exception: \""+e+"\"; "+addWarn);
303 protected synchronized void
304 remove(InstanceIdentifier<AsId> iid, AsId val) {
305 LOG.debug("received delete router config asNum {}", val.getLocalAs().intValue());
306 synchronized(BgpConfigurationManager.this) {
307 BgpRouter br = getClient(yangObj);
311 int asNum = val.getLocalAs().intValue();
314 } catch (Exception e) {
315 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "+delWarn);
317 if (bgpManager.getBgpCounters() != null) {
318 bgpManager.stopBgpCountersTask();
323 protected void update(InstanceIdentifier<AsId> iid,
324 AsId oldval, AsId newval) {
325 LOG.error(yangObj + updWarn);
328 public void close() {
330 for (i=0 ; i < reactors.length ; i++) {
331 if (reactors[i] == AsIdReactor.class) {
335 registrations[i].close();
339 public class GracefulRestartReactor
340 extends AbstractDataChangeListener<GracefulRestart>
341 implements AutoCloseable {
343 private static final String yangObj = "graceful-restart ";
345 public GracefulRestartReactor() {
346 super(GracefulRestart.class);
349 protected synchronized void
350 add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
351 synchronized(BgpConfigurationManager.this) {
352 BgpRouter br = getClient(yangObj);
357 br.addGracefulRestart(val.getStalepathTime().intValue());
358 } catch (Exception e) {
359 LOG.error(yangObj+"Add received exception: \""+e+"\"; "+addWarn);
364 protected synchronized void
365 remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
366 LOG.debug("received delete GracefulRestart config val {}", val.getStalepathTime().intValue());
367 synchronized(BgpConfigurationManager.this) {
368 BgpRouter br = getClient(yangObj);
373 br.delGracefulRestart();
374 } catch (Exception e) {
375 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
381 protected void update(InstanceIdentifier<GracefulRestart> iid,
382 GracefulRestart oldval, GracefulRestart newval) {
383 LOG.debug("received update GracefulRestart config val {}", newval.getStalepathTime().intValue());
384 synchronized(BgpConfigurationManager.this) {
385 BgpRouter br = getClient(yangObj);
390 br.addGracefulRestart(newval.getStalepathTime().intValue());
391 } catch (Exception e) {
392 LOG.error(yangObj+"update received exception: \""+e+"\"; "+addWarn);
397 public void close() {
399 for (i=0 ; i < reactors.length ; i++) {
400 if (reactors[i] == GracefulRestartReactor.class) {
404 registrations[i].close();
408 public class LoggingReactor
409 extends AbstractDataChangeListener<Logging>
410 implements AutoCloseable {
412 private static final String yangObj = "logging ";
414 public LoggingReactor() {
415 super(Logging.class);
418 protected synchronized void
419 add(InstanceIdentifier<Logging> iid, Logging val) {
420 synchronized(BgpConfigurationManager.this) {
421 BgpRouter br = getClient(yangObj);
426 br.setLogging(val.getFile(),val.getLevel());
427 } catch (Exception e) {
428 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
434 protected synchronized void
435 remove(InstanceIdentifier<Logging> iid, Logging val) {
436 LOG.debug("received remove Logging config val {}", val.getLevel());
437 synchronized(BgpConfigurationManager.this) {
438 BgpRouter br = getClient(yangObj);
443 br.setLogging(DEF_LOGFILE, DEF_LOGLEVEL);
444 } catch (Exception e) {
445 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
451 protected void update(InstanceIdentifier<Logging> iid,
452 Logging oldval, Logging newval) {
453 synchronized(BgpConfigurationManager.this) {
454 BgpRouter br = getClient(yangObj);
459 br.setLogging(newval.getFile(),newval.getLevel());
460 } catch (Exception e) {
461 LOG.error(yangObj+"newval received exception: \""+e+"\"; "
467 public void close() {
469 for (i=0 ; i < reactors.length ; i++) {
470 if (reactors[i] == LoggingReactor.class) {
474 registrations[i].close();
478 public class NeighborsReactor
479 extends AbstractDataChangeListener<Neighbors>
480 implements AutoCloseable {
482 private static final String yangObj = "neighbors ";
484 public NeighborsReactor() {
485 super(Neighbors.class);
488 protected synchronized void
489 add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
490 LOG.debug("received add Neighbors config val {}", val.getAddress().getValue());
491 synchronized(BgpConfigurationManager.this) {
492 BgpRouter br = getClient(yangObj);
496 String peerIp = val.getAddress().getValue();
497 int as = val.getRemoteAs().intValue();
499 //itmProvider.buildTunnelsToDCGW(new IpAddress(peerIp.toCharArray()));
500 br.addNeighbor(peerIp, as);
502 } catch (Exception e) {
503 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
509 protected synchronized void
510 remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
511 LOG.debug("received remove Neighbors config val {}", val.getAddress().getValue());
512 synchronized(BgpConfigurationManager.this) {
513 BgpRouter br = getClient(yangObj);
517 String peerIp = val.getAddress().getValue();
519 //itmProvider.deleteTunnelsToDCGW(new IpAddress(val.getAddress().getValue().toCharArray()));
520 br.delNeighbor(peerIp);
521 } catch (Exception e) {
522 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
528 protected void update(InstanceIdentifier<Neighbors> iid,
529 Neighbors oldval, Neighbors newval) {
530 //purposefully nothing to do.
533 public void close() {
535 for (i=0 ; i < reactors.length ; i++) {
536 if (reactors[i] == NeighborsReactor.class) {
540 registrations[i].close();
544 public class EbgpMultihopReactor
545 extends AbstractDataChangeListener<EbgpMultihop>
546 implements AutoCloseable {
548 private static final String yangObj = "ebgp-multihop ";
550 public EbgpMultihopReactor() {
551 super(EbgpMultihop.class);
554 protected synchronized void
555 add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
556 LOG.debug("received add EbgpMultihop config val {}", val.getPeerIp().getValue());
557 synchronized(BgpConfigurationManager.this) {
558 BgpRouter br = getClient(yangObj);
562 String peerIp = val.getPeerIp().getValue();
564 br.addEbgpMultihop(peerIp, val.getNhops().intValue());
565 } catch (Exception e) {
566 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
572 protected synchronized void
573 remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
574 LOG.debug("received remove EbgpMultihop config val {}", val.getPeerIp().getValue());
575 synchronized(BgpConfigurationManager.this) {
576 BgpRouter br = getClient(yangObj);
580 String peerIp = val.getPeerIp().getValue();
582 br.delEbgpMultihop(peerIp);
583 } catch (Exception e) {
584 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
590 protected void update(InstanceIdentifier<EbgpMultihop> iid,
591 EbgpMultihop oldval, EbgpMultihop newval) {
592 LOG.error(yangObj + updWarn);
595 public void close() {
597 for (i=0 ; i < reactors.length ; i++) {
598 if (reactors[i] == EbgpMultihopReactor.class) {
602 registrations[i].close();
606 public class UpdateSourceReactor
607 extends AbstractDataChangeListener<UpdateSource>
608 implements AutoCloseable {
610 private static final String yangObj = "update-source ";
612 public UpdateSourceReactor() {
613 super(UpdateSource.class);
616 protected synchronized void
617 add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
618 LOG.debug("received add UpdateSource config val {}", val.getSourceIp().getValue());
619 synchronized(BgpConfigurationManager.this) {
620 BgpRouter br = getClient(yangObj);
624 String peerIp = val.getPeerIp().getValue();
626 br.addUpdateSource(peerIp, val.getSourceIp().getValue());
627 } catch (Exception e) {
628 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
634 protected synchronized void
635 remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
636 LOG.debug("received remove UpdateSource config val {}", val.getSourceIp().getValue());
637 synchronized(BgpConfigurationManager.this) {
638 BgpRouter br = getClient(yangObj);
642 String peerIp = val.getPeerIp().getValue();
644 br.delUpdateSource(peerIp);
645 } catch (Exception e) {
646 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
652 protected void update(InstanceIdentifier<UpdateSource> iid,
653 UpdateSource oldval, UpdateSource newval) {
654 LOG.error(yangObj + updWarn);
657 public void close() {
659 for (i=0 ; i < reactors.length ; i++) {
660 if (reactors[i] == UpdateSourceReactor.class) {
664 registrations[i].close();
668 public class AddressFamiliesReactor
669 extends AbstractDataChangeListener<AddressFamilies>
670 implements AutoCloseable {
672 private static final String yangObj = "address-families ";
674 public AddressFamiliesReactor() {
675 super(AddressFamilies.class);
678 protected synchronized void
679 add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
680 LOG.debug("received add AddressFamilies config val {}", val.getPeerIp().getValue());
681 synchronized(BgpConfigurationManager.this) {
682 BgpRouter br = getClient(yangObj);
686 String peerIp = val.getPeerIp().getValue();
687 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
688 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
690 br.addAddressFamily(peerIp, afi, safi);
691 } catch (Exception e) {
692 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
698 protected synchronized void
699 remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
700 LOG.debug("received remove AddressFamilies config val {}", val.getPeerIp().getValue());
701 synchronized(BgpConfigurationManager.this) {
702 BgpRouter br = getClient(yangObj);
706 String peerIp = val.getPeerIp().getValue();
707 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
708 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
710 br.delAddressFamily(peerIp, afi, safi);
711 } catch (Exception e) {
712 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
718 protected void update(InstanceIdentifier<AddressFamilies> iid,
719 AddressFamilies oldval, AddressFamilies newval) {
720 LOG.error(yangObj + updWarn);
723 public void close() {
725 for (i=0 ; i < reactors.length ; i++) {
726 if (reactors[i] == AddressFamiliesReactor.class) {
730 registrations[i].close();
734 public class NetworksReactor
735 extends AbstractDataChangeListener<Networks>
736 implements AutoCloseable {
738 private static final String yangObj = "networks ";
740 public NetworksReactor() {
741 super(Networks.class);
744 protected synchronized void
745 add(InstanceIdentifier<Networks> iid, Networks val) {
746 LOG.debug("received add Networks config val {}", val.getPrefixLen());
747 synchronized(BgpConfigurationManager.this) {
748 BgpRouter br = getClient(yangObj);
752 String rd = val.getRd();
753 String pfxlen = val.getPrefixLen();
754 String nh = val.getNexthop().getValue();
755 Long label = val.getLabel();
756 int lbl = (label == null) ? qbgpConstants.LBL_NO_LABEL
759 br.addPrefix(rd, pfxlen, nh, lbl);
760 } catch (Exception e) {
761 LOG.error(yangObj+"Add received exception: \""+e+"\"; "+addWarn);
766 protected synchronized void
767 remove(InstanceIdentifier<Networks> iid, Networks val) {
768 LOG.debug("received remove Networks config val {}", val.getPrefixLen());
769 synchronized(BgpConfigurationManager.this) {
770 BgpRouter br = getClient(yangObj);
774 String rd = val.getRd();
775 String pfxlen = val.getPrefixLen();
776 Long label = val.getLabel();
777 int lbl = (label == null) ? 0 : label.intValue();
778 if (rd == null && lbl > 0) {
779 //LU prefix is being deleted.
780 rd = Integer.toString(lbl);
783 br.delPrefix(rd, pfxlen);
784 } catch (Exception e) {
785 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
791 protected void update(InstanceIdentifier<Networks> iid,
792 Networks oldval, Networks newval) {
793 LOG.error(yangObj + updWarn);
796 public void close() {
798 for (i=0 ; i < reactors.length ; i++) {
799 if (reactors[i] == NetworksReactor.class) {
803 registrations[i].close();
807 public class VrfsReactor
808 extends AbstractDataChangeListener<Vrfs>
809 implements AutoCloseable {
811 private static final String yangObj = "vrfs ";
813 public VrfsReactor() {
817 protected synchronized void
818 add(InstanceIdentifier<Vrfs> iid, Vrfs val) {
819 LOG.debug("received add Vrfs config val {}", val.getRd());
820 synchronized(BgpConfigurationManager.this) {
821 BgpRouter br = getClient(yangObj);
826 br.addVrf(val.getRd(), val.getImportRts(),
828 } catch (Exception e) {
829 LOG.error(yangObj+"Add received exception: \""+e+"\"; "
835 protected synchronized void
836 remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
837 LOG.debug("received remove Vrfs config val {}", val.getRd());
838 synchronized(BgpConfigurationManager.this) {
839 BgpRouter br = getClient(yangObj);
844 br.delVrf(val.getRd());
845 } catch (Exception e) {
846 LOG.error(yangObj+" Delete received exception: \""+e+"\"; "
852 protected void update(InstanceIdentifier<Vrfs> iid,
853 Vrfs oldval, Vrfs newval) {
854 LOG.error(yangObj + updWarn);
857 public void close() {
859 for (i=0 ; i < reactors.length ; i++) {
860 if (reactors[i] == VrfsReactor.class) {
864 registrations[i].close();
868 Future lastCleanupJob;
869 AtomicReference<Future> lastCleanupJobReference = new AtomicReference<>();
871 AtomicBoolean started = new AtomicBoolean(false);
872 public class BgpReactor
873 extends AbstractDataChangeListener<Bgp>
874 implements AutoCloseable {
876 private static final String yangObj = "Bgp ";
878 public BgpReactor() {
882 protected synchronized void
883 add(InstanceIdentifier<Bgp> iid, Bgp val) {
884 LOG.debug("received add Bgp config replaying the config");
887 } catch (Exception e) {
889 synchronized(BgpConfigurationManager.this) {
892 if (isIpAvailable(odlThriftIp)) {
895 ipActivationCheckTimer.scheduleAtFixedRate(new TimerTask() {
897 if (isIpAvailable(odlThriftIp)) {
899 ipActivationCheckTimer.cancel();
908 protected synchronized void
909 remove(InstanceIdentifier<Bgp> iid, Bgp val) {
910 LOG.debug("received remove Bgp config");
911 synchronized(BgpConfigurationManager.this) {
916 protected void update(InstanceIdentifier<Bgp> iid,
917 Bgp oldval, Bgp newval) {
918 synchronized(BgpConfigurationManager.this) {
923 public void close() {
925 for (i=0 ; i < reactors.length ; i++) {
926 if (reactors[i] == BgpReactor.class) {
930 registrations[i].close();
934 public void readOdlThriftIpForBgpCommunication() {
935 File f = new File(CLUSTER_CONF_FILE);
937 odlThriftIp = "127.0.0.1";
940 BufferedReader br = null;
942 br = new BufferedReader(new InputStreamReader(
943 new FileInputStream(f)));
944 String line = br.readLine();
945 while (line != null) {
946 if (line.contains(SDNC_BGP_MIP)) {
948 odlThriftIp = line.substring(line.lastIndexOf(" ")+1);
951 line = br.readLine();
953 } catch (Exception e) {
955 try {br.close();} catch (Exception ignore){}
959 public boolean isIpAvailable(String odlip) {
963 if ("127.0.0.1".equals(odlip)) {
966 Enumeration e = NetworkInterface.getNetworkInterfaces();
967 while(e.hasMoreElements())
969 NetworkInterface n = (NetworkInterface) e.nextElement();
970 Enumeration ee = n.getInetAddresses();
971 while (ee.hasMoreElements())
973 InetAddress i = (InetAddress) ee.nextElement();
974 if (odlip.equals(i.getHostAddress())) {
980 } catch (Exception e) {
985 public void bgpRestarted() {
987 * If there a thread which in the process of stale cleanup, cancel it
988 * and start a new thread (to avoid processing same again).
990 if (lastCleanupJobReference.get() != null) {
991 lastCleanupJobReference.get().cancel(true);
992 lastCleanupJobReference.set(null);
994 Runnable task = new Runnable() {
998 long startTime = System.currentTimeMillis();
999 LOG.error("started creating stale fib map ");
1000 createStaleFibMap();
1001 long endTime = System.currentTimeMillis();
1002 LOG.error("took {} msecs for stale fib map creation ", endTime - startTime);
1003 LOG.error("started bgp config replay ");
1004 startTime = endTime;
1006 endTime = System.currentTimeMillis();
1007 LOG.error("took {} msecs for bgp replay ", endTime - startTime);
1008 long route_sync_time = BGP_RESTART_ROUTE_SYNC_SEC;
1010 route_sync_time = bgpManager.getConfig().getGracefulRestart().getStalepathTime();
1011 } catch (Exception e) {
1012 LOG.error("BGP config/Stale-path time is not set");
1014 Thread.sleep(route_sync_time * 1000L);
1015 new RouteCleanup().call();
1017 } catch (Exception eCancel) {
1018 LOG.error("Stale Cleanup Task Cancelled", eCancel);
1022 lastCleanupJob = executor.submit(task);
1023 lastCleanupJobReference.set(lastCleanupJob);
1026 private static void doRouteSync() {
1027 BgpSyncHandle bsh = BgpSyncHandle.getInstance();
1028 LOG.debug("Starting BGP route sync");
1030 bgpRouter.initRibSync(bsh);
1031 } catch (Exception e) {
1032 LOG.error("Route sync aborted, exception when initialzing: "+e);
1035 while (bsh.getState() != bsh.DONE) {
1036 Routes routes = null;
1038 routes = bgpRouter.doRibSync(bsh);
1039 } catch (Exception e) {
1040 LOG.error("Route sync aborted, exception when syncing: "+e);
1043 Iterator<Update> updates = routes.getUpdatesIterator();
1044 while (updates.hasNext()) {
1045 Update u = updates.next();
1046 Map<String, Map<String, String>> stale_fib_rd_map = BgpConfigurationManager.getStaledFibEntriesMap();
1047 String rd = u.getRd();
1048 String nexthop = u.getNexthop();
1049 int label = u.getLabel();
1050 String prefix = u.getPrefix();
1051 int plen = u.getPrefixlen();
1052 onUpdatePushRoute(rd, prefix, plen, nexthop, label);
1056 LOG.debug("Ending BGP route-sync");
1057 bgpRouter.endRibSync(bsh);
1058 } catch (Exception e) {
1062 /* onUpdatePushRoute
1063 * Get Stale fib map, and compare current route/fib entry.
1064 * - Entry compare shall include NextHop, Label.
1065 * - If entry matches: delete from STALE Map. NO Change to FIB Config DS.
1066 * - If entry nor found, add to FIB Config DS.
1067 * - If entry found, but either Label/NextHop doesnt match.
1068 * - Update FIB Config DS with modified values.
1069 * - delete from Stale Map.
1071 public static void onUpdatePushRoute(String rd, String prefix, int plen,
1072 String nexthop, int label) {
1073 Map<String, Map<String, String>> stale_fib_rd_map = BgpConfigurationManager.getStaledFibEntriesMap();
1074 boolean addroute = false;
1075 if (!stale_fib_rd_map.isEmpty()) {
1076 // restart Scenario, as MAP is not empty.
1077 Map<String, String> map = stale_fib_rd_map.get(rd);
1079 String nexthoplabel = map.get(prefix + "/" + plen);
1080 if (null == nexthoplabel) {
1081 // New Entry, which happend to be added during restart.
1084 map.remove(prefix + "/" + plen);
1085 if (isRouteModified(nexthop, label, nexthoplabel)) {
1086 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix,
1087 plen, nexthop, label);
1088 // Existing entry, where in Nexthop/Label got modified during restart
1094 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix,
1095 plen, nexthop, label);
1099 fib.addFibEntryToDS(rd, prefix + "/" + plen,
1104 private static boolean isRouteModified(String nexthop, int label, String nexthoplabel) {
1105 return !nexthoplabel.isEmpty() && !nexthoplabel.equals(nexthop+"/"+label);
1108 static private void replayNbrConfig(List<Neighbors> n, BgpRouter br) {
1109 for (Neighbors nbr : n) {
1111 br.addNeighbor(nbr.getAddress().getValue(),
1112 nbr.getRemoteAs().intValue());
1113 //itmProvider.buildTunnelsToDCGW(new IpAddress(nbr.getAddress().getValue().toCharArray()));
1114 } catch (Exception e) {
1115 LOG.error("Replay:addNbr() received exception: \""+e+"\"");
1118 EbgpMultihop en = nbr.getEbgpMultihop();
1121 br.addEbgpMultihop(en.getPeerIp().getValue(),
1122 en.getNhops().intValue());
1123 } catch (Exception e) {
1124 LOG.error("Replay:addEBgp() received exception: \""+e+"\"");
1127 UpdateSource us = nbr.getUpdateSource();
1130 br.addUpdateSource(us.getPeerIp().getValue(),
1131 us.getSourceIp().getValue());
1132 } catch (Exception e) {
1133 LOG.error("Replay:addUS() received exception: \""+e+"\"");
1136 List<AddressFamilies> afs = nbr.getAddressFamilies();
1138 for (AddressFamilies af : afs) {
1139 af_afi afi = af_afi.findByValue(af.getAfi().intValue());
1140 af_safi safi = af_safi.findByValue(af.getSafi().intValue());
1142 br.addAddressFamily(af.getPeerIp().getValue(), afi, safi);
1143 } catch (Exception e) {
1144 LOG.error("Replay:addAf() received exception: \""+e+"\"");
1151 public static String getConfigHost() {
1152 if (config == null) {
1153 return cHostStartup;
1155 ConfigServer ts = config.getConfigServer();
1156 return (ts == null ? cHostStartup : ts.getHost().getValue());
1159 public static int getConfigPort() {
1160 if (config == null) {
1161 return Integer.parseInt(cPortStartup);
1163 ConfigServer ts = config.getConfigServer();
1164 return (ts == null ? Integer.parseInt(cPortStartup) :
1165 ts.getPort().intValue());
1168 public static synchronized void replay() {
1169 String host = getConfigHost();
1170 int port = getConfigPort();
1171 boolean res = bgpRouter.connect(host, port);
1173 String msg = "Cannot connect to BGP config server at "+host+":"+port;
1174 if (config != null) {
1175 msg += "; Configuration Replay aborted";
1180 if (config == null) {
1183 BgpRouter br = bgpRouter;
1184 AsId a = config.getAsId();
1188 int asNum = a.getLocalAs().intValue();
1189 Ipv4Address routerId = a.getRouterId();
1190 Long spt = a.getStalepathTime();
1191 Boolean afb = a.isAnnounceFbit();
1192 String rid = (routerId == null) ? "" : routerId.getValue();
1193 int stalepathTime = (spt == null) ? 90 : spt.intValue();
1194 boolean announceFbit = (afb == null) ? false : afb.booleanValue();
1196 br.startBgp(asNum, rid, stalepathTime, announceFbit);
1197 } catch (BgpRouterException bre) {
1198 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
1201 LOG.error("Replay: startBgp() received exception: \""
1202 +bre+"\"; "+addWarn);
1204 } catch (Exception e) {
1205 //not unusual. We may have restarted & BGP is already on
1206 LOG.error("Replay:startBgp() received exception: \""+e+"\"");
1209 if (bgpManager.getBgpCounters() == null) {
1210 bgpManager.startBgpCountersTask();
1213 Logging l = config.getLogging();
1216 br.setLogging(l.getFile(), l.getLevel());
1217 } catch (Exception e) {
1218 LOG.error("Replay:setLogging() received exception: \""+e+"\"");
1222 GracefulRestart g = config.getGracefulRestart();
1225 br.addGracefulRestart(g.getStalepathTime().intValue());
1226 } catch (Exception e) {
1227 LOG.error("Replay:addGr() received exception: \""+e+"\"");
1231 List<Neighbors> n = config.getNeighbors();
1233 replayNbrConfig(n, br);
1236 List<Vrfs> v = config.getVrfs();
1238 for (Vrfs vrf : v) {
1240 br.addVrf(vrf.getRd(), vrf.getImportRts(),
1241 vrf.getExportRts());
1242 } catch (Exception e) {
1243 LOG.error("Replay:addVrf() received exception: \""+e+"\"");
1248 List<Networks> ln = config.getNetworks();
1250 for (Networks net : ln) {
1251 String rd = net.getRd();
1252 String pfxlen = net.getPrefixLen();
1253 String nh = net.getNexthop().getValue();
1254 Long label = net.getLabel();
1255 int lbl = (label == null) ? 0 : label.intValue();
1256 if (rd == null && lbl > 0) {
1257 //LU prefix is being deleted.
1258 rd = Integer.toString(lbl);
1261 br.addPrefix(rd, pfxlen, nh, lbl);
1262 } catch (Exception e) {
1263 LOG.error("Replay:addPfx() received exception: \""+e+"\"");
1269 private <T extends DataObject> void update(InstanceIdentifier<T> iid, T dto) {
1270 BgpUtil.update(broker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1273 private <T extends DataObject> void asyncWrite(InstanceIdentifier<T> iid, T dto) {
1274 BgpUtil.write(broker,LogicalDatastoreType.CONFIGURATION,iid,dto);
1277 private <T extends DataObject> void delete(InstanceIdentifier<T> iid) {
1278 BgpUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, iid);
1281 public synchronized void
1282 startConfig(String bgpHost, int thriftPort) {
1283 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1284 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1285 InstanceIdentifier<ConfigServer> iid = iib.build();
1286 Ipv4Address ipAddr = new Ipv4Address(bgpHost);
1287 ConfigServer dto = new ConfigServerBuilder().setHost(ipAddr)
1288 .setPort((long) thriftPort).build();
1292 public synchronized void
1293 startBgp(int as, String routerId, int spt, boolean fbit) {
1294 Long localAs = (long) as;
1295 Ipv4Address rid = (routerId == null) ?
1296 null : new Ipv4Address(routerId);
1297 Long staleTime = (long) spt;
1298 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1299 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1300 InstanceIdentifier<AsId> iid = iib.build();
1301 AsId dto = new AsIdBuilder().setLocalAs(localAs)
1303 .setStalepathTime(staleTime)
1304 .setAnnounceFbit(fbit).build();
1308 public synchronized void
1309 addLogging(String fileName, String logLevel) {
1310 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1311 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1312 InstanceIdentifier<Logging> iid = iib.build();
1313 Logging dto = new LoggingBuilder().setFile(fileName)
1314 .setLevel(logLevel).build();
1318 public synchronized void
1319 addGracefulRestart(int staleTime) {
1320 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1321 InstanceIdentifier.builder(Bgp.class).child(GracefulRestart.class);
1322 InstanceIdentifier<GracefulRestart> iid = iib.build();
1323 GracefulRestart dto = new GracefulRestartBuilder()
1324 .setStalepathTime((long)staleTime).build();
1328 public synchronized void
1329 addNeighbor(String nbrIp, int remoteAs) {
1330 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1331 Long rAs = (long) remoteAs;
1332 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1333 InstanceIdentifier.builder(Bgp.class)
1334 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1335 InstanceIdentifier<Neighbors> iid = iib.build();
1336 Neighbors dto = new NeighborsBuilder().setAddress(nbrAddr)
1337 .setRemoteAs(rAs).build();
1341 public synchronized void
1342 addUpdateSource(String nbrIp, String srcIp) {
1343 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1344 Ipv4Address srcAddr = new Ipv4Address(srcIp);
1345 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1346 InstanceIdentifier.builder(Bgp.class)
1347 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1348 .child(UpdateSource.class);
1349 InstanceIdentifier<UpdateSource> iid = iib.build();
1350 UpdateSource dto = new UpdateSourceBuilder().setPeerIp(nbrAddr)
1351 .setSourceIp(srcAddr).build();
1355 public synchronized void
1356 addEbgpMultihop(String nbrIp, int nHops) {
1357 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1358 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1359 InstanceIdentifier.builder(Bgp.class)
1360 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1361 .child(EbgpMultihop.class);
1362 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1363 EbgpMultihop dto = new EbgpMultihopBuilder().setPeerIp(nbrAddr)
1364 .setNhops((long)nHops).build();
1368 public synchronized void
1369 addAddressFamily(String nbrIp, int afi, int safi) {
1370 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1371 Long a = (long) afi;
1372 Long sa = (long) safi;
1373 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1374 InstanceIdentifier.builder(Bgp.class)
1375 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1376 .child(AddressFamilies.class, new AddressFamiliesKey(a, sa));
1377 InstanceIdentifier<AddressFamilies> iid = iib.build();
1378 AddressFamilies dto = new AddressFamiliesBuilder().setPeerIp(nbrAddr)
1379 .setAfi(a).setSafi(sa).build();
1383 public synchronized void
1384 addPrefix(String rd, String pfx, String nh, int lbl) {
1385 Ipv4Address nexthop = new Ipv4Address(nh);
1386 Long label = (long) lbl;
1387 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
1388 InstanceIdentifier.builder(Bgp.class)
1389 .child(Networks.class, new NetworksKey(pfx, rd));
1390 InstanceIdentifier<Networks> iid = iib.build();
1391 Networks dto = new NetworksBuilder().setRd(rd)
1393 .setNexthop(nexthop)
1394 .setLabel(label).build();
1398 public synchronized void
1399 addVrf(String rd, List<String> irts, List<String> erts) {
1400 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1401 InstanceIdentifier.builder(Bgp.class)
1402 .child(Vrfs.class, new VrfsKey(rd));
1403 InstanceIdentifier<Vrfs> iid = iib.build();
1404 Vrfs dto = new VrfsBuilder().setRd(rd)
1406 .setExportRts(erts).build();
1408 asyncWrite(iid, dto);
1411 public synchronized void stopConfig() {
1412 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1413 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1414 InstanceIdentifier<ConfigServer> iid = iib.build();
1418 public synchronized void stopBgp() {
1419 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1420 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1421 InstanceIdentifier<AsId> iid = iib.build();
1425 public synchronized void delLogging() {
1426 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1427 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1428 InstanceIdentifier<Logging> iid = iib.build();
1432 public synchronized void delGracefulRestart() {
1433 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1434 InstanceIdentifier.builder(Bgp.class)
1435 .child(GracefulRestart.class);
1436 InstanceIdentifier<GracefulRestart> iid = iib.build();
1440 public synchronized void delNeighbor(String nbrIp) {
1441 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1442 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1443 InstanceIdentifier.builder(Bgp.class)
1444 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1445 InstanceIdentifier<Neighbors> iid = iib.build();
1449 public synchronized void delUpdateSource(String nbrIp) {
1450 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1451 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1452 InstanceIdentifier.builder(Bgp.class)
1453 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1454 .child(UpdateSource.class);
1455 InstanceIdentifier<UpdateSource> iid = iib.build();
1459 public synchronized void delEbgpMultihop(String nbrIp) {
1460 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1461 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1462 InstanceIdentifier.builder(Bgp.class)
1463 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1464 .child(EbgpMultihop.class);
1465 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1469 public synchronized void
1470 delAddressFamily(String nbrIp, int afi, int safi) {
1471 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1472 Long a = (long) afi;
1473 Long sa = (long) safi;
1474 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1475 InstanceIdentifier.builder(Bgp.class)
1476 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1477 .child(AddressFamilies.class, new AddressFamiliesKey(a, sa));
1478 InstanceIdentifier<AddressFamilies> iid = iib.build();
1482 public synchronized void delPrefix(String rd, String pfx) {
1483 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
1484 InstanceIdentifier.builder(Bgp.class)
1485 .child(Networks.class, new NetworksKey(pfx, rd));
1486 InstanceIdentifier<Networks> iid = iib.build();
1490 public synchronized void delVrf(String rd) {
1491 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1492 InstanceIdentifier.builder(Bgp.class)
1493 .child(Vrfs.class, new VrfsKey(rd));
1494 InstanceIdentifier<Vrfs> iid = iib.build();
1498 static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
1500 * Remove Stale Marked Routes after timer expiry.
1502 class RouteCleanup implements Callable<Integer> {
1504 public Integer call () {
1505 int totalCleared = 0;
1507 if (staledFibEntriesMap.isEmpty()) {
1508 LOG.info("BGP: RouteCleanup timertask tirggered but STALED FIB MAP is EMPTY");
1510 for (String rd : staledFibEntriesMap.keySet()) {
1511 if (Thread.interrupted()) {
1514 Map<String, String> map = staledFibEntriesMap.get(rd);
1516 for (String prefix : map.keySet()) {
1517 if (Thread.interrupted()) {
1522 bgpManager.deletePrefix(rd, prefix);
1523 } catch (Exception e) {
1524 LOG.error("BGP: RouteCleanup deletePrefix failed rd:{}, prefix{}" + rd.toString() + prefix);
1530 } catch(Exception e) {
1531 LOG.error("Cleanup Thread Got interrupted, Failed to cleanup stale routes ", e);
1533 staledFibEntriesMap.clear();
1535 LOG.error("cleared {} stale routes after bgp restart", totalCleared);
1541 * BGP restart scenario, ODL-BGP manager was/is running.
1542 * On re-sync notification, Get a copy of FIB database.
1544 public static void createStaleFibMap() {
1545 int totalStaledCount = 0;
1547 staledFibEntriesMap.clear();
1548 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
1549 DataBroker db = BgpUtil.getBroker();
1551 LOG.error("Couldn't find BgpUtil broker while creating createStaleFibMap");
1555 Optional<FibEntries> fibEntries = BgpUtil.read(BgpUtil.getBroker(),
1556 LogicalDatastoreType.CONFIGURATION, id);
1557 if (fibEntries.isPresent()) {
1558 List<VrfTables> stale_vrfTables = fibEntries.get().getVrfTables();
1559 for (VrfTables vrfTable : stale_vrfTables) {
1560 Map<String, String> stale_fib_ent_map = new HashMap<>();
1561 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
1562 if (Thread.interrupted()) {
1566 //Create MAP from stale_vrfTables.
1567 stale_fib_ent_map.put(vrfEntry.getDestPrefix(), vrfEntry.getNextHopAddress() + "/" + vrfEntry.getLabel());
1569 staledFibEntriesMap.put(vrfTable.getRouteDistinguisher(), stale_fib_ent_map);
1572 LOG.error("createStaleFibMap:: FIBentries.class is not present");
1574 } catch (Exception e) {
1575 LOG.error("createStaleFibMap:: erorr ", e);
1577 LOG.error("created {} staled entries ", totalStaledCount);
1580 //map<rd, map<prefix/len, nexthop/label>>
1581 public static Map<String, Map<String, String>> getStaledFibEntriesMap() {
1582 return staledFibEntriesMap;