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;
15 import java.lang.reflect.*;
16 import java.net.InetAddress;
17 import java.net.NetworkInterface;
18 import java.util.concurrent.*;
19 import java.util.concurrent.atomic.AtomicBoolean;
21 import org.opendaylight.netvirt.bgpmanager.api.RouteOrigin;
22 import org.opendaylight.netvirt.bgpmanager.commands.ClearBgpCli;
23 import org.opendaylight.netvirt.bgpmanager.thrift.gen.*;
24 import org.opendaylight.netvirt.bgpmanager.thrift.client.*;
25 import org.opendaylight.netvirt.bgpmanager.thrift.server.*;
26 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
27 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
28 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
29 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipChange;
30 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipListener;
31 import org.opendaylight.controller.md.sal.common.api.clustering.EntityOwnershipService;
32 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
33 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
34 import org.opendaylight.genius.utils.clustering.EntityOwnerUtils;
35 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.*;
36 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.*;
37 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.*;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.*;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
42 import org.opendaylight.yangtools.concepts.ListenerRegistration;
43 import org.opendaylight.yangtools.yang.binding.DataObject;
44 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
45 import org.osgi.framework.Bundle;
46 import org.osgi.framework.BundleContext;
47 import org.osgi.framework.FrameworkUtil;
48 import org.slf4j.Logger;
49 import org.slf4j.LoggerFactory;
51 public class BgpConfigurationManager {
52 private static final Logger LOG =
53 LoggerFactory.getLogger(BgpConfigurationManager.class);
54 private static DataBroker broker;
55 private static FibDSWriter fib;
56 private static Bgp config;
57 private static BgpRouter bgpRouter;
58 private static BgpThriftService updateServer;
60 private static final String DEF_LOGFILE = "/var/log/bgp_debug.log";
61 private static final String DEF_LOGLEVEL = "errors";
62 private static final String UPDATE_PORT = "bgp.thrift.service.port";
63 private static final String CONFIG_HOST = "vpnservice.bgpspeaker.host.name";
64 private static final String CONFIG_PORT = "vpnservice.bgpspeaker.thrift.port";
65 private static final String DEF_UPORT = "6644";
66 private static final String DEF_CHOST = "127.0.0.1";
67 private static final String DEF_CPORT = "7644";
68 private static final String SDNC_BGP_MIP = "sdnc_bgp_mip";
69 private static final String CLUSTER_CONF_FILE = "/cluster/etc/cluster.conf";
70 private static final Timer ipActivationCheckTimer = new Timer();
71 private static final int STALE_FIB_WAIT = 60;
72 private static final int RESTART_DEFAULT_GR = 90;
73 private long StaleStartTime = 0;
74 private long StaleEndTime = 0;
75 private long CfgReplayStartTime = 0;
76 private long CfgReplayEndTime = 0;
77 private long StaleCleanupTime = 0;
79 public long getStaleCleanupTime() {
80 return StaleCleanupTime;
83 public void setStaleCleanupTime(long staleCleanupTime) {
84 StaleCleanupTime = staleCleanupTime;
87 public long getCfgReplayEndTime() {
88 return CfgReplayEndTime;
91 public void setCfgReplayEndTime(long cfgReplayEndTime) {
92 CfgReplayEndTime = cfgReplayEndTime;
95 public long getCfgReplayStartTime() {
96 return CfgReplayStartTime;
99 public void setCfgReplayStartTime(long cfgReplayStartTime) {
100 CfgReplayStartTime = cfgReplayStartTime;
103 public long getStaleEndTime() {
107 public void setStaleEndTime(long staleEndTime) {
108 StaleEndTime = staleEndTime;
111 public long getStaleStartTime() {
112 return StaleStartTime;
115 public void setStaleStartTime(long staleStartTime) {
116 StaleStartTime = staleStartTime;
120 // to have stale FIB map (RD, Prefix)
121 // number of seconds wait for route sync-up between ODL and BGP.
122 private static final int BGP_RESTART_ROUTE_SYNC_SEC = 360;
124 static String odlThriftIp = "127.0.0.1";
125 private static String cHostStartup;
126 private static String cPortStartup;
127 private static CountDownLatch initer = new CountDownLatch(1);
128 //static IITMProvider itmProvider;
129 public static BgpManager bgpManager;
130 //map<rd, map<prefix/len, nexthop/label>>
131 private static Map<String, Map<String, String>> staledFibEntriesMap = new ConcurrentHashMap<>();
133 static final String BGP_ENTITY_TYPE_FOR_OWNERSHIP = "bgp";
134 static final String BGP_ENTITY_NAME = "bgp";
136 static int totalStaledCount = 0;
137 static int totalCleared = 0;
139 private static final Class[] reactors =
141 ConfigServerReactor.class, AsIdReactor.class,
142 GracefulRestartReactor.class, LoggingReactor.class,
143 NeighborsReactor.class, UpdateSourceReactor.class,
144 EbgpMultihopReactor.class, AddressFamiliesReactor.class,
145 NetworksReactor.class, VrfsReactor.class, BgpReactor.class
148 private ListenerRegistration<DataChangeListener>[] registrations;
149 EntityOwnershipService entityOwnershipService;
151 private Object createListener(Class<?> cls) {
156 ctor = cls.getConstructor(BgpConfigurationManager.class);
157 obj = ctor.newInstance(this);
158 } catch (Exception e) {
159 LOG.error("Failed to create listener object", e);
164 private void registerCallbacks() {
165 String emsg = "Failed to register listener";
166 registrations = new ListenerRegistration[reactors.length];
167 InstanceIdentifier<?> iid = InstanceIdentifier.create(Bgp.class);
168 for (Class reactor : reactors) {
169 Object obj = createListener(reactor);
170 String dclName = obj.getClass().getName();
172 AsyncDataTreeChangeListenerBase dcl = (AsyncDataTreeChangeListenerBase) obj;
173 dcl.registerListener(LogicalDatastoreType.CONFIGURATION, broker);
174 } catch (Exception e) {
176 throw new IllegalStateException(emsg + " " + dclName, e);
181 public void close() {
182 if (updateServer != null) {
187 private boolean configExists() throws InterruptedException, ExecutionException, TimeoutException {
188 InstanceIdentifier.InstanceIdentifierBuilder<Bgp> iib =
189 InstanceIdentifier.builder(Bgp.class);
190 InstanceIdentifier<Bgp> iid = iib.build();
191 Optional<Bgp> b = BgpUtil.read(broker,
192 LogicalDatastoreType.CONFIGURATION, iid);
193 return b.isPresent();
196 private String getProperty(String var, String def) {
197 Bundle b = FrameworkUtil.getBundle(BgpManager.class);
201 BundleContext context = b.getBundleContext();
202 if (context == null) {
205 String s = context.getProperty(var);
206 return (s == null ? def : s);
209 static BgpConfigurationManager bgpConfigurationManager;
211 public BgpConfigurationManager(BgpManager bgpMgr) throws InterruptedException, ExecutionException, TimeoutException {
212 broker = bgpMgr.getBroker();
213 fib = bgpMgr.getFibWriter();
216 bgpRouter = BgpRouter.getInstance();
217 String uPort = getProperty(UPDATE_PORT, DEF_UPORT);
218 cHostStartup = getProperty(CONFIG_HOST, DEF_CHOST);
219 cPortStartup = getProperty(CONFIG_PORT, DEF_CPORT);
220 VtyshCli.setHostAddr(cHostStartup);
221 ClearBgpCli.setHostAddr(cHostStartup);
222 LOG.info("UpdateServer at localhost:" + uPort + " ConfigServer at "
223 + cHostStartup + ":" + cPortStartup);
224 updateServer = new BgpThriftService(Integer.parseInt(uPort), bgpMgr);
225 updateServer.start();
226 readOdlThriftIpForBgpCommunication();
229 LOG.info("BGP Configuration manager initialized");
232 bgpConfigurationManager = this;
235 boolean ignoreClusterDcnEventForFollower() {
236 return !EntityOwnerUtils.amIEntityOwner(BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME);
240 config = bgpManager.getConfig();
244 public void setEntityOwnershipService(EntityOwnershipService entityOwnershipService) {
245 this.entityOwnershipService = entityOwnershipService;
247 EntityOwnerUtils.registerEntityCandidateForOwnerShip(entityOwnershipService,
248 BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME, new EntityOwnershipListener() {
250 public void ownershipChanged(EntityOwnershipChange ownershipChange) {
251 LOG.trace("entity owner change event fired");
252 if (ownershipChange.hasOwner() && ownershipChange.isOwner()) {
253 LOG.trace("This PL is the Owner");
257 LOG.error("Not owner: hasOwner: {}, isOwner: {}",ownershipChange.hasOwner(),
258 ownershipChange.isOwner() );
262 } catch (Exception e) {
263 LOG.error("failed to register bgp entity", e);
267 public EntityOwnershipService getEntityOwnershipService() {
268 return entityOwnershipService;
271 private static final String addWarn =
272 "Config store updated; undo with Delete if needed.";
273 private static final String delWarn =
274 "Config store updated; undo with Add if needed.";
275 private static final String updWarn =
276 "Update operation not supported; Config store updated;"
277 + " restore with another Update if needed.";
279 public class ConfigServerReactor
280 extends AsyncDataTreeChangeListenerBase<ConfigServer, ConfigServerReactor>
281 implements AutoCloseable, ClusteredDataTreeChangeListener <ConfigServer> {
282 private static final String yangObj = "config-server ";
284 public ConfigServerReactor() {
285 super(ConfigServer.class, ConfigServerReactor.class);
288 protected synchronized void
289 add(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
290 LOG.trace("received bgp connect config host {}", val.getHost().getValue());
291 if (ignoreClusterDcnEventForFollower()) {
297 } catch (Exception e) {
299 LOG.debug("issueing bgp router connect to host {}", val.getHost().getValue());
300 synchronized (BgpConfigurationManager.this) {
301 boolean res = bgpRouter.connect(val.getHost().getValue(),
302 val.getPort().intValue());
304 LOG.error(yangObj + "Add failed; " + addWarn);
310 protected ConfigServerReactor getDataTreeChangeListener() {
311 return ConfigServerReactor.this;
315 protected InstanceIdentifier<ConfigServer> getWildCardPath() {
316 return InstanceIdentifier.create(Bgp.class).child(ConfigServer.class);
319 protected synchronized void
320 remove(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
321 LOG.trace("received bgp disconnect");
322 if (ignoreClusterDcnEventForFollower()) {
325 synchronized (BgpConfigurationManager.this) {
326 bgpRouter.disconnect();
330 protected void update(InstanceIdentifier<ConfigServer> iid,
331 ConfigServer oldval, ConfigServer newval) {
332 LOG.trace("received bgp Connection update");
333 if (ignoreClusterDcnEventForFollower()) {
336 LOG.error(yangObj + updWarn);
340 public void close() {
343 } catch (Exception e) {
349 private BgpRouter getClient(String yangObj) {
350 if (bgpRouter == null) {
351 LOG.warn(yangObj + ": configuration received when BGP is inactive");
356 public class AsIdReactor
357 extends AsyncDataTreeChangeListenerBase<AsId, AsIdReactor>
358 implements AutoCloseable, ClusteredDataTreeChangeListener<AsId> {
360 private static final String yangObj = "as-id ";
362 public AsIdReactor() {
363 super(AsId.class, AsIdReactor.class);
366 protected synchronized void
367 add(InstanceIdentifier<AsId> iid, AsId val) {
368 LOG.error("received bgp add asid");
369 if (ignoreClusterDcnEventForFollower()) {
372 LOG.debug("received add router config asNum {}", val.getLocalAs().intValue());
373 synchronized (BgpConfigurationManager.this) {
374 BgpRouter br = getClient(yangObj);
376 LOG.error("no bgp router client found exiting asid add");
379 int asNum = val.getLocalAs().intValue();
380 Ipv4Address routerId = val.getRouterId();
381 Boolean afb = val.isAnnounceFbit();
382 String rid = (routerId == null) ? "" : routerId.getValue();
383 int stalepathTime = (int) getStalePathtime(RESTART_DEFAULT_GR, val);
384 boolean announceFbit = (afb == null) ? false : afb.booleanValue();
386 br.startBgp(asNum, rid, stalepathTime, announceFbit);
387 if (bgpManager.getBgpCounters() == null) {
388 bgpManager.startBgpCountersTask();
390 } catch (BgpRouterException bre) {
391 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
392 LOG.error(yangObj + "Add requested when BGP is already active");
394 LOG.error(yangObj + "Add received exception: \""
395 + bre + "\"; " + addWarn);
397 } catch (Exception e) {
398 LOG.error(yangObj + "Add received exception: \"" + e + "\"; " + addWarn);
404 protected AsIdReactor getDataTreeChangeListener() {
405 return AsIdReactor.this;
409 protected InstanceIdentifier<AsId> getWildCardPath() {
410 return InstanceIdentifier.create(Bgp.class).child(AsId.class);
413 protected synchronized void
414 remove(InstanceIdentifier<AsId> iid, AsId val) {
415 LOG.error("received delete router config asNum {}", val.getLocalAs().intValue());
416 if (ignoreClusterDcnEventForFollower()) {
419 synchronized (BgpConfigurationManager.this) {
420 BgpRouter br = getClient(yangObj);
424 int asNum = val.getLocalAs().intValue();
427 } catch (Exception e) {
428 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; " + delWarn);
430 if (bgpManager.getBgpCounters() != null) {
431 bgpManager.stopBgpCountersTask();
436 protected void update(InstanceIdentifier<AsId> iid,
437 AsId oldval, AsId newval) {
438 if (ignoreClusterDcnEventForFollower()) {
441 LOG.error(yangObj + updWarn);
445 public void close() {
448 } catch (Exception e) {
454 public class GracefulRestartReactor
455 extends AsyncDataTreeChangeListenerBase<GracefulRestart, GracefulRestartReactor>
456 implements AutoCloseable, ClusteredDataTreeChangeListener<GracefulRestart> {
458 private static final String yangObj = "graceful-restart ";
460 public GracefulRestartReactor() {
461 super(GracefulRestart.class, GracefulRestartReactor.class);
464 protected synchronized void
465 add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
466 if (ignoreClusterDcnEventForFollower()) {
469 synchronized (BgpConfigurationManager.this) {
470 BgpRouter br = getClient(yangObj);
475 br.addGracefulRestart(val.getStalepathTime().intValue());
476 } catch (Exception e) {
477 LOG.error(yangObj + "Add received exception: \"" + e + "\"; " + addWarn);
483 protected GracefulRestartReactor getDataTreeChangeListener() {
484 return GracefulRestartReactor.this;
488 protected InstanceIdentifier<GracefulRestart> getWildCardPath() {
489 return InstanceIdentifier.create(Bgp.class).child(GracefulRestart.class);
492 protected synchronized void
493 remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
494 if (ignoreClusterDcnEventForFollower()) {
497 LOG.debug("received delete GracefulRestart config val {}", val.getStalepathTime().intValue());
498 synchronized (BgpConfigurationManager.this) {
499 BgpRouter br = getClient(yangObj);
504 br.delGracefulRestart();
505 } catch (Exception e) {
506 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
512 protected void update(InstanceIdentifier<GracefulRestart> iid,
513 GracefulRestart oldval, GracefulRestart newval) {
514 if (ignoreClusterDcnEventForFollower()) {
517 LOG.debug("received update GracefulRestart config val {}", newval.getStalepathTime().intValue());
518 synchronized (BgpConfigurationManager.this) {
519 BgpRouter br = getClient(yangObj);
524 br.addGracefulRestart(newval.getStalepathTime().intValue());
525 } catch (Exception e) {
526 LOG.error(yangObj + "update received exception: \"" + e + "\"; " + addWarn);
532 public void close() {
535 } catch (Exception e) {
541 public class LoggingReactor
542 extends AsyncDataTreeChangeListenerBase<Logging, LoggingReactor>
543 implements AutoCloseable, ClusteredDataTreeChangeListener<Logging> {
545 private static final String yangObj = "logging ";
547 public LoggingReactor() {
548 super(Logging.class, LoggingReactor.class);
551 protected synchronized void
552 add(InstanceIdentifier<Logging> iid, Logging val) {
553 if (ignoreClusterDcnEventForFollower()) {
556 synchronized (BgpConfigurationManager.this) {
557 BgpRouter br = getClient(yangObj);
562 br.setLogging(val.getFile(), val.getLevel());
563 } catch (Exception e) {
564 LOG.error(yangObj + "Add received exception: \"" + e + "\"; "
571 protected LoggingReactor getDataTreeChangeListener() {
572 return LoggingReactor.this;
576 protected InstanceIdentifier<Logging> getWildCardPath() {
577 return InstanceIdentifier.create(Bgp.class).child(Logging.class);
580 protected synchronized void
581 remove(InstanceIdentifier<Logging> iid, Logging val) {
582 if (ignoreClusterDcnEventForFollower()) {
585 LOG.debug("received remove Logging config val {}", val.getLevel());
586 synchronized (BgpConfigurationManager.this) {
587 BgpRouter br = getClient(yangObj);
592 br.setLogging(DEF_LOGFILE, DEF_LOGLEVEL);
593 } catch (Exception e) {
594 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
600 protected void update(InstanceIdentifier<Logging> iid,
601 Logging oldval, Logging newval) {
602 if (ignoreClusterDcnEventForFollower()) {
605 synchronized (BgpConfigurationManager.this) {
606 BgpRouter br = getClient(yangObj);
611 br.setLogging(newval.getFile(), newval.getLevel());
612 } catch (Exception e) {
613 LOG.error(yangObj + "newval received exception: \"" + e + "\"; "
620 public void close() {
623 } catch (Exception e) {
629 public class NeighborsReactor
630 extends AsyncDataTreeChangeListenerBase<Neighbors, NeighborsReactor>
631 implements AutoCloseable, ClusteredDataTreeChangeListener<Neighbors> {
633 private static final String yangObj = "neighbors ";
635 public NeighborsReactor() {
636 super(Neighbors.class, NeighborsReactor.class);
639 protected synchronized void
640 add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
641 if (ignoreClusterDcnEventForFollower()) {
644 LOG.debug("received add Neighbors config val {}", val.getAddress().getValue());
645 synchronized (BgpConfigurationManager.this) {
646 BgpRouter br = getClient(yangObj);
650 String peerIp = val.getAddress().getValue();
651 int as = val.getRemoteAs().intValue();
653 //itmProvider.buildTunnelsToDCGW(new IpAddress(peerIp.toCharArray()));
654 br.addNeighbor(peerIp, as);
656 } catch (Exception e) {
657 LOG.error(yangObj + "Add received exception: \"" + e + "\"; "
664 protected NeighborsReactor getDataTreeChangeListener() {
665 return NeighborsReactor.this;
669 protected InstanceIdentifier<Neighbors> getWildCardPath() {
670 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class);
673 protected synchronized void
674 remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
675 if (ignoreClusterDcnEventForFollower()) {
678 LOG.debug("received remove Neighbors config val {}", val.getAddress().getValue());
679 synchronized (BgpConfigurationManager.this) {
680 BgpRouter br = getClient(yangObj);
684 String peerIp = val.getAddress().getValue();
686 //itmProvider.deleteTunnelsToDCGW(new IpAddress(val.getAddress().getValue().toCharArray()));
687 br.delNeighbor(peerIp);
688 } catch (Exception e) {
689 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
695 protected void update(InstanceIdentifier<Neighbors> iid,
696 Neighbors oldval, Neighbors newval) {
697 if (ignoreClusterDcnEventForFollower()) {
700 //purposefully nothing to do.
704 public void close() {
707 } catch (Exception e) {
713 public class EbgpMultihopReactor
714 extends AsyncDataTreeChangeListenerBase<EbgpMultihop, EbgpMultihopReactor>
715 implements AutoCloseable, ClusteredDataTreeChangeListener<EbgpMultihop> {
717 private static final String yangObj = "ebgp-multihop ";
719 public EbgpMultihopReactor() {
720 super(EbgpMultihop.class, EbgpMultihopReactor.class);
723 protected synchronized void
724 add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
725 if (ignoreClusterDcnEventForFollower()) {
728 LOG.debug("received add EbgpMultihop config val {}", val.getPeerIp().getValue());
729 synchronized (BgpConfigurationManager.this) {
730 BgpRouter br = getClient(yangObj);
734 String peerIp = val.getPeerIp().getValue();
736 br.addEbgpMultihop(peerIp, val.getNhops().intValue());
737 } catch (Exception e) {
738 LOG.error(yangObj + "Add received exception: \"" + e + "\"; "
745 protected EbgpMultihopReactor getDataTreeChangeListener() {
746 return EbgpMultihopReactor.this;
750 protected InstanceIdentifier<EbgpMultihop> getWildCardPath() {
751 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(EbgpMultihop.class);
754 protected synchronized void
755 remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
756 if (ignoreClusterDcnEventForFollower()) {
759 LOG.debug("received remove EbgpMultihop config val {}", val.getPeerIp().getValue());
760 synchronized (BgpConfigurationManager.this) {
761 BgpRouter br = getClient(yangObj);
765 String peerIp = val.getPeerIp().getValue();
767 br.delEbgpMultihop(peerIp);
768 } catch (Exception e) {
769 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
775 protected void update(InstanceIdentifier<EbgpMultihop> iid,
776 EbgpMultihop oldval, EbgpMultihop newval) {
777 if (ignoreClusterDcnEventForFollower()) {
780 LOG.error(yangObj + updWarn);
784 public void close() {
787 } catch (Exception e) {
793 public class UpdateSourceReactor
794 extends AsyncDataTreeChangeListenerBase<UpdateSource, UpdateSourceReactor>
795 implements AutoCloseable, ClusteredDataTreeChangeListener<UpdateSource> {
797 private static final String yangObj = "update-source ";
799 public UpdateSourceReactor() {
800 super(UpdateSource.class, UpdateSourceReactor.class);
803 protected synchronized void
804 add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
805 if (ignoreClusterDcnEventForFollower()) {
808 LOG.debug("received add UpdateSource config val {}", val.getSourceIp().getValue());
809 synchronized (BgpConfigurationManager.this) {
810 BgpRouter br = getClient(yangObj);
814 String peerIp = val.getPeerIp().getValue();
816 br.addUpdateSource(peerIp, val.getSourceIp().getValue());
817 } catch (Exception e) {
818 LOG.error(yangObj + "Add received exception: \"" + e + "\"; "
825 protected UpdateSourceReactor getDataTreeChangeListener() {
826 return UpdateSourceReactor.this;
830 protected InstanceIdentifier<UpdateSource> getWildCardPath() {
831 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(UpdateSource.class);
834 protected synchronized void
835 remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
836 if (ignoreClusterDcnEventForFollower()) {
839 LOG.debug("received remove UpdateSource config val {}", val.getSourceIp().getValue());
840 synchronized (BgpConfigurationManager.this) {
841 BgpRouter br = getClient(yangObj);
845 String peerIp = val.getPeerIp().getValue();
847 br.delUpdateSource(peerIp);
848 } catch (Exception e) {
849 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
855 protected void update(InstanceIdentifier<UpdateSource> iid,
856 UpdateSource oldval, UpdateSource newval) {
857 if (ignoreClusterDcnEventForFollower()) {
860 LOG.error(yangObj + updWarn);
864 public void close() {
867 } catch (Exception e) {
873 public class AddressFamiliesReactor
874 extends AsyncDataTreeChangeListenerBase<AddressFamilies, AddressFamiliesReactor>
875 implements AutoCloseable, ClusteredDataTreeChangeListener<AddressFamilies> {
877 private static final String yangObj = "address-families ";
879 public AddressFamiliesReactor() {
880 super(AddressFamilies.class, AddressFamiliesReactor.class);
883 protected synchronized void
884 add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
885 if (ignoreClusterDcnEventForFollower()) {
888 LOG.debug("received add AddressFamilies config val {}", val.getPeerIp().getValue());
889 synchronized (BgpConfigurationManager.this) {
890 BgpRouter br = getClient(yangObj);
894 String peerIp = val.getPeerIp().getValue();
895 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
896 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
898 br.addAddressFamily(peerIp, afi, safi);
899 } catch (Exception e) {
900 LOG.error(yangObj + "Add received exception: \"" + e + "\"; "
907 protected AddressFamiliesReactor getDataTreeChangeListener() {
908 return AddressFamiliesReactor.this;
912 protected InstanceIdentifier<AddressFamilies> getWildCardPath() {
913 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(AddressFamilies.class);
916 protected synchronized void
917 remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
918 if (ignoreClusterDcnEventForFollower()) {
921 LOG.debug("received remove AddressFamilies config val {}", val.getPeerIp().getValue());
922 synchronized (BgpConfigurationManager.this) {
923 BgpRouter br = getClient(yangObj);
927 String peerIp = val.getPeerIp().getValue();
928 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
929 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
931 br.delAddressFamily(peerIp, afi, safi);
932 } catch (Exception e) {
933 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
939 protected void update(InstanceIdentifier<AddressFamilies> iid,
940 AddressFamilies oldval, AddressFamilies newval) {
941 if (ignoreClusterDcnEventForFollower()) {
944 LOG.error(yangObj + updWarn);
948 public void close() {
951 } catch (Exception e) {
957 public class NetworksReactor
958 extends AsyncDataTreeChangeListenerBase<Networks, NetworksReactor>
959 implements AutoCloseable, ClusteredDataTreeChangeListener<Networks> {
961 private static final String yangObj = "networks ";
963 public NetworksReactor() {
964 super(Networks.class, NetworksReactor.class);
967 public NetworksReactor getDataTreeChangeListener() {
968 return NetworksReactor.this;
971 protected synchronized void
972 add(InstanceIdentifier<Networks> iid, Networks val) {
973 if (ignoreClusterDcnEventForFollower()) {
976 LOG.debug("received add Networks config val {}", val.getPrefixLen());
977 synchronized (BgpConfigurationManager.this) {
978 BgpRouter br = getClient(yangObj);
982 String rd = val.getRd();
983 String pfxlen = val.getPrefixLen();
984 String nh = val.getNexthop().getValue();
985 Long label = val.getLabel();
986 int lbl = (label == null) ? qbgpConstants.LBL_NO_LABEL
989 br.addPrefix(rd, pfxlen, nh, lbl);
990 } catch (Exception e) {
991 LOG.error(yangObj + "Add received exception: \"" + e + "\"; " + addWarn);
997 protected InstanceIdentifier<Networks> getWildCardPath() {
998 return InstanceIdentifier.create(Bgp.class).child(Networks.class);
1001 protected synchronized void
1002 remove(InstanceIdentifier<Networks> iid, Networks val) {
1003 if (ignoreClusterDcnEventForFollower()) {
1006 LOG.debug("received remove Networks config val {}", val.getPrefixLen());
1007 synchronized (BgpConfigurationManager.this) {
1008 BgpRouter br = getClient(yangObj);
1012 String rd = val.getRd();
1013 String pfxlen = val.getPrefixLen();
1014 Long label = val.getLabel();
1015 int lbl = (label == null) ? 0 : label.intValue();
1016 if (rd == null && lbl > 0) {
1017 //LU prefix is being deleted.
1018 rd = Integer.toString(lbl);
1021 br.delPrefix(rd, pfxlen);
1022 } catch (Exception e) {
1023 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
1029 protected void update(final InstanceIdentifier<Networks> iid,
1030 final Networks oldval, final Networks newval) {
1031 if (ignoreClusterDcnEventForFollower()) {
1034 LOG.debug("received update networks config val {}", newval.getPrefixLen());
1035 remove(iid, oldval);
1036 timer.schedule(new TimerTask() {
1041 }, Integer.getInteger("bgp.nexthop.update.delay.in.secs", 5) * 1000);
1045 public void close() {
1048 } catch (Exception e) {
1049 e.printStackTrace();
1054 static Timer timer = new Timer();
1056 public class VrfsReactor
1057 extends AsyncDataTreeChangeListenerBase<Vrfs, VrfsReactor>
1058 implements AutoCloseable, ClusteredDataTreeChangeListener<Vrfs> {
1060 private static final String yangObj = "vrfs ";
1062 public VrfsReactor() {
1063 super(Vrfs.class, VrfsReactor.class);
1066 protected synchronized void
1067 add(InstanceIdentifier<Vrfs> iid, Vrfs val) {
1068 if (ignoreClusterDcnEventForFollower()) {
1071 LOG.debug("received add Vrfs config val {}", val.getRd());
1072 synchronized (BgpConfigurationManager.this) {
1073 BgpRouter br = getClient(yangObj);
1078 br.addVrf(val.getRd(), val.getImportRts(),
1079 val.getExportRts());
1080 } catch (Exception e) {
1081 LOG.error(yangObj + "Add received exception: \"" + e + "\"; "
1088 protected VrfsReactor getDataTreeChangeListener() {
1089 return VrfsReactor.this;
1093 protected InstanceIdentifier<Vrfs> getWildCardPath() {
1094 return InstanceIdentifier.create(Bgp.class).child(Vrfs.class);
1097 protected synchronized void
1098 remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
1099 if (ignoreClusterDcnEventForFollower()) {
1102 LOG.debug("received remove Vrfs config val {}", val.getRd());
1103 synchronized (BgpConfigurationManager.this) {
1104 BgpRouter br = getClient(yangObj);
1109 br.delVrf(val.getRd());
1110 } catch (Exception e) {
1111 LOG.error(yangObj + " Delete received exception: \"" + e + "\"; "
1117 protected void update(InstanceIdentifier<Vrfs> iid,
1118 Vrfs oldval, Vrfs newval) {
1119 if (ignoreClusterDcnEventForFollower()) {
1122 LOG.debug("VRFS: Update getting triggered for VRFS rd {}", oldval.getRd());
1123 LOG.error(yangObj + updWarn);
1127 public void close() {
1130 } catch (Exception e) {
1131 e.printStackTrace();
1136 Future lastCleanupJob;
1137 Future lastReplayJobFt = null;
1138 protected void activateMIP() {
1140 LOG.trace("BgpReactor: Executing MIP Activate command");
1141 Process process_bgp = Runtime.getRuntime().exec("cluster ip -a sdnc_bgp_mip");
1142 Process process_os = Runtime.getRuntime().exec("cluster ip -a sdnc_os_mip");
1143 LOG.trace("bgpMIP Activated");
1145 } catch (IOException io) {
1146 LOG.error("IO Exception got while activating mip: ", io);
1147 } catch (Exception e) {
1148 LOG.error("Exception got while activating mip: ", e);
1152 AtomicBoolean started = new AtomicBoolean(false);
1154 public class BgpReactor
1155 extends AsyncDataTreeChangeListenerBase<Bgp, BgpReactor>
1156 implements AutoCloseable, ClusteredDataTreeChangeListener<Bgp> {
1158 private static final String yangObj = "Bgp ";
1160 public BgpReactor() {
1161 super(Bgp.class, BgpReactor.class);
1165 protected synchronized void
1166 add(InstanceIdentifier<Bgp> iid, Bgp val) {
1167 LOG.error("received add Bgp config replaying the config");
1171 } catch (Exception e) {
1173 synchronized (BgpConfigurationManager.this) {
1175 if (ignoreClusterDcnEventForFollower()) {
1179 if (isIpAvailable(odlThriftIp)) {
1182 ipActivationCheckTimer.scheduleAtFixedRate(new TimerTask() {
1185 if (isIpAvailable(odlThriftIp)) {
1187 ipActivationCheckTimer.cancel();
1189 LOG.trace("waiting for odlThriftIP: {} to be present", odlThriftIp);
1198 protected BgpReactor getDataTreeChangeListener() {
1199 return BgpReactor.this;
1203 protected InstanceIdentifier<Bgp> getWildCardPath() {
1204 return InstanceIdentifier.create(Bgp.class);
1207 protected synchronized void
1208 remove(InstanceIdentifier<Bgp> iid, Bgp val) {
1209 if (ignoreClusterDcnEventForFollower()) {
1212 LOG.debug("received remove Bgp config");
1213 synchronized (BgpConfigurationManager.this) {
1218 protected void update(InstanceIdentifier<Bgp> iid,
1219 Bgp oldval, Bgp newval) {
1220 if (ignoreClusterDcnEventForFollower()) {
1223 synchronized (BgpConfigurationManager.this) {
1229 public void close() {
1232 } catch (Exception e) {
1233 e.printStackTrace();
1238 public void readOdlThriftIpForBgpCommunication() {
1239 File f = new File(CLUSTER_CONF_FILE);
1241 odlThriftIp = "127.0.0.1";
1244 BufferedReader br = null;
1246 br = new BufferedReader(new InputStreamReader(
1247 new FileInputStream(f)));
1248 String line = br.readLine();
1249 while (line != null) {
1250 if (line.contains(SDNC_BGP_MIP)) {
1252 odlThriftIp = line.substring(line.lastIndexOf(" ") + 1);
1255 line = br.readLine();
1257 } catch (Exception e) {
1261 } catch (Exception ignore) {
1266 public boolean isIpAvailable(String odlip) {
1269 if (odlip != null) {
1270 if ("127.0.0.1".equals(odlip)) {
1273 Enumeration e = NetworkInterface.getNetworkInterfaces();
1274 while (e.hasMoreElements()) {
1275 NetworkInterface n = (NetworkInterface) e.nextElement();
1276 Enumeration ee = n.getInetAddresses();
1277 while (ee.hasMoreElements()) {
1278 InetAddress i = (InetAddress) ee.nextElement();
1279 if (odlip.equals(i.getHostAddress())) {
1286 } catch (Exception e) {
1291 public static long getStalePathtime(int defValue, AsId as_num) {
1294 spt = bgpManager.getConfig().getGracefulRestart().getStalepathTime();
1295 } catch (Exception e) {
1297 spt = as_num.getStalepathTime();
1298 LOG.trace("BGP config/Stale-path time is not set using graceful");
1299 } catch (Exception ignore) {
1300 LOG.trace("BGP AS id is not set using graceful");
1305 LOG.trace("BGP config/Stale-path time is not set using graceful/start-bgp");
1311 public synchronized void bgpRestarted() {
1313 * If there a thread which in the process of stale cleanup, cancel it
1314 * and start a new thread (to avoid processing same again).
1316 if (previousReplayJobInProgress()) {
1317 cancelPreviousReplayJob();
1319 Runnable task = new Runnable() {
1323 LOG.error("running bgp replay task ");
1324 if (get() == null) {
1325 String host = getConfigHost();
1326 int port = getConfigPort();
1327 LOG.info("connecting to bgp host {} ", host);
1329 boolean res = bgpRouter.connect(host, port);
1330 LOG.error("no config to push in bgp replay task ");
1333 setStaleStartTime(System.currentTimeMillis());
1334 LOG.error("started creating stale fib map ");
1335 createStaleFibMap();
1336 setStaleEndTime(System.currentTimeMillis());
1337 LOG.error("took {} msecs for stale fib map creation ", getStaleEndTime()- getStaleStartTime());
1338 LOG.error("started bgp config replay ");
1339 setCfgReplayStartTime(System.currentTimeMillis());
1341 setCfgReplayEndTime(System.currentTimeMillis());
1342 LOG.error("took {} msecs for bgp replay ", getCfgReplayEndTime() - getCfgReplayStartTime());
1343 long route_sync_time = getStalePathtime(BGP_RESTART_ROUTE_SYNC_SEC, config.getAsId());
1344 Thread.sleep(route_sync_time * 1000L);
1345 setStaleCleanupTime(route_sync_time);
1346 new RouteCleanup().call();
1347 } catch (Exception eCancel) {
1348 LOG.error("Stale Cleanup Task Cancelled", eCancel);
1352 lastReplayJobFt = executor.submit(task);
1355 private boolean previousReplayJobInProgress() {
1356 return lastReplayJobFt != null && !lastReplayJobFt.isDone();
1359 private void cancelPreviousReplayJob() {
1361 LOG.error("cancelling already running bgp replay task");
1362 lastReplayJobFt.cancel(true);
1363 lastReplayJobFt = null;
1365 } catch (Throwable e) {
1366 LOG.error("Failed to cancel previous replay job ",e);
1370 private static void doRouteSync() {
1371 BgpSyncHandle bsh = BgpSyncHandle.getInstance();
1372 LOG.error("Starting BGP route sync");
1374 bgpRouter.initRibSync(bsh);
1375 } catch (Exception e) {
1376 LOG.error("Route sync aborted, exception when initializing: " + e);
1379 while (bsh.getState() != bsh.DONE) {
1380 Routes routes = null;
1382 routes = bgpRouter.doRibSync(bsh);
1383 } catch (Exception e) {
1384 LOG.error("Route sync aborted, exception when syncing: " + e);
1387 Iterator<Update> updates = routes.getUpdatesIterator();
1388 while (updates.hasNext()) {
1389 Update u = updates.next();
1390 Map<String, Map<String, String>> stale_fib_rd_map = BgpConfigurationManager.getStaledFibEntriesMap();
1391 String rd = u.getRd();
1392 String nexthop = u.getNexthop();
1393 int label = u.getLabel();
1394 String prefix = u.getPrefix();
1395 int plen = u.getPrefixlen();
1396 onUpdatePushRoute(rd, prefix, plen, nexthop, label);
1400 LOG.error("Ending BGP route-sync");
1401 bgpRouter.endRibSync(bsh);
1402 } catch (Exception e) {
1406 /* onUpdatePushRoute
1407 * Get Stale fib map, and compare current route/fib entry.
1408 * - Entry compare shall include NextHop, Label.
1409 * - If entry matches: delete from STALE Map. NO Change to FIB Config DS.
1410 * - If entry not found, add to FIB Config DS.
1411 * - If entry found, but either Label/NextHop doesn't match.
1412 * - Update FIB Config DS with modified values.
1413 * - delete from Stale Map.
1415 public static void onUpdatePushRoute(String rd, String prefix, int plen, String nextHop, int label) {
1416 Map<String, Map<String, String>> stale_fib_rd_map = BgpConfigurationManager.getStaledFibEntriesMap();
1417 boolean addroute = false;
1418 if (!stale_fib_rd_map.isEmpty()) {
1419 // restart Scenario, as MAP is not empty.
1420 Map<String, String> map = stale_fib_rd_map.get(rd);
1422 String nexthoplabel = map.get(prefix + "/" + plen);
1423 if (null == nexthoplabel) {
1424 // New Entry, which happened to be added during restart.
1427 map.remove(prefix + "/" + plen);
1428 if (isRouteModified(nextHop, label, nexthoplabel)) {
1429 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
1430 // Existing entry, where in Nexthop/Label got modified during restart
1436 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
1440 LOG.info("ADD: Adding Fib entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, label);
1441 fib.addFibEntryToDS(rd, prefix + "/" + plen, Arrays.asList(nextHop), label, RouteOrigin.BGP);
1442 LOG.info("ADD: Added Fib entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, label);
1446 private static boolean isRouteModified(String nexthop, int label, String nexthoplabel) {
1447 return !nexthoplabel.isEmpty() && !nexthoplabel.equals(nexthop + "/" + label);
1450 static private void replayNbrConfig(List<Neighbors> n, BgpRouter br) {
1451 for (Neighbors nbr : n) {
1453 br.addNeighbor(nbr.getAddress().getValue(),
1454 nbr.getRemoteAs().intValue());
1455 //itmProvider.buildTunnelsToDCGW(new IpAddress(nbr.getAddress().getValue().toCharArray()));
1456 } catch (Exception e) {
1457 LOG.error("Replay:addNbr() received exception: \"" + e + "\"");
1460 EbgpMultihop en = nbr.getEbgpMultihop();
1463 br.addEbgpMultihop(en.getPeerIp().getValue(),
1464 en.getNhops().intValue());
1465 } catch (Exception e) {
1466 LOG.error("Replay:addEBgp() received exception: \"" + e + "\"");
1469 UpdateSource us = nbr.getUpdateSource();
1472 br.addUpdateSource(us.getPeerIp().getValue(),
1473 us.getSourceIp().getValue());
1474 } catch (Exception e) {
1475 LOG.error("Replay:addUS() received exception: \"" + e + "\"");
1478 List<AddressFamilies> afs = nbr.getAddressFamilies();
1480 for (AddressFamilies af : afs) {
1481 af_afi afi = af_afi.findByValue(af.getAfi().intValue());
1482 af_safi safi = af_safi.findByValue(af.getSafi().intValue());
1484 br.addAddressFamily(af.getPeerIp().getValue(), afi, safi);
1485 } catch (Exception e) {
1486 LOG.error("Replay:addAf() received exception: \"" + e + "\"");
1493 public static String getConfigHost() {
1494 if (config == null) {
1495 return cHostStartup;
1497 ConfigServer ts = config.getConfigServer();
1498 return (ts == null ? cHostStartup : ts.getHost().getValue());
1501 public static int getConfigPort() {
1502 if (config == null) {
1503 return Integer.parseInt(cPortStartup);
1505 ConfigServer ts = config.getConfigServer();
1506 return (ts == null ? Integer.parseInt(cPortStartup) :
1507 ts.getPort().intValue());
1510 public static synchronized void replay() {
1511 synchronized (bgpConfigurationManager) {
1512 String host = getConfigHost();
1513 int port = getConfigPort();
1514 LOG.error("connecting to bgp host {} ", host);
1516 boolean res = bgpRouter.connect(host, port);
1518 String msg = "Cannot connect to BGP config server at " + host + ":" + port;
1519 if (config != null) {
1520 msg += "; Configuration Replay aborted";
1525 config = bgpManager.getConfig();
1526 if (config == null) {
1527 LOG.error("bgp config is empty nothing to push to bgp");
1530 BgpRouter br = bgpRouter;
1531 AsId a = config.getAsId();
1535 int asNum = a.getLocalAs().intValue();
1536 Ipv4Address routerId = a.getRouterId();
1537 Long spt = a.getStalepathTime();
1538 Boolean afb = a.isAnnounceFbit();
1539 String rid = (routerId == null) ? "" : routerId.getValue();
1540 int stalepathTime = (int) getStalePathtime(0, config.getAsId());
1541 boolean announceFbit = (afb == null) ? false : afb.booleanValue();
1543 br.startBgp(asNum, rid, stalepathTime, announceFbit);
1544 } catch (BgpRouterException bre) {
1545 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
1548 LOG.error("Replay: startBgp() received exception: \""
1549 + bre + "\"; " + addWarn);
1551 } catch (Exception e) {
1552 //not unusual. We may have restarted & BGP is already on
1553 LOG.error("Replay:startBgp() received exception: \"" + e + "\"");
1556 if (bgpManager.getBgpCounters() == null) {
1557 bgpManager.startBgpCountersTask();
1560 Logging l = config.getLogging();
1563 br.setLogging(l.getFile(), l.getLevel());
1564 } catch (Exception e) {
1565 LOG.error("Replay:setLogging() received exception: \"" + e + "\"");
1569 GracefulRestart g = config.getGracefulRestart();
1572 br.addGracefulRestart(g.getStalepathTime().intValue());
1573 } catch (Exception e) {
1574 LOG.error("Replay:addGr() received exception: \"" + e + "\"");
1578 List<Neighbors> n = config.getNeighbors();
1580 LOG.error("configuring existing Neighbors present for replay total neighbors {}", n.size());
1581 replayNbrConfig(n, br);
1583 LOG.error("no Neighbors present for replay config ");
1586 List<Vrfs> v = config.getVrfs();
1588 for (Vrfs vrf : v) {
1590 br.addVrf(vrf.getRd(), vrf.getImportRts(),
1591 vrf.getExportRts());
1592 } catch (Exception e) {
1593 LOG.error("Replay:addVrf() received exception: \"" + e + "\"");
1598 List<Networks> ln = config.getNetworks();
1600 for (Networks net : ln) {
1601 String rd = net.getRd();
1602 String pfxlen = net.getPrefixLen();
1603 String nh = net.getNexthop().getValue();
1604 Long label = net.getLabel();
1605 int lbl = (label == null) ? 0 : label.intValue();
1606 if (rd == null && lbl > 0) {
1607 //LU prefix is being deleted.
1608 rd = Integer.toString(lbl);
1611 br.addPrefix(rd, pfxlen, nh, lbl);
1612 } catch (Exception e) {
1613 LOG.error("Replay:addPfx() received exception: \"" + e + "\"");
1620 private <T extends DataObject> void update(InstanceIdentifier<T> iid, T dto) {
1621 BgpUtil.update(broker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1624 private <T extends DataObject> void asyncWrite(InstanceIdentifier<T> iid, T dto) {
1625 BgpUtil.write(broker, LogicalDatastoreType.CONFIGURATION, iid, dto);
1628 private <T extends DataObject> void delete(InstanceIdentifier<T> iid) {
1629 BgpUtil.delete(broker, LogicalDatastoreType.CONFIGURATION, iid);
1632 public synchronized void
1633 startConfig(String bgpHost, int thriftPort) {
1634 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1635 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1636 InstanceIdentifier<ConfigServer> iid = iib.build();
1637 Ipv4Address ipAddr = new Ipv4Address(bgpHost);
1638 ConfigServer dto = new ConfigServerBuilder().setHost(ipAddr)
1639 .setPort((long) thriftPort).build();
1643 public synchronized void
1644 startBgp(int as, String routerId, int spt, boolean fbit) {
1645 Long localAs = (long) as;
1646 Ipv4Address rid = (routerId == null) ?
1647 null : new Ipv4Address(routerId);
1648 Long staleTime = (long) spt;
1649 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1650 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1651 InstanceIdentifier<AsId> iid = iib.build();
1652 AsId dto = new AsIdBuilder().setLocalAs(localAs)
1654 .setStalepathTime(staleTime)
1655 .setAnnounceFbit(fbit).build();
1659 public synchronized void
1660 addLogging(String fileName, String logLevel) {
1661 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1662 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1663 InstanceIdentifier<Logging> iid = iib.build();
1664 Logging dto = new LoggingBuilder().setFile(fileName)
1665 .setLevel(logLevel).build();
1669 public synchronized void
1670 addGracefulRestart(int staleTime) {
1671 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1672 InstanceIdentifier.builder(Bgp.class).child(GracefulRestart.class);
1673 InstanceIdentifier<GracefulRestart> iid = iib.build();
1674 GracefulRestart dto = new GracefulRestartBuilder()
1675 .setStalepathTime((long) staleTime).build();
1679 public synchronized void
1680 addNeighbor(String nbrIp, int remoteAs) {
1681 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1682 Long rAs = (long) remoteAs;
1683 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1684 InstanceIdentifier.builder(Bgp.class)
1685 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1686 InstanceIdentifier<Neighbors> iid = iib.build();
1687 Neighbors dto = new NeighborsBuilder().setAddress(nbrAddr)
1688 .setRemoteAs(rAs).build();
1692 public synchronized void
1693 addUpdateSource(String nbrIp, String srcIp) {
1694 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1695 Ipv4Address srcAddr = new Ipv4Address(srcIp);
1696 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1697 InstanceIdentifier.builder(Bgp.class)
1698 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1699 .child(UpdateSource.class);
1700 InstanceIdentifier<UpdateSource> iid = iib.build();
1701 UpdateSource dto = new UpdateSourceBuilder().setPeerIp(nbrAddr)
1702 .setSourceIp(srcAddr).build();
1706 public synchronized void
1707 addEbgpMultihop(String nbrIp, int nHops) {
1708 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1709 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1710 InstanceIdentifier.builder(Bgp.class)
1711 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1712 .child(EbgpMultihop.class);
1713 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1714 EbgpMultihop dto = new EbgpMultihopBuilder().setPeerIp(nbrAddr)
1715 .setNhops((long) nHops).build();
1719 public synchronized void
1720 addAddressFamily(String nbrIp, int afi, int safi) {
1721 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1722 Long a = (long) afi;
1723 Long sa = (long) safi;
1724 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1725 InstanceIdentifier.builder(Bgp.class)
1726 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1727 .child(AddressFamilies.class, new AddressFamiliesKey(a, sa));
1728 InstanceIdentifier<AddressFamilies> iid = iib.build();
1729 AddressFamilies dto = new AddressFamiliesBuilder().setPeerIp(nbrAddr)
1730 .setAfi(a).setSafi(sa).build();
1734 public synchronized void
1735 addPrefix(String rd, String pfx, List<String> nhList, int lbl) {
1736 for (String nh : nhList) {
1737 Ipv4Address nexthop = new Ipv4Address(nh);
1738 Long label = (long) lbl;
1739 InstanceIdentifier<Networks> iid = InstanceIdentifier.builder(Bgp.class)
1740 .child(Networks.class, new NetworksKey(pfx, rd)).build();
1741 Networks dto = new NetworksBuilder().setRd(rd).setPrefixLen(pfx).setNexthop(nexthop)
1742 .setLabel(label).build();
1747 public synchronized void
1748 addVrf(String rd, List<String> irts, List<String> erts) {
1749 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1750 InstanceIdentifier.builder(Bgp.class)
1751 .child(Vrfs.class, new VrfsKey(rd));
1752 InstanceIdentifier<Vrfs> iid = iib.build();
1753 Vrfs dto = new VrfsBuilder().setRd(rd)
1755 .setExportRts(erts).build();
1757 asyncWrite(iid, dto);
1760 public synchronized void stopConfig() {
1761 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
1762 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
1763 InstanceIdentifier<ConfigServer> iid = iib.build();
1767 public synchronized void stopBgp() {
1768 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
1769 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
1770 InstanceIdentifier<AsId> iid = iib.build();
1774 public synchronized void delLogging() {
1775 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
1776 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
1777 InstanceIdentifier<Logging> iid = iib.build();
1781 public synchronized void delGracefulRestart() {
1782 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
1783 InstanceIdentifier.builder(Bgp.class)
1784 .child(GracefulRestart.class);
1785 InstanceIdentifier<GracefulRestart> iid = iib.build();
1789 public synchronized void delNeighbor(String nbrIp) {
1790 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1791 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
1792 InstanceIdentifier.builder(Bgp.class)
1793 .child(Neighbors.class, new NeighborsKey(nbrAddr));
1794 InstanceIdentifier<Neighbors> iid = iib.build();
1798 public synchronized void delUpdateSource(String nbrIp) {
1799 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1800 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
1801 InstanceIdentifier.builder(Bgp.class)
1802 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1803 .child(UpdateSource.class);
1804 InstanceIdentifier<UpdateSource> iid = iib.build();
1808 public synchronized void delEbgpMultihop(String nbrIp) {
1809 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1810 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
1811 InstanceIdentifier.builder(Bgp.class)
1812 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1813 .child(EbgpMultihop.class);
1814 InstanceIdentifier<EbgpMultihop> iid = iib.build();
1818 public synchronized void
1819 delAddressFamily(String nbrIp, int afi, int safi) {
1820 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
1821 Long a = (long) afi;
1822 Long sa = (long) safi;
1823 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
1824 InstanceIdentifier.builder(Bgp.class)
1825 .child(Neighbors.class, new NeighborsKey(nbrAddr))
1826 .child(AddressFamilies.class, new AddressFamiliesKey(a, sa));
1827 InstanceIdentifier<AddressFamilies> iid = iib.build();
1831 public synchronized void delPrefix(String rd, String pfx) {
1832 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
1833 InstanceIdentifier.builder(Bgp.class)
1834 .child(Networks.class, new NetworksKey(pfx, rd));
1835 InstanceIdentifier<Networks> iid = iib.build();
1839 public synchronized void delVrf(String rd) {
1840 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
1841 InstanceIdentifier.builder(Bgp.class)
1842 .child(Vrfs.class, new VrfsKey(rd));
1843 InstanceIdentifier<Vrfs> iid = iib.build();
1847 static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
1850 * Remove Stale Marked Routes after timer expiry.
1852 class RouteCleanup implements Callable<Integer> {
1855 public Integer call() {
1858 if (staledFibEntriesMap.isEmpty()) {
1859 LOG.info("BGP: RouteCleanup timertask tirggered but STALED FIB MAP is EMPTY");
1861 for (String rd : staledFibEntriesMap.keySet()) {
1862 if (Thread.interrupted()) {
1865 Map<String, String> map = staledFibEntriesMap.get(rd);
1867 for (String prefix : map.keySet()) {
1868 if (Thread.interrupted()) {
1873 LOG.error("BGP: RouteCleanup deletePrefix called but not executed rd:{}, prefix{}" + rd.toString() + prefix);
1874 // fib.removeFibEntryFromDS(rd, prefix);
1875 } catch (Exception e) {
1876 LOG.error("BGP: RouteCleanup deletePrefix failed rd:{}, prefix{}" + rd.toString() + prefix);
1882 } catch (Exception e) {
1883 LOG.error("Cleanup Thread Got interrupted, Failed to cleanup stale routes ", e);
1885 staledFibEntriesMap.clear();
1887 LOG.error("cleared {} stale routes after bgp restart", totalCleared);
1893 * BGP restart scenario, ODL-BGP manager was/is running.
1894 * On re-sync notification, Get a copy of FIB database.
1896 public static void createStaleFibMap() {
1897 totalStaledCount = 0;
1900 * at the time Stale FIB creation, Wait till all PENDING write transaction
1901 * to complete (or)wait for max timeout value of STALE_FIB_WAIT Seconds.
1903 int retry = STALE_FIB_WAIT;
1904 while ((BgpUtil.getGetPendingWrTransaction() != 0) && (retry > 0)) {
1908 LOG.error("TimeOut occured {} seconds, in waiting stale fib create", STALE_FIB_WAIT);
1911 staledFibEntriesMap.clear();
1912 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
1913 DataBroker db = BgpUtil.getBroker();
1915 LOG.error("Couldn't find BgpUtil broker while creating createStaleFibMap");
1919 Optional<FibEntries> fibEntries = BgpUtil.read(BgpUtil.getBroker(),
1920 LogicalDatastoreType.CONFIGURATION, id);
1921 if (fibEntries.isPresent()) {
1922 List<VrfTables> stale_vrfTables = fibEntries.get().getVrfTables();
1923 for (VrfTables vrfTable : stale_vrfTables) {
1924 Map<String, String> stale_fib_ent_map = new HashMap<>();
1925 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
1926 if (Thread.interrupted()) {
1930 //Create MAP from stale_vrfTables.
1931 //FIXME: Once odl-fib.yang is updated with latest yang to contain nexthopaddresslist
1932 // for (String nextHop : vrfEntry.getNextHopAddressList()) {
1933 // stale_fib_ent_map.put(vrfEntry.getDestPrefix(), nextHop + "/" + vrfEntry.getLabel());
1937 staledFibEntriesMap.put(vrfTable.getRouteDistinguisher(), stale_fib_ent_map);
1940 LOG.error("createStaleFibMap:: FIBentries.class is not present");
1942 } catch (Exception e) {
1943 LOG.error("createStaleFibMap:: error ", e);
1945 LOG.error("created {} staled entries ", totalStaledCount);
1948 //map<rd, map<prefix/len, nexthop/label>>
1949 public static Map<String, Map<String, String>> getStaledFibEntriesMap() {
1950 return staledFibEntriesMap;
1953 //TODO: below function is for testing purpose with cli
1954 public static void onUpdateWithdrawRoute(String rd, String prefix, int plen) {
1955 LOG.debug("Route del ** {} ** {}/{} ", rd, prefix, plen);
1957 fib.removeFibEntryFromDS(rd, prefix + "/" + plen);
1958 } catch (Throwable e) {
1959 LOG.error("failed to handle withdraw route ", e);
1962 public boolean isBgpConnected(){
1963 return bgpRouter.isBgpConnected();
1965 public long getLastConnectedTS() {
1966 return bgpRouter.getLastConnectedTS();
1968 public long getConnectTS() {
1969 return bgpRouter.getConnectTS();
1971 public long getStartTS() {
1972 return bgpRouter.getStartTS();
1974 public static int getTotalStaledCount() {return totalStaledCount;}
1975 public static int getTotalCleared() { return totalCleared;}