2 * Copyright © 2015, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.bgpmanager;
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.net.InetAddresses;
13 import com.google.common.util.concurrent.ThreadFactoryBuilder;
14 import io.netty.util.concurrent.GlobalEventExecutor;
15 import java.lang.reflect.Constructor;
16 import java.lang.reflect.InvocationTargetException;
17 import java.net.InetAddress;
18 import java.net.InetSocketAddress;
19 import java.net.NetworkInterface;
20 import java.net.SocketException;
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Enumeration;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
29 import java.util.Objects;
30 import java.util.Timer;
31 import java.util.concurrent.Callable;
32 import java.util.concurrent.ConcurrentHashMap;
33 import java.util.concurrent.CountDownLatch;
34 import java.util.concurrent.ExecutionException;
35 import java.util.concurrent.Executors;
36 import java.util.concurrent.Future;
37 import java.util.concurrent.ScheduledExecutorService;
38 import java.util.concurrent.ScheduledFuture;
39 import java.util.concurrent.TimeUnit;
40 import java.util.concurrent.TimeoutException;
41 import java.util.concurrent.atomic.AtomicInteger;
42 import java.util.concurrent.atomic.AtomicReference;
43 import javax.annotation.Nullable;
44 import javax.annotation.PreDestroy;
45 import javax.inject.Inject;
46 import javax.inject.Singleton;
47 import org.apache.thrift.TApplicationException;
48 import org.apache.thrift.TException;
49 import org.apache.thrift.transport.TTransport;
50 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
51 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
52 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
53 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
54 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
55 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
56 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
57 import org.opendaylight.genius.mdsalutil.NwConstants;
58 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
59 import org.opendaylight.infrautils.metrics.MetricProvider;
60 import org.opendaylight.mdsal.eos.binding.api.Entity;
61 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
62 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipListenerRegistration;
63 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
64 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
65 import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
66 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
67 import org.opendaylight.netvirt.bgpmanager.commands.ClearBgpCli;
68 import org.opendaylight.netvirt.bgpmanager.oam.BgpAlarms;
69 import org.opendaylight.netvirt.bgpmanager.oam.BgpConstants;
70 import org.opendaylight.netvirt.bgpmanager.oam.BgpCounters;
71 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouter;
72 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouterException;
73 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpSyncHandle;
74 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Routes;
75 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Update;
76 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
77 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
78 import org.opendaylight.netvirt.bgpmanager.thrift.gen.protocol_type;
79 import org.opendaylight.netvirt.bgpmanager.thrift.gen.qbgpConstants;
80 import org.opendaylight.netvirt.bgpmanager.thrift.server.BgpThriftService;
81 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
82 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.IVpnLinkService;
83 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfig;
84 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfigBuilder;
85 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.AddressFamily;
86 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
87 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.BgpControlPlaneType;
88 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.EncapType;
89 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.TcpMd5SignaturePasswordType;
90 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsId;
91 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsIdBuilder;
92 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServer;
93 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServerBuilder;
94 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.DcgwTepList;
95 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestart;
96 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestartBuilder;
97 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Logging;
98 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.LoggingBuilder;
99 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Multipath;
100 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.MultipathBuilder;
101 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.MultipathKey;
102 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Neighbors;
103 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsBuilder;
104 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsKey;
105 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Networks;
106 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksBuilder;
107 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksKey;
108 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpath;
109 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpathBuilder;
110 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpathKey;
111 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Vrfs;
112 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsBuilder;
113 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsKey;
114 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTep;
115 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepBuilder;
116 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepKey;
117 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamilies;
118 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesBuilder;
119 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesKey;
120 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihop;
121 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihopBuilder;
122 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSource;
123 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSourceBuilder;
124 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfs.AddressFamiliesVrf;
125 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfs.AddressFamiliesVrfBuilder;
126 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.TcpSecurityOption;
127 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.tcp.security.option.TcpMd5SignatureOption;
128 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.tcp.security.option.TcpMd5SignatureOptionBuilder;
129 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
130 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
131 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
132 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
133 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
134 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.macvrfentries.MacVrfEntry;
135 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
136 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
137 import org.opendaylight.yangtools.yang.binding.DataObject;
138 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
139 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
140 import org.osgi.framework.BundleContext;
141 import org.osgi.util.tracker.ServiceTracker;
142 import org.slf4j.Logger;
143 import org.slf4j.LoggerFactory;
146 public class BgpConfigurationManager {
147 private static final Logger LOG = LoggerFactory.getLogger(BgpConfigurationManager.class);
149 // to have stale FIB map (RD, Prefix)
150 // number of seconds wait for route sync-up between ODL and BGP
151 private static final int BGP_RESTART_ROUTE_SYNC_SEC = 600;
152 private static final String UPDATE_PORT = "bgp.thrift.service.port";
153 private static final String CONFIG_HOST = "vpnservice.bgpspeaker.host.name";
154 private static final String CONFIG_PORT = "vpnservice.bgpspeaker.thrift.port";
155 private static final String DEF_UPORT = "6644";
156 private static final String DEF_CHOST = "255.255.255.255"; // Invalid Host IP
157 private static final String DEF_CPORT = "7644";
158 private static final String DEF_BGP_SDNC_MIP = "127.0.0.1";
159 //vpnservice.bgp.thrift.bgp.mip is the MIP present with ODL. Here we open 6644 port
160 private static final String BGP_SDNC_MIP = "vpnservice.bgp.thrift.bgp.mip";
161 private static final int RESTART_DEFAULT_GR = 90;
162 private static final int DS_RETRY_COUNT = 100; //100 retries, each after WAIT_TIME_BETWEEN_EACH_TRY_MILLIS seconds
163 private static final long WAIT_TIME_BETWEEN_EACH_TRY_MILLIS = 1000L; //one second sleep after every retry
164 private static final String BGP_ENTITY_TYPE_FOR_OWNERSHIP = "bgp";
165 private static final String BGP_EOR_DELAY = "vpnservice.bgp.eordelay";
166 private static final String DEF_BGP_EOR_DELAY = "1800";
167 private static final String BGP_ENTITY_NAME = "bgp";
168 private static final String ADD_WARN = "Config store updated; undo with Delete if needed.";
169 private static final String DEL_WARN = "Config store updated; undo with Add if needed.";
170 private static final String UPD_WARN = "Update operation not supported; Config store updated;"
171 + " restore with another Update if needed.";
172 private static long bgp_as_num = 0;
174 private static final Class<?>[] REACTORS = {
175 ConfigServerReactor.class, AsIdReactor.class,
176 GracefulRestartReactor.class, LoggingReactor.class,
177 NeighborsReactor.class, UpdateSourceReactor.class,
178 EbgpMultihopReactor.class, AddressFamiliesReactor.class,
179 NetworksReactor.class, VrfsReactor.class, BgpReactor.class,
180 MultipathReactor.class, VrfMaxpathReactor.class, BfdConfigReactor.class
183 private IBgpManager bgpManager;
184 private final DataBroker dataBroker;
185 private final FibDSWriter fibDSWriter;
186 private final IVpnLinkService vpnLinkService;
187 private final BundleContext bundleContext;
188 private final BgpUtil bgpUtil;
189 private volatile Bgp config;
190 private final BgpRouter bgpRouter;
191 private final BgpSyncHandle bgpSyncHandle = new BgpSyncHandle();
192 private volatile BgpThriftService bgpThriftService = null;
193 private final int delayEorSeconds;
195 private final CountDownLatch initer = new CountDownLatch(1);
197 private final String hostStartup;
198 private final String portStartup;
200 private final AtomicReference<BgpCounters> bgpCountersReference = new AtomicReference<>();
201 private ScheduledFuture<?> bgpCountersTask;
203 private final AtomicReference<BgpAlarms> bgpAlarmsReference = new AtomicReference<>();
204 private ScheduledFuture<?> bgpAlarmsTask;
206 private Future<?> lastReplayJobFt;
207 private ScheduledFuture<?> routeCleanupFuture;
209 private long staleStartTime;
210 private long staleEndTime;
211 private long cfgReplayStartTime;
212 private long cfgReplayEndTime;
213 private long staleCleanupTime;
214 private int totalStaledCount;
215 private int totalCleared;
216 private int totalExternalRoutes;
217 private int totalExternalMacRoutes;
219 private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(
220 new ThreadFactoryBuilder().setNameFormat("BgpConfigurationManager-%d").setDaemon(true).build());
223 * this map store the new address families to send to quagga. When it is sended you must clear it.
224 * The keys String are rd (route distinguisher).
226 private final ConcurrentHashMap<String, List<AddressFamiliesVrf>> mapNewAdFamily = new ConcurrentHashMap<>();
228 // map<rd, map<prefix/len:nexthop, label>>
229 private final Map<String, Map<String, Long>> staledFibEntriesMap = new ConcurrentHashMap<>();
231 // map<rd, map<tep-ip, map<mac, l2vni>>>
232 private final Map<String, Map<String, Map<String, Long>>> rt2TepMap = new ConcurrentHashMap<>();
234 private final List<AutoCloseable> listeners = new ArrayList<>();
236 private final EntityOwnershipUtils entityOwnershipUtils;
237 private final EntityOwnershipCandidateRegistration candidateRegistration;
238 private final EntityOwnershipListenerRegistration entityListenerRegistration;
239 private final MetricProvider metricProvider;
242 public BgpConfigurationManager(final DataBroker dataBroker,
243 final EntityOwnershipService entityOwnershipService,
244 final FibDSWriter fibDSWriter,
245 final IVpnLinkService vpnLinkSrvce,
246 final BundleContext bundleContext,
247 final BgpUtil bgpUtil,
248 final MetricProvider metricProvider) {
249 this.dataBroker = dataBroker;
250 this.fibDSWriter = fibDSWriter;
251 this.vpnLinkService = vpnLinkSrvce;
252 this.bundleContext = bundleContext;
253 this.bgpUtil = bgpUtil;
254 this.metricProvider = metricProvider;
255 hostStartup = getProperty(CONFIG_HOST, DEF_CHOST);
256 portStartup = getProperty(CONFIG_PORT, DEF_CPORT);
257 LOG.info("ConfigServer at {}:{}", hostStartup, portStartup);
258 VtyshCli.setHostAddr(hostStartup);
259 ClearBgpCli.setHostAddr(hostStartup);
260 bgpRouter = BgpRouter.newInstance(this::getConfig, this::isBGPEntityOwner);
261 delayEorSeconds = Integer.parseInt(getProperty(BGP_EOR_DELAY, DEF_BGP_EOR_DELAY));
263 entityOwnershipUtils = new EntityOwnershipUtils(entityOwnershipService);
265 candidateRegistration = registerEntityCandidate(entityOwnershipService);
266 entityListenerRegistration = registerEntityListener(entityOwnershipService);
268 /*register callbacks for reactors, shall be called after EoS registration.
269 * as listeners user EoS service to identify Owner node. Listener call-backs
270 * can get triggered immediately after registeration (before EoS register complete)
274 LOG.info("BGP Configuration manager initialized");
277 GlobalEventExecutor.INSTANCE.execute(() -> {
278 ServiceTracker<IBgpManager, ?> tracker = null;
280 tracker = new ServiceTracker<>(bundleContext, IBgpManager.class, null);
282 bgpManager = (IBgpManager) tracker.waitForService(TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES));
283 Preconditions.checkState(bgpManager != null, "IBgpManager service not found");
284 } catch (InterruptedException e) {
285 throw new IllegalStateException("Error retrieving IBgpManager service", e);
287 if (tracker != null) {
292 String updatePort = getProperty(UPDATE_PORT, DEF_UPORT);
293 if (InetAddresses.isInetAddress(getBgpSdncMipIp())) {
294 InetSocketAddress bgpThriftServerSocketAddr = new InetSocketAddress(getBgpSdncMipIp(),
295 Integer.parseInt(updatePort));
296 bgpThriftService = new BgpThriftService(bgpThriftServerSocketAddr, bgpManager, this);
297 if (isBGPEntityOwner()) {
298 //I am EoS owner of BGP, opening bgp thrift UPDATE-SERVER port.
299 LOG.info("BGP Configuration manager initialized: UPDATE-SERVER started");
300 bgpThriftService.start();
302 LOG.info("UPDATE server started :ip:port={}:{}", getBgpSdncMipIp(), updatePort);
304 LOG.error("Failed to init UPDATE server invalid ip:port={}:{}", getBgpSdncMipIp(), updatePort);
306 LOG.info("BgpConfigurationManager initialized. IBgpManager={}", bgpManager);
310 public String getBgpSdncMipIp() {
311 return getProperty(BGP_SDNC_MIP, DEF_BGP_SDNC_MIP);
314 public long getStaleCleanupTime() {
315 return staleCleanupTime;
318 public void setStaleCleanupTime(long staleCleanupTime) {
319 this.staleCleanupTime = staleCleanupTime;
322 public long getCfgReplayEndTime() {
323 return cfgReplayEndTime;
326 public void setCfgReplayEndTime(long cfgReplayEndTime) {
327 this.cfgReplayEndTime = cfgReplayEndTime;
330 public long getCfgReplayStartTime() {
331 return cfgReplayStartTime;
334 public void setCfgReplayStartTime(long cfgReplayStartTime) {
335 this.cfgReplayStartTime = cfgReplayStartTime;
338 public long getStaleEndTime() {
342 public void setStaleEndTime(long staleEndTime) {
343 this.staleEndTime = staleEndTime;
346 public long getStaleStartTime() {
347 return staleStartTime;
350 public void setStaleStartTime(long staleStartTime) {
351 this.staleStartTime = staleStartTime;
354 private Object createListener(Class<?> cls) {
356 Constructor<?> ctor = cls.getConstructor(BgpConfigurationManager.class);
357 return ctor.newInstance(this);
358 } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException
360 LOG.error("Failed to create listener object", e);
365 private void registerCallbacks() {
366 for (Class<?> reactor : REACTORS) {
367 Object obj = createListener(reactor);
369 AsyncDataTreeChangeListenerBase dcl = (AsyncDataTreeChangeListenerBase) obj;
370 dcl.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
376 @SuppressWarnings("checkstyle:IllegalCatch")
378 public void close() {
381 if (bgpThriftService != null) {
382 bgpThriftService.stop();
383 bgpThriftService = null;
386 if (isBgpConnected()) {
387 //disconnect the CONFIG SERVER port (which was )opened during I was Owner
388 bgpRouter.disconnect();
391 if (candidateRegistration != null) {
392 candidateRegistration.close();
395 entityListenerRegistration.close();
397 listeners.forEach(l -> {
400 } catch (Exception e) {
401 LOG.warn("Error closing {}", l ,e);
405 LOG.info("{} close", getClass().getSimpleName());
408 private String getProperty(String var, String def) {
409 String property = bundleContext.getProperty(var);
410 return property == null ? def : property;
413 private EntityOwnershipCandidateRegistration registerEntityCandidate(
414 final EntityOwnershipService entityOwnershipService) {
416 return entityOwnershipService.registerCandidate(
417 new Entity(BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME));
418 } catch (CandidateAlreadyRegisteredException e) {
419 LOG.error("failed to register bgp entity", e);
424 private EntityOwnershipListenerRegistration registerEntityListener(
425 final EntityOwnershipService entityOwnershipService) {
426 return entityOwnershipService.registerListener(BGP_ENTITY_TYPE_FOR_OWNERSHIP, ownershipChange -> {
427 LOG.trace("entity owner change event fired: {}", ownershipChange);
429 if (ownershipChange.getState() == EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED) {
430 LOG.trace("This PL is the Owner");
431 if (bgpThriftService != null) {
432 //opening UPDATE-SERVER port.
433 bgpThriftService.start();
435 LOG.error("I am the owner of BGP entity, but bgpThriftService is not initialized yet");
439 LOG.debug("Not owner: hasOwner: {}, isOwner: {}", ownershipChange.getState().hasOwner(),
440 ownershipChange.getState().isOwner());
441 if (bgpThriftService != null && bgpThriftService.isBgpThriftServiceStarted()) {
442 //close the bgp Thrift Update-SERVER port opened on non-Entity Owner
443 bgpThriftService.stop();
444 bgpThriftService = null;
446 if (isBgpConnected()) {
447 //disconnect the CONFIG SERVER port (which was )opened during I was Owner
448 bgpRouter.disconnect();
454 public boolean isBGPEntityOwner() {
455 if (entityOwnershipUtils == null) {
456 LOG.error("entityOwnershipUtils is NULL when listener callbacks fired");
459 return entityOwnershipUtils.isEntityOwner(new Entity(BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME), 0, 1);
463 config = getConfig();
467 public class ConfigServerReactor
468 extends AsyncDataTreeChangeListenerBase<ConfigServer, ConfigServerReactor>
469 implements ClusteredDataTreeChangeListener<ConfigServer> {
470 private static final String YANG_OBJ = "config-server ";
472 public ConfigServerReactor() {
473 super(ConfigServer.class, ConfigServerReactor.class);
477 protected void add(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
478 LOG.trace("received bgp connect config host {}", val.getHost().getValue());
479 if (!isBGPEntityOwner()) {
485 } catch (InterruptedException e) {
488 LOG.debug("issueing bgp router connect to host {}", val.getHost().getValue());
489 bgpRouter.configServerUpdated();
490 synchronized (BgpConfigurationManager.this) {
491 boolean res = bgpRouter.connect(val.getHost().getValue(),
492 val.getPort().intValue());
494 LOG.error(YANG_OBJ + "Add failed; " + ADD_WARN);
497 VtyshCli.setHostAddr(val.getHost().getValue());
498 ClearBgpCli.setHostAddr(val.getHost().getValue());
502 protected ConfigServerReactor getDataTreeChangeListener() {
503 return ConfigServerReactor.this;
507 protected InstanceIdentifier<ConfigServer> getWildCardPath() {
508 return InstanceIdentifier.create(Bgp.class).child(ConfigServer.class);
512 protected void remove(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
513 LOG.trace("received bgp disconnect");
514 if (!isBGPEntityOwner()) {
518 bgpRouter.configServerUpdated();
520 synchronized (BgpConfigurationManager.this) {
521 if (bgp_as_num != 0) {
523 bgpRouter.stopBgp(bgp_as_num);
524 stopBgpCountersTask();
526 } catch (TException | BgpRouterException e) {
527 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
530 LOG.debug("bgp as-id is null while removing config-server");
532 bgpRouter.disconnect();
537 protected void update(InstanceIdentifier<ConfigServer> iid,
538 ConfigServer oldval, ConfigServer newval) {
539 LOG.trace("received bgp Connection update");
540 if (!isBGPEntityOwner()) {
543 LOG.error(YANG_OBJ + UPD_WARN);
547 private BgpRouter getClient(String yangObj) {
548 if (bgpRouter == null || !bgpRouter.isBgpConnected()) {
549 LOG.warn("{}: configuration received when BGP is inactive", yangObj);
555 public class AsIdReactor
556 extends AsyncDataTreeChangeListenerBase<AsId, AsIdReactor>
557 implements ClusteredDataTreeChangeListener<AsId> {
559 private static final String YANG_OBJ = "as-id ";
561 public AsIdReactor() {
562 super(AsId.class, AsIdReactor.class);
566 protected void add(InstanceIdentifier<AsId> iid, AsId val) {
567 LOG.error("received bgp add asid {}", val);
568 if (!isBGPEntityOwner()) {
571 LOG.debug("received add router config asNum {}", val.getLocalAs());
572 bgp_as_num = val.getLocalAs().longValue();
573 synchronized (BgpConfigurationManager.this) {
574 BgpRouter br = getClient(YANG_OBJ);
576 LOG.debug("{} Unable to process add for asNum {}; {} {}", YANG_OBJ, val.getLocalAs(),
577 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
582 startBgpCountersTask();
583 startBgpAlarmsTask();
588 protected AsIdReactor getDataTreeChangeListener() {
589 return AsIdReactor.this;
593 protected InstanceIdentifier<AsId> getWildCardPath() {
594 return InstanceIdentifier.create(Bgp.class).child(AsId.class);
598 protected void remove(InstanceIdentifier<AsId> iid, AsId val) {
599 LOG.error("received delete router config asNum {}", val.getLocalAs());
600 if (!isBGPEntityOwner()) {
603 synchronized (BgpConfigurationManager.this) {
604 long asNum = val.getLocalAs();
605 BgpRouter br = getClient(YANG_OBJ);
608 LOG.debug("{} Unable to process remove for asNum {}; {} {}", YANG_OBJ, asNum,
609 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
614 } catch (TException | BgpRouterException e) {
615 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
618 stopBgpCountersTask();
621 Bgp conf = getConfig();
623 LOG.error("Config Null while removing the as-id");
626 LOG.debug("Removing external routes from FIB");
627 deleteExternalFibRoutes();
628 List<Neighbors> nbrs = conf.getNeighbors();
629 if (nbrs != null && nbrs.size() > 0) {
630 LOG.error("Tring to remove the as-id when neighbor config is already present");
631 for (Neighbors nbr : nbrs) {
632 LOG.debug("Removing Neighbor {} from Data store", nbr.getAddress().getValue());
633 delNeighbor(nbr.getAddress().getValue());
640 protected void update(InstanceIdentifier<AsId> iid,
641 AsId oldval, AsId newval) {
642 if (!isBGPEntityOwner()) {
645 LOG.error(YANG_OBJ + UPD_WARN);
649 public class GracefulRestartReactor
650 extends AsyncDataTreeChangeListenerBase<GracefulRestart, GracefulRestartReactor>
651 implements ClusteredDataTreeChangeListener<GracefulRestart> {
653 private static final String YANG_OBJ = "graceful-restart ";
655 public GracefulRestartReactor() {
656 super(GracefulRestart.class, GracefulRestartReactor.class);
660 protected void add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
661 if (!isBGPEntityOwner()) {
664 synchronized (BgpConfigurationManager.this) {
665 int stalePathTime = val.getStalepathTime().intValue();
666 BgpRouter br = getClient(YANG_OBJ);
668 LOG.error("{} Unable to add stale-path time {}; {} {}", YANG_OBJ, stalePathTime,
669 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
673 br.addGracefulRestart(stalePathTime);
674 } catch (TException | BgpRouterException e) {
675 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
681 protected GracefulRestartReactor getDataTreeChangeListener() {
682 return GracefulRestartReactor.this;
686 protected InstanceIdentifier<GracefulRestart> getWildCardPath() {
687 return InstanceIdentifier.create(Bgp.class).child(GracefulRestart.class);
691 protected void remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
692 if (!isBGPEntityOwner()) {
695 LOG.debug("received delete GracefulRestart config val {}", val.getStalepathTime().intValue());
696 synchronized (BgpConfigurationManager.this) {
697 BgpRouter br = getClient(YANG_OBJ);
699 LOG.error("{} Unable to delete stale-path time; {} {}", YANG_OBJ,
700 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
704 br.delGracefulRestart();
705 } catch (TException | BgpRouterException e) {
706 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
712 protected void update(InstanceIdentifier<GracefulRestart> iid,
713 GracefulRestart oldval, GracefulRestart newval) {
714 if (!isBGPEntityOwner()) {
717 LOG.debug("received update GracefulRestart config val {}", newval.getStalepathTime().intValue());
718 synchronized (BgpConfigurationManager.this) {
719 int stalePathTime = newval.getStalepathTime().intValue();
720 BgpRouter br = getClient(YANG_OBJ);
722 LOG.error("{} Unable to update stale-path time to {}; {} {}", YANG_OBJ, stalePathTime,
723 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
727 br.addGracefulRestart(stalePathTime);
728 } catch (TException | BgpRouterException e) {
729 LOG.error("{} update received exception; {}", YANG_OBJ, ADD_WARN, e);
735 public class LoggingReactor
736 extends AsyncDataTreeChangeListenerBase<Logging, LoggingReactor>
737 implements ClusteredDataTreeChangeListener<Logging> {
739 private static final String YANG_OBJ = "logging ";
741 public LoggingReactor() {
742 super(Logging.class, LoggingReactor.class);
746 protected void add(InstanceIdentifier<Logging> iid, Logging val) {
747 if (!isBGPEntityOwner()) {
750 synchronized (BgpConfigurationManager.this) {
751 BgpRouter br = getClient(YANG_OBJ);
753 LOG.error("{} Unable to add logging for qbgp; {} {}", YANG_OBJ,
754 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
758 br.setLogging(val.getFile(), val.getLevel());
759 } catch (TException | BgpRouterException e) {
760 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
766 protected LoggingReactor getDataTreeChangeListener() {
767 return LoggingReactor.this;
771 protected InstanceIdentifier<Logging> getWildCardPath() {
772 return InstanceIdentifier.create(Bgp.class).child(Logging.class);
776 protected void remove(InstanceIdentifier<Logging> iid, Logging val) {
777 if (!isBGPEntityOwner()) {
780 LOG.debug("received remove Logging config val {}", val.getLevel());
781 synchronized (BgpConfigurationManager.this) {
782 BgpRouter br = getClient(YANG_OBJ);
784 LOG.error("{} Unable to remove logging for qbgp; {} {}", YANG_OBJ,
785 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
789 br.setLogging(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
790 } catch (TException | BgpRouterException e) {
791 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
797 protected void update(InstanceIdentifier<Logging> iid,
798 Logging oldval, Logging newval) {
799 if (!isBGPEntityOwner()) {
802 synchronized (BgpConfigurationManager.this) {
803 BgpRouter br = getClient(YANG_OBJ);
805 LOG.error("{} Unable to update logging for qbgp; {} {}", YANG_OBJ,
806 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
810 br.setLogging(newval.getFile(), newval.getLevel());
811 } catch (TException | BgpRouterException e) {
812 LOG.error("{} newval received exception; {}", YANG_OBJ, ADD_WARN, e);
818 public class NeighborsReactor
819 extends AsyncDataTreeChangeListenerBase<Neighbors, NeighborsReactor>
820 implements ClusteredDataTreeChangeListener<Neighbors> {
822 private static final String YANG_OBJ = "neighbors ";
824 public NeighborsReactor() {
825 super(Neighbors.class, NeighborsReactor.class);
829 protected void add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
830 if (!isBGPEntityOwner()) {
833 LOG.debug("received add Neighbors config val {}", val.getAddress().getValue());
834 synchronized (BgpConfigurationManager.this) {
835 String peerIp = val.getAddress().getValue();
836 long as = val.getRemoteAs();
837 final String md5Secret = extractMd5Secret(val);
838 BgpRouter br = getClient(YANG_OBJ);
840 LOG.debug("{} Unable to process add for peer {} as {}; {} {}", YANG_OBJ, peerIp, as,
841 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
845 //itmProvider.buildTunnelsToDCGW(new IpAddress(peerIp.toCharArray()));
846 br.addNeighbor(peerIp, as, md5Secret);
848 } catch (TException | BgpRouterException e) {
849 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
855 protected NeighborsReactor getDataTreeChangeListener() {
856 return NeighborsReactor.this;
860 protected InstanceIdentifier<Neighbors> getWildCardPath() {
861 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class);
865 protected void remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
866 if (!isBGPEntityOwner()) {
869 LOG.debug("received remove Neighbors config val {}", val.getAddress().getValue());
870 synchronized (BgpConfigurationManager.this) {
871 String peerIp = val.getAddress().getValue();
872 BgpRouter br = getClient(YANG_OBJ);
874 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
875 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
879 //itmProvider.deleteTunnelsToDCGW(new IpAddress(val.getAddress().getValue().toCharArray()));
880 br.delNeighbor(peerIp);
881 } catch (TException | BgpRouterException e) {
882 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
885 final BgpAlarms bgpAlarms = getBgpAlarms();
886 if (bgpAlarms != null) {
887 bgpAlarms.clearBgpNbrDownAlarm(peerIp);
890 if (bgpUtil.isBfdEnabled()) {
891 final BgpCounters bgpCounters = getBgpCounters();
892 if (bgpCounters != null) {
893 bgpCounters.clearBfdNbrCounters(peerIp);
900 protected void update(InstanceIdentifier<Neighbors> iid,
901 Neighbors oldval, Neighbors newval) {
902 if (!isBGPEntityOwner()) {
905 //purposefully nothing to do.
909 public class EbgpMultihopReactor
910 extends AsyncDataTreeChangeListenerBase<EbgpMultihop, EbgpMultihopReactor>
911 implements ClusteredDataTreeChangeListener<EbgpMultihop> {
913 private static final String YANG_OBJ = "ebgp-multihop ";
915 public EbgpMultihopReactor() {
916 super(EbgpMultihop.class, EbgpMultihopReactor.class);
920 protected void add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
921 if (!isBGPEntityOwner()) {
924 LOG.debug("received add EbgpMultihop config val {}", val.getPeerIp().getValue());
925 synchronized (BgpConfigurationManager.this) {
926 String peerIp = val.getPeerIp().getValue();
927 BgpRouter br = getClient(YANG_OBJ);
929 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
930 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
934 br.addEbgpMultihop(peerIp, val.getNhops().intValue());
935 } catch (TException | BgpRouterException e) {
936 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
942 protected EbgpMultihopReactor getDataTreeChangeListener() {
943 return EbgpMultihopReactor.this;
947 protected InstanceIdentifier<EbgpMultihop> getWildCardPath() {
948 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(EbgpMultihop.class);
952 protected void remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
953 if (!isBGPEntityOwner()) {
956 LOG.debug("received remove EbgpMultihop config val {}", val.getPeerIp().getValue());
957 synchronized (BgpConfigurationManager.this) {
958 String peerIp = val.getPeerIp().getValue();
959 BgpRouter br = getClient(YANG_OBJ);
961 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
962 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
966 br.delEbgpMultihop(peerIp);
967 } catch (TException | BgpRouterException e) {
968 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
974 protected void update(InstanceIdentifier<EbgpMultihop> iid,
975 EbgpMultihop oldval, EbgpMultihop newval) {
976 if (!isBGPEntityOwner()) {
979 LOG.error(YANG_OBJ + UPD_WARN);
983 public class UpdateSourceReactor
984 extends AsyncDataTreeChangeListenerBase<UpdateSource, UpdateSourceReactor>
985 implements ClusteredDataTreeChangeListener<UpdateSource> {
987 private static final String YANG_OBJ = "update-source ";
989 public UpdateSourceReactor() {
990 super(UpdateSource.class, UpdateSourceReactor.class);
994 protected void add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
995 if (!isBGPEntityOwner()) {
998 LOG.debug("received add UpdateSource config val {}", val.getSourceIp().getValue());
999 synchronized (BgpConfigurationManager.this) {
1000 String peerIp = val.getPeerIp().getValue();
1001 BgpRouter br = getClient(YANG_OBJ);
1003 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
1004 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1008 br.addUpdateSource(peerIp, val.getSourceIp().getValue());
1009 } catch (TException | BgpRouterException e) {
1010 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1016 protected UpdateSourceReactor getDataTreeChangeListener() {
1017 return UpdateSourceReactor.this;
1021 protected InstanceIdentifier<UpdateSource> getWildCardPath() {
1022 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(UpdateSource.class);
1026 protected void remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
1027 if (!isBGPEntityOwner()) {
1030 LOG.debug("received remove UpdateSource config val {}", val.getSourceIp().getValue());
1031 synchronized (BgpConfigurationManager.this) {
1032 String peerIp = val.getPeerIp().getValue();
1033 BgpRouter br = getClient(YANG_OBJ);
1035 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
1036 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1040 br.delUpdateSource(peerIp);
1041 } catch (TException | BgpRouterException e) {
1042 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1048 protected void update(InstanceIdentifier<UpdateSource> iid,
1049 UpdateSource oldval, UpdateSource newval) {
1050 if (!isBGPEntityOwner()) {
1053 LOG.error(YANG_OBJ + UPD_WARN);
1057 public class AddressFamiliesReactor
1058 extends AsyncDataTreeChangeListenerBase<AddressFamilies, AddressFamiliesReactor>
1059 implements ClusteredDataTreeChangeListener<AddressFamilies> {
1061 private static final String YANG_OBJ = "address-families ";
1063 public AddressFamiliesReactor() {
1064 super(AddressFamilies.class, AddressFamiliesReactor.class);
1068 protected void add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
1069 if (!isBGPEntityOwner()) {
1072 LOG.debug("received add AddressFamilies config val {}", val.getPeerIp().getValue());
1073 synchronized (BgpConfigurationManager.this) {
1074 String peerIp = val.getPeerIp().getValue();
1075 BgpRouter br = getClient(YANG_OBJ);
1077 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
1078 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1081 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
1082 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
1084 br.addAddressFamily(peerIp, afi, safi);
1085 } catch (TException | BgpRouterException e) {
1086 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1092 protected AddressFamiliesReactor getDataTreeChangeListener() {
1093 return AddressFamiliesReactor.this;
1097 protected InstanceIdentifier<AddressFamilies> getWildCardPath() {
1098 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(AddressFamilies.class);
1102 protected void remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
1103 if (!isBGPEntityOwner()) {
1106 LOG.debug("received remove AddressFamilies config val {}", val.getPeerIp().getValue());
1107 synchronized (BgpConfigurationManager.this) {
1108 String peerIp = val.getPeerIp().getValue();
1109 BgpRouter br = getClient(YANG_OBJ);
1111 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
1112 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1115 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
1116 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
1118 br.delAddressFamily(peerIp, afi, safi);
1119 } catch (TException | BgpRouterException e) {
1120 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1126 protected void update(InstanceIdentifier<AddressFamilies> iid,
1127 AddressFamilies oldval, AddressFamilies newval) {
1128 if (!isBGPEntityOwner()) {
1131 LOG.error(YANG_OBJ + UPD_WARN);
1135 public class NetworksReactor
1136 extends AsyncDataTreeChangeListenerBase<Networks, NetworksReactor>
1137 implements ClusteredDataTreeChangeListener<Networks> {
1139 private static final String YANG_OBJ = "networks ";
1141 public NetworksReactor() {
1142 super(Networks.class, NetworksReactor.class);
1146 public NetworksReactor getDataTreeChangeListener() {
1147 return NetworksReactor.this;
1151 protected void add(InstanceIdentifier<Networks> iid, Networks val) {
1152 if (!isBGPEntityOwner()) {
1155 LOG.debug("received add Networks config val {}", val.getPrefixLen());
1156 synchronized (BgpConfigurationManager.this) {
1157 String rd = val.getRd();
1158 String pfxlen = val.getPrefixLen();
1159 String nh = val.getNexthop().getValue();
1160 BgpRouter br = getClient(YANG_OBJ);
1162 LOG.debug("{} Unable to process add for rd {} prefix {} nexthop {}; {} {}", YANG_OBJ, rd, pfxlen,
1163 nh, BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1166 Long label = val.getLabel();
1167 int lbl = label == null ? qbgpConstants.LBL_NO_LABEL
1169 int l3vni = val.getL3vni() == null ? qbgpConstants.LBL_NO_LABEL
1170 : val.getL3vni().intValue();
1171 int l2vni = val.getL2vni() == null ? qbgpConstants.LBL_NO_LABEL
1172 : val.getL2vni().intValue();
1174 BgpControlPlaneType protocolType = val.getBgpControlPlaneType();
1175 int ethernetTag = val.getEthtag().intValue();
1176 String esi = val.getEsi();
1177 String macaddress = val.getMacaddress();
1178 EncapType encapType = val.getEncapType();
1179 String routerMac = val.getRoutermac();
1182 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, l2vni, BgpUtil.convertToThriftProtocolType(protocolType),
1183 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
1184 } catch (TException | BgpRouterException e) {
1185 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1191 protected InstanceIdentifier<Networks> getWildCardPath() {
1192 return InstanceIdentifier.create(Bgp.class).child(Networks.class);
1196 protected void remove(InstanceIdentifier<Networks> iid, Networks val) {
1197 if (!isBGPEntityOwner()) {
1200 LOG.debug("received remove Networks config val {}", val.getPrefixLen());
1201 synchronized (BgpConfigurationManager.this) {
1202 String rd = val.getRd();
1203 String pfxlen = val.getPrefixLen();
1204 BgpRouter br = getClient(YANG_OBJ);
1206 LOG.debug("{} Unable to process remove for rd {} prefix {}; {} {}", YANG_OBJ, rd, pfxlen,
1207 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1210 Long label = val.getLabel();
1211 int lbl = label == null ? 0 : label.intValue();
1212 if (rd == null && lbl > 0) {
1213 //LU prefix is being deleted.
1214 rd = Integer.toString(lbl);
1217 br.delPrefix(rd, pfxlen);
1218 } catch (TException | BgpRouterException e) {
1219 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1224 /**get the value AFI from a prefix as "x.x.x.x/x".
1226 * @param pfxlen the prefix to get an afi
1227 * @return the afi value as you are need
1229 public int testValueAFI(String pfxlen) {
1230 int afiNew = af_afi.AFI_IP.getValue();
1232 String ipOnly = pfxlen.substring(0, pfxlen.lastIndexOf("/"));
1233 java.net.Inet6Address.getByName(ipOnly);
1234 afiNew = af_afi.AFI_IPV6.getValue();
1235 } catch (java.net.UnknownHostException e) {
1236 //ce n'est pas de l'ipv6
1243 protected void update(final InstanceIdentifier<Networks> iid,
1244 final Networks oldval, final Networks newval) {
1245 if (!isBGPEntityOwner()) {
1248 if (oldval.equals(newval)) {
1249 //Update: OLD and New values are same, no need to trigger remove/add.
1250 LOG.debug("received Updated for the same OLD and New values. RD: {}, Prefix: {}, Label: {}, NH: {}",
1251 oldval.getRd(), oldval.getPrefixLen(), oldval.getLabel(), oldval.getNexthop());
1254 LOG.debug("update networks old val RD: {}, Prefix: {}, Label: {}, NH: {} "
1255 + "new val RD: {}, Prefix: {}, Label: {}, NH: {}",
1256 oldval.getRd(), oldval.getPrefixLen(), oldval.getLabel(), oldval.getNexthop(),
1257 newval.getRd(), newval.getPrefixLen(), newval.getLabel(), newval.getNexthop());
1258 remove(iid, oldval);
1263 static Timer timer = new Timer();
1265 public class VrfsReactor
1266 extends AsyncDataTreeChangeListenerBase<Vrfs, VrfsReactor>
1267 implements ClusteredDataTreeChangeListener<Vrfs> {
1269 private static final String YANG_OBJ = "vrfs ";
1271 public VrfsReactor() {
1272 super(Vrfs.class, VrfsReactor.class);
1276 protected void add(InstanceIdentifier<Vrfs> iid, Vrfs vrfs) {
1277 if (!isBGPEntityOwner()) {
1280 LOG.debug("received add Vrfs config value {}", vrfs.getRd());
1281 synchronized (BgpConfigurationManager.this) {
1282 String rd = vrfs.getRd();
1283 BgpRouter br = getClient(YANG_OBJ);
1285 LOG.debug("{} Unable to process add for rd {}; {} {}", YANG_OBJ, rd,
1286 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1290 List<AddressFamiliesVrf> vrfAddrFamilyList = vrfs.getAddressFamiliesVrf();
1291 for (AddressFamiliesVrf vrfAddrFamily : vrfAddrFamilyList) {
1292 /*add to br the new vrfs arguments*/
1293 br.addVrf(BgpUtil.getLayerType(vrfAddrFamily), rd, vrfs.getImportRts(), vrfs.getExportRts()
1296 /*add to br the vrfs contained in mapNewAdFamily*/
1297 List<AddressFamiliesVrf> vrfAddrFamilyListFromMap = mapNewAdFamily.get(rd);
1298 if (vrfAddrFamilyListFromMap == null) {
1302 for (AddressFamiliesVrf adf : vrfAddrFamilyListFromMap) {
1303 if (vrfAddrFamilyList.contains(adf)) {
1304 mapNewAdFamily.remove(rd);
1305 } else if (adf != null) {
1307 br.addVrf(BgpUtil.getLayerType(adf), rd, vrfs.getImportRts(), vrfs.getExportRts()
1309 // remove AddressFamiliesVrf which was already added to BGP
1310 vrfAddrFamilyListFromMap.remove(adf);
1311 if (vrfAddrFamilyListFromMap.isEmpty()) {
1312 // remove Vrf entry from temp mapNewAdFamily if all its AddressFamiliesVrf was
1314 mapNewAdFamily.remove(rd);
1318 } catch (TException | BgpRouterException e) {
1319 LOG.error("{} get {}, Add received exception", YANG_OBJ, ADD_WARN, e);
1325 protected VrfsReactor getDataTreeChangeListener() {
1326 return VrfsReactor.this;
1330 protected InstanceIdentifier<Vrfs> getWildCardPath() {
1331 return InstanceIdentifier.create(Bgp.class).child(Vrfs.class);
1335 protected void remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
1336 if (!isBGPEntityOwner()) {
1339 LOG.debug("received remove Vrfs config val {}", val.getRd());
1340 synchronized (BgpConfigurationManager.this) {
1341 String rd = val.getRd();
1342 BgpRouter br = getClient(YANG_OBJ);
1344 LOG.debug("{} Unable to process remove for rd {}; {} {}", YANG_OBJ, rd,
1345 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1349 List<AddressFamiliesVrf> adf = mapNewAdFamily.get(rd);
1350 adf = adf != null ? adf : new ArrayList<>();
1351 for (AddressFamiliesVrf s : val.getAddressFamiliesVrf()) {
1352 br.delVrf(rd, s.getAfi(), s.getSafi());
1353 adf.remove(s);// remove in the map the vrf in waiting for advertise quagga
1355 if (adf.isEmpty()) {
1356 mapNewAdFamily.remove(rd);
1358 } catch (TException | BgpRouterException e) {
1359 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1365 protected void update(InstanceIdentifier<Vrfs> iid,
1366 Vrfs oldval, Vrfs newval) {
1367 if (oldval != null && newval != null) {
1368 LOG.debug("received update Vrfs config val {}, VRFS: Update getting triggered for VRFS rd {}",
1369 newval.getRd(), oldval.getRd());
1371 LOG.debug("received update Vrfs config val {}, from old vrf {}",
1374 if (!isBGPEntityOwner()) {
1378 List<AddressFamiliesVrf> adFamilyVrfToDel = new ArrayList<>();
1379 List<AddressFamiliesVrf> adFamilyVrfToAdd = new ArrayList<>();
1380 List<AddressFamiliesVrf> oldlistAdFamilies = new ArrayList<>();
1381 List<AddressFamiliesVrf> newlistAdFamilies = new ArrayList<>();
1382 if (oldval != null) {
1383 oldlistAdFamilies = oldval.getAddressFamiliesVrf() == null
1384 ? new ArrayList<>() : oldval.getAddressFamiliesVrf();
1386 if (newval != null) {
1387 newlistAdFamilies = newval.getAddressFamiliesVrf() == null
1388 ? new ArrayList<>() : newval.getAddressFamiliesVrf();
1390 /*find old AddressFamily to remove from new configuration*/
1391 for (AddressFamiliesVrf adVrf : oldlistAdFamilies) {
1392 if (!newlistAdFamilies.contains(adVrf)) {
1393 adFamilyVrfToDel.add(adVrf);
1396 /*find new AddressFamily to add to unexisting configuration*/
1397 for (AddressFamiliesVrf adVrf : newlistAdFamilies) {
1398 if (!oldlistAdFamilies.contains(adVrf)) {
1399 adFamilyVrfToAdd.add(adVrf);
1402 String rd = newval != null ? newval.getRd() : null;
1404 BgpRouter br = getClient(YANG_OBJ);
1406 LOG.debug("{} Unable to process add for rd {}; {} {}", YANG_OBJ, rd,
1407 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1411 for (AddressFamiliesVrf adfvrf : adFamilyVrfToAdd) {
1413 LOG.debug("call addVRf rd {} afi {} safi {}", rd, adfvrf.getAfi(), adfvrf.getSafi());
1414 br.addVrf(BgpUtil.getLayerType(adfvrf), rd, newval.getImportRts(),
1415 newval.getExportRts());
1416 } catch (TException | BgpRouterException e) {
1417 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1421 for (AddressFamiliesVrf adfToDel : adFamilyVrfToDel) {
1423 LOG.debug("call delVRf rd {} afi {} safi {}", rd, adfToDel.getAfi(), adfToDel.getSafi());
1424 br.delVrf(rd, adfToDel.getAfi(), adfToDel.getSafi());
1425 } catch (TException | BgpRouterException e) {
1426 LOG.error("{} delVrf received exception; {}", YANG_OBJ, ADD_WARN, e);
1433 public class BgpReactor
1434 extends AsyncDataTreeChangeListenerBase<Bgp, BgpReactor>
1435 implements ClusteredDataTreeChangeListener<Bgp> {
1437 private static final String YANG_OBJ = "Bgp ";
1439 public BgpReactor() {
1440 super(Bgp.class, BgpReactor.class);
1445 protected void add(InstanceIdentifier<Bgp> iid, Bgp val) {
1446 LOG.debug("received add Bgp config");
1450 } catch (InterruptedException e) {
1453 synchronized (BgpConfigurationManager.this) {
1455 if (!isBGPEntityOwner()) {
1462 protected BgpReactor getDataTreeChangeListener() {
1463 return BgpReactor.this;
1467 protected InstanceIdentifier<Bgp> getWildCardPath() {
1468 return InstanceIdentifier.create(Bgp.class);
1472 protected void remove(InstanceIdentifier<Bgp> iid, Bgp val) {
1473 if (!isBGPEntityOwner()) {
1476 LOG.debug("received remove Bgp config");
1482 protected void update(InstanceIdentifier<Bgp> iid,
1483 Bgp oldval, Bgp newval) {
1484 if (!isBGPEntityOwner()) {
1492 @SuppressWarnings("deprecation")
1493 public class MultipathReactor
1494 extends AsyncDataTreeChangeListenerBase<Multipath, MultipathReactor>
1495 implements ClusteredDataTreeChangeListener<Multipath> {
1497 private static final String YANG_OBJ = "multipath ";
1499 public MultipathReactor() {
1500 super(Multipath.class, MultipathReactor.class);
1505 protected MultipathReactor getDataTreeChangeListener() {
1506 return MultipathReactor.this;
1510 protected InstanceIdentifier<Multipath> getWildCardPath() {
1511 return InstanceIdentifier.create(Bgp.class).child(Multipath.class);
1515 protected void remove(InstanceIdentifier<Multipath> iid, Multipath val) {
1516 executor.execute(new MultipathStatusChange(val));
1520 protected void update(InstanceIdentifier<Multipath> iid, Multipath oldval, Multipath newval) {
1521 executor.execute(new MultipathStatusChange(newval));
1525 protected void add(InstanceIdentifier<Multipath> key, Multipath dataObjectModification) {
1526 executor.execute(new MultipathStatusChange(dataObjectModification));
1529 class MultipathStatusChange implements Runnable {
1531 Multipath multipath;
1533 MultipathStatusChange(Multipath multipath) {
1534 this.multipath = multipath;
1539 if (isBGPEntityOwner()) {
1540 synchronized (BgpConfigurationManager.this) {
1542 BgpRouter br = getClient(YANG_OBJ);
1545 af_afi afi = af_afi.findByValue(multipath.getAfi().intValue());
1546 af_safi safi = af_safi.findByValue(multipath.getSafi().intValue());
1549 if (multipath.isMultipathEnabled()) {
1550 br.enableMultipath(afi, safi);
1552 br.disableMultipath(afi, safi);
1554 } catch (TException | BgpRouterException e) {
1555 LOG.error("{} received exception", YANG_OBJ, e);
1565 public void close() {
1570 @SuppressWarnings("deprecation")
1571 public class VrfMaxpathReactor
1572 extends AsyncDataTreeChangeListenerBase<VrfMaxpath, VrfMaxpathReactor>
1573 implements ClusteredDataTreeChangeListener<VrfMaxpath> {
1575 private static final String YANG_OBJ = "vrfMaxpath ";
1577 public VrfMaxpathReactor() {
1578 super(VrfMaxpath.class, VrfMaxpathReactor.class);
1583 protected VrfMaxpathReactor getDataTreeChangeListener() {
1584 return VrfMaxpathReactor.this;
1588 protected InstanceIdentifier<VrfMaxpath> getWildCardPath() {
1589 return InstanceIdentifier.create(Bgp.class).child(VrfMaxpath.class);
1592 class VrfMaxPathConfigurator implements Runnable {
1594 VrfMaxpath vrfMaxpathVal;
1596 VrfMaxPathConfigurator(VrfMaxpath vrfMaxPathVal) {
1597 this.vrfMaxpathVal = vrfMaxPathVal;
1602 if (isBGPEntityOwner()) {
1603 synchronized (BgpConfigurationManager.this) {
1604 BgpRouter br = getClient(YANG_OBJ);
1607 br.multipaths(vrfMaxpathVal.getRd(), vrfMaxpathVal.getMaxpaths());
1608 LOG.debug("Maxpath for vrf {} is {}", vrfMaxpathVal.getRd(),
1609 vrfMaxpathVal.getMaxpaths());
1610 } catch (TException | BgpRouterException e) {
1611 LOG.error("{} received exception", YANG_OBJ, e);
1620 protected void remove(InstanceIdentifier<VrfMaxpath> iid, VrfMaxpath vrfMaxPathVal) {
1621 if (isBGPEntityOwner()) {
1622 synchronized (BgpConfigurationManager.this) {
1623 BgpRouter br = getClient(YANG_OBJ);
1626 br.multipaths(vrfMaxPathVal.getRd(), BgpConstants.BGP_DEFAULT_MULTIPATH);
1627 LOG.debug("Del Maxpath for vrf: {} ", vrfMaxPathVal.getRd());
1628 } catch (TException | BgpRouterException e) {
1629 LOG.error(YANG_OBJ + " del received exception:", e);
1637 protected void update(InstanceIdentifier<VrfMaxpath> iid,
1638 VrfMaxpath oldval, VrfMaxpath newval) {
1639 if (!Objects.equals(oldval.getMaxpaths(), newval.getMaxpaths())) {
1640 executor.execute(new VrfMaxPathConfigurator(newval));
1645 protected void add(InstanceIdentifier<VrfMaxpath> instanceIdentifier, VrfMaxpath vrfMaxpathVal) {
1646 executor.execute(new VrfMaxPathConfigurator(vrfMaxpathVal));
1650 public void close() {
1655 public class BfdConfigReactor
1656 extends AsyncDataTreeChangeListenerBase<BfdConfig, BfdConfigReactor>
1657 implements ClusteredDataTreeChangeListener<BfdConfig> {
1659 private static final String YANG_OBJ = "BfdConfig ";
1661 public BfdConfigReactor() {
1662 super(BfdConfig.class, BfdConfigReactor.class);
1666 protected void add(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
1667 if (!isBGPEntityOwner()) {
1670 BgpRouter br = getClient(YANG_OBJ);
1671 LOG.debug("received bfd config: bfd enabled {} min-rx {} min-tx {} detect-mul {} mhop {}",
1672 val.isBfdEnabled(), val.getMinRx(), val.getMinTx(),
1673 val.getDetectMult(), val.isMultihop());
1675 LOG.debug(YANG_OBJ + "{} Unable to process add {}",
1676 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1679 if (val.isBfdEnabled() == false) {
1680 LOG.debug("BFD not enabled. Ignoring the config add");
1683 int minRx = val.getMinRx().intValue();
1684 int minTx = val.getMinTx().intValue();
1685 int detectMult = val.getDetectMult().intValue();
1686 boolean multiHop = val.isMultihop();
1688 br.addBfd(detectMult, minRx, minTx,multiHop);
1689 } catch (TException | BgpRouterException e) {
1690 LOG.error("{} get {}, Add received exception;", YANG_OBJ, ADD_WARN, e);
1695 protected BfdConfigReactor getDataTreeChangeListener() {
1696 return BfdConfigReactor.this;
1700 protected InstanceIdentifier<BfdConfig> getWildCardPath() {
1701 return InstanceIdentifier.create(BfdConfig.class);
1705 protected void remove(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
1706 if (!isBGPEntityOwner()) {
1709 LOG.debug("received bfd config removal");
1710 BgpRouter br = getClient(YANG_OBJ);
1712 LOG.debug("{} Unable to process del {} {}", YANG_OBJ,
1713 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1718 } catch (TException | BgpRouterException e) {
1719 LOG.error("{} get {}, Del received exception;", YANG_OBJ, ADD_WARN, e);
1725 protected void update(InstanceIdentifier<BfdConfig> iid,
1726 BfdConfig oldval, BfdConfig newval) {
1727 LOG.debug("received bfd config: updated oldval bfd enabled {}"
1728 + "min-rx {} min-tx {} detect-mul {} mhop {}",
1729 oldval.isBfdEnabled(), oldval.getMinRx(), oldval.getMinTx(),
1730 oldval.getDetectMult(), oldval.isMultihop());
1731 LOG.debug("received bfd config: updated newval bfd enabled {}"
1732 + "min-rx {} min-tx {} detect-mul {} mhop {}",
1733 newval.isBfdEnabled(), newval.getMinRx(), newval.getMinTx(),
1734 newval.getDetectMult(), newval.isMultihop());
1735 if (oldval.isBfdEnabled()) {
1736 LOG.debug("deleting bfd config on an update");
1737 remove(iid, oldval);
1739 LOG.debug("adding bfd config on an update");
1745 public boolean isIpAvailable(String odlip) {
1748 if (odlip != null) {
1749 if ("127.0.0.1".equals(odlip)) {
1752 Enumeration<NetworkInterface> networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces();
1753 while (networkInterfaceEnumeration.hasMoreElements()) {
1754 NetworkInterface networkInterface = networkInterfaceEnumeration.nextElement();
1755 Enumeration<InetAddress> inetAddressEnumeration = networkInterface.getInetAddresses();
1756 while (inetAddressEnumeration.hasMoreElements()) {
1757 InetAddress inetAddress = inetAddressEnumeration.nextElement();
1758 if (odlip.equals(inetAddress.getHostAddress())) {
1764 } catch (SocketException e) {
1770 public long getStalePathtime(int defValue, AsId asId) {
1773 spt = getConfig().getGracefulRestart().getStalepathTime();
1774 } catch (NullPointerException e) {
1776 spt = asId.getStalepathTime();
1777 LOG.trace("BGP config/Stale-path time is not set using graceful");
1778 } catch (NullPointerException ignore) {
1779 LOG.trace("BGP AS id is not set using graceful");
1784 LOG.trace("BGP config/Stale-path time is not set using graceful/start-bgp");
1790 public static boolean isValidConfigBgpHostPort(String bgpHost, int bgpPort) {
1791 if (!bgpHost.equals(DEF_CHOST)) {
1798 public synchronized void bgpRestarted() {
1800 * If there a thread which in the process of stale cleanup, cancel it
1801 * and start a new thread (to avoid processing same again).
1803 if (previousReplayJobInProgress()) {
1804 cancelPreviousReplayJob();
1806 Runnable task = () -> {
1808 LOG.info("running bgp replay task ");
1809 if (get() == null) {
1810 String host = getConfigHost();
1811 int port = getConfigPort();
1812 LOG.info("connecting to bgp host {} ", host);
1813 bgpRouter.connect(host, port);
1814 LOG.info("no config to push in bgp replay task ");
1817 setStaleStartTime(System.currentTimeMillis());
1818 LOG.info("started creating stale fibDSWriter map ");
1819 createStaleFibMap();
1820 setStaleEndTime(System.currentTimeMillis());
1821 LOG.info("took {} msecs for stale fibDSWriter map creation ", getStaleEndTime() - getStaleStartTime());
1822 LOG.info("started bgp config replay ");
1823 setCfgReplayStartTime(System.currentTimeMillis());
1824 boolean replaySucceded = replay();
1825 setCfgReplayEndTime(System.currentTimeMillis());
1826 LOG.info("took {} msecs for bgp replay ", getCfgReplayEndTime() - getCfgReplayStartTime());
1827 if (replaySucceded) {
1828 LOG.info("starting the stale cleanup timer");
1829 long routeSyncTime = getStalePathtime(BGP_RESTART_ROUTE_SYNC_SEC, config.getAsId());
1830 setStaleCleanupTime(routeSyncTime);
1831 routeCleanupFuture = executor.schedule(new RouteCleanup(), routeSyncTime, TimeUnit.SECONDS);
1833 staledFibEntriesMap.clear();
1835 } catch (InterruptedException | TimeoutException | ExecutionException eCancel) {
1836 LOG.error("Stale Cleanup Task Cancelled", eCancel);
1839 lastReplayJobFt = executor.submit(task);
1842 private boolean previousReplayJobInProgress() {
1843 return lastReplayJobFt != null && !lastReplayJobFt.isDone();
1846 private void cancelPreviousReplayJob() {
1848 LOG.error("cancelling already running bgp replay task");
1849 if (lastReplayJobFt != null) {
1850 lastReplayJobFt.cancel(true);
1851 lastReplayJobFt = null;
1852 staledFibEntriesMap.clear();
1854 if (routeCleanupFuture != null) {
1855 routeCleanupFuture.cancel(true);
1856 routeCleanupFuture = null;
1857 staledFibEntriesMap.clear();
1860 } catch (InterruptedException e) {
1861 LOG.error("Failed to cancel previous replay job ", e);
1865 private void doRouteSync() {
1866 LOG.error("Starting BGP route sync");
1868 bgpRouter.initRibSync(bgpSyncHandle);
1869 } catch (BgpRouterException e) {
1870 LOG.error("Route sync aborted, exception when initializing", e);
1873 while (bgpSyncHandle.getState() != BgpSyncHandle.DONE) {
1874 for (af_afi afi : af_afi.values()) {
1875 Routes routes = null;
1877 routes = bgpRouter.doRibSync(bgpSyncHandle, afi);
1878 } catch (TException | BgpRouterException e) {
1879 LOG.error("Route sync aborted, exception when syncing", e);
1882 Iterator<Update> updates = routes.getUpdatesIterator();
1883 while (updates.hasNext()) {
1884 Update update = updates.next();
1885 String rd = update.getRd();
1886 String nexthop = update.getNexthop();
1888 // TODO: decide correct label here
1889 int label = update.getL3label();
1890 int l2label = update.getL2label();
1892 String prefix = update.getPrefix();
1893 int plen = update.getPrefixlen();
1896 // TODO: protocol type will not be available in "update"
1897 // use "rd" to query vrf table and obtain the protocol_type.
1898 // Currently using PROTOCOL_EVPN as default.
1900 protocol_type.PROTOCOL_EVPN,
1905 update.getMacaddress(),
1908 update.getRoutermac(),
1914 LOG.error("Ending BGP route-sync");
1915 bgpRouter.endRibSync(bgpSyncHandle);
1916 } catch (BgpRouterException e) {
1921 public void addTepToElanDS(String rd, String tepIp, String mac, Long l2vni) {
1922 boolean needUpdate = addToRt2TepMap(rd, tepIp, mac, l2vni);
1924 LOG.info("Adding tepIp {} with RD {} to ELan DS", tepIp, rd);
1925 bgpUtil.addTepToElanInstance(rd, tepIp);
1927 LOG.debug("Skipping the Elan update for RT2 from tep {} rd {}", tepIp, rd);
1931 public void deleteTepfromElanDS(String rd, String tepIp, String mac) {
1932 boolean needUpdate = deleteFromRt2TepMap(rd, tepIp, mac);
1934 LOG.info("Deleting tepIp {} with RD {} to ELan DS", tepIp, rd);
1935 bgpUtil.deleteTepFromElanInstance(rd, tepIp);
1937 LOG.debug("Skipping the Elan update for RT2 withdraw from tep {} rd {}", tepIp, rd);
1941 /* onUpdatePushRoute
1942 * Get Stale fibDSWriter map, and compare current route/fibDSWriter entry.
1943 * - Entry compare shall include NextHop, Label.
1944 * - If entry matches: delete from STALE Map. NO Change to FIB Config DS.
1945 * - If entry not found, add to FIB Config DS.
1946 * - If entry found, but either Label/NextHop doesn't match.
1947 * - Update FIB Config DS with modified values.
1948 * - delete from Stale Map.
1951 public void onUpdatePushRoute(protocol_type protocolType, String rd, String prefix, int plen, String nextHop,
1952 String macaddress, int label, int l2label, String routermac, af_afi afi) {
1953 boolean addroute = false;
1954 boolean macupdate = false;
1956 VrfEntry.EncapType encapType = VrfEntry.EncapType.Mplsgre;
1957 if (protocolType.equals(protocol_type.PROTOCOL_EVPN)) {
1958 encapType = VrfEntry.EncapType.Vxlan;
1959 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = bgpUtil.getVpnInstanceOpData(rd);
1960 if (vpnInstanceOpDataEntry != null) {
1961 if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
1962 LOG.info("Got RT2 route for RD {} l3label {} l2label {} from tep {} with mac {} remote RD {}",
1963 vpnInstanceOpDataEntry.getVpnInstanceName(), label, l2label, nextHop, macaddress, rd);
1964 addTepToElanDS(rd, nextHop, macaddress, (long)l2label);
1967 l3vni = vpnInstanceOpDataEntry.getL3vni();
1970 LOG.error("No corresponding vpn instance found for rd {}. Aborting.", rd);
1975 if (!staledFibEntriesMap.isEmpty()) {
1976 // restart Scenario, as MAP is not empty.
1977 Map<String, Long> map = staledFibEntriesMap.get(rd);
1979 String prefixNextHop = appendNextHopToPrefix(prefix + "/" + plen, nextHop);
1980 Long labelInStaleMap = map.get(prefixNextHop);
1981 if (null == labelInStaleMap) {
1982 // New Entry, which happened to be added during restart.
1985 map.remove(prefixNextHop);
1986 if (isRouteModified(label, labelInStaleMap)) {
1987 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
1988 // Existing entry, where in Label got modified during restart
1993 LOG.debug("rd {} map is null while processing prefix {} ", rd, prefix);
1997 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
2001 LOG.info("ADD: Adding Mac Fib entry rd {} mac{} nexthop {} l2vni {}", rd, macaddress, nextHop, l2label);
2002 fibDSWriter.addMacEntryToDS(rd, macaddress, prefix, Collections.singletonList(nextHop),
2003 encapType, l2label, routermac, RouteOrigin.BGP);
2004 LOG.info("ADD: Added Mac Fib entry rd {} prefix {} nexthop {} label {}", rd, macaddress, nextHop, l2label);
2005 } else if (addroute) {
2006 LOG.info("ADD: Adding Fib entry rd {} prefix {} nexthop {} label {} afi {}",
2007 rd, prefix, nextHop, label, afi);
2008 // TODO: modify addFibEntryToDS signature
2009 List<String> nextHopList = Collections.singletonList(nextHop);
2010 fibDSWriter.addFibEntryToDS(rd, prefix + "/" + plen, nextHopList, encapType, label, l3vni,
2011 routermac, RouteOrigin.BGP);
2012 LOG.info("ADD: Added Fib entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, label);
2013 String vpnName = bgpUtil.getVpnNameFromRd(rd);
2014 if (vpnName != null) {
2015 vpnLinkService.leakRouteIfNeeded(vpnName, prefix, nextHopList, label, RouteOrigin.BGP,
2016 NwConstants.ADD_FLOW);
2021 public void onUpdateWithdrawRoute(protocol_type protocolType, String rd, String prefix, int plen, String nextHop,
2022 String macaddress) {
2024 boolean macupdate = false;
2025 if (protocolType.equals(protocol_type.PROTOCOL_EVPN)) {
2026 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = bgpUtil.getVpnInstanceOpData(rd);
2027 if (vpnInstanceOpDataEntry != null) {
2028 vni = vpnInstanceOpDataEntry.getL3vni();
2029 if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
2030 LOG.debug("Got RT2 withdraw for RD {} {} from tep {} with mac {} remote RD {}",
2031 vpnInstanceOpDataEntry.getVpnInstanceName(), vni, nextHop, macaddress, rd);
2032 deleteTepfromElanDS(rd, nextHop, macaddress);
2033 LOG.debug("For rd {}. skipping fib update", rd);
2037 LOG.error("No corresponding vpn instance found for rd {}. Aborting.", rd);
2042 LOG.info("Removing Mac Fib entry rd {} mac{} nexthop {} ", rd, macaddress, nextHop);
2043 fibDSWriter.removeMacEntryFromDS(rd, macaddress);
2044 LOG.info("Removed Mac Fib entry rd {} prefix {} nexthop {} ", rd, macaddress, nextHop);
2046 LOG.info("REMOVE: Removing Fib entry rd {} prefix {}", rd, prefix);
2047 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix + "/" + plen, nextHop);
2048 LOG.info("REMOVE: Removed Fib entry rd {} prefix {}", rd, prefix);
2052 //TODO: below function is for testing purpose with cli
2053 public void onUpdateWithdrawRoute(String rd, String prefix, int plen, String nexthop) {
2054 LOG.debug("Route del ** {} ** {}/{} ", rd, prefix, plen);
2055 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix + "/" + plen, nexthop);
2056 String vpnName = bgpUtil.getVpnNameFromRd(rd);
2057 if (vpnName != null) {
2058 vpnLinkService.leakRouteIfNeeded(vpnName, prefix, null /*nextHopList*/, 0 /*INVALID_LABEL*/,
2059 RouteOrigin.BGP, NwConstants.DEL_FLOW);
2063 public void peerDown(String ipAddress, long asNumber) {
2064 List<String> tepIpList = bgpUtil.getDcgwTepConfig(ipAddress);
2065 if (tepIpList == null) {
2066 LOG.error("No Tep IP configured for DCGW {} on a peerDown", ipAddress);
2069 tepIpList.forEach(tepIp -> {
2070 bgpUtil.removeOrUpdateLBGroups(tepIp, NwConstants.MOD_FLOW, false);
2074 public void peerUp(String ipAddress, long asNumber) {
2075 List<String> tepIpList = bgpUtil.getDcgwTepConfig(ipAddress);
2076 if (tepIpList == null) {
2077 LOG.error("No Tep IP configured for DCGW {} on a peerUp", ipAddress);
2080 tepIpList.forEach(tepIp -> {
2081 bgpUtil.removeOrUpdateLBGroups(tepIp, NwConstants.MOD_FLOW, true);
2085 private static boolean isRouteModified(int label, Long labelInStaleMap) {
2086 return labelInStaleMap != null && !labelInStaleMap.equals(Long.valueOf(label));
2089 static class ReplayNbr {
2091 boolean shouldRetry = false;
2093 public Neighbors getNbr() {
2097 public boolean isShouldRetry() {
2101 public void setShouldRetry(boolean retryNbr) {
2102 this.shouldRetry = retryNbr;
2105 ReplayNbr(Neighbors nbr, boolean shouldRetry) {
2107 this.shouldRetry = shouldRetry;
2111 private static boolean replayNbrConfig(List<Neighbors> neighbors, BgpRouter br) {
2112 if (neighbors == null || neighbors.isEmpty()) {
2113 LOG.error("Replaying nbr configuration, received NULL list ");
2117 List<ReplayNbr> replayNbrList = new ArrayList<>();
2118 for (Neighbors nbr : neighbors) {
2120 replayNbrList.add(new ReplayNbr(nbr, true));
2123 final int numberOfNbrRetries = 3;
2124 RetryOnException nbrRetry = new RetryOnException(numberOfNbrRetries);
2126 for (ReplayNbr replayNbr : replayNbrList) {
2127 if (!replayNbr.isShouldRetry()) {
2130 boolean replayDone = false;
2131 LOG.debug("Replaying addNbr {}", replayNbr.getNbr().getAddress().getValue());
2134 final String md5password = extractMd5Secret(replayNbr.getNbr());
2135 br.addNeighbor(replayNbr.getNbr().getAddress().getValue(),
2136 replayNbr.getNbr().getRemoteAs().longValue(), md5password);
2138 } catch (TApplicationException tae) {
2139 LOG.debug("Replaying addNbr {}, tapplicationexception: ",
2140 replayNbr.getNbr().getAddress().getValue(), tae);
2141 if (tae.getType() == BgpRouterException.BGP_ERR_PEER_EXISTS) {
2142 LOG.debug("Replaying addNbr Neighbor already present");
2145 } catch (TException | BgpRouterException eNbr) {
2146 LOG.debug("Replaying addNbr {}, exception: ", replayNbr.getNbr().getAddress().getValue(), eNbr);
2149 LOG.debug("Replay addNbr {} successful", replayNbr.getNbr().getAddress().getValue());
2151 //Update Source handling
2152 UpdateSource us = replayNbr.getNbr().getUpdateSource();
2154 LOG.debug("Replaying updatesource {} to peer {}", us.getSourceIp().getValue(),
2155 us.getPeerIp().getValue());
2157 br.addUpdateSource(us.getPeerIp().getValue(),
2158 us.getSourceIp().getValue());
2159 } catch (TException | BgpRouterException eUs) {
2160 LOG.debug("Replaying UpdateSource for Nbr {}, exception:",
2161 replayNbr.getNbr().getAddress().getValue(), eUs);
2163 LOG.debug("Replay updatesource {} successful", us.getSourceIp().getValue());
2166 EbgpMultihop en = replayNbr.getNbr().getEbgpMultihop();
2169 br.addEbgpMultihop(en.getPeerIp().getValue(),
2170 en.getNhops().intValue());
2171 } catch (TException | BgpRouterException eEbgpMhop) {
2172 LOG.debug("Replaying EbgpMultihop for Nbr {}, exception: ",
2173 replayNbr.getNbr().getAddress().getValue(), eEbgpMhop);
2178 List<AddressFamilies> afs = replayNbr.getNbr().getAddressFamilies();
2180 for (AddressFamilies af : afs) {
2181 af_afi afi = af_afi.findByValue(af.getAfi().intValue());
2182 af_safi safi = af_safi.findByValue(af.getSafi().intValue());
2184 br.addAddressFamily(af.getPeerIp().getValue(), afi, safi);
2185 } catch (TException | BgpRouterException eAFs) {
2186 LOG.debug("Replaying AddressFamily for Nbr {}, exception:",
2187 replayNbr.getNbr().getAddress().getValue(), eAFs);
2191 //replay is success --> no need to replay this nbr in next iteration.
2192 replayNbr.setShouldRetry(replayDone ? false : true);
2194 } while (nbrRetry.decrementAndRetry());
2195 boolean replaySuccess = true;
2196 for (ReplayNbr replayNbr : replayNbrList) {
2197 replaySuccess = replaySuccess && !replayNbr.isShouldRetry();
2199 return replaySuccess;
2202 public String getConfigHost() {
2203 if (config == null) {
2206 ConfigServer ts = config.getConfigServer();
2207 return ts == null ? hostStartup : ts.getHost().getValue();
2210 public int getConfigPort() {
2211 if (config == null) {
2212 return Integer.parseInt(portStartup);
2214 ConfigServer ts = config.getConfigServer();
2215 return ts == null ? Integer.parseInt(portStartup) :
2216 ts.getPort().intValue();
2219 public Bgp getConfig() {
2220 AtomicInteger bgpDSretryCount = new AtomicInteger(DS_RETRY_COUNT);
2221 while (0 != bgpDSretryCount.decrementAndGet()) {
2223 return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
2224 InstanceIdentifier.create(Bgp.class)).orNull();
2225 } catch (ReadFailedException e) {
2226 //Config DS may not be up, so sleep for 1 second and retry
2227 LOG.debug("failed to get bgp config, may be DS is yet in consistent state(?)", e);
2229 Thread.sleep(WAIT_TIME_BETWEEN_EACH_TRY_MILLIS);
2230 } catch (InterruptedException timerEx) {
2231 LOG.debug("WAIT_TIME_BETWEEN_EACH_TRY_MILLIS, Timer got interrupted while waiting for"
2232 + "config DS availability", timerEx);
2236 LOG.error("failed to get bgp config");
2240 @SuppressWarnings("checkstyle:IllegalCatch")
2241 public synchronized boolean replay() throws InterruptedException, TimeoutException, ExecutionException {
2242 boolean replaySucceded = true;
2243 boolean doRouteSync = false;
2244 String host = getConfigHost();
2245 int port = getConfigPort();
2246 LOG.error("connecting to bgp host {} ", host);
2247 boolean res = bgpRouter.connect(host, port);
2249 LOG.error("Cannot connect to BGP config server at {} {}", host, port);
2250 return replaySucceded;
2252 config = getConfig();
2253 if (config == null) {
2254 LOG.error("bgp config is empty nothing to push to bgp");
2255 return replaySucceded;
2257 BgpRouter br = bgpRouter;
2258 AsId asId = config.getAsId();
2260 LOG.error("bgp as-id is null");
2261 return replaySucceded;
2263 long asNum = asId.getLocalAs();
2264 IpAddress routerId = asId.getRouterId();
2265 String rid = routerId == null ? "" : routerId.stringValue();
2266 int stalepathTime = (int) getStalePathtime(RESTART_DEFAULT_GR, config.getAsId());
2267 boolean announceFbit = true;
2268 boolean replayDone = false;
2269 final int numberOfStartBgpRetries = 3;
2270 RetryOnException startBgpRetry = new RetryOnException(numberOfStartBgpRetries);
2273 LOG.debug("Replaying BGPConfig ");
2274 br.startBgp(asNum, rid, stalepathTime, announceFbit);
2275 LOG.debug("Replay BGPConfig successful");
2278 } catch (BgpRouterException bre) {
2279 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
2280 LOG.debug("Starting the routesync for exception", bre);
2281 startBgpRetry.errorOccured();
2282 if (!startBgpRetry.shouldRetry()) {
2287 LOG.error("Replay: startBgp() received exception error {} : ",
2288 bre.getErrorCode(), bre);
2289 startBgpRetry.errorOccured();
2291 } catch (TApplicationException tae) {
2292 if (tae.getType() == BgpRouterException.BGP_ERR_ACTIVE) {
2293 LOG.debug("Starting the routesync for exception", tae);
2294 startBgpRetry.errorOccured();
2295 if (!startBgpRetry.shouldRetry()) {
2299 } else if (tae.getType() == BgpRouterException.BGP_ERR_COMMON_FAILURE) {
2300 LOG.debug("Starting the routesync for AS-ID started exception", tae);
2301 startBgpRetry.errorOccured();
2302 if (!startBgpRetry.shouldRetry()) {
2307 LOG.error("Replay: startBgp() received exception type {}: ",
2308 tae.getType(), tae);
2309 startBgpRetry.errorOccured();
2311 } catch (Exception e) {
2312 //not unusual. We may have restarted & BGP is already on
2313 LOG.error("Replay:startBgp() received exception: ", e);
2314 startBgpRetry.errorOccured();
2316 } while (startBgpRetry.shouldRetry());
2318 replaySucceded = replayDone;
2320 startBgpCountersTask();
2321 startBgpAlarmsTask();
2324 * commenting this due to a bug with QBGP. Will uncomment once QBGP fix is done.
2325 * This wont have any functional impacts
2328 // br.delayEOR(delayEorSeconds);
2329 //} catch (TException | BgpRouterException e) {
2330 // LOG.error("Replay: delayEOR() number of seconds to wait for EOR from ODL:", e);
2333 BfdConfig bfdConfig = bgpUtil.getBfdConfig();
2334 if (bfdConfig != null) {
2335 if (bfdConfig.isBfdEnabled()) {
2336 LOG.debug("Replaying bfd config min-rx {} min-tx {} detect-mul {} mhop {}",
2337 bfdConfig.getMinRx(), bfdConfig.getMinTx(),
2338 bfdConfig.getDetectMult(), bfdConfig.isMultihop());
2340 br.addBfd(bfdConfig.getDetectMult().intValue(), bfdConfig.getMinRx().intValue(),
2341 bfdConfig.getMinTx().intValue(), bfdConfig.isMultihop());
2342 } catch (TException | BgpRouterException e) {
2343 LOG.error("Replay:addBfd() received exception", e);
2348 List<Neighbors> neighbors = config.getNeighbors();
2349 if (neighbors != null) {
2350 LOG.error("configuring existing Neighbors present for replay total neighbors {}", neighbors.size());
2351 boolean neighborConfigReplayResult = replayNbrConfig(neighbors, br);
2352 if (neighborConfigReplayResult == false) {
2353 replaySucceded = false;
2356 LOG.error("no Neighbors present for replay config ");
2359 Logging logging = config.getLogging();
2360 if (logging != null) {
2362 br.setLogging(logging.getFile(), logging.getLevel());
2363 } catch (TException | BgpRouterException e) {
2364 LOG.error("Replay:setLogging() received exception", e);
2368 GracefulRestart gracefulRestart = config.getGracefulRestart();
2369 if (gracefulRestart != null) {
2371 br.addGracefulRestart(gracefulRestart.getStalepathTime().intValue());
2372 } catch (TException | BgpRouterException e) {
2373 LOG.error("Replay:addGr() received exception", e);
2377 List<Vrfs> vrfs = config.getVrfs();
2379 vrfs = new ArrayList<>();
2381 for (Vrfs vrf : vrfs) {
2382 for (AddressFamiliesVrf adf : vrf.getAddressFamiliesVrf()) {
2384 br.addVrf(BgpUtil.getLayerType(adf), vrf.getRd(), vrf.getImportRts(),
2385 vrf.getExportRts());
2386 } catch (TException | BgpRouterException e) {
2387 LOG.error("Replay:addVrf() received exception", e);
2392 List<Networks> ln = config.getNetworks();
2394 for (Networks net : ln) {
2395 String rd = net.getRd();
2396 String pfxlen = net.getPrefixLen();
2397 String nh = net.getNexthop().getValue();
2398 Long label = net.getLabel();
2399 int lbl = label == null ? 0 : label.intValue();
2400 int l3vni = net.getL3vni() == null ? 0 : net.getL3vni().intValue();
2401 int l2vni = net.getL2vni() == null ? 0 : net.getL2vni().intValue();
2402 if (rd == null && lbl > 0) {
2403 //LU prefix is being deleted.
2404 rd = Integer.toString(lbl);
2407 BgpControlPlaneType protocolType = net.getBgpControlPlaneType();
2408 int ethernetTag = net.getEthtag().intValue();
2409 String esi = net.getEsi();
2410 String macaddress = net.getMacaddress();
2411 EncapType encapType = net.getEncapType();
2412 String routerMac = net.getRoutermac();
2415 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, l2vni,
2416 BgpUtil.convertToThriftProtocolType(protocolType),
2417 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
2418 } catch (TException | BgpRouterException e) {
2419 LOG.error("Replay:addPfx() received exception", e);
2425 List<Multipath> multipaths = config.getMultipath();
2427 if (multipaths != null) {
2428 for (Multipath multipath : multipaths) {
2429 if (multipath != null) {
2430 af_afi afi = af_afi.findByValue(multipath.getAfi().intValue());
2431 af_safi safi = af_safi.findByValue(multipath.getSafi().intValue());
2434 if (multipath.isMultipathEnabled()) {
2435 br.enableMultipath(afi, safi);
2437 br.disableMultipath(afi, safi);
2439 } catch (TException | BgpRouterException e) {
2440 LOG.info("Replay:multipaths() received exception", e);
2445 List<VrfMaxpath> vrfMaxpaths = config.getVrfMaxpath();
2446 if (vrfMaxpaths != null) {
2447 for (VrfMaxpath vrfMaxpath : vrfMaxpaths) {
2449 br.multipaths(vrfMaxpath.getRd(), vrfMaxpath.getMaxpaths());
2450 } catch (TException | BgpRouterException e) {
2451 LOG.info("Replay:vrfMaxPath() received exception", e);
2456 //send End of Rib Marker to Qthriftd.
2457 final int numberOfEORRetries = 3;
2458 RetryOnException eorRetry = new RetryOnException(numberOfEORRetries);
2462 LOG.debug("Replay sendEOR {} successful");
2464 } catch (Exception e) {
2465 eorRetry.errorOccured();
2466 LOG.error("Replay:sedEOR() received exception:", e);
2468 } while (eorRetry.shouldRetry());
2471 LOG.debug("starting route sync for Thrift BGP_ERR_COMMON_FAILURE exception "
2472 + "happened earlier");
2476 return replaySucceded;
2479 private <T extends DataObject> void update(InstanceIdentifier<T> iid, T dto) {
2480 bgpUtil.update(iid, dto);
2483 private <T extends DataObject> void delete(InstanceIdentifier<T> iid) {
2484 bgpUtil.delete(iid);
2487 public void startConfig(String bgpHost, int thriftPort) {
2488 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
2489 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
2490 InstanceIdentifier<ConfigServer> iid = iib.build();
2491 Ipv4Address ipAddr = new Ipv4Address(bgpHost);
2492 ConfigServer dto = new ConfigServerBuilder().setHost(ipAddr)
2493 .setPort((long) thriftPort).build();
2497 public void startBgp(long as, String routerId, int spt, boolean fbit) {
2498 IpAddress rid = routerId == null ? null : IpAddressBuilder.getDefaultInstance(routerId);
2499 Long staleTime = (long) spt;
2500 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
2501 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
2502 InstanceIdentifier<AsId> iid = iib.build();
2503 AsId dto = new AsIdBuilder().setLocalAs(as)
2505 .setStalepathTime(staleTime)
2506 .setAnnounceFbit(fbit).build();
2510 public void startBfd(long detectMult, long minRx, long minTx, boolean multiHop) {
2511 InstanceIdentifier.InstanceIdentifierBuilder<BfdConfig> iib =
2512 InstanceIdentifier.builder(BfdConfig.class);
2513 InstanceIdentifier<BfdConfig> iid = iib.build();
2514 BfdConfig dto = new BfdConfigBuilder()
2515 .setBfdEnabled(true)
2516 .setMultihop(multiHop)
2519 .setDetectMult(detectMult)
2524 public void addDcgwTep(String dcgwIp, String tepIp) {
2525 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2526 InstanceIdentifier.builder(Bgp.class)
2527 .child(DcgwTepList.class)
2528 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2529 InstanceIdentifier<DcgwTep> iid = iib.build();
2530 ArrayList<String> tepList = new ArrayList<String>();
2532 DcgwTep dto = new DcgwTepBuilder().setDcGwIp(dcgwIp).setTepIps(tepList)
2537 public void addLogging(String fileName, String logLevel) {
2538 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
2539 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
2540 InstanceIdentifier<Logging> iid = iib.build();
2541 Logging dto = new LoggingBuilder().setFile(fileName)
2542 .setLevel(logLevel).build();
2546 public void addGracefulRestart(int staleTime) {
2547 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
2548 InstanceIdentifier.builder(Bgp.class).child(GracefulRestart.class);
2549 InstanceIdentifier<GracefulRestart> iid = iib.build();
2550 GracefulRestart dto = new GracefulRestartBuilder()
2551 .setStalepathTime((long) staleTime).build();
2555 public void addNeighbor(
2556 String nbrIp, long remoteAs, @Nullable final TcpMd5SignaturePasswordType md5Secret) {
2557 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2558 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
2559 InstanceIdentifier.builder(Bgp.class)
2560 .child(Neighbors.class, new NeighborsKey(nbrAddr));
2561 InstanceIdentifier<Neighbors> iid = iib.build();
2562 TcpSecurityOption tcpSecOption = null;
2563 if (md5Secret != null) {
2564 tcpSecOption = new TcpMd5SignatureOptionBuilder().setTcpMd5SignaturePassword(md5Secret).build();
2565 } // else let tcpSecOption be null
2566 Neighbors dto = new NeighborsBuilder().setAddress(nbrAddr)
2567 .setRemoteAs(remoteAs).setTcpSecurityOption(tcpSecOption).build();
2569 } // public addNeighbor(nbrIp, remoteAs, md5Secret)
2571 public void addUpdateSource(String nbrIp, String srcIp) {
2572 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2573 Ipv4Address srcAddr = new Ipv4Address(srcIp);
2574 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
2575 InstanceIdentifier.builder(Bgp.class)
2576 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2577 .child(UpdateSource.class);
2578 InstanceIdentifier<UpdateSource> iid = iib.build();
2579 UpdateSource dto = new UpdateSourceBuilder().setPeerIp(nbrAddr)
2580 .setSourceIp(srcAddr).build();
2584 public void addEbgpMultihop(String nbrIp, int hops) {
2585 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2586 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
2587 InstanceIdentifier.builder(Bgp.class)
2588 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2589 .child(EbgpMultihop.class);
2590 InstanceIdentifier<EbgpMultihop> iid = iib.build();
2591 EbgpMultihop dto = new EbgpMultihopBuilder().setPeerIp(nbrAddr)
2592 .setNhops((long) hops).build();
2596 public void addAddressFamily(String nbrIp, int afi, int safi) {
2597 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2598 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
2599 InstanceIdentifier.builder(Bgp.class)
2600 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2601 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
2602 InstanceIdentifier<AddressFamilies> iid = iib.build();
2603 AddressFamilies dto = new AddressFamiliesBuilder().setPeerIp(nbrAddr)
2604 .setAfi((long) afi).setSafi((long) safi).build();
2608 public void addPrefix(String rd, String macAddress, String pfx, List<String> nhList,
2609 VrfEntry.EncapType encapType, long lbl, long l3vni, long l2vni, String gatewayMac) {
2610 for (String nh : nhList) {
2611 Ipv4Address nexthop = nh != null ? new Ipv4Address(nh) : null;
2613 InstanceIdentifier<Networks> iid = InstanceIdentifier.builder(Bgp.class)
2614 .child(Networks.class, new NetworksKey(pfx, rd)).build();
2615 NetworksBuilder networksBuilder = new NetworksBuilder().setRd(rd).setPrefixLen(pfx).setNexthop(nexthop)
2616 .setLabel(label).setEthtag(BgpConstants.DEFAULT_ETH_TAG);
2617 buildVpnEncapSpecificInfo(networksBuilder, encapType, label, l3vni, l2vni, macAddress, gatewayMac);
2618 update(iid, networksBuilder.build());
2622 private static void buildVpnEncapSpecificInfo(NetworksBuilder builder, VrfEntry.EncapType encapType, long label,
2623 long l3vni, long l2vni, String macAddress, String gatewayMac) {
2624 if (encapType.equals(VrfEntry.EncapType.Mplsgre)) {
2625 builder.setLabel(label).setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLL3VPN)
2626 .setEncapType(EncapType.GRE);
2628 builder.setL3vni(l3vni).setL2vni(l2vni).setMacaddress(macAddress).setRoutermac(gatewayMac)
2629 .setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLEVPN).setEncapType(EncapType.VXLAN);
2633 // TODO: add LayerType as arg - supports command
2634 public void addVrf(String rd, List<String> irts, List<String> erts, AddressFamily addressFamily) {
2635 Vrfs vrf = bgpUtil.getVrfFromRd(rd);
2636 List<AddressFamiliesVrf> adfList = new ArrayList<>(1);
2638 adfList = vrf.getAddressFamiliesVrf();
2640 AddressFamiliesVrfBuilder adfBuilder = new AddressFamiliesVrfBuilder();
2641 if (addressFamily.equals(AddressFamily.IPV4)) {
2642 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2643 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2644 } else if (addressFamily.equals(AddressFamily.IPV6)) {
2645 adfBuilder.setAfi((long) af_afi.AFI_IPV6.getValue());
2646 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2647 } else if (addressFamily.equals(AddressFamily.L2VPN)) {
2648 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2649 adfBuilder.setSafi((long) af_safi.SAFI_EVPN.getValue());
2651 AddressFamiliesVrf adf = adfBuilder.build();
2653 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib = InstanceIdentifier.builder(Bgp.class)
2654 .child(Vrfs.class, new VrfsKey(rd));
2655 InstanceIdentifier<Vrfs> iid = iib.build();
2656 Vrfs dto = new VrfsBuilder().setRd(rd).setImportRts(irts)
2657 .setExportRts(erts).setAddressFamiliesVrf(adfList).build();
2659 List<AddressFamiliesVrf> listAdFamilies = mapNewAdFamily.get(rd);
2660 if (listAdFamilies != null) {
2661 listAdFamilies.add(adf);
2663 mapNewAdFamily.put(rd, adfList);
2667 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
2668 } catch (TransactionCommitFailedException e) {
2669 LOG.error("Error adding VRF to datastore", e);
2670 throw new RuntimeException(e);
2673 // enable multipath by default in all VRFs
2674 setMultipaths(rd, BgpConstants.BGP_DEFAULT_MULTIPATH);
2677 public void stopConfig() {
2678 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
2679 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
2680 InstanceIdentifier<ConfigServer> iid = iib.build();
2684 public void stopBgp() {
2685 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
2686 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
2687 InstanceIdentifier<AsId> iid = iib.build();
2691 public void stopBfd() {
2692 InstanceIdentifier.InstanceIdentifierBuilder<BfdConfig> iib =
2693 InstanceIdentifier.builder(BfdConfig.class);
2694 InstanceIdentifier<BfdConfig> iid = iib.build();
2698 public void delDcgwTep(String dcgwIp, String tepIp) {
2699 if (tepIp == null) {
2700 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2701 InstanceIdentifier.builder(Bgp.class)
2702 .child(DcgwTepList.class)
2703 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2704 InstanceIdentifier<DcgwTep> iid = iib.build();
2707 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2708 InstanceIdentifier.builder(Bgp.class)
2709 .child(DcgwTepList.class)
2710 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2711 InstanceIdentifier<DcgwTep> iid = iib.build();
2712 List<String> tepIpList = bgpUtil.getDcgwTepConfig(dcgwIp);
2713 if (tepIpList == null) {
2714 LOG.error("No Tep IP configured for DCGW {} on deleting the dcgwtep", dcgwIp);
2717 List<String> newTepIpList = new ArrayList<String>();
2718 tepIpList.forEach(tep -> {
2719 if (!tep.equals(tepIp)) {
2720 newTepIpList.add(tep);
2723 DcgwTep dto = new DcgwTepBuilder().setDcGwIp(dcgwIp).setTepIps(newTepIpList)
2726 SingleTransactionDataBroker.syncWrite(dataBroker,
2727 LogicalDatastoreType.CONFIGURATION, iid, dto);
2728 } catch (TransactionCommitFailedException e) {
2729 LOG.error("delDcgwTep: Error deleting DCGW Tep", e);
2730 throw new RuntimeException(e);
2735 public void delLogging() {
2736 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
2737 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
2738 InstanceIdentifier<Logging> iid = iib.build();
2742 public void delGracefulRestart() {
2743 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
2744 InstanceIdentifier.builder(Bgp.class)
2745 .child(GracefulRestart.class);
2746 InstanceIdentifier<GracefulRestart> iid = iib.build();
2750 public void delNeighbor(String nbrIp) {
2751 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2752 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
2753 InstanceIdentifier.builder(Bgp.class)
2754 .child(Neighbors.class, new NeighborsKey(nbrAddr));
2755 InstanceIdentifier<Neighbors> iid = iib.build();
2759 public void delUpdateSource(String nbrIp) {
2760 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2761 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
2762 InstanceIdentifier.builder(Bgp.class)
2763 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2764 .child(UpdateSource.class);
2765 InstanceIdentifier<UpdateSource> iid = iib.build();
2769 public void delEbgpMultihop(String nbrIp) {
2770 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2771 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
2772 InstanceIdentifier.builder(Bgp.class)
2773 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2774 .child(EbgpMultihop.class);
2775 InstanceIdentifier<EbgpMultihop> iid = iib.build();
2779 public void delAddressFamily(String nbrIp, int afi, int safi) {
2780 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2781 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
2782 InstanceIdentifier.builder(Bgp.class)
2783 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2784 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
2785 InstanceIdentifier<AddressFamilies> iid = iib.build();
2789 public void delPrefix(String rd, String pfx) {
2790 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
2791 InstanceIdentifier.builder(Bgp.class)
2792 .child(Networks.class, new NetworksKey(pfx, rd));
2793 InstanceIdentifier<Networks> iid = iib.build();
2797 public boolean delVrf(String rd, AddressFamily addressFamily) {
2798 if (addressFamily == null) {
2799 LOG.error("delVrf: vrf {}, addressFamily invalid", rd);
2803 AddressFamiliesVrfBuilder adfBuilder = new AddressFamiliesVrfBuilder();
2804 if (addressFamily.equals(AddressFamily.IPV4)) {
2805 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2806 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2807 } else if (addressFamily.equals(AddressFamily.IPV6)) {
2808 adfBuilder.setAfi((long) af_afi.AFI_IPV6.getValue());
2809 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2810 } else if (addressFamily.equals(AddressFamily.L2VPN)) {
2811 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2812 adfBuilder.setSafi((long) af_safi.SAFI_EVPN.getValue());
2814 LOG.debug("delVrf: Received Delete VRF : rd:{}, address family: {} {}", rd,
2815 adfBuilder.getAfi(), adfBuilder.getSafi());
2817 Vrfs vrfOriginal = bgpUtil.getVrfFromRd(rd);
2818 if (vrfOriginal == null) {
2819 LOG.error("delVrf: no vrf with existing rd {}. step aborted", rd);
2823 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
2824 InstanceIdentifier.builder(Bgp.class)
2825 .child(Vrfs.class, new VrfsKey(rd));
2827 InstanceIdentifier<Vrfs> iid = iib.build();
2829 @SuppressWarnings("static-access")
2830 InstanceIdentifier<Bgp> iid6 = iid.builder(Bgp.class).build()
2831 .child(Multipath.class, new MultipathKey(adfBuilder.getAfi(), adfBuilder.getSafi())).create(Bgp.class);
2832 InstanceIdentifierBuilder<Vrfs> iib3 = iid6.child(Vrfs.class, new VrfsKey(rd)).builder();
2833 InstanceIdentifier<Vrfs> iidFinal = iib3.build();
2835 //** update or delete the vrfs with the rest of AddressFamilies already present in the last list
2836 AddressFamiliesVrf adfToDel = adfBuilder.build();
2837 List<AddressFamiliesVrf> adfListOriginal = vrfOriginal.getAddressFamiliesVrf() == null
2838 ? new ArrayList<>() : vrfOriginal.getAddressFamiliesVrf();
2839 List<AddressFamiliesVrf> adfListToRemoveFromOriginal = new ArrayList<>();
2840 adfListOriginal.forEach(adf -> {
2841 if (adf.equals(adfToDel)) {
2842 adfListToRemoveFromOriginal.add(adfToDel);
2846 for (AddressFamiliesVrf adfToRemove : adfListToRemoveFromOriginal) {
2847 adfListOriginal.remove(adfToRemove);
2849 SingleTransactionDataBroker.syncWrite(dataBroker,
2850 LogicalDatastoreType.CONFIGURATION, iid, vrfOriginal);
2851 } catch (TransactionCommitFailedException e) {
2852 LOG.error("delVrf: Error updating VRF to datastore", e);
2853 throw new RuntimeException(e);
2856 if (adfListOriginal.isEmpty()) {
2857 LOG.debug("delVrf: delete iid: {}", iidFinal);
2861 // not all is removed
2865 public void setMultipathStatus(af_afi afi, af_safi safi, boolean enable) {
2866 long lafi = afi.getValue();
2867 long lsafi = safi.getValue();
2869 InstanceIdentifier.InstanceIdentifierBuilder<Multipath> iib =
2872 .child(Multipath.class,
2873 new MultipathKey(Long.valueOf(afi.getValue()), Long.valueOf(safi.getValue())));
2875 Multipath dto = new MultipathBuilder().setAfi(lafi).setSafi(lsafi).setMultipathEnabled(enable).build();
2876 update(iib.build(), dto);
2879 public void setMultipaths(String rd, int maxpath) {
2880 InstanceIdentifier.InstanceIdentifierBuilder<VrfMaxpath> iib =
2883 .child(VrfMaxpath.class, new VrfMaxpathKey(rd));
2885 VrfMaxpath dto = new VrfMaxpathBuilder().setRd(rd).setMaxpaths(maxpath).build();
2886 update(iib.build(), dto);
2889 public void delMultipaths(String rd) {
2890 InstanceIdentifier.InstanceIdentifierBuilder<VrfMaxpath> iib =
2891 InstanceIdentifier.builder(Bgp.class)
2892 .child(VrfMaxpath.class, new VrfMaxpathKey(rd));
2893 InstanceIdentifier<VrfMaxpath> iid = iib.build();
2898 * Remove Stale Marked Routes after timer expiry.
2900 private class RouteCleanup implements Callable<Integer> {
2903 public Integer call() {
2906 if (staledFibEntriesMap.isEmpty()) {
2907 LOG.info("BGP: RouteCleanup timertask tirggered but STALED FIB MAP is EMPTY");
2909 for (String rd : staledFibEntriesMap.keySet()) {
2910 if (Thread.interrupted()) {
2913 Map<String, Long> map = staledFibEntriesMap.get(rd);
2915 for (String key : map.keySet()) {
2916 if (Thread.interrupted()) {
2919 String prefix = extractPrefix(key);
2920 String nextHop = extractNextHop(key);
2922 LOG.debug("BGP: RouteCleanup deletePrefix called for : rd:{}, prefix{}, nextHop:{}",
2923 rd, prefix, nextHop);
2924 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix, nextHop);
2930 staledFibEntriesMap.clear();
2932 LOG.error("cleared {} stale routes after bgp restart", totalCleared);
2938 * BGP restart scenario, ODL-BGP manager was/is running.
2939 * On re-sync notification, Get a copy of FIB database.
2941 public void createStaleFibMap() {
2942 totalStaledCount = 0;
2944 staledFibEntriesMap.clear();
2945 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
2947 Optional<FibEntries> fibEntries = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2948 LogicalDatastoreType.CONFIGURATION, id);
2949 if (fibEntries.isPresent()) {
2950 List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
2951 for (VrfTables vrfTable : staleVrfTables) {
2952 Map<String, Long> staleFibEntMap = new HashMap<>();
2953 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
2954 if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
2955 //Stale marking and cleanup is only meant for the routes learned through BGP.
2958 if (Thread.interrupted()) {
2962 //Create MAP from staleVrfTables.
2963 vrfEntry.getRoutePaths()
2965 routePath -> staleFibEntMap.put(
2966 appendNextHopToPrefix(vrfEntry.getDestPrefix(),
2967 routePath.getNexthopAddress()), routePath.getLabel()));
2969 staledFibEntriesMap.put(vrfTable.getRouteDistinguisher(), staleFibEntMap);
2972 LOG.error("createStaleFibMap:: FIBentries.class is not present");
2974 } catch (ReadFailedException e) {
2975 LOG.error("createStaleFibMap:: error ", e);
2977 LOG.error("created {} staled entries ", totalStaledCount);
2981 * BGP config remove scenario, Need to remove all the
2982 * external routes from FIB.
2984 public void deleteExternalFibRoutes() {
2985 totalExternalRoutes = 0;
2986 totalExternalMacRoutes = 0;
2988 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
2990 Optional<FibEntries> fibEntries = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2991 LogicalDatastoreType.CONFIGURATION, id);
2992 if (fibEntries.isPresent()) {
2993 if (fibEntries.get().getVrfTables() == null) {
2994 LOG.error("deleteExternalFibRoutes::getVrfTables is null");
2997 List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
2998 for (VrfTables vrfTable : staleVrfTables) {
2999 String rd = vrfTable.getRouteDistinguisher();
3000 if (vrfTable.getVrfEntry() != null) {
3001 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
3002 if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
3003 //route cleanup is only meant for the routes learned through BGP.
3006 totalExternalRoutes++;
3007 fibDSWriter.removeFibEntryFromDS(rd, vrfEntry.getDestPrefix());
3009 } else if (vrfTable.getMacVrfEntry() != null) {
3010 for (MacVrfEntry macEntry : vrfTable.getMacVrfEntry()) {
3011 if (RouteOrigin.value(macEntry.getOrigin()) != RouteOrigin.BGP) {
3012 //route cleanup is only meant for the routes learned through BGP.
3015 totalExternalMacRoutes++;
3016 fibDSWriter.removeMacEntryFromDS(rd, macEntry.getMac());
3021 LOG.error("deleteExternalFibRoutes:: FIBentries.class is not present");
3023 } catch (ReadFailedException e) {
3024 LOG.error("deleteExternalFibRoutes:: error ", e);
3026 LOG.debug("deleted {} fib entries {} mac entries", totalExternalRoutes, totalExternalMacRoutes);
3029 public boolean addToRt2TepMap(String rd, String tepIp, String mac, Long l2vni) {
3030 boolean isFirstMacUpdateFromTep = false;
3031 if (rt2TepMap.containsKey(rd)) {
3032 if (rt2TepMap.get(rd).containsKey(tepIp)) {
3033 LOG.debug("RT2 with mac {} l2vni {} from existing rd {} and tep-ip {}. No Elan DS write required",
3034 mac, l2vni, rd, tepIp);
3035 rt2TepMap.get(rd).get(tepIp).put(mac, l2vni);
3037 LOG.debug("RT2 with mac {} l2vni {} from existing rd {} and new tep-ip {}",
3038 mac, l2vni, rd, tepIp);
3039 isFirstMacUpdateFromTep = true;
3040 Map<String, Long> macList = new HashMap<>();
3041 macList.put(mac, l2vni);
3042 rt2TepMap.get(rd).put(tepIp, macList);
3045 LOG.debug("RT2 with mac {} l2vni {} from new rd {} and tep ip {}",
3046 mac, l2vni, rd, tepIp);
3047 isFirstMacUpdateFromTep = true;
3048 Map<String, Long> macList = new HashMap<>();
3049 macList.put(mac, l2vni);
3050 Map<String, Map<String, Long>> tepIpMacMap = new HashMap<>();
3051 tepIpMacMap.put(tepIp, macList);
3052 rt2TepMap.put(rd, tepIpMacMap);
3054 return isFirstMacUpdateFromTep;
3057 public boolean deleteFromRt2TepMap(String rd, String tepIp, String mac) {
3058 boolean isLastMacUpdateFromTep = false;
3059 LOG.debug("RT2 withdraw with rd {} mac {} tep-ip {} ", rd, mac, tepIp);
3060 if (rt2TepMap.containsKey(rd)) {
3061 if (rt2TepMap.get(rd).containsKey(tepIp)) {
3062 if (rt2TepMap.get(rd).get(tepIp).containsKey(mac)) {
3063 LOG.debug("RT2 Withdraw : Removing the mac {} from Map", mac);
3064 rt2TepMap.get(rd).get(tepIp).remove(mac);
3065 if (rt2TepMap.get(rd).get(tepIp).isEmpty()) {
3066 isLastMacUpdateFromTep = true;
3067 LOG.debug("RT2 Withdraw : Removing the tep-ip {} from Map", tepIp);
3068 rt2TepMap.get(rd).remove(tepIp);
3069 if (rt2TepMap.get(rd).isEmpty()) {
3070 LOG.debug("RT2 Withdraw : Removing the rd {} from Map", rd);
3071 rt2TepMap.remove(rd);
3077 return isLastMacUpdateFromTep;
3080 public Collection<String> getTepIPs(String rd) {
3081 final Map<String, Map<String, Long>> tepIpMap = rt2TepMap.get(rd);
3082 return tepIpMap != null ? tepIpMap.keySet() : Collections.emptyList();
3085 public boolean isBgpConnected() {
3086 return (bgpRouter == null) ? false : bgpRouter.isBgpConnected();
3089 public long getLastConnectedTS() {
3090 return (bgpRouter == null) ? 0 : bgpRouter.getLastConnectedTS();
3093 public long getConnectTS() {
3094 return (bgpRouter == null) ? 0 : bgpRouter.getConnectTS();
3097 public long getStartTS() {
3098 return (bgpRouter == null) ? 0 : bgpRouter.getStartTS();
3101 public TTransport getTransport() {
3102 return bgpRouter.getTransport();
3105 public int getTotalStaledCount() {
3106 return totalStaledCount;
3109 public int getTotalCleared() {
3110 return totalCleared;
3113 public BgpCounters getBgpCounters() {
3114 return bgpCountersReference.get();
3117 private void startBgpCountersTask() {
3118 if (getBgpCounters() == null && bgpCountersReference.compareAndSet(null,
3119 new BgpCounters(getBgpSdncMipIp(), metricProvider))) {
3120 bgpCountersTask = executor.scheduleAtFixedRate(bgpCountersReference.get(), 0, 120 * 1000,
3121 TimeUnit.MILLISECONDS);
3122 LOG.info("Bgp Counters task scheduled for every two minutes.");
3124 bgpManager.setQbgpLog(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
3128 private void stopBgpCountersTask() {
3129 final BgpCounters bgpCounters = bgpCountersReference.getAndSet(null);
3130 if (bgpCounters != null) {
3131 bgpCountersTask.cancel(true);
3132 bgpCounters.close();
3136 private void startBgpAlarmsTask() {
3137 if (getBgpAlarms() == null && bgpAlarmsReference.compareAndSet(null, new BgpAlarms(this))) {
3138 bgpAlarmsReference.get().init();
3139 bgpAlarmsTask = executor.scheduleAtFixedRate(bgpAlarmsReference.get(), 0, 60 * 1000, TimeUnit.MILLISECONDS);
3140 LOG.info("Bgp Alarms task scheduled for every minute.");
3142 LOG.trace("Bgp Alarms task already scheduled for every minute.");
3146 private void stopBgpAlarmsTask() {
3147 final BgpAlarms bgpAlarms = bgpAlarmsReference.getAndSet(null);
3148 if (bgpAlarms != null) {
3149 bgpAlarmsTask.cancel(true);
3154 public BgpAlarms getBgpAlarms() {
3155 return bgpAlarmsReference.get();
3158 public void getPeerStatus(String nbrIp, long nbrAsNum) throws
3159 BgpRouterException, TException {
3160 bgpRouter.getPeerStatus(nbrIp, nbrAsNum);
3163 private static String appendNextHopToPrefix(String prefix, String nextHop) {
3164 return prefix + ":" + nextHop;
3167 private static String extractPrefix(String prefixNextHop) {
3168 return prefixNextHop.split(":")[0];
3171 private static String extractNextHop(String prefixNextHop) {
3172 return prefixNextHop.split(":")[1];
3175 private static String extractMd5Secret(final Neighbors val) {
3176 String md5Secret = null;
3177 TcpSecurityOption tcpSecOpt = val.getTcpSecurityOption();
3178 if (tcpSecOpt != null) {
3179 if (tcpSecOpt instanceof TcpMd5SignatureOption) {
3180 md5Secret = ((TcpMd5SignatureOption) tcpSecOpt).getTcpMd5SignaturePassword().getValue();
3181 } else { // unknown TcpSecurityOption
3182 LOG.debug("neighbors Ignored unknown tcp-security-option of peer {}", val.getAddress().getValue());
3186 } // private method extractMd5Secret