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 static org.opendaylight.netvirt.bgpmanager.oam.BgpConstants.HISTORY_LIMIT;
11 import static org.opendaylight.netvirt.bgpmanager.oam.BgpConstants.HISTORY_THRESHOLD;
13 import com.google.common.base.Optional;
14 import com.google.common.base.Preconditions;
15 import com.google.common.net.InetAddresses;
16 import com.google.common.util.concurrent.ThreadFactoryBuilder;
17 import io.netty.util.concurrent.GlobalEventExecutor;
18 import java.lang.reflect.Constructor;
19 import java.lang.reflect.InvocationTargetException;
20 import java.net.InetAddress;
21 import java.net.InetSocketAddress;
22 import java.net.NetworkInterface;
23 import java.net.SocketException;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.Enumeration;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
32 import java.util.Objects;
33 import java.util.Timer;
34 import java.util.concurrent.Callable;
35 import java.util.concurrent.ConcurrentHashMap;
36 import java.util.concurrent.CountDownLatch;
37 import java.util.concurrent.ExecutionException;
38 import java.util.concurrent.Executors;
39 import java.util.concurrent.Future;
40 import java.util.concurrent.ScheduledExecutorService;
41 import java.util.concurrent.ScheduledFuture;
42 import java.util.concurrent.TimeUnit;
43 import java.util.concurrent.TimeoutException;
44 import java.util.concurrent.atomic.AtomicInteger;
45 import java.util.concurrent.atomic.AtomicReference;
46 import javax.annotation.Nullable;
47 import javax.annotation.PreDestroy;
48 import javax.inject.Inject;
49 import javax.inject.Singleton;
50 import org.apache.thrift.TApplicationException;
51 import org.apache.thrift.TException;
52 import org.apache.thrift.transport.TTransport;
53 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
54 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
55 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
56 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
57 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
58 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
59 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
60 import org.opendaylight.genius.mdsalutil.NwConstants;
61 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
62 import org.opendaylight.infrautils.metrics.MetricProvider;
63 import org.opendaylight.mdsal.eos.binding.api.Entity;
64 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
65 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipListenerRegistration;
66 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
67 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
68 import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
69 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
70 import org.opendaylight.netvirt.bgpmanager.commands.ClearBgpCli;
71 import org.opendaylight.netvirt.bgpmanager.oam.BgpAlarms;
72 import org.opendaylight.netvirt.bgpmanager.oam.BgpConstants;
73 import org.opendaylight.netvirt.bgpmanager.oam.BgpCounters;
74 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouter;
75 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouterException;
76 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpSyncHandle;
77 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Routes;
78 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Update;
79 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
80 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
81 import org.opendaylight.netvirt.bgpmanager.thrift.gen.protocol_type;
82 import org.opendaylight.netvirt.bgpmanager.thrift.gen.qbgpConstants;
83 import org.opendaylight.netvirt.bgpmanager.thrift.server.BgpThriftService;
84 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
85 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.IVpnLinkService;
86 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionHistory;
87 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
88 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfig;
89 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfigBuilder;
90 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.AddressFamily;
91 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
92 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.BgpControlPlaneType;
93 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.EncapType;
94 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.TcpMd5SignaturePasswordType;
95 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsId;
96 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsIdBuilder;
97 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServer;
98 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServerBuilder;
99 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.DcgwTepList;
100 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestart;
101 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestartBuilder;
102 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Logging;
103 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.LoggingBuilder;
104 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Multipath;
105 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.MultipathBuilder;
106 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.MultipathKey;
107 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Neighbors;
108 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsBuilder;
109 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsKey;
110 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Networks;
111 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksBuilder;
112 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksKey;
113 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpath;
114 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpathBuilder;
115 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpathKey;
116 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Vrfs;
117 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsBuilder;
118 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsKey;
119 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTep;
120 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepBuilder;
121 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepKey;
122 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamilies;
123 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesBuilder;
124 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesKey;
125 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihop;
126 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihopBuilder;
127 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSource;
128 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSourceBuilder;
129 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfs.AddressFamiliesVrf;
130 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfs.AddressFamiliesVrfBuilder;
131 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.TcpSecurityOption;
132 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.tcp.security.option.TcpMd5SignatureOption;
133 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.tcp.security.option.TcpMd5SignatureOptionBuilder;
134 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
135 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
136 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.macvrfentries.MacVrfEntry;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
142 import org.opendaylight.yangtools.yang.binding.DataObject;
143 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
144 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
145 import org.osgi.framework.BundleContext;
146 import org.osgi.util.tracker.ServiceTracker;
147 import org.slf4j.Logger;
148 import org.slf4j.LoggerFactory;
151 public class BgpConfigurationManager {
152 private static final Logger LOG = LoggerFactory.getLogger(BgpConfigurationManager.class);
154 // to have stale FIB map (RD, Prefix)
155 // number of seconds wait for route sync-up between ODL and BGP
156 private static final int BGP_RESTART_ROUTE_SYNC_SEC = 600;
157 private static final String UPDATE_PORT = "bgp.thrift.service.port";
158 private static final String CONFIG_HOST = "vpnservice.bgpspeaker.host.name";
159 private static final String CONFIG_PORT = "vpnservice.bgpspeaker.thrift.port";
160 private static final String DEF_UPORT = "6644";
161 private static final String DEF_CHOST = "255.255.255.255"; // Invalid Host IP
162 private static final String DEF_CPORT = "7644";
163 private static final String DEF_BGP_SDNC_MIP = "127.0.0.1";
164 //vpnservice.bgp.thrift.bgp.mip is the MIP present with ODL. Here we open 6644 port
165 private static final String BGP_SDNC_MIP = "vpnservice.bgp.thrift.bgp.mip";
166 private static final int RESTART_DEFAULT_GR = 90;
167 private static final int DS_RETRY_COUNT = 100; //100 retries, each after WAIT_TIME_BETWEEN_EACH_TRY_MILLIS seconds
168 private static final long WAIT_TIME_BETWEEN_EACH_TRY_MILLIS = 1000L; //one second sleep after every retry
169 private static final String BGP_ENTITY_TYPE_FOR_OWNERSHIP = "bgp";
170 private static final String BGP_EOR_DELAY = "vpnservice.bgp.eordelay";
171 private static final String DEF_BGP_EOR_DELAY = "1800";
172 private static final String BGP_ENTITY_NAME = "bgp";
173 private static final String ADD_WARN = "Config store updated; undo with Delete if needed.";
174 private static final String DEL_WARN = "Config store updated; undo with Add if needed.";
175 private static final String UPD_WARN = "Update operation not supported; Config store updated;"
176 + " restore with another Update if needed.";
177 private static long bgp_as_num = 0;
179 private static final Class<?>[] REACTORS = {
180 ConfigServerReactor.class, AsIdReactor.class,
181 GracefulRestartReactor.class, LoggingReactor.class,
182 NeighborsReactor.class, UpdateSourceReactor.class,
183 EbgpMultihopReactor.class, AddressFamiliesReactor.class,
184 NetworksReactor.class, VrfsReactor.class, BgpReactor.class,
185 MultipathReactor.class, VrfMaxpathReactor.class, BfdConfigReactor.class
188 private IBgpManager bgpManager;
189 private final DataBroker dataBroker;
190 private final FibDSWriter fibDSWriter;
191 private final IVpnLinkService vpnLinkService;
192 private final BundleContext bundleContext;
193 private final BgpUtil bgpUtil;
194 private volatile Bgp config;
195 private final BgpRouter bgpRouter;
196 private final BgpSyncHandle bgpSyncHandle = new BgpSyncHandle();
197 private volatile BgpThriftService bgpThriftService = null;
198 private final int delayEorSeconds;
200 private final CountDownLatch initer = new CountDownLatch(1);
202 private final String hostStartup;
203 private final String portStartup;
205 private final AtomicReference<BgpCounters> bgpCountersReference = new AtomicReference<>();
206 private ScheduledFuture<?> bgpCountersTask;
208 private final AtomicReference<BgpAlarms> bgpAlarmsReference = new AtomicReference<>();
209 private ScheduledFuture<?> bgpAlarmsTask;
211 private Future<?> lastReplayJobFt;
212 private ScheduledFuture<?> routeCleanupFuture;
214 private long staleStartTime;
215 private long staleEndTime;
216 private long cfgReplayStartTime;
217 private long cfgReplayEndTime;
218 private long staleCleanupTime;
219 private int totalStaledCount;
220 private int totalCleared;
221 private int totalExternalRoutes;
222 private int totalExternalMacRoutes;
224 private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(
225 new ThreadFactoryBuilder().setNameFormat("BgpConfigurationManager-%d").setDaemon(true).build());
228 * this map store the new address families to send to quagga. When it is sended you must clear it.
229 * The keys String are rd (route distinguisher).
231 private final ConcurrentHashMap<String, List<AddressFamiliesVrf>> mapNewAdFamily = new ConcurrentHashMap<>();
233 // map<rd, map<prefix/len:nexthop, label>>
234 private final Map<String, Map<String, Long>> staledFibEntriesMap = new ConcurrentHashMap<>();
236 // map<rd, map<tep-ip, map<mac, l2vni>>>
237 private final Map<String, Map<String, Map<String, Long>>> rt2TepMap = new ConcurrentHashMap<>();
239 private final List<AutoCloseable> listeners = new ArrayList<>();
241 private final EntityOwnershipUtils entityOwnershipUtils;
242 private final EntityOwnershipCandidateRegistration candidateRegistration;
243 private final EntityOwnershipListenerRegistration entityListenerRegistration;
244 private final MetricProvider metricProvider;
245 private final TransactionHistory bgpUpdatesHistory;
248 public BgpConfigurationManager(final DataBroker dataBroker,
249 final EntityOwnershipService entityOwnershipService,
250 final FibDSWriter fibDSWriter,
251 final IVpnLinkService vpnLinkSrvce,
252 final BundleContext bundleContext,
253 final BgpUtil bgpUtil,
254 final MetricProvider metricProvider) {
255 this.dataBroker = dataBroker;
256 this.fibDSWriter = fibDSWriter;
257 this.vpnLinkService = vpnLinkSrvce;
258 this.bundleContext = bundleContext;
259 this.bgpUtil = bgpUtil;
260 this.metricProvider = metricProvider;
261 hostStartup = getProperty(CONFIG_HOST, DEF_CHOST);
262 portStartup = getProperty(CONFIG_PORT, DEF_CPORT);
263 LOG.info("ConfigServer at {}:{}", hostStartup, portStartup);
264 VtyshCli.setHostAddr(hostStartup);
265 ClearBgpCli.setHostAddr(hostStartup);
266 bgpUpdatesHistory = new TransactionHistory(HISTORY_LIMIT, HISTORY_THRESHOLD);
267 bgpRouter = BgpRouter.newInstance(this::getConfig, this::isBGPEntityOwner, bgpUpdatesHistory);
268 delayEorSeconds = Integer.parseInt(getProperty(BGP_EOR_DELAY, DEF_BGP_EOR_DELAY));
270 entityOwnershipUtils = new EntityOwnershipUtils(entityOwnershipService);
272 candidateRegistration = registerEntityCandidate(entityOwnershipService);
273 entityListenerRegistration = registerEntityListener(entityOwnershipService);
275 /*register callbacks for reactors, shall be called after EoS registration.
276 * as listeners user EoS service to identify Owner node. Listener call-backs
277 * can get triggered immediately after registeration (before EoS register complete)
281 LOG.info("BGP Configuration manager initialized");
284 GlobalEventExecutor.INSTANCE.execute(() -> {
285 ServiceTracker<IBgpManager, ?> tracker = null;
287 tracker = new ServiceTracker<>(bundleContext, IBgpManager.class, null);
289 bgpManager = (IBgpManager) tracker.waitForService(TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES));
290 Preconditions.checkState(bgpManager != null, "IBgpManager service not found");
291 } catch (InterruptedException e) {
292 throw new IllegalStateException("Error retrieving IBgpManager service", e);
294 if (tracker != null) {
299 String updatePort = getProperty(UPDATE_PORT, DEF_UPORT);
300 if (InetAddresses.isInetAddress(getBgpSdncMipIp())) {
301 InetSocketAddress bgpThriftServerSocketAddr = new InetSocketAddress(getBgpSdncMipIp(),
302 Integer.parseInt(updatePort));
303 bgpThriftService = new BgpThriftService(bgpThriftServerSocketAddr, bgpManager, this);
304 if (isBGPEntityOwner()) {
305 //I am EoS owner of BGP, opening bgp thrift UPDATE-SERVER port.
306 LOG.info("BGP Configuration manager initialized: UPDATE-SERVER started");
307 bgpThriftService.start();
309 LOG.info("UPDATE server started :ip:port={}:{}", getBgpSdncMipIp(), updatePort);
311 LOG.error("Failed to init UPDATE server invalid ip:port={}:{}", getBgpSdncMipIp(), updatePort);
313 LOG.info("BgpConfigurationManager initialized. IBgpManager={}", bgpManager);
317 public String getBgpSdncMipIp() {
318 return getProperty(BGP_SDNC_MIP, DEF_BGP_SDNC_MIP);
321 public long getStaleCleanupTime() {
322 return staleCleanupTime;
325 public void setStaleCleanupTime(long staleCleanupTime) {
326 this.staleCleanupTime = staleCleanupTime;
329 public long getCfgReplayEndTime() {
330 return cfgReplayEndTime;
333 public void setCfgReplayEndTime(long cfgReplayEndTime) {
334 this.cfgReplayEndTime = cfgReplayEndTime;
337 public TransactionHistory getBgpUpdatesHistory() {
338 return bgpUpdatesHistory;
341 public long getCfgReplayStartTime() {
342 return cfgReplayStartTime;
345 public void setCfgReplayStartTime(long cfgReplayStartTime) {
346 this.cfgReplayStartTime = cfgReplayStartTime;
349 public long getStaleEndTime() {
353 public void setStaleEndTime(long staleEndTime) {
354 this.staleEndTime = staleEndTime;
357 public long getStaleStartTime() {
358 return staleStartTime;
361 public void setStaleStartTime(long staleStartTime) {
362 this.staleStartTime = staleStartTime;
365 private Object createListener(Class<?> cls) {
367 Constructor<?> ctor = cls.getConstructor(BgpConfigurationManager.class);
368 return ctor.newInstance(this);
369 } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException
371 LOG.error("Failed to create listener object", e);
376 private void registerCallbacks() {
377 for (Class<?> reactor : REACTORS) {
378 Object obj = createListener(reactor);
380 AsyncDataTreeChangeListenerBase dcl = (AsyncDataTreeChangeListenerBase) obj;
381 dcl.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
387 @SuppressWarnings("checkstyle:IllegalCatch")
389 public void close() {
392 if (bgpThriftService != null) {
393 bgpThriftService.stop();
394 bgpThriftService = null;
397 if (isBgpConnected()) {
398 //disconnect the CONFIG SERVER port (which was )opened during I was Owner
399 bgpRouter.disconnect();
402 if (candidateRegistration != null) {
403 candidateRegistration.close();
406 entityListenerRegistration.close();
408 listeners.forEach(l -> {
411 } catch (Exception e) {
412 LOG.warn("Error closing {}", l ,e);
416 LOG.info("{} close", getClass().getSimpleName());
419 private String getProperty(String var, String def) {
420 String property = bundleContext.getProperty(var);
421 return property == null ? def : property;
424 private EntityOwnershipCandidateRegistration registerEntityCandidate(
425 final EntityOwnershipService entityOwnershipService) {
427 return entityOwnershipService.registerCandidate(
428 new Entity(BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME));
429 } catch (CandidateAlreadyRegisteredException e) {
430 LOG.error("failed to register bgp entity", e);
435 private EntityOwnershipListenerRegistration registerEntityListener(
436 final EntityOwnershipService entityOwnershipService) {
437 return entityOwnershipService.registerListener(BGP_ENTITY_TYPE_FOR_OWNERSHIP, ownershipChange -> {
438 LOG.trace("entity owner change event fired: {}", ownershipChange);
440 if (ownershipChange.getState() == EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED) {
441 LOG.trace("This PL is the Owner");
442 if (bgpThriftService != null) {
443 //opening UPDATE-SERVER port.
444 bgpThriftService.start();
446 LOG.error("I am the owner of BGP entity, but bgpThriftService is not initialized yet");
450 LOG.debug("Not owner: hasOwner: {}, isOwner: {}", ownershipChange.getState().hasOwner(),
451 ownershipChange.getState().isOwner());
452 if (bgpThriftService != null && bgpThriftService.isBgpThriftServiceStarted()) {
453 //close the bgp Thrift Update-SERVER port opened on non-Entity Owner
454 bgpThriftService.stop();
455 bgpThriftService = null;
457 if (isBgpConnected()) {
458 //disconnect the CONFIG SERVER port (which was )opened during I was Owner
459 bgpRouter.disconnect();
465 public boolean isBGPEntityOwner() {
466 if (entityOwnershipUtils == null) {
467 LOG.error("entityOwnershipUtils is NULL when listener callbacks fired");
470 return entityOwnershipUtils.isEntityOwner(new Entity(BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME), 0, 1);
474 config = getConfig();
478 public class ConfigServerReactor
479 extends AsyncDataTreeChangeListenerBase<ConfigServer, ConfigServerReactor>
480 implements ClusteredDataTreeChangeListener<ConfigServer> {
481 private static final String YANG_OBJ = "config-server ";
483 public ConfigServerReactor() {
484 super(ConfigServer.class, ConfigServerReactor.class);
488 protected void add(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
489 LOG.trace("received bgp connect config host {}", val.getHost().getValue());
490 if (!isBGPEntityOwner()) {
496 } catch (InterruptedException e) {
499 LOG.debug("issueing bgp router connect to host {}", val.getHost().getValue());
500 bgpRouter.configServerUpdated();
501 synchronized (BgpConfigurationManager.this) {
502 boolean res = bgpRouter.connect(val.getHost().getValue(),
503 val.getPort().intValue());
505 LOG.error(YANG_OBJ + "Add failed; " + ADD_WARN);
508 VtyshCli.setHostAddr(val.getHost().getValue());
509 ClearBgpCli.setHostAddr(val.getHost().getValue());
513 protected ConfigServerReactor getDataTreeChangeListener() {
514 return ConfigServerReactor.this;
518 protected InstanceIdentifier<ConfigServer> getWildCardPath() {
519 return InstanceIdentifier.create(Bgp.class).child(ConfigServer.class);
523 protected void remove(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
524 LOG.trace("received bgp disconnect");
525 if (!isBGPEntityOwner()) {
529 bgpRouter.configServerUpdated();
531 synchronized (BgpConfigurationManager.this) {
532 if (bgp_as_num != 0) {
534 bgpRouter.stopBgp(bgp_as_num);
535 stopBgpCountersTask();
537 } catch (TException | BgpRouterException e) {
538 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
541 LOG.debug("bgp as-id is null while removing config-server");
543 bgpRouter.disconnect();
548 protected void update(InstanceIdentifier<ConfigServer> iid,
549 ConfigServer oldval, ConfigServer newval) {
550 LOG.trace("received bgp Connection update");
551 if (!isBGPEntityOwner()) {
554 LOG.error(YANG_OBJ + UPD_WARN);
558 private BgpRouter getClient(String yangObj) {
559 if (bgpRouter == null || !bgpRouter.isBgpConnected()) {
560 LOG.warn("{}: configuration received when BGP is inactive", yangObj);
566 public class AsIdReactor
567 extends AsyncDataTreeChangeListenerBase<AsId, AsIdReactor>
568 implements ClusteredDataTreeChangeListener<AsId> {
570 private static final String YANG_OBJ = "as-id ";
572 public AsIdReactor() {
573 super(AsId.class, AsIdReactor.class);
577 protected void add(InstanceIdentifier<AsId> iid, AsId val) {
578 LOG.error("received bgp add asid {}", val);
579 if (!isBGPEntityOwner()) {
582 LOG.debug("received add router config asNum {}", val.getLocalAs());
583 bgp_as_num = val.getLocalAs().longValue();
584 synchronized (BgpConfigurationManager.this) {
585 BgpRouter br = getClient(YANG_OBJ);
587 LOG.debug("{} Unable to process add for asNum {}; {} {}", YANG_OBJ, val.getLocalAs(),
588 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
593 startBgpCountersTask();
594 startBgpAlarmsTask();
599 protected AsIdReactor getDataTreeChangeListener() {
600 return AsIdReactor.this;
604 protected InstanceIdentifier<AsId> getWildCardPath() {
605 return InstanceIdentifier.create(Bgp.class).child(AsId.class);
609 protected void remove(InstanceIdentifier<AsId> iid, AsId val) {
610 LOG.error("received delete router config asNum {}", val.getLocalAs());
611 if (!isBGPEntityOwner()) {
614 synchronized (BgpConfigurationManager.this) {
615 long asNum = val.getLocalAs();
616 BgpRouter br = getClient(YANG_OBJ);
619 LOG.debug("{} Unable to process remove for asNum {}; {} {}", YANG_OBJ, asNum,
620 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
625 } catch (TException | BgpRouterException e) {
626 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
629 stopBgpCountersTask();
632 Bgp conf = getConfig();
634 LOG.error("Config Null while removing the as-id");
637 LOG.debug("Removing external routes from FIB");
638 deleteExternalFibRoutes();
639 List<Neighbors> nbrs = conf.getNeighbors();
640 if (nbrs != null && nbrs.size() > 0) {
641 LOG.error("Tring to remove the as-id when neighbor config is already present");
642 for (Neighbors nbr : nbrs) {
643 LOG.debug("Removing Neighbor {} from Data store", nbr.getAddress().getValue());
644 delNeighbor(nbr.getAddress().getValue());
651 protected void update(InstanceIdentifier<AsId> iid,
652 AsId oldval, AsId newval) {
653 if (!isBGPEntityOwner()) {
656 LOG.error(YANG_OBJ + UPD_WARN);
660 public class GracefulRestartReactor
661 extends AsyncDataTreeChangeListenerBase<GracefulRestart, GracefulRestartReactor>
662 implements ClusteredDataTreeChangeListener<GracefulRestart> {
664 private static final String YANG_OBJ = "graceful-restart ";
666 public GracefulRestartReactor() {
667 super(GracefulRestart.class, GracefulRestartReactor.class);
671 protected void add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
672 if (!isBGPEntityOwner()) {
675 synchronized (BgpConfigurationManager.this) {
676 int stalePathTime = val.getStalepathTime().intValue();
677 BgpRouter br = getClient(YANG_OBJ);
679 LOG.error("{} Unable to add stale-path time {}; {} {}", YANG_OBJ, stalePathTime,
680 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
684 br.addGracefulRestart(stalePathTime);
685 } catch (TException | BgpRouterException e) {
686 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
692 protected GracefulRestartReactor getDataTreeChangeListener() {
693 return GracefulRestartReactor.this;
697 protected InstanceIdentifier<GracefulRestart> getWildCardPath() {
698 return InstanceIdentifier.create(Bgp.class).child(GracefulRestart.class);
702 protected void remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
703 if (!isBGPEntityOwner()) {
706 LOG.debug("received delete GracefulRestart config val {}", val.getStalepathTime().intValue());
707 synchronized (BgpConfigurationManager.this) {
708 BgpRouter br = getClient(YANG_OBJ);
710 LOG.error("{} Unable to delete stale-path time; {} {}", YANG_OBJ,
711 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
715 br.delGracefulRestart();
716 } catch (TException | BgpRouterException e) {
717 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
723 protected void update(InstanceIdentifier<GracefulRestart> iid,
724 GracefulRestart oldval, GracefulRestart newval) {
725 if (!isBGPEntityOwner()) {
728 LOG.debug("received update GracefulRestart config val {}", newval.getStalepathTime().intValue());
729 synchronized (BgpConfigurationManager.this) {
730 int stalePathTime = newval.getStalepathTime().intValue();
731 BgpRouter br = getClient(YANG_OBJ);
733 LOG.error("{} Unable to update stale-path time to {}; {} {}", YANG_OBJ, stalePathTime,
734 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
738 br.addGracefulRestart(stalePathTime);
739 } catch (TException | BgpRouterException e) {
740 LOG.error("{} update received exception; {}", YANG_OBJ, ADD_WARN, e);
746 public class LoggingReactor
747 extends AsyncDataTreeChangeListenerBase<Logging, LoggingReactor>
748 implements ClusteredDataTreeChangeListener<Logging> {
750 private static final String YANG_OBJ = "logging ";
752 public LoggingReactor() {
753 super(Logging.class, LoggingReactor.class);
757 protected void add(InstanceIdentifier<Logging> iid, Logging val) {
758 if (!isBGPEntityOwner()) {
761 synchronized (BgpConfigurationManager.this) {
762 BgpRouter br = getClient(YANG_OBJ);
764 LOG.error("{} Unable to add logging for qbgp; {} {}", YANG_OBJ,
765 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
769 br.setLogging(val.getFile(), val.getLevel());
770 } catch (TException | BgpRouterException e) {
771 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
777 protected LoggingReactor getDataTreeChangeListener() {
778 return LoggingReactor.this;
782 protected InstanceIdentifier<Logging> getWildCardPath() {
783 return InstanceIdentifier.create(Bgp.class).child(Logging.class);
787 protected void remove(InstanceIdentifier<Logging> iid, Logging val) {
788 if (!isBGPEntityOwner()) {
791 LOG.debug("received remove Logging config val {}", val.getLevel());
792 synchronized (BgpConfigurationManager.this) {
793 BgpRouter br = getClient(YANG_OBJ);
795 LOG.error("{} Unable to remove logging for qbgp; {} {}", YANG_OBJ,
796 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
800 br.setLogging(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
801 } catch (TException | BgpRouterException e) {
802 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
808 protected void update(InstanceIdentifier<Logging> iid,
809 Logging oldval, Logging newval) {
810 if (!isBGPEntityOwner()) {
813 synchronized (BgpConfigurationManager.this) {
814 BgpRouter br = getClient(YANG_OBJ);
816 LOG.error("{} Unable to update logging for qbgp; {} {}", YANG_OBJ,
817 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
821 br.setLogging(newval.getFile(), newval.getLevel());
822 } catch (TException | BgpRouterException e) {
823 LOG.error("{} newval received exception; {}", YANG_OBJ, ADD_WARN, e);
829 public class NeighborsReactor
830 extends AsyncDataTreeChangeListenerBase<Neighbors, NeighborsReactor>
831 implements ClusteredDataTreeChangeListener<Neighbors> {
833 private static final String YANG_OBJ = "neighbors ";
835 public NeighborsReactor() {
836 super(Neighbors.class, NeighborsReactor.class);
840 protected void add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
841 if (!isBGPEntityOwner()) {
844 LOG.debug("received add Neighbors config val {}", val.getAddress().getValue());
845 synchronized (BgpConfigurationManager.this) {
846 String peerIp = val.getAddress().getValue();
847 long as = val.getRemoteAs();
848 final String md5Secret = extractMd5Secret(val);
849 BgpRouter br = getClient(YANG_OBJ);
851 LOG.debug("{} Unable to process add for peer {} as {}; {} {}", YANG_OBJ, peerIp, as,
852 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
856 //itmProvider.buildTunnelsToDCGW(new IpAddress(peerIp.toCharArray()));
857 br.addNeighbor(peerIp, as, md5Secret);
859 } catch (TException | BgpRouterException e) {
860 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
866 protected NeighborsReactor getDataTreeChangeListener() {
867 return NeighborsReactor.this;
871 protected InstanceIdentifier<Neighbors> getWildCardPath() {
872 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class);
876 protected void remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
877 if (!isBGPEntityOwner()) {
880 LOG.debug("received remove Neighbors config val {}", val.getAddress().getValue());
881 synchronized (BgpConfigurationManager.this) {
882 String peerIp = val.getAddress().getValue();
883 BgpRouter br = getClient(YANG_OBJ);
885 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
886 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
890 //itmProvider.deleteTunnelsToDCGW(new IpAddress(val.getAddress().getValue().toCharArray()));
891 br.delNeighbor(peerIp);
892 } catch (TException | BgpRouterException e) {
893 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
896 final BgpAlarms bgpAlarms = getBgpAlarms();
897 if (bgpAlarms != null) {
898 bgpAlarms.clearBgpNbrDownAlarm(peerIp);
901 if (bgpUtil.isBfdEnabled()) {
902 final BgpCounters bgpCounters = getBgpCounters();
903 if (bgpCounters != null) {
904 bgpCounters.clearBfdNbrCounters(peerIp);
911 protected void update(InstanceIdentifier<Neighbors> iid,
912 Neighbors oldval, Neighbors newval) {
913 if (!isBGPEntityOwner()) {
916 //purposefully nothing to do.
920 public class EbgpMultihopReactor
921 extends AsyncDataTreeChangeListenerBase<EbgpMultihop, EbgpMultihopReactor>
922 implements ClusteredDataTreeChangeListener<EbgpMultihop> {
924 private static final String YANG_OBJ = "ebgp-multihop ";
926 public EbgpMultihopReactor() {
927 super(EbgpMultihop.class, EbgpMultihopReactor.class);
931 protected void add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
932 if (!isBGPEntityOwner()) {
935 LOG.debug("received add EbgpMultihop config val {}", val.getPeerIp().getValue());
936 synchronized (BgpConfigurationManager.this) {
937 String peerIp = val.getPeerIp().getValue();
938 BgpRouter br = getClient(YANG_OBJ);
940 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
941 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
945 br.addEbgpMultihop(peerIp, val.getNhops().intValue());
946 } catch (TException | BgpRouterException e) {
947 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
953 protected EbgpMultihopReactor getDataTreeChangeListener() {
954 return EbgpMultihopReactor.this;
958 protected InstanceIdentifier<EbgpMultihop> getWildCardPath() {
959 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(EbgpMultihop.class);
963 protected void remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
964 if (!isBGPEntityOwner()) {
967 LOG.debug("received remove EbgpMultihop config val {}", val.getPeerIp().getValue());
968 synchronized (BgpConfigurationManager.this) {
969 String peerIp = val.getPeerIp().getValue();
970 BgpRouter br = getClient(YANG_OBJ);
972 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
973 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
977 br.delEbgpMultihop(peerIp);
978 } catch (TException | BgpRouterException e) {
979 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
985 protected void update(InstanceIdentifier<EbgpMultihop> iid,
986 EbgpMultihop oldval, EbgpMultihop newval) {
987 if (!isBGPEntityOwner()) {
990 LOG.error(YANG_OBJ + UPD_WARN);
994 public class UpdateSourceReactor
995 extends AsyncDataTreeChangeListenerBase<UpdateSource, UpdateSourceReactor>
996 implements ClusteredDataTreeChangeListener<UpdateSource> {
998 private static final String YANG_OBJ = "update-source ";
1000 public UpdateSourceReactor() {
1001 super(UpdateSource.class, UpdateSourceReactor.class);
1005 protected void add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
1006 if (!isBGPEntityOwner()) {
1009 LOG.debug("received add UpdateSource config val {}", val.getSourceIp().getValue());
1010 synchronized (BgpConfigurationManager.this) {
1011 String peerIp = val.getPeerIp().getValue();
1012 BgpRouter br = getClient(YANG_OBJ);
1014 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
1015 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1019 br.addUpdateSource(peerIp, val.getSourceIp().getValue());
1020 } catch (TException | BgpRouterException e) {
1021 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1027 protected UpdateSourceReactor getDataTreeChangeListener() {
1028 return UpdateSourceReactor.this;
1032 protected InstanceIdentifier<UpdateSource> getWildCardPath() {
1033 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(UpdateSource.class);
1037 protected void remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
1038 if (!isBGPEntityOwner()) {
1041 LOG.debug("received remove UpdateSource config val {}", val.getSourceIp().getValue());
1042 synchronized (BgpConfigurationManager.this) {
1043 String peerIp = val.getPeerIp().getValue();
1044 BgpRouter br = getClient(YANG_OBJ);
1046 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
1047 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1051 br.delUpdateSource(peerIp);
1052 } catch (TException | BgpRouterException e) {
1053 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1059 protected void update(InstanceIdentifier<UpdateSource> iid,
1060 UpdateSource oldval, UpdateSource newval) {
1061 if (!isBGPEntityOwner()) {
1064 LOG.error(YANG_OBJ + UPD_WARN);
1068 public class AddressFamiliesReactor
1069 extends AsyncDataTreeChangeListenerBase<AddressFamilies, AddressFamiliesReactor>
1070 implements ClusteredDataTreeChangeListener<AddressFamilies> {
1072 private static final String YANG_OBJ = "address-families ";
1074 public AddressFamiliesReactor() {
1075 super(AddressFamilies.class, AddressFamiliesReactor.class);
1079 protected void add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
1080 if (!isBGPEntityOwner()) {
1083 LOG.debug("received add AddressFamilies config val {}", val.getPeerIp().getValue());
1084 synchronized (BgpConfigurationManager.this) {
1085 String peerIp = val.getPeerIp().getValue();
1086 BgpRouter br = getClient(YANG_OBJ);
1088 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
1089 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1092 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
1093 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
1095 br.addAddressFamily(peerIp, afi, safi);
1096 } catch (TException | BgpRouterException e) {
1097 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1103 protected AddressFamiliesReactor getDataTreeChangeListener() {
1104 return AddressFamiliesReactor.this;
1108 protected InstanceIdentifier<AddressFamilies> getWildCardPath() {
1109 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(AddressFamilies.class);
1113 protected void remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
1114 if (!isBGPEntityOwner()) {
1117 LOG.debug("received remove AddressFamilies config val {}", val.getPeerIp().getValue());
1118 synchronized (BgpConfigurationManager.this) {
1119 String peerIp = val.getPeerIp().getValue();
1120 BgpRouter br = getClient(YANG_OBJ);
1122 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
1123 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1126 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
1127 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
1129 br.delAddressFamily(peerIp, afi, safi);
1130 } catch (TException | BgpRouterException e) {
1131 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1137 protected void update(InstanceIdentifier<AddressFamilies> iid,
1138 AddressFamilies oldval, AddressFamilies newval) {
1139 if (!isBGPEntityOwner()) {
1142 LOG.error(YANG_OBJ + UPD_WARN);
1146 public class NetworksReactor
1147 extends AsyncDataTreeChangeListenerBase<Networks, NetworksReactor>
1148 implements ClusteredDataTreeChangeListener<Networks> {
1150 private static final String YANG_OBJ = "networks ";
1152 public NetworksReactor() {
1153 super(Networks.class, NetworksReactor.class);
1157 public NetworksReactor getDataTreeChangeListener() {
1158 return NetworksReactor.this;
1162 protected void add(InstanceIdentifier<Networks> iid, Networks val) {
1163 if (!isBGPEntityOwner()) {
1166 LOG.debug("received add Networks config val {}", val.getPrefixLen());
1167 synchronized (BgpConfigurationManager.this) {
1168 String rd = val.getRd();
1169 String pfxlen = val.getPrefixLen();
1170 String nh = val.getNexthop().getValue();
1171 BgpRouter br = getClient(YANG_OBJ);
1173 LOG.debug("{} Unable to process add for rd {} prefix {} nexthop {}; {} {}", YANG_OBJ, rd, pfxlen,
1174 nh, BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1177 Long label = val.getLabel();
1178 int lbl = label == null ? qbgpConstants.LBL_NO_LABEL
1180 int l3vni = val.getL3vni() == null ? qbgpConstants.LBL_NO_LABEL
1181 : val.getL3vni().intValue();
1182 int l2vni = val.getL2vni() == null ? qbgpConstants.LBL_NO_LABEL
1183 : val.getL2vni().intValue();
1185 BgpControlPlaneType protocolType = val.getBgpControlPlaneType();
1186 int ethernetTag = val.getEthtag().intValue();
1187 String esi = val.getEsi();
1188 String macaddress = val.getMacaddress();
1189 EncapType encapType = val.getEncapType();
1190 String routerMac = val.getRoutermac();
1193 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, l2vni, BgpUtil.convertToThriftProtocolType(protocolType),
1194 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
1195 } catch (TException | BgpRouterException e) {
1196 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1202 protected InstanceIdentifier<Networks> getWildCardPath() {
1203 return InstanceIdentifier.create(Bgp.class).child(Networks.class);
1207 protected void remove(InstanceIdentifier<Networks> iid, Networks val) {
1208 if (!isBGPEntityOwner()) {
1211 LOG.debug("received remove Networks config val {}", val.getPrefixLen());
1212 synchronized (BgpConfigurationManager.this) {
1213 String rd = val.getRd();
1214 String pfxlen = val.getPrefixLen();
1215 BgpRouter br = getClient(YANG_OBJ);
1217 LOG.debug("{} Unable to process remove for rd {} prefix {}; {} {}", YANG_OBJ, rd, pfxlen,
1218 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1221 Long label = val.getLabel();
1222 int lbl = label == null ? 0 : label.intValue();
1223 if (rd == null && lbl > 0) {
1224 //LU prefix is being deleted.
1225 rd = Integer.toString(lbl);
1228 br.delPrefix(rd, pfxlen);
1229 } catch (TException | BgpRouterException e) {
1230 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1235 /**get the value AFI from a prefix as "x.x.x.x/x".
1237 * @param pfxlen the prefix to get an afi
1238 * @return the afi value as you are need
1240 public int testValueAFI(String pfxlen) {
1241 int afiNew = af_afi.AFI_IP.getValue();
1243 String ipOnly = pfxlen.substring(0, pfxlen.lastIndexOf("/"));
1244 java.net.Inet6Address.getByName(ipOnly);
1245 afiNew = af_afi.AFI_IPV6.getValue();
1246 } catch (java.net.UnknownHostException e) {
1247 //ce n'est pas de l'ipv6
1254 protected void update(final InstanceIdentifier<Networks> iid,
1255 final Networks oldval, final Networks newval) {
1256 if (!isBGPEntityOwner()) {
1259 if (oldval.equals(newval)) {
1260 //Update: OLD and New values are same, no need to trigger remove/add.
1261 LOG.debug("received Updated for the same OLD and New values. RD: {}, Prefix: {}, Label: {}, NH: {}",
1262 oldval.getRd(), oldval.getPrefixLen(), oldval.getLabel(), oldval.getNexthop());
1265 LOG.debug("update networks old val RD: {}, Prefix: {}, Label: {}, NH: {} "
1266 + "new val RD: {}, Prefix: {}, Label: {}, NH: {}",
1267 oldval.getRd(), oldval.getPrefixLen(), oldval.getLabel(), oldval.getNexthop(),
1268 newval.getRd(), newval.getPrefixLen(), newval.getLabel(), newval.getNexthop());
1269 remove(iid, oldval);
1274 static Timer timer = new Timer();
1276 public class VrfsReactor
1277 extends AsyncDataTreeChangeListenerBase<Vrfs, VrfsReactor>
1278 implements ClusteredDataTreeChangeListener<Vrfs> {
1280 private static final String YANG_OBJ = "vrfs ";
1282 public VrfsReactor() {
1283 super(Vrfs.class, VrfsReactor.class);
1287 protected void add(InstanceIdentifier<Vrfs> iid, Vrfs vrfs) {
1288 if (!isBGPEntityOwner()) {
1291 LOG.debug("received add Vrfs config value {}", vrfs.getRd());
1292 synchronized (BgpConfigurationManager.this) {
1293 String rd = vrfs.getRd();
1294 BgpRouter br = getClient(YANG_OBJ);
1296 LOG.debug("{} Unable to process add for rd {}; {} {}", YANG_OBJ, rd,
1297 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1301 List<AddressFamiliesVrf> vrfAddrFamilyList = vrfs.getAddressFamiliesVrf();
1302 for (AddressFamiliesVrf vrfAddrFamily : vrfAddrFamilyList) {
1303 /*add to br the new vrfs arguments*/
1304 br.addVrf(BgpUtil.getLayerType(vrfAddrFamily), rd, vrfs.getImportRts(), vrfs.getExportRts()
1307 /*add to br the vrfs contained in mapNewAdFamily*/
1308 List<AddressFamiliesVrf> vrfAddrFamilyListFromMap = mapNewAdFamily.get(rd);
1309 if (vrfAddrFamilyListFromMap == null) {
1313 for (AddressFamiliesVrf adf : vrfAddrFamilyListFromMap) {
1314 if (vrfAddrFamilyList.contains(adf)) {
1315 mapNewAdFamily.remove(rd);
1316 } else if (adf != null) {
1318 br.addVrf(BgpUtil.getLayerType(adf), rd, vrfs.getImportRts(), vrfs.getExportRts()
1320 // remove AddressFamiliesVrf which was already added to BGP
1321 vrfAddrFamilyListFromMap.remove(adf);
1322 if (vrfAddrFamilyListFromMap.isEmpty()) {
1323 // remove Vrf entry from temp mapNewAdFamily if all its AddressFamiliesVrf was
1325 mapNewAdFamily.remove(rd);
1329 } catch (TException | BgpRouterException e) {
1330 LOG.error("{} get {}, Add received exception", YANG_OBJ, ADD_WARN, e);
1336 protected VrfsReactor getDataTreeChangeListener() {
1337 return VrfsReactor.this;
1341 protected InstanceIdentifier<Vrfs> getWildCardPath() {
1342 return InstanceIdentifier.create(Bgp.class).child(Vrfs.class);
1346 protected void remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
1347 if (!isBGPEntityOwner()) {
1350 LOG.debug("received remove Vrfs config val {}", val.getRd());
1351 synchronized (BgpConfigurationManager.this) {
1352 String rd = val.getRd();
1353 BgpRouter br = getClient(YANG_OBJ);
1355 LOG.debug("{} Unable to process remove for rd {}; {} {}", YANG_OBJ, rd,
1356 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1360 List<AddressFamiliesVrf> adf = mapNewAdFamily.get(rd);
1361 adf = adf != null ? adf : new ArrayList<>();
1362 for (AddressFamiliesVrf s : val.getAddressFamiliesVrf()) {
1363 br.delVrf(rd, s.getAfi(), s.getSafi());
1364 adf.remove(s);// remove in the map the vrf in waiting for advertise quagga
1366 if (adf.isEmpty()) {
1367 mapNewAdFamily.remove(rd);
1369 } catch (TException | BgpRouterException e) {
1370 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1376 protected void update(InstanceIdentifier<Vrfs> iid,
1377 Vrfs oldval, Vrfs newval) {
1378 if (oldval != null && newval != null) {
1379 LOG.debug("received update Vrfs config val {}, VRFS: Update getting triggered for VRFS rd {}",
1380 newval.getRd(), oldval.getRd());
1382 LOG.debug("received update Vrfs config val {}, from old vrf {}",
1385 if (!isBGPEntityOwner()) {
1389 List<AddressFamiliesVrf> adFamilyVrfToDel = new ArrayList<>();
1390 List<AddressFamiliesVrf> adFamilyVrfToAdd = new ArrayList<>();
1391 List<AddressFamiliesVrf> oldlistAdFamilies = new ArrayList<>();
1392 List<AddressFamiliesVrf> newlistAdFamilies = new ArrayList<>();
1393 if (oldval != null) {
1394 oldlistAdFamilies = oldval.getAddressFamiliesVrf() == null
1395 ? new ArrayList<>() : oldval.getAddressFamiliesVrf();
1397 if (newval != null) {
1398 newlistAdFamilies = newval.getAddressFamiliesVrf() == null
1399 ? new ArrayList<>() : newval.getAddressFamiliesVrf();
1401 /*find old AddressFamily to remove from new configuration*/
1402 for (AddressFamiliesVrf adVrf : oldlistAdFamilies) {
1403 if (!newlistAdFamilies.contains(adVrf)) {
1404 adFamilyVrfToDel.add(adVrf);
1407 /*find new AddressFamily to add to unexisting configuration*/
1408 for (AddressFamiliesVrf adVrf : newlistAdFamilies) {
1409 if (!oldlistAdFamilies.contains(adVrf)) {
1410 adFamilyVrfToAdd.add(adVrf);
1413 String rd = newval != null ? newval.getRd() : null;
1415 BgpRouter br = getClient(YANG_OBJ);
1417 LOG.debug("{} Unable to process add for rd {}; {} {}", YANG_OBJ, rd,
1418 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1422 for (AddressFamiliesVrf adfvrf : adFamilyVrfToAdd) {
1424 LOG.debug("call addVRf rd {} afi {} safi {}", rd, adfvrf.getAfi(), adfvrf.getSafi());
1425 br.addVrf(BgpUtil.getLayerType(adfvrf), rd, newval.getImportRts(),
1426 newval.getExportRts());
1427 } catch (TException | BgpRouterException e) {
1428 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1432 for (AddressFamiliesVrf adfToDel : adFamilyVrfToDel) {
1434 LOG.debug("call delVRf rd {} afi {} safi {}", rd, adfToDel.getAfi(), adfToDel.getSafi());
1435 br.delVrf(rd, adfToDel.getAfi(), adfToDel.getSafi());
1436 } catch (TException | BgpRouterException e) {
1437 LOG.error("{} delVrf received exception; {}", YANG_OBJ, ADD_WARN, e);
1444 public class BgpReactor
1445 extends AsyncDataTreeChangeListenerBase<Bgp, BgpReactor>
1446 implements ClusteredDataTreeChangeListener<Bgp> {
1448 private static final String YANG_OBJ = "Bgp ";
1450 public BgpReactor() {
1451 super(Bgp.class, BgpReactor.class);
1456 protected void add(InstanceIdentifier<Bgp> iid, Bgp val) {
1457 LOG.debug("received add Bgp config");
1461 } catch (InterruptedException e) {
1464 synchronized (BgpConfigurationManager.this) {
1466 if (!isBGPEntityOwner()) {
1473 protected BgpReactor getDataTreeChangeListener() {
1474 return BgpReactor.this;
1478 protected InstanceIdentifier<Bgp> getWildCardPath() {
1479 return InstanceIdentifier.create(Bgp.class);
1483 protected void remove(InstanceIdentifier<Bgp> iid, Bgp val) {
1484 if (!isBGPEntityOwner()) {
1487 LOG.debug("received remove Bgp config");
1493 protected void update(InstanceIdentifier<Bgp> iid,
1494 Bgp oldval, Bgp newval) {
1495 if (!isBGPEntityOwner()) {
1503 @SuppressWarnings("deprecation")
1504 public class MultipathReactor
1505 extends AsyncDataTreeChangeListenerBase<Multipath, MultipathReactor>
1506 implements ClusteredDataTreeChangeListener<Multipath> {
1508 private static final String YANG_OBJ = "multipath ";
1510 public MultipathReactor() {
1511 super(Multipath.class, MultipathReactor.class);
1516 protected MultipathReactor getDataTreeChangeListener() {
1517 return MultipathReactor.this;
1521 protected InstanceIdentifier<Multipath> getWildCardPath() {
1522 return InstanceIdentifier.create(Bgp.class).child(Multipath.class);
1526 protected void remove(InstanceIdentifier<Multipath> iid, Multipath val) {
1527 executor.execute(new MultipathStatusChange(val));
1531 protected void update(InstanceIdentifier<Multipath> iid, Multipath oldval, Multipath newval) {
1532 executor.execute(new MultipathStatusChange(newval));
1536 protected void add(InstanceIdentifier<Multipath> key, Multipath dataObjectModification) {
1537 executor.execute(new MultipathStatusChange(dataObjectModification));
1540 class MultipathStatusChange implements Runnable {
1542 Multipath multipath;
1544 MultipathStatusChange(Multipath multipath) {
1545 this.multipath = multipath;
1550 if (isBGPEntityOwner()) {
1551 synchronized (BgpConfigurationManager.this) {
1553 BgpRouter br = getClient(YANG_OBJ);
1556 af_afi afi = af_afi.findByValue(multipath.getAfi().intValue());
1557 af_safi safi = af_safi.findByValue(multipath.getSafi().intValue());
1560 if (multipath.isMultipathEnabled()) {
1561 br.enableMultipath(afi, safi);
1563 br.disableMultipath(afi, safi);
1565 } catch (TException | BgpRouterException e) {
1566 LOG.error("{} received exception", YANG_OBJ, e);
1576 public void close() {
1581 @SuppressWarnings("deprecation")
1582 public class VrfMaxpathReactor
1583 extends AsyncDataTreeChangeListenerBase<VrfMaxpath, VrfMaxpathReactor>
1584 implements ClusteredDataTreeChangeListener<VrfMaxpath> {
1586 private static final String YANG_OBJ = "vrfMaxpath ";
1588 public VrfMaxpathReactor() {
1589 super(VrfMaxpath.class, VrfMaxpathReactor.class);
1594 protected VrfMaxpathReactor getDataTreeChangeListener() {
1595 return VrfMaxpathReactor.this;
1599 protected InstanceIdentifier<VrfMaxpath> getWildCardPath() {
1600 return InstanceIdentifier.create(Bgp.class).child(VrfMaxpath.class);
1603 class VrfMaxPathConfigurator implements Runnable {
1605 VrfMaxpath vrfMaxpathVal;
1607 VrfMaxPathConfigurator(VrfMaxpath vrfMaxPathVal) {
1608 this.vrfMaxpathVal = vrfMaxPathVal;
1613 if (isBGPEntityOwner()) {
1614 synchronized (BgpConfigurationManager.this) {
1615 BgpRouter br = getClient(YANG_OBJ);
1618 br.multipaths(vrfMaxpathVal.getRd(), vrfMaxpathVal.getMaxpaths());
1619 LOG.debug("Maxpath for vrf {} is {}", vrfMaxpathVal.getRd(),
1620 vrfMaxpathVal.getMaxpaths());
1621 } catch (TException | BgpRouterException e) {
1622 LOG.error("{} received exception", YANG_OBJ, e);
1631 protected void remove(InstanceIdentifier<VrfMaxpath> iid, VrfMaxpath vrfMaxPathVal) {
1632 if (isBGPEntityOwner()) {
1633 synchronized (BgpConfigurationManager.this) {
1634 BgpRouter br = getClient(YANG_OBJ);
1637 br.multipaths(vrfMaxPathVal.getRd(), BgpConstants.BGP_DEFAULT_MULTIPATH);
1638 LOG.debug("Del Maxpath for vrf: {} ", vrfMaxPathVal.getRd());
1639 } catch (TException | BgpRouterException e) {
1640 LOG.error(YANG_OBJ + " del received exception:", e);
1648 protected void update(InstanceIdentifier<VrfMaxpath> iid,
1649 VrfMaxpath oldval, VrfMaxpath newval) {
1650 if (!Objects.equals(oldval.getMaxpaths(), newval.getMaxpaths())) {
1651 executor.execute(new VrfMaxPathConfigurator(newval));
1656 protected void add(InstanceIdentifier<VrfMaxpath> instanceIdentifier, VrfMaxpath vrfMaxpathVal) {
1657 executor.execute(new VrfMaxPathConfigurator(vrfMaxpathVal));
1661 public void close() {
1666 public class BfdConfigReactor
1667 extends AsyncDataTreeChangeListenerBase<BfdConfig, BfdConfigReactor>
1668 implements ClusteredDataTreeChangeListener<BfdConfig> {
1670 private static final String YANG_OBJ = "BfdConfig ";
1672 public BfdConfigReactor() {
1673 super(BfdConfig.class, BfdConfigReactor.class);
1677 protected void add(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
1678 if (!isBGPEntityOwner()) {
1681 BgpRouter br = getClient(YANG_OBJ);
1682 LOG.debug("received bfd config: bfd enabled {} min-rx {} min-tx {} detect-mul {} mhop {}",
1683 val.isBfdEnabled(), val.getMinRx(), val.getMinTx(),
1684 val.getDetectMult(), val.isMultihop());
1686 LOG.debug(YANG_OBJ + "{} Unable to process add {}",
1687 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1690 if (val.isBfdEnabled() == false) {
1691 LOG.debug("BFD not enabled. Ignoring the config add");
1694 int minRx = val.getMinRx().intValue();
1695 int minTx = val.getMinTx().intValue();
1696 int detectMult = val.getDetectMult().intValue();
1697 boolean multiHop = val.isMultihop();
1699 br.addBfd(detectMult, minRx, minTx,multiHop);
1700 } catch (TException | BgpRouterException e) {
1701 LOG.error("{} get {}, Add received exception;", YANG_OBJ, ADD_WARN, e);
1706 protected BfdConfigReactor getDataTreeChangeListener() {
1707 return BfdConfigReactor.this;
1711 protected InstanceIdentifier<BfdConfig> getWildCardPath() {
1712 return InstanceIdentifier.create(BfdConfig.class);
1716 protected void remove(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
1717 if (!isBGPEntityOwner()) {
1720 LOG.debug("received bfd config removal");
1721 BgpRouter br = getClient(YANG_OBJ);
1723 LOG.debug("{} Unable to process del {} {}", YANG_OBJ,
1724 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1729 } catch (TException | BgpRouterException e) {
1730 LOG.error("{} get {}, Del received exception;", YANG_OBJ, ADD_WARN, e);
1736 protected void update(InstanceIdentifier<BfdConfig> iid,
1737 BfdConfig oldval, BfdConfig newval) {
1738 LOG.debug("received bfd config: updated oldval bfd enabled {}"
1739 + "min-rx {} min-tx {} detect-mul {} mhop {}",
1740 oldval.isBfdEnabled(), oldval.getMinRx(), oldval.getMinTx(),
1741 oldval.getDetectMult(), oldval.isMultihop());
1742 LOG.debug("received bfd config: updated newval bfd enabled {}"
1743 + "min-rx {} min-tx {} detect-mul {} mhop {}",
1744 newval.isBfdEnabled(), newval.getMinRx(), newval.getMinTx(),
1745 newval.getDetectMult(), newval.isMultihop());
1746 if (oldval.isBfdEnabled()) {
1747 LOG.debug("deleting bfd config on an update");
1748 remove(iid, oldval);
1750 LOG.debug("adding bfd config on an update");
1756 public boolean isIpAvailable(String odlip) {
1759 if (odlip != null) {
1760 if ("127.0.0.1".equals(odlip)) {
1763 Enumeration<NetworkInterface> networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces();
1764 while (networkInterfaceEnumeration.hasMoreElements()) {
1765 NetworkInterface networkInterface = networkInterfaceEnumeration.nextElement();
1766 Enumeration<InetAddress> inetAddressEnumeration = networkInterface.getInetAddresses();
1767 while (inetAddressEnumeration.hasMoreElements()) {
1768 InetAddress inetAddress = inetAddressEnumeration.nextElement();
1769 if (odlip.equals(inetAddress.getHostAddress())) {
1775 } catch (SocketException e) {
1781 public long getStalePathtime(int defValue, AsId asId) {
1784 spt = getConfig().getGracefulRestart().getStalepathTime();
1785 } catch (NullPointerException e) {
1787 spt = asId.getStalepathTime();
1788 LOG.trace("BGP config/Stale-path time is not set using graceful");
1789 } catch (NullPointerException ignore) {
1790 LOG.trace("BGP AS id is not set using graceful");
1795 LOG.trace("BGP config/Stale-path time is not set using graceful/start-bgp");
1801 public static boolean isValidConfigBgpHostPort(String bgpHost, int bgpPort) {
1802 if (!bgpHost.equals(DEF_CHOST)) {
1809 public synchronized void bgpRestarted() {
1811 * If there a thread which in the process of stale cleanup, cancel it
1812 * and start a new thread (to avoid processing same again).
1814 if (previousReplayJobInProgress()) {
1815 cancelPreviousReplayJob();
1817 Runnable task = () -> {
1819 LOG.info("running bgp replay task ");
1820 if (get() == null) {
1821 String host = getConfigHost();
1822 int port = getConfigPort();
1823 LOG.info("connecting to bgp host {} ", host);
1824 bgpRouter.connect(host, port);
1825 LOG.info("no config to push in bgp replay task ");
1828 setStaleStartTime(System.currentTimeMillis());
1829 LOG.info("started creating stale fibDSWriter map ");
1830 createStaleFibMap();
1831 setStaleEndTime(System.currentTimeMillis());
1832 LOG.info("took {} msecs for stale fibDSWriter map creation ", getStaleEndTime() - getStaleStartTime());
1833 LOG.info("started bgp config replay ");
1834 setCfgReplayStartTime(System.currentTimeMillis());
1835 boolean replaySucceded = replay();
1836 setCfgReplayEndTime(System.currentTimeMillis());
1837 LOG.info("took {} msecs for bgp replay ", getCfgReplayEndTime() - getCfgReplayStartTime());
1838 if (replaySucceded) {
1839 LOG.info("starting the stale cleanup timer");
1840 long routeSyncTime = getStalePathtime(BGP_RESTART_ROUTE_SYNC_SEC, config.getAsId());
1841 setStaleCleanupTime(routeSyncTime);
1842 routeCleanupFuture = executor.schedule(new RouteCleanup(), routeSyncTime, TimeUnit.SECONDS);
1844 staledFibEntriesMap.clear();
1846 } catch (InterruptedException | TimeoutException | ExecutionException eCancel) {
1847 LOG.error("Stale Cleanup Task Cancelled", eCancel);
1850 lastReplayJobFt = executor.submit(task);
1853 private boolean previousReplayJobInProgress() {
1854 return lastReplayJobFt != null && !lastReplayJobFt.isDone();
1857 private void cancelPreviousReplayJob() {
1859 LOG.error("cancelling already running bgp replay task");
1860 if (lastReplayJobFt != null) {
1861 lastReplayJobFt.cancel(true);
1862 lastReplayJobFt = null;
1863 staledFibEntriesMap.clear();
1865 if (routeCleanupFuture != null) {
1866 routeCleanupFuture.cancel(true);
1867 routeCleanupFuture = null;
1868 staledFibEntriesMap.clear();
1871 } catch (InterruptedException e) {
1872 LOG.error("Failed to cancel previous replay job ", e);
1876 private void doRouteSync() {
1877 LOG.error("Starting BGP route sync");
1879 bgpRouter.initRibSync(bgpSyncHandle);
1880 } catch (BgpRouterException e) {
1881 LOG.error("Route sync aborted, exception when initializing", e);
1884 while (bgpSyncHandle.getState() != BgpSyncHandle.DONE) {
1885 for (af_afi afi : af_afi.values()) {
1886 Routes routes = null;
1888 routes = bgpRouter.doRibSync(bgpSyncHandle, afi);
1889 } catch (TException | BgpRouterException e) {
1890 LOG.error("Route sync aborted, exception when syncing", e);
1893 Iterator<Update> updates = routes.getUpdatesIterator();
1894 while (updates.hasNext()) {
1895 Update update = updates.next();
1896 String rd = update.getRd();
1897 String nexthop = update.getNexthop();
1899 // TODO: decide correct label here
1900 int label = update.getL3label();
1901 int l2label = update.getL2label();
1903 String prefix = update.getPrefix();
1904 int plen = update.getPrefixlen();
1907 // TODO: protocol type will not be available in "update"
1908 // use "rd" to query vrf table and obtain the protocol_type.
1909 // Currently using PROTOCOL_EVPN as default.
1911 protocol_type.PROTOCOL_EVPN,
1916 update.getMacaddress(),
1919 update.getRoutermac(),
1925 LOG.error("Ending BGP route-sync");
1926 bgpRouter.endRibSync(bgpSyncHandle);
1927 } catch (BgpRouterException e) {
1932 public void addTepToElanDS(String rd, String tepIp, String mac, Long l2vni) {
1933 boolean needUpdate = addToRt2TepMap(rd, tepIp, mac, l2vni);
1935 LOG.info("Adding tepIp {} with RD {} to ELan DS", tepIp, rd);
1936 bgpUtil.addTepToElanInstance(rd, tepIp);
1938 LOG.debug("Skipping the Elan update for RT2 from tep {} rd {}", tepIp, rd);
1942 public void deleteTepfromElanDS(String rd, String tepIp, String mac) {
1943 boolean needUpdate = deleteFromRt2TepMap(rd, tepIp, mac);
1945 LOG.info("Deleting tepIp {} with RD {} to ELan DS", tepIp, rd);
1946 bgpUtil.deleteTepFromElanInstance(rd, tepIp);
1948 LOG.debug("Skipping the Elan update for RT2 withdraw from tep {} rd {}", tepIp, rd);
1952 /* onUpdatePushRoute
1953 * Get Stale fibDSWriter map, and compare current route/fibDSWriter entry.
1954 * - Entry compare shall include NextHop, Label.
1955 * - If entry matches: delete from STALE Map. NO Change to FIB Config DS.
1956 * - If entry not found, add to FIB Config DS.
1957 * - If entry found, but either Label/NextHop doesn't match.
1958 * - Update FIB Config DS with modified values.
1959 * - delete from Stale Map.
1962 public void onUpdatePushRoute(protocol_type protocolType, String rd, String prefix, int plen, String nextHop,
1963 String macaddress, int label, int l2label, String routermac, af_afi afi) {
1964 PrefixUpdateEvent prefixUpdateEvent = new PrefixUpdateEvent(protocolType,rd,prefix,plen,nextHop,
1965 macaddress,label,l2label,routermac,afi);
1966 bgpUpdatesHistory.addToHistory(TransactionType.ADD, prefixUpdateEvent);
1967 boolean addroute = false;
1968 boolean macupdate = false;
1970 VrfEntry.EncapType encapType = VrfEntry.EncapType.Mplsgre;
1971 if (protocolType.equals(protocol_type.PROTOCOL_EVPN)) {
1972 encapType = VrfEntry.EncapType.Vxlan;
1973 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = bgpUtil.getVpnInstanceOpData(rd);
1974 if (vpnInstanceOpDataEntry != null) {
1975 if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
1976 LOG.info("Got RT2 route for RD {} l3label {} l2label {} from tep {} with mac {} remote RD {}",
1977 vpnInstanceOpDataEntry.getVpnInstanceName(), label, l2label, nextHop, macaddress, rd);
1978 addTepToElanDS(rd, nextHop, macaddress, (long)l2label);
1981 l3vni = vpnInstanceOpDataEntry.getL3vni();
1984 LOG.error("No corresponding vpn instance found for rd {}. Aborting.", rd);
1989 if (!staledFibEntriesMap.isEmpty()) {
1990 // restart Scenario, as MAP is not empty.
1991 Map<String, Long> map = staledFibEntriesMap.get(rd);
1993 String prefixNextHop = appendNextHopToPrefix(prefix + "/" + plen, nextHop);
1994 Long labelInStaleMap = map.get(prefixNextHop);
1995 if (null == labelInStaleMap) {
1996 // New Entry, which happened to be added during restart.
1999 map.remove(prefixNextHop);
2000 if (isRouteModified(label, labelInStaleMap)) {
2001 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
2002 // Existing entry, where in Label got modified during restart
2007 LOG.debug("rd {} map is null while processing prefix {} ", rd, prefix);
2011 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
2015 LOG.info("ADD: Adding Mac Fib entry rd {} mac{} nexthop {} l2vni {}", rd, macaddress, nextHop, l2label);
2016 fibDSWriter.addMacEntryToDS(rd, macaddress, prefix, Collections.singletonList(nextHop),
2017 encapType, l2label, routermac, RouteOrigin.BGP);
2018 LOG.info("ADD: Added Mac Fib entry rd {} prefix {} nexthop {} label {}", rd, macaddress, nextHop, l2label);
2019 } else if (addroute) {
2020 LOG.info("ADD: Adding Fib entry rd {} prefix {} nexthop {} label {} afi {}",
2021 rd, prefix, nextHop, label, afi);
2022 // TODO: modify addFibEntryToDS signature
2023 List<String> nextHopList = Collections.singletonList(nextHop);
2024 fibDSWriter.addFibEntryToDS(rd, prefix + "/" + plen, nextHopList, encapType, label, l3vni,
2025 routermac, RouteOrigin.BGP);
2026 LOG.info("ADD: Added Fib entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, label);
2027 String vpnName = bgpUtil.getVpnNameFromRd(rd);
2028 if (vpnName != null) {
2029 vpnLinkService.leakRouteIfNeeded(vpnName, prefix, nextHopList, label, RouteOrigin.BGP,
2030 NwConstants.ADD_FLOW);
2035 public void onUpdateWithdrawRoute(protocol_type protocolType, String rd, String prefix, int plen, String nextHop,
2036 String macaddress) {
2037 PrefixWithdrawEvent prefixWithdrawEvent = new PrefixWithdrawEvent(protocolType,rd,prefix,plen,
2038 nextHop,macaddress);
2039 bgpUpdatesHistory.addToHistory(TransactionType.ADD, prefixWithdrawEvent);
2041 boolean macupdate = false;
2042 if (protocolType.equals(protocol_type.PROTOCOL_EVPN)) {
2043 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = bgpUtil.getVpnInstanceOpData(rd);
2044 if (vpnInstanceOpDataEntry != null) {
2045 vni = vpnInstanceOpDataEntry.getL3vni();
2046 if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
2047 LOG.debug("Got RT2 withdraw for RD {} {} from tep {} with mac {} remote RD {}",
2048 vpnInstanceOpDataEntry.getVpnInstanceName(), vni, nextHop, macaddress, rd);
2049 deleteTepfromElanDS(rd, nextHop, macaddress);
2050 LOG.debug("For rd {}. skipping fib update", rd);
2054 LOG.error("No corresponding vpn instance found for rd {}. Aborting.", rd);
2059 LOG.info("Removing Mac Fib entry rd {} mac{} nexthop {} ", rd, macaddress, nextHop);
2060 fibDSWriter.removeMacEntryFromDS(rd, macaddress);
2061 LOG.info("Removed Mac Fib entry rd {} prefix {} nexthop {} ", rd, macaddress, nextHop);
2063 LOG.info("REMOVE: Removing Fib entry rd {} prefix {}", rd, prefix);
2064 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix + "/" + plen, nextHop);
2065 LOG.info("REMOVE: Removed Fib entry rd {} prefix {}", rd, prefix);
2069 //TODO: below function is for testing purpose with cli
2070 public void onUpdateWithdrawRoute(String rd, String prefix, int plen, String nexthop) {
2071 LOG.debug("Route del ** {} ** {}/{} ", rd, prefix, plen);
2072 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix + "/" + plen, nexthop);
2073 String vpnName = bgpUtil.getVpnNameFromRd(rd);
2074 if (vpnName != null) {
2075 vpnLinkService.leakRouteIfNeeded(vpnName, prefix, null /*nextHopList*/, 0 /*INVALID_LABEL*/,
2076 RouteOrigin.BGP, NwConstants.DEL_FLOW);
2080 public void peerDown(String ipAddress, long asNumber) {
2081 List<String> tepIpList = bgpUtil.getDcgwTepConfig(ipAddress);
2082 if (tepIpList == null) {
2083 LOG.error("No Tep IP configured for DCGW {} on a peerDown", ipAddress);
2086 tepIpList.forEach(tepIp -> {
2087 bgpUtil.removeOrUpdateLBGroups(tepIp, NwConstants.MOD_FLOW, false);
2091 public void peerUp(String ipAddress, long asNumber) {
2092 List<String> tepIpList = bgpUtil.getDcgwTepConfig(ipAddress);
2093 if (tepIpList == null) {
2094 LOG.error("No Tep IP configured for DCGW {} on a peerUp", ipAddress);
2097 tepIpList.forEach(tepIp -> {
2098 bgpUtil.removeOrUpdateLBGroups(tepIp, NwConstants.MOD_FLOW, true);
2102 private static boolean isRouteModified(int label, Long labelInStaleMap) {
2103 return labelInStaleMap != null && !labelInStaleMap.equals(Long.valueOf(label));
2106 static class ReplayNbr {
2108 boolean shouldRetry = false;
2110 public Neighbors getNbr() {
2114 public boolean isShouldRetry() {
2118 public void setShouldRetry(boolean retryNbr) {
2119 this.shouldRetry = retryNbr;
2122 ReplayNbr(Neighbors nbr, boolean shouldRetry) {
2124 this.shouldRetry = shouldRetry;
2128 private static boolean replayNbrConfig(List<Neighbors> neighbors, BgpRouter br) {
2129 if (neighbors == null || neighbors.isEmpty()) {
2130 LOG.error("Replaying nbr configuration, received NULL list ");
2134 List<ReplayNbr> replayNbrList = new ArrayList<>();
2135 for (Neighbors nbr : neighbors) {
2137 replayNbrList.add(new ReplayNbr(nbr, true));
2140 final int numberOfNbrRetries = 3;
2141 RetryOnException nbrRetry = new RetryOnException(numberOfNbrRetries);
2143 for (ReplayNbr replayNbr : replayNbrList) {
2144 if (!replayNbr.isShouldRetry()) {
2147 boolean replayDone = false;
2148 LOG.debug("Replaying addNbr {}", replayNbr.getNbr().getAddress().getValue());
2151 final String md5password = extractMd5Secret(replayNbr.getNbr());
2152 br.addNeighbor(replayNbr.getNbr().getAddress().getValue(),
2153 replayNbr.getNbr().getRemoteAs().longValue(), md5password);
2155 } catch (TApplicationException tae) {
2156 LOG.debug("Replaying addNbr {}, tapplicationexception: ",
2157 replayNbr.getNbr().getAddress().getValue(), tae);
2158 if (tae.getType() == BgpRouterException.BGP_ERR_PEER_EXISTS) {
2159 LOG.debug("Replaying addNbr Neighbor already present");
2162 } catch (TException | BgpRouterException eNbr) {
2163 LOG.debug("Replaying addNbr {}, exception: ", replayNbr.getNbr().getAddress().getValue(), eNbr);
2166 LOG.debug("Replay addNbr {} successful", replayNbr.getNbr().getAddress().getValue());
2168 //Update Source handling
2169 UpdateSource us = replayNbr.getNbr().getUpdateSource();
2171 LOG.debug("Replaying updatesource {} to peer {}", us.getSourceIp().getValue(),
2172 us.getPeerIp().getValue());
2174 br.addUpdateSource(us.getPeerIp().getValue(),
2175 us.getSourceIp().getValue());
2176 } catch (TException | BgpRouterException eUs) {
2177 LOG.debug("Replaying UpdateSource for Nbr {}, exception:",
2178 replayNbr.getNbr().getAddress().getValue(), eUs);
2180 LOG.debug("Replay updatesource {} successful", us.getSourceIp().getValue());
2183 EbgpMultihop en = replayNbr.getNbr().getEbgpMultihop();
2186 br.addEbgpMultihop(en.getPeerIp().getValue(),
2187 en.getNhops().intValue());
2188 } catch (TException | BgpRouterException eEbgpMhop) {
2189 LOG.debug("Replaying EbgpMultihop for Nbr {}, exception: ",
2190 replayNbr.getNbr().getAddress().getValue(), eEbgpMhop);
2195 List<AddressFamilies> afs = replayNbr.getNbr().getAddressFamilies();
2197 for (AddressFamilies af : afs) {
2198 af_afi afi = af_afi.findByValue(af.getAfi().intValue());
2199 af_safi safi = af_safi.findByValue(af.getSafi().intValue());
2201 br.addAddressFamily(af.getPeerIp().getValue(), afi, safi);
2202 } catch (TException | BgpRouterException eAFs) {
2203 LOG.debug("Replaying AddressFamily for Nbr {}, exception:",
2204 replayNbr.getNbr().getAddress().getValue(), eAFs);
2208 //replay is success --> no need to replay this nbr in next iteration.
2209 replayNbr.setShouldRetry(replayDone ? false : true);
2211 } while (nbrRetry.decrementAndRetry());
2212 boolean replaySuccess = true;
2213 for (ReplayNbr replayNbr : replayNbrList) {
2214 replaySuccess = replaySuccess && !replayNbr.isShouldRetry();
2216 return replaySuccess;
2219 public String getConfigHost() {
2220 if (config == null) {
2223 ConfigServer ts = config.getConfigServer();
2224 return ts == null ? hostStartup : ts.getHost().getValue();
2227 public int getConfigPort() {
2228 if (config == null) {
2229 return Integer.parseInt(portStartup);
2231 ConfigServer ts = config.getConfigServer();
2232 return ts == null ? Integer.parseInt(portStartup) :
2233 ts.getPort().intValue();
2236 public Bgp getConfig() {
2237 AtomicInteger bgpDSretryCount = new AtomicInteger(DS_RETRY_COUNT);
2238 while (0 != bgpDSretryCount.decrementAndGet()) {
2240 return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
2241 InstanceIdentifier.create(Bgp.class)).orNull();
2242 } catch (ReadFailedException e) {
2243 //Config DS may not be up, so sleep for 1 second and retry
2244 LOG.debug("failed to get bgp config, may be DS is yet in consistent state(?)", e);
2246 Thread.sleep(WAIT_TIME_BETWEEN_EACH_TRY_MILLIS);
2247 } catch (InterruptedException timerEx) {
2248 LOG.debug("WAIT_TIME_BETWEEN_EACH_TRY_MILLIS, Timer got interrupted while waiting for"
2249 + "config DS availability", timerEx);
2253 LOG.error("failed to get bgp config");
2257 @SuppressWarnings("checkstyle:IllegalCatch")
2258 public synchronized boolean replay() throws InterruptedException, TimeoutException, ExecutionException {
2259 boolean replaySucceded = true;
2260 boolean doRouteSync = false;
2261 String host = getConfigHost();
2262 int port = getConfigPort();
2263 LOG.error("connecting to bgp host {} ", host);
2264 boolean res = bgpRouter.connect(host, port);
2266 LOG.error("Cannot connect to BGP config server at {} {}", host, port);
2267 return replaySucceded;
2269 config = getConfig();
2270 if (config == null) {
2271 LOG.error("bgp config is empty nothing to push to bgp");
2272 return replaySucceded;
2274 BgpRouter br = bgpRouter;
2275 AsId asId = config.getAsId();
2277 LOG.error("bgp as-id is null");
2278 return replaySucceded;
2280 long asNum = asId.getLocalAs();
2281 IpAddress routerId = asId.getRouterId();
2282 String rid = routerId == null ? "" : routerId.stringValue();
2283 int stalepathTime = (int) getStalePathtime(RESTART_DEFAULT_GR, config.getAsId());
2284 boolean announceFbit = true;
2285 boolean replayDone = false;
2286 final int numberOfStartBgpRetries = 3;
2287 RetryOnException startBgpRetry = new RetryOnException(numberOfStartBgpRetries);
2290 LOG.debug("Replaying BGPConfig ");
2291 br.startBgp(asNum, rid, stalepathTime, announceFbit);
2292 LOG.debug("Replay BGPConfig successful");
2295 } catch (BgpRouterException bre) {
2296 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
2297 LOG.debug("Starting the routesync for exception", bre);
2298 startBgpRetry.errorOccured();
2299 if (!startBgpRetry.shouldRetry()) {
2304 LOG.error("Replay: startBgp() received exception error {} : ",
2305 bre.getErrorCode(), bre);
2306 startBgpRetry.errorOccured();
2308 } catch (TApplicationException tae) {
2309 if (tae.getType() == BgpRouterException.BGP_ERR_ACTIVE) {
2310 LOG.debug("Starting the routesync for exception", tae);
2311 startBgpRetry.errorOccured();
2312 if (!startBgpRetry.shouldRetry()) {
2316 } else if (tae.getType() == BgpRouterException.BGP_ERR_COMMON_FAILURE) {
2317 LOG.debug("Starting the routesync for AS-ID started exception", tae);
2318 startBgpRetry.errorOccured();
2319 if (!startBgpRetry.shouldRetry()) {
2324 LOG.error("Replay: startBgp() received exception type {}: ",
2325 tae.getType(), tae);
2326 startBgpRetry.errorOccured();
2328 } catch (Exception e) {
2329 //not unusual. We may have restarted & BGP is already on
2330 LOG.error("Replay:startBgp() received exception: ", e);
2331 startBgpRetry.errorOccured();
2333 } while (startBgpRetry.shouldRetry());
2335 replaySucceded = replayDone;
2337 startBgpCountersTask();
2338 startBgpAlarmsTask();
2341 * commenting this due to a bug with QBGP. Will uncomment once QBGP fix is done.
2342 * This wont have any functional impacts
2345 // br.delayEOR(delayEorSeconds);
2346 //} catch (TException | BgpRouterException e) {
2347 // LOG.error("Replay: delayEOR() number of seconds to wait for EOR from ODL:", e);
2350 BfdConfig bfdConfig = bgpUtil.getBfdConfig();
2351 if (bfdConfig != null) {
2352 if (bfdConfig.isBfdEnabled()) {
2353 LOG.debug("Replaying bfd config min-rx {} min-tx {} detect-mul {} mhop {}",
2354 bfdConfig.getMinRx(), bfdConfig.getMinTx(),
2355 bfdConfig.getDetectMult(), bfdConfig.isMultihop());
2357 br.addBfd(bfdConfig.getDetectMult().intValue(), bfdConfig.getMinRx().intValue(),
2358 bfdConfig.getMinTx().intValue(), bfdConfig.isMultihop());
2359 } catch (TException | BgpRouterException e) {
2360 LOG.error("Replay:addBfd() received exception", e);
2365 List<Neighbors> neighbors = config.getNeighbors();
2366 if (neighbors != null) {
2367 LOG.error("configuring existing Neighbors present for replay total neighbors {}", neighbors.size());
2368 boolean neighborConfigReplayResult = replayNbrConfig(neighbors, br);
2369 if (neighborConfigReplayResult == false) {
2370 replaySucceded = false;
2373 LOG.error("no Neighbors present for replay config ");
2376 Logging logging = config.getLogging();
2377 if (logging != null) {
2379 br.setLogging(logging.getFile(), logging.getLevel());
2380 } catch (TException | BgpRouterException e) {
2381 LOG.error("Replay:setLogging() received exception", e);
2385 GracefulRestart gracefulRestart = config.getGracefulRestart();
2386 if (gracefulRestart != null) {
2388 br.addGracefulRestart(gracefulRestart.getStalepathTime().intValue());
2389 } catch (TException | BgpRouterException e) {
2390 LOG.error("Replay:addGr() received exception", e);
2394 List<Vrfs> vrfs = config.getVrfs();
2396 vrfs = new ArrayList<>();
2398 for (Vrfs vrf : vrfs) {
2399 for (AddressFamiliesVrf adf : vrf.getAddressFamiliesVrf()) {
2401 br.addVrf(BgpUtil.getLayerType(adf), vrf.getRd(), vrf.getImportRts(),
2402 vrf.getExportRts());
2403 } catch (TException | BgpRouterException e) {
2404 LOG.error("Replay:addVrf() received exception", e);
2409 List<Networks> ln = config.getNetworks();
2411 for (Networks net : ln) {
2412 String rd = net.getRd();
2413 String pfxlen = net.getPrefixLen();
2414 String nh = net.getNexthop().getValue();
2415 Long label = net.getLabel();
2416 int lbl = label == null ? 0 : label.intValue();
2417 int l3vni = net.getL3vni() == null ? 0 : net.getL3vni().intValue();
2418 int l2vni = net.getL2vni() == null ? 0 : net.getL2vni().intValue();
2419 if (rd == null && lbl > 0) {
2420 //LU prefix is being deleted.
2421 rd = Integer.toString(lbl);
2424 BgpControlPlaneType protocolType = net.getBgpControlPlaneType();
2425 int ethernetTag = net.getEthtag().intValue();
2426 String esi = net.getEsi();
2427 String macaddress = net.getMacaddress();
2428 EncapType encapType = net.getEncapType();
2429 String routerMac = net.getRoutermac();
2432 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, l2vni,
2433 BgpUtil.convertToThriftProtocolType(protocolType),
2434 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
2435 } catch (TException | BgpRouterException e) {
2436 LOG.error("Replay:addPfx() received exception", e);
2442 List<Multipath> multipaths = config.getMultipath();
2444 if (multipaths != null) {
2445 for (Multipath multipath : multipaths) {
2446 if (multipath != null) {
2447 af_afi afi = af_afi.findByValue(multipath.getAfi().intValue());
2448 af_safi safi = af_safi.findByValue(multipath.getSafi().intValue());
2451 if (multipath.isMultipathEnabled()) {
2452 br.enableMultipath(afi, safi);
2454 br.disableMultipath(afi, safi);
2456 } catch (TException | BgpRouterException e) {
2457 LOG.info("Replay:multipaths() received exception", e);
2462 List<VrfMaxpath> vrfMaxpaths = config.getVrfMaxpath();
2463 if (vrfMaxpaths != null) {
2464 for (VrfMaxpath vrfMaxpath : vrfMaxpaths) {
2466 br.multipaths(vrfMaxpath.getRd(), vrfMaxpath.getMaxpaths());
2467 } catch (TException | BgpRouterException e) {
2468 LOG.info("Replay:vrfMaxPath() received exception", e);
2473 //send End of Rib Marker to Qthriftd.
2474 final int numberOfEORRetries = 3;
2475 RetryOnException eorRetry = new RetryOnException(numberOfEORRetries);
2479 LOG.debug("Replay sendEOR {} successful");
2481 } catch (Exception e) {
2482 eorRetry.errorOccured();
2483 LOG.error("Replay:sedEOR() received exception:", e);
2485 } while (eorRetry.shouldRetry());
2488 LOG.debug("starting route sync for Thrift BGP_ERR_COMMON_FAILURE exception "
2489 + "happened earlier");
2493 return replaySucceded;
2496 private <T extends DataObject> void update(InstanceIdentifier<T> iid, T dto) {
2497 bgpUtil.update(iid, dto);
2500 private <T extends DataObject> void delete(InstanceIdentifier<T> iid) {
2501 bgpUtil.delete(iid);
2504 public void startConfig(String bgpHost, int thriftPort) {
2505 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
2506 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
2507 InstanceIdentifier<ConfigServer> iid = iib.build();
2508 Ipv4Address ipAddr = new Ipv4Address(bgpHost);
2509 ConfigServer dto = new ConfigServerBuilder().setHost(ipAddr)
2510 .setPort((long) thriftPort).build();
2514 public void startBgp(long as, String routerId, int spt, boolean fbit) {
2515 IpAddress rid = routerId == null ? null : IpAddressBuilder.getDefaultInstance(routerId);
2516 Long staleTime = (long) spt;
2517 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
2518 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
2519 InstanceIdentifier<AsId> iid = iib.build();
2520 AsId dto = new AsIdBuilder().setLocalAs(as)
2522 .setStalepathTime(staleTime)
2523 .setAnnounceFbit(fbit).build();
2527 public void startBfd(long detectMult, long minRx, long minTx, boolean multiHop) {
2528 InstanceIdentifier.InstanceIdentifierBuilder<BfdConfig> iib =
2529 InstanceIdentifier.builder(BfdConfig.class);
2530 InstanceIdentifier<BfdConfig> iid = iib.build();
2531 BfdConfig dto = new BfdConfigBuilder()
2532 .setBfdEnabled(true)
2533 .setMultihop(multiHop)
2536 .setDetectMult(detectMult)
2541 public void addDcgwTep(String dcgwIp, String tepIp) {
2542 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2543 InstanceIdentifier.builder(Bgp.class)
2544 .child(DcgwTepList.class)
2545 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2546 InstanceIdentifier<DcgwTep> iid = iib.build();
2547 ArrayList<String> tepList = new ArrayList<String>();
2549 DcgwTep dto = new DcgwTepBuilder().setDcGwIp(dcgwIp).setTepIps(tepList)
2554 public void addLogging(String fileName, String logLevel) {
2555 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
2556 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
2557 InstanceIdentifier<Logging> iid = iib.build();
2558 Logging dto = new LoggingBuilder().setFile(fileName)
2559 .setLevel(logLevel).build();
2563 public void addGracefulRestart(int staleTime) {
2564 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
2565 InstanceIdentifier.builder(Bgp.class).child(GracefulRestart.class);
2566 InstanceIdentifier<GracefulRestart> iid = iib.build();
2567 GracefulRestart dto = new GracefulRestartBuilder()
2568 .setStalepathTime((long) staleTime).build();
2572 public void addNeighbor(
2573 String nbrIp, long remoteAs, @Nullable final TcpMd5SignaturePasswordType md5Secret) {
2574 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2575 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
2576 InstanceIdentifier.builder(Bgp.class)
2577 .child(Neighbors.class, new NeighborsKey(nbrAddr));
2578 InstanceIdentifier<Neighbors> iid = iib.build();
2579 TcpSecurityOption tcpSecOption = null;
2580 if (md5Secret != null) {
2581 tcpSecOption = new TcpMd5SignatureOptionBuilder().setTcpMd5SignaturePassword(md5Secret).build();
2582 } // else let tcpSecOption be null
2583 Neighbors dto = new NeighborsBuilder().setAddress(nbrAddr)
2584 .setRemoteAs(remoteAs).setTcpSecurityOption(tcpSecOption).build();
2586 } // public addNeighbor(nbrIp, remoteAs, md5Secret)
2588 public void addUpdateSource(String nbrIp, String srcIp) {
2589 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2590 Ipv4Address srcAddr = new Ipv4Address(srcIp);
2591 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
2592 InstanceIdentifier.builder(Bgp.class)
2593 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2594 .child(UpdateSource.class);
2595 InstanceIdentifier<UpdateSource> iid = iib.build();
2596 UpdateSource dto = new UpdateSourceBuilder().setPeerIp(nbrAddr)
2597 .setSourceIp(srcAddr).build();
2601 public void addEbgpMultihop(String nbrIp, int hops) {
2602 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2603 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
2604 InstanceIdentifier.builder(Bgp.class)
2605 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2606 .child(EbgpMultihop.class);
2607 InstanceIdentifier<EbgpMultihop> iid = iib.build();
2608 EbgpMultihop dto = new EbgpMultihopBuilder().setPeerIp(nbrAddr)
2609 .setNhops((long) hops).build();
2613 public void addAddressFamily(String nbrIp, int afi, int safi) {
2614 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2615 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
2616 InstanceIdentifier.builder(Bgp.class)
2617 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2618 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
2619 InstanceIdentifier<AddressFamilies> iid = iib.build();
2620 AddressFamilies dto = new AddressFamiliesBuilder().setPeerIp(nbrAddr)
2621 .setAfi((long) afi).setSafi((long) safi).build();
2625 public void addPrefix(String rd, String macAddress, String pfx, List<String> nhList,
2626 VrfEntry.EncapType encapType, long lbl, long l3vni, long l2vni, String gatewayMac) {
2627 for (String nh : nhList) {
2628 Ipv4Address nexthop = nh != null ? new Ipv4Address(nh) : null;
2630 InstanceIdentifier<Networks> iid = InstanceIdentifier.builder(Bgp.class)
2631 .child(Networks.class, new NetworksKey(pfx, rd)).build();
2632 NetworksBuilder networksBuilder = new NetworksBuilder().setRd(rd).setPrefixLen(pfx).setNexthop(nexthop)
2633 .setLabel(label).setEthtag(BgpConstants.DEFAULT_ETH_TAG);
2634 buildVpnEncapSpecificInfo(networksBuilder, encapType, label, l3vni, l2vni, macAddress, gatewayMac);
2635 update(iid, networksBuilder.build());
2639 private static void buildVpnEncapSpecificInfo(NetworksBuilder builder, VrfEntry.EncapType encapType, long label,
2640 long l3vni, long l2vni, String macAddress, String gatewayMac) {
2641 if (encapType.equals(VrfEntry.EncapType.Mplsgre)) {
2642 builder.setLabel(label).setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLL3VPN)
2643 .setEncapType(EncapType.GRE);
2645 builder.setL3vni(l3vni).setL2vni(l2vni).setMacaddress(macAddress).setRoutermac(gatewayMac)
2646 .setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLEVPN).setEncapType(EncapType.VXLAN);
2650 // TODO: add LayerType as arg - supports command
2651 public void addVrf(String rd, List<String> irts, List<String> erts, AddressFamily addressFamily) {
2652 Vrfs vrf = bgpUtil.getVrfFromRd(rd);
2653 List<AddressFamiliesVrf> adfList = new ArrayList<>(1);
2655 adfList = vrf.getAddressFamiliesVrf();
2657 AddressFamiliesVrfBuilder adfBuilder = new AddressFamiliesVrfBuilder();
2658 if (addressFamily.equals(AddressFamily.IPV4)) {
2659 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2660 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2661 } else if (addressFamily.equals(AddressFamily.IPV6)) {
2662 adfBuilder.setAfi((long) af_afi.AFI_IPV6.getValue());
2663 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2664 } else if (addressFamily.equals(AddressFamily.L2VPN)) {
2665 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2666 adfBuilder.setSafi((long) af_safi.SAFI_EVPN.getValue());
2668 AddressFamiliesVrf adf = adfBuilder.build();
2670 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib = InstanceIdentifier.builder(Bgp.class)
2671 .child(Vrfs.class, new VrfsKey(rd));
2672 InstanceIdentifier<Vrfs> iid = iib.build();
2673 Vrfs dto = new VrfsBuilder().setRd(rd).setImportRts(irts)
2674 .setExportRts(erts).setAddressFamiliesVrf(adfList).build();
2676 List<AddressFamiliesVrf> listAdFamilies = mapNewAdFamily.get(rd);
2677 if (listAdFamilies != null) {
2678 listAdFamilies.add(adf);
2680 mapNewAdFamily.put(rd, adfList);
2684 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
2685 } catch (TransactionCommitFailedException e) {
2686 LOG.error("Error adding VRF to datastore", e);
2687 throw new RuntimeException(e);
2690 // enable multipath by default in all VRFs
2691 setMultipaths(rd, BgpConstants.BGP_DEFAULT_MULTIPATH);
2694 public void stopConfig() {
2695 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
2696 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
2697 InstanceIdentifier<ConfigServer> iid = iib.build();
2701 public void stopBgp() {
2702 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
2703 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
2704 InstanceIdentifier<AsId> iid = iib.build();
2708 public void stopBfd() {
2709 InstanceIdentifier.InstanceIdentifierBuilder<BfdConfig> iib =
2710 InstanceIdentifier.builder(BfdConfig.class);
2711 InstanceIdentifier<BfdConfig> iid = iib.build();
2715 public void delDcgwTep(String dcgwIp, String tepIp) {
2716 if (tepIp == null) {
2717 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2718 InstanceIdentifier.builder(Bgp.class)
2719 .child(DcgwTepList.class)
2720 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2721 InstanceIdentifier<DcgwTep> iid = iib.build();
2724 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2725 InstanceIdentifier.builder(Bgp.class)
2726 .child(DcgwTepList.class)
2727 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2728 InstanceIdentifier<DcgwTep> iid = iib.build();
2729 List<String> tepIpList = bgpUtil.getDcgwTepConfig(dcgwIp);
2730 if (tepIpList == null) {
2731 LOG.error("No Tep IP configured for DCGW {} on deleting the dcgwtep", dcgwIp);
2734 List<String> newTepIpList = new ArrayList<String>();
2735 tepIpList.forEach(tep -> {
2736 if (!tep.equals(tepIp)) {
2737 newTepIpList.add(tep);
2740 DcgwTep dto = new DcgwTepBuilder().setDcGwIp(dcgwIp).setTepIps(newTepIpList)
2743 SingleTransactionDataBroker.syncWrite(dataBroker,
2744 LogicalDatastoreType.CONFIGURATION, iid, dto);
2745 } catch (TransactionCommitFailedException e) {
2746 LOG.error("delDcgwTep: Error deleting DCGW Tep", e);
2747 throw new RuntimeException(e);
2752 public void delLogging() {
2753 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
2754 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
2755 InstanceIdentifier<Logging> iid = iib.build();
2759 public void delGracefulRestart() {
2760 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
2761 InstanceIdentifier.builder(Bgp.class)
2762 .child(GracefulRestart.class);
2763 InstanceIdentifier<GracefulRestart> iid = iib.build();
2767 public void delNeighbor(String nbrIp) {
2768 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2769 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
2770 InstanceIdentifier.builder(Bgp.class)
2771 .child(Neighbors.class, new NeighborsKey(nbrAddr));
2772 InstanceIdentifier<Neighbors> iid = iib.build();
2776 public void delUpdateSource(String nbrIp) {
2777 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2778 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
2779 InstanceIdentifier.builder(Bgp.class)
2780 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2781 .child(UpdateSource.class);
2782 InstanceIdentifier<UpdateSource> iid = iib.build();
2786 public void delEbgpMultihop(String nbrIp) {
2787 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2788 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
2789 InstanceIdentifier.builder(Bgp.class)
2790 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2791 .child(EbgpMultihop.class);
2792 InstanceIdentifier<EbgpMultihop> iid = iib.build();
2796 public void delAddressFamily(String nbrIp, int afi, int safi) {
2797 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2798 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
2799 InstanceIdentifier.builder(Bgp.class)
2800 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2801 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
2802 InstanceIdentifier<AddressFamilies> iid = iib.build();
2806 public void delPrefix(String rd, String pfx) {
2807 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
2808 InstanceIdentifier.builder(Bgp.class)
2809 .child(Networks.class, new NetworksKey(pfx, rd));
2810 InstanceIdentifier<Networks> iid = iib.build();
2814 public boolean delVrf(String rd, AddressFamily addressFamily) {
2815 if (addressFamily == null) {
2816 LOG.error("delVrf: vrf {}, addressFamily invalid", rd);
2820 AddressFamiliesVrfBuilder adfBuilder = new AddressFamiliesVrfBuilder();
2821 if (addressFamily.equals(AddressFamily.IPV4)) {
2822 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2823 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2824 } else if (addressFamily.equals(AddressFamily.IPV6)) {
2825 adfBuilder.setAfi((long) af_afi.AFI_IPV6.getValue());
2826 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2827 } else if (addressFamily.equals(AddressFamily.L2VPN)) {
2828 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2829 adfBuilder.setSafi((long) af_safi.SAFI_EVPN.getValue());
2831 LOG.debug("delVrf: Received Delete VRF : rd:{}, address family: {} {}", rd,
2832 adfBuilder.getAfi(), adfBuilder.getSafi());
2834 Vrfs vrfOriginal = bgpUtil.getVrfFromRd(rd);
2835 if (vrfOriginal == null) {
2836 LOG.error("delVrf: no vrf with existing rd {}. step aborted", rd);
2840 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
2841 InstanceIdentifier.builder(Bgp.class)
2842 .child(Vrfs.class, new VrfsKey(rd));
2844 InstanceIdentifier<Vrfs> iid = iib.build();
2846 @SuppressWarnings("static-access")
2847 InstanceIdentifier<Bgp> iid6 = iid.builder(Bgp.class).build()
2848 .child(Multipath.class, new MultipathKey(adfBuilder.getAfi(), adfBuilder.getSafi())).create(Bgp.class);
2849 InstanceIdentifierBuilder<Vrfs> iib3 = iid6.child(Vrfs.class, new VrfsKey(rd)).builder();
2850 InstanceIdentifier<Vrfs> iidFinal = iib3.build();
2852 //** update or delete the vrfs with the rest of AddressFamilies already present in the last list
2853 AddressFamiliesVrf adfToDel = adfBuilder.build();
2854 List<AddressFamiliesVrf> adfListOriginal = vrfOriginal.getAddressFamiliesVrf() == null
2855 ? new ArrayList<>() : vrfOriginal.getAddressFamiliesVrf();
2856 List<AddressFamiliesVrf> adfListToRemoveFromOriginal = new ArrayList<>();
2857 adfListOriginal.forEach(adf -> {
2858 if (adf.equals(adfToDel)) {
2859 adfListToRemoveFromOriginal.add(adfToDel);
2863 for (AddressFamiliesVrf adfToRemove : adfListToRemoveFromOriginal) {
2864 adfListOriginal.remove(adfToRemove);
2866 SingleTransactionDataBroker.syncWrite(dataBroker,
2867 LogicalDatastoreType.CONFIGURATION, iid, vrfOriginal);
2868 } catch (TransactionCommitFailedException e) {
2869 LOG.error("delVrf: Error updating VRF to datastore", e);
2870 throw new RuntimeException(e);
2873 if (adfListOriginal.isEmpty()) {
2874 LOG.debug("delVrf: delete iid: {}", iidFinal);
2878 // not all is removed
2882 public void setMultipathStatus(af_afi afi, af_safi safi, boolean enable) {
2883 long lafi = afi.getValue();
2884 long lsafi = safi.getValue();
2886 InstanceIdentifier.InstanceIdentifierBuilder<Multipath> iib =
2889 .child(Multipath.class,
2890 new MultipathKey(Long.valueOf(afi.getValue()), Long.valueOf(safi.getValue())));
2892 Multipath dto = new MultipathBuilder().setAfi(lafi).setSafi(lsafi).setMultipathEnabled(enable).build();
2893 update(iib.build(), dto);
2896 public void setMultipaths(String rd, int maxpath) {
2897 InstanceIdentifier.InstanceIdentifierBuilder<VrfMaxpath> iib =
2900 .child(VrfMaxpath.class, new VrfMaxpathKey(rd));
2902 VrfMaxpath dto = new VrfMaxpathBuilder().setRd(rd).setMaxpaths(maxpath).build();
2903 update(iib.build(), dto);
2906 public void delMultipaths(String rd) {
2907 InstanceIdentifier.InstanceIdentifierBuilder<VrfMaxpath> iib =
2908 InstanceIdentifier.builder(Bgp.class)
2909 .child(VrfMaxpath.class, new VrfMaxpathKey(rd));
2910 InstanceIdentifier<VrfMaxpath> iid = iib.build();
2915 * Remove Stale Marked Routes after timer expiry.
2917 private class RouteCleanup implements Callable<Integer> {
2920 public Integer call() {
2923 if (staledFibEntriesMap.isEmpty()) {
2924 LOG.info("BGP: RouteCleanup timertask tirggered but STALED FIB MAP is EMPTY");
2926 for (String rd : staledFibEntriesMap.keySet()) {
2927 if (Thread.interrupted()) {
2930 Map<String, Long> map = staledFibEntriesMap.get(rd);
2932 for (String key : map.keySet()) {
2933 if (Thread.interrupted()) {
2936 String prefix = extractPrefix(key);
2937 String nextHop = extractNextHop(key);
2939 LOG.debug("BGP: RouteCleanup deletePrefix called for : rd:{}, prefix{}, nextHop:{}",
2940 rd, prefix, nextHop);
2941 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix, nextHop);
2947 staledFibEntriesMap.clear();
2949 LOG.error("cleared {} stale routes after bgp restart", totalCleared);
2955 * BGP restart scenario, ODL-BGP manager was/is running.
2956 * On re-sync notification, Get a copy of FIB database.
2958 public void createStaleFibMap() {
2959 totalStaledCount = 0;
2961 staledFibEntriesMap.clear();
2962 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
2964 Optional<FibEntries> fibEntries = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2965 LogicalDatastoreType.CONFIGURATION, id);
2966 if (fibEntries.isPresent()) {
2967 List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
2968 for (VrfTables vrfTable : staleVrfTables) {
2969 Map<String, Long> staleFibEntMap = new HashMap<>();
2970 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
2971 if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
2972 //Stale marking and cleanup is only meant for the routes learned through BGP.
2975 if (Thread.interrupted()) {
2979 //Create MAP from staleVrfTables.
2980 vrfEntry.getRoutePaths()
2982 routePath -> staleFibEntMap.put(
2983 appendNextHopToPrefix(vrfEntry.getDestPrefix(),
2984 routePath.getNexthopAddress()), routePath.getLabel()));
2986 staledFibEntriesMap.put(vrfTable.getRouteDistinguisher(), staleFibEntMap);
2989 LOG.error("createStaleFibMap:: FIBentries.class is not present");
2991 } catch (ReadFailedException e) {
2992 LOG.error("createStaleFibMap:: error ", e);
2994 LOG.error("created {} staled entries ", totalStaledCount);
2998 * BGP config remove scenario, Need to remove all the
2999 * external routes from FIB.
3001 public void deleteExternalFibRoutes() {
3002 totalExternalRoutes = 0;
3003 totalExternalMacRoutes = 0;
3005 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
3007 Optional<FibEntries> fibEntries = SingleTransactionDataBroker.syncReadOptional(dataBroker,
3008 LogicalDatastoreType.CONFIGURATION, id);
3009 if (fibEntries.isPresent()) {
3010 if (fibEntries.get().getVrfTables() == null) {
3011 LOG.error("deleteExternalFibRoutes::getVrfTables is null");
3014 List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
3015 for (VrfTables vrfTable : staleVrfTables) {
3016 String rd = vrfTable.getRouteDistinguisher();
3017 if (vrfTable.getVrfEntry() != null) {
3018 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
3019 if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
3020 //route cleanup is only meant for the routes learned through BGP.
3023 totalExternalRoutes++;
3024 fibDSWriter.removeFibEntryFromDS(rd, vrfEntry.getDestPrefix());
3026 } else if (vrfTable.getMacVrfEntry() != null) {
3027 for (MacVrfEntry macEntry : vrfTable.getMacVrfEntry()) {
3028 if (RouteOrigin.value(macEntry.getOrigin()) != RouteOrigin.BGP) {
3029 //route cleanup is only meant for the routes learned through BGP.
3032 totalExternalMacRoutes++;
3033 fibDSWriter.removeMacEntryFromDS(rd, macEntry.getMac());
3038 LOG.error("deleteExternalFibRoutes:: FIBentries.class is not present");
3040 } catch (ReadFailedException e) {
3041 LOG.error("deleteExternalFibRoutes:: error ", e);
3043 LOG.debug("deleted {} fib entries {} mac entries", totalExternalRoutes, totalExternalMacRoutes);
3046 public boolean addToRt2TepMap(String rd, String tepIp, String mac, Long l2vni) {
3047 boolean isFirstMacUpdateFromTep = false;
3048 if (rt2TepMap.containsKey(rd)) {
3049 if (rt2TepMap.get(rd).containsKey(tepIp)) {
3050 LOG.debug("RT2 with mac {} l2vni {} from existing rd {} and tep-ip {}. No Elan DS write required",
3051 mac, l2vni, rd, tepIp);
3052 rt2TepMap.get(rd).get(tepIp).put(mac, l2vni);
3054 LOG.debug("RT2 with mac {} l2vni {} from existing rd {} and new tep-ip {}",
3055 mac, l2vni, rd, tepIp);
3056 isFirstMacUpdateFromTep = true;
3057 Map<String, Long> macList = new HashMap<>();
3058 macList.put(mac, l2vni);
3059 rt2TepMap.get(rd).put(tepIp, macList);
3062 LOG.debug("RT2 with mac {} l2vni {} from new rd {} and tep ip {}",
3063 mac, l2vni, rd, tepIp);
3064 isFirstMacUpdateFromTep = true;
3065 Map<String, Long> macList = new HashMap<>();
3066 macList.put(mac, l2vni);
3067 Map<String, Map<String, Long>> tepIpMacMap = new HashMap<>();
3068 tepIpMacMap.put(tepIp, macList);
3069 rt2TepMap.put(rd, tepIpMacMap);
3071 return isFirstMacUpdateFromTep;
3074 public boolean deleteFromRt2TepMap(String rd, String tepIp, String mac) {
3075 boolean isLastMacUpdateFromTep = false;
3076 LOG.debug("RT2 withdraw with rd {} mac {} tep-ip {} ", rd, mac, tepIp);
3077 if (rt2TepMap.containsKey(rd)) {
3078 if (rt2TepMap.get(rd).containsKey(tepIp)) {
3079 if (rt2TepMap.get(rd).get(tepIp).containsKey(mac)) {
3080 LOG.debug("RT2 Withdraw : Removing the mac {} from Map", mac);
3081 rt2TepMap.get(rd).get(tepIp).remove(mac);
3082 if (rt2TepMap.get(rd).get(tepIp).isEmpty()) {
3083 isLastMacUpdateFromTep = true;
3084 LOG.debug("RT2 Withdraw : Removing the tep-ip {} from Map", tepIp);
3085 rt2TepMap.get(rd).remove(tepIp);
3086 if (rt2TepMap.get(rd).isEmpty()) {
3087 LOG.debug("RT2 Withdraw : Removing the rd {} from Map", rd);
3088 rt2TepMap.remove(rd);
3094 return isLastMacUpdateFromTep;
3097 public Collection<String> getTepIPs(String rd) {
3098 final Map<String, Map<String, Long>> tepIpMap = rt2TepMap.get(rd);
3099 return tepIpMap != null ? tepIpMap.keySet() : Collections.emptyList();
3102 public boolean isBgpConnected() {
3103 return (bgpRouter == null) ? false : bgpRouter.isBgpConnected();
3106 public long getLastConnectedTS() {
3107 return (bgpRouter == null) ? 0 : bgpRouter.getLastConnectedTS();
3110 public long getConnectTS() {
3111 return (bgpRouter == null) ? 0 : bgpRouter.getConnectTS();
3114 public long getStartTS() {
3115 return (bgpRouter == null) ? 0 : bgpRouter.getStartTS();
3118 public TTransport getTransport() {
3119 return bgpRouter.getTransport();
3122 public int getTotalStaledCount() {
3123 return totalStaledCount;
3126 public int getTotalCleared() {
3127 return totalCleared;
3130 public BgpCounters getBgpCounters() {
3131 return bgpCountersReference.get();
3134 private void startBgpCountersTask() {
3135 if (getBgpCounters() == null && bgpCountersReference.compareAndSet(null,
3136 new BgpCounters(getBgpSdncMipIp(), metricProvider))) {
3137 bgpCountersTask = executor.scheduleAtFixedRate(bgpCountersReference.get(), 0, 120 * 1000,
3138 TimeUnit.MILLISECONDS);
3139 LOG.info("Bgp Counters task scheduled for every two minutes.");
3141 bgpManager.setQbgpLog(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
3145 private void stopBgpCountersTask() {
3146 final BgpCounters bgpCounters = bgpCountersReference.getAndSet(null);
3147 if (bgpCounters != null) {
3148 bgpCountersTask.cancel(true);
3149 bgpCounters.close();
3153 private void startBgpAlarmsTask() {
3154 if (getBgpAlarms() == null && bgpAlarmsReference.compareAndSet(null, new BgpAlarms(this))) {
3155 bgpAlarmsReference.get().init();
3156 bgpAlarmsTask = executor.scheduleAtFixedRate(bgpAlarmsReference.get(), 0, 60 * 1000, TimeUnit.MILLISECONDS);
3157 LOG.info("Bgp Alarms task scheduled for every minute.");
3159 LOG.trace("Bgp Alarms task already scheduled for every minute.");
3163 private void stopBgpAlarmsTask() {
3164 final BgpAlarms bgpAlarms = bgpAlarmsReference.getAndSet(null);
3165 if (bgpAlarms != null) {
3166 bgpAlarmsTask.cancel(true);
3171 public BgpAlarms getBgpAlarms() {
3172 return bgpAlarmsReference.get();
3175 public void getPeerStatus(String nbrIp, long nbrAsNum) throws
3176 BgpRouterException, TException {
3177 bgpRouter.getPeerStatus(nbrIp, nbrAsNum);
3180 private static String appendNextHopToPrefix(String prefix, String nextHop) {
3181 return prefix + ":" + nextHop;
3184 private static String extractPrefix(String prefixNextHop) {
3185 return prefixNextHop.split(":")[0];
3188 private static String extractNextHop(String prefixNextHop) {
3189 return prefixNextHop.split(":")[1];
3192 private static String extractMd5Secret(final Neighbors val) {
3193 String md5Secret = null;
3194 TcpSecurityOption tcpSecOpt = val.getTcpSecurityOption();
3195 if (tcpSecOpt != null) {
3196 if (tcpSecOpt instanceof TcpMd5SignatureOption) {
3197 md5Secret = ((TcpMd5SignatureOption) tcpSecOpt).getTcpMd5SignaturePassword().getValue();
3198 } else { // unknown TcpSecurityOption
3199 LOG.debug("neighbors Ignored unknown tcp-security-option of peer {}", val.getAddress().getValue());
3203 } // private method extractMd5Secret