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 edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
18 import io.netty.util.concurrent.GlobalEventExecutor;
19 import java.lang.reflect.Constructor;
20 import java.lang.reflect.InvocationTargetException;
21 import java.net.InetAddress;
22 import java.net.InetSocketAddress;
23 import java.net.NetworkInterface;
24 import java.net.SocketException;
25 import java.util.ArrayList;
26 import java.util.Collection;
27 import java.util.Collections;
28 import java.util.Enumeration;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List;
33 import java.util.Objects;
34 import java.util.Timer;
35 import java.util.concurrent.Callable;
36 import java.util.concurrent.ConcurrentHashMap;
37 import java.util.concurrent.CountDownLatch;
38 import java.util.concurrent.ExecutionException;
39 import java.util.concurrent.Executors;
40 import java.util.concurrent.Future;
41 import java.util.concurrent.ScheduledExecutorService;
42 import java.util.concurrent.ScheduledFuture;
43 import java.util.concurrent.TimeUnit;
44 import java.util.concurrent.TimeoutException;
45 import java.util.concurrent.atomic.AtomicInteger;
46 import java.util.concurrent.atomic.AtomicReference;
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.eclipse.jdt.annotation.Nullable;
54 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
55 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
56 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
57 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
58 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
59 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
60 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
61 import org.opendaylight.genius.mdsalutil.NwConstants;
62 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
63 import org.opendaylight.infrautils.metrics.MetricProvider;
64 import org.opendaylight.mdsal.eos.binding.api.Entity;
65 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
66 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipListenerRegistration;
67 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
68 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
69 import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
70 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
71 import org.opendaylight.netvirt.bgpmanager.commands.ClearBgpCli;
72 import org.opendaylight.netvirt.bgpmanager.oam.BgpAlarms;
73 import org.opendaylight.netvirt.bgpmanager.oam.BgpConstants;
74 import org.opendaylight.netvirt.bgpmanager.oam.BgpCounters;
75 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouter;
76 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouterException;
77 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpSyncHandle;
78 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Routes;
79 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Update;
80 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
81 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
82 import org.opendaylight.netvirt.bgpmanager.thrift.gen.protocol_type;
83 import org.opendaylight.netvirt.bgpmanager.thrift.gen.qbgpConstants;
84 import org.opendaylight.netvirt.bgpmanager.thrift.server.BgpThriftService;
85 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
86 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.IVpnLinkService;
87 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionHistory;
88 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
89 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfig;
90 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfigBuilder;
91 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.AddressFamily;
92 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
93 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.BgpControlPlaneType;
94 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.EncapType;
95 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.TcpMd5SignaturePasswordType;
96 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsId;
97 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsIdBuilder;
98 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServer;
99 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServerBuilder;
100 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.DcgwTepList;
101 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestart;
102 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestartBuilder;
103 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Logging;
104 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.LoggingBuilder;
105 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Multipath;
106 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.MultipathBuilder;
107 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.MultipathKey;
108 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Neighbors;
109 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsBuilder;
110 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsKey;
111 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Networks;
112 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksBuilder;
113 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksKey;
114 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpath;
115 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpathBuilder;
116 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpathKey;
117 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Vrfs;
118 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsBuilder;
119 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsKey;
120 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTep;
121 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepBuilder;
122 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepKey;
123 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamilies;
124 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesBuilder;
125 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesKey;
126 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihop;
127 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihopBuilder;
128 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSource;
129 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSourceBuilder;
130 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfs.AddressFamiliesVrf;
131 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfs.AddressFamiliesVrfBuilder;
132 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.TcpSecurityOption;
133 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.tcp.security.option.TcpMd5SignatureOption;
134 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.tcp.security.option.TcpMd5SignatureOptionBuilder;
135 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
136 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
137 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.macvrfentries.MacVrfEntry;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
142 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
143 import org.opendaylight.yangtools.yang.binding.DataObject;
144 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
145 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
146 import org.opendaylight.yangtools.yang.common.Uint32;
147 import org.osgi.framework.BundleContext;
148 import org.osgi.util.tracker.ServiceTracker;
149 import org.slf4j.Logger;
150 import org.slf4j.LoggerFactory;
153 public class BgpConfigurationManager {
154 private static final Logger LOG = LoggerFactory.getLogger(BgpConfigurationManager.class);
156 // to have stale FIB map (RD, Prefix)
157 // number of seconds wait for route sync-up between ODL and BGP
158 private static final int BGP_RESTART_ROUTE_SYNC_SEC = 600;
159 private static final String UPDATE_PORT = "bgp.thrift.service.port";
160 private static final String CONFIG_HOST = "vpnservice.bgpspeaker.host.name";
161 private static final String CONFIG_PORT = "vpnservice.bgpspeaker.thrift.port";
162 private static final String DEF_UPORT = "6644";
163 private static final String DEF_CHOST = "255.255.255.255"; // Invalid Host IP
164 private static final String DEF_CPORT = "7644";
165 private static final String DEF_BGP_SDNC_MIP = "127.0.0.1";
166 //vpnservice.bgp.thrift.bgp.mip is the MIP present with ODL. Here we open 6644 port
167 private static final String BGP_SDNC_MIP = "vpnservice.bgp.thrift.bgp.mip";
168 private static final String BGP_GR_RESTART_TIMER_PROPERTY = "vpnservice.bgp.gr.timer";
169 private static final String BGP_KA_TIMER_PROPERTY = "vpnservice.bgp.ka.timer";
170 private static final String BGP_HOLD_TIMER_PROPERTY = "vpnservice.bgp.hold.timer";
171 private static final String BGP_EOR_DELAY_PROPERTY = "vpnservice.bgp.eordelay";
172 private static final int DEF_BGP_KA_TIME = 60;
173 private static final int DEF_BGP_HOLD_TIME = 180;
174 private static final int DEF_BGP_GR_TIME = 4000;
175 private static final int RESTART_DEFAULT_GR = 90;
176 private static final int DS_RETRY_COUNT = 100; //100 retries, each after WAIT_TIME_BETWEEN_EACH_TRY_MILLIS seconds
177 private static final long WAIT_TIME_BETWEEN_EACH_TRY_MILLIS = 1000L; //one second sleep after every retry
178 private static final String BGP_ENTITY_TYPE_FOR_OWNERSHIP = "bgp";
179 private static final String BGP_EOR_DELAY = "vpnservice.bgp.eordelay";
180 private static final String DEF_BGP_EOR_DELAY = "1800";
181 private static final String BGP_ENTITY_NAME = "bgp";
182 private static final String ADD_WARN = "Config store updated; undo with Delete if needed.";
183 private static final String DEL_WARN = "Config store updated; undo with Add if needed.";
184 private static final String UPD_WARN = "Update operation not supported; Config store updated;"
185 + " restore with another Update if needed.";
186 private static long bgp_as_num = 0;
187 private int bgpKaTime = 0;
188 private int bgpHoldTime = 0;
189 private int bgpGrRestartTime = 0;
191 private static final Class<?>[] REACTORS = {
192 ConfigServerReactor.class, AsIdReactor.class,
193 GracefulRestartReactor.class, LoggingReactor.class,
194 NeighborsReactor.class, UpdateSourceReactor.class,
195 EbgpMultihopReactor.class, AddressFamiliesReactor.class,
196 NetworksReactor.class, VrfsReactor.class, BgpReactor.class,
197 MultipathReactor.class, VrfMaxpathReactor.class, BfdConfigReactor.class
200 private IBgpManager bgpManager;
201 private final DataBroker dataBroker;
202 private final FibDSWriter fibDSWriter;
203 private final IVpnLinkService vpnLinkService;
204 private final BundleContext bundleContext;
205 private final BgpUtil bgpUtil;
206 private volatile Bgp config;
207 private final BgpRouter bgpRouter;
208 private final BgpSyncHandle bgpSyncHandle = new BgpSyncHandle();
209 private volatile BgpThriftService bgpThriftService = null;
210 private final int delayEorSeconds;
212 private final CountDownLatch initer = new CountDownLatch(1);
214 private final String hostStartup;
215 private final String portStartup;
217 private final AtomicReference<BgpCounters> bgpCountersReference = new AtomicReference<>();
218 private ScheduledFuture<?> bgpCountersTask;
220 private final AtomicReference<BgpAlarms> bgpAlarmsReference = new AtomicReference<>();
221 private ScheduledFuture<?> bgpAlarmsTask;
223 private Future<?> lastReplayJobFt;
224 private ScheduledFuture<?> routeCleanupFuture;
226 private long staleStartTime;
227 private long staleEndTime;
228 private long cfgReplayStartTime;
229 private long cfgReplayEndTime;
230 private long staleCleanupTime;
231 private int totalStaledCount;
232 private int totalCleared;
233 private int totalExternalRoutes;
234 private int totalExternalMacRoutes;
236 private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(
237 new ThreadFactoryBuilder().setNameFormat("BgpConfigurationManager-%d").setDaemon(true).build());
240 * this map store the new address families to send to quagga. When it is sended you must clear it.
241 * The keys String are rd (route distinguisher).
243 private final ConcurrentHashMap<String, List<AddressFamiliesVrf>> mapNewAdFamily = new ConcurrentHashMap<>();
245 // map<rd, map<prefix/len:nexthop, label>>
246 private final Map<String, Map<String, Uint32>> staledFibEntriesMap = new ConcurrentHashMap<>();
248 // map<rd, map<tep-ip, map<mac, l2vni>>>
249 private final Map<String, Map<String, Map<String, Uint32>>> rt2TepMap = new ConcurrentHashMap<>();
251 private final List<AutoCloseable> listeners = new ArrayList<>();
253 private final EntityOwnershipUtils entityOwnershipUtils;
254 private final EntityOwnershipCandidateRegistration candidateRegistration;
255 private final EntityOwnershipListenerRegistration entityListenerRegistration;
256 private final MetricProvider metricProvider;
257 private final TransactionHistory bgpUpdatesHistory;
260 public BgpConfigurationManager(final DataBroker dataBroker,
261 final EntityOwnershipService entityOwnershipService,
262 final FibDSWriter fibDSWriter,
263 final IVpnLinkService vpnLinkSrvce,
264 final BundleContext bundleContext,
265 final BgpUtil bgpUtil,
266 final MetricProvider metricProvider) {
267 this.dataBroker = dataBroker;
268 this.fibDSWriter = fibDSWriter;
269 this.vpnLinkService = vpnLinkSrvce;
270 this.bundleContext = bundleContext;
271 this.bgpUtil = bgpUtil;
272 this.metricProvider = metricProvider;
273 hostStartup = getProperty(CONFIG_HOST, DEF_CHOST);
274 portStartup = getProperty(CONFIG_PORT, DEF_CPORT);
276 Integer.parseInt(getProperty(BGP_KA_TIMER_PROPERTY,
277 Integer.toString(DEF_BGP_KA_TIME)));
279 Integer.parseInt(getProperty(BGP_HOLD_TIMER_PROPERTY,
280 Integer.toString(DEF_BGP_HOLD_TIME)));
282 Integer.parseInt(getProperty(BGP_GR_RESTART_TIMER_PROPERTY,
283 Integer.toString(DEF_BGP_GR_TIME)));
284 LOG.info("ConfigServer at {}:{}", hostStartup, portStartup);
285 VtyshCli.setHostAddr(hostStartup);
286 ClearBgpCli.setHostAddr(hostStartup);
287 bgpUpdatesHistory = new TransactionHistory(HISTORY_LIMIT, HISTORY_THRESHOLD);
288 bgpRouter = BgpRouter.newInstance(this::getConfig, this::isBGPEntityOwner, bgpUpdatesHistory);
289 delayEorSeconds = Integer.parseInt(getProperty(BGP_EOR_DELAY, DEF_BGP_EOR_DELAY));
291 entityOwnershipUtils = new EntityOwnershipUtils(entityOwnershipService);
293 candidateRegistration = registerEntityCandidate(entityOwnershipService);
294 entityListenerRegistration = registerEntityListener(entityOwnershipService);
296 LOG.info("BGP Configuration manager initialized");
299 GlobalEventExecutor.INSTANCE.execute(() -> {
300 ServiceTracker<IBgpManager, ?> tracker = null;
302 tracker = new ServiceTracker<>(bundleContext, IBgpManager.class, null);
304 bgpManager = (IBgpManager) tracker.waitForService(TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES));
305 Preconditions.checkState(bgpManager != null, "IBgpManager service not found");
306 } catch (InterruptedException e) {
307 throw new IllegalStateException("Error retrieving IBgpManager service", e);
309 if (tracker != null) {
314 String updatePort = getProperty(UPDATE_PORT, DEF_UPORT);
315 if (InetAddresses.isInetAddress(getBgpSdncMipIp())) {
316 InetSocketAddress bgpThriftServerSocketAddr = new InetSocketAddress(getBgpSdncMipIp(),
317 Integer.parseInt(updatePort));
318 bgpThriftService = new BgpThriftService(bgpThriftServerSocketAddr, bgpManager, this);
319 if (isBGPEntityOwner()) {
320 //I am EoS owner of BGP, opening bgp thrift UPDATE-SERVER port.
321 LOG.info("BGP Configuration manager initialized: UPDATE-SERVER started");
322 bgpThriftService.start();
324 LOG.info("UPDATE server started :ip:port={}:{}", getBgpSdncMipIp(), updatePort);
326 LOG.error("Failed to init UPDATE server invalid ip:port={}:{}", getBgpSdncMipIp(), updatePort);
330 LOG.info("BgpConfigurationManager initialized. IBgpManager={}", bgpManager);
333 public String getBgpSdncMipIp() {
334 return getProperty(BGP_SDNC_MIP, DEF_BGP_SDNC_MIP);
337 public long getStaleCleanupTime() {
338 return staleCleanupTime;
341 public void setStaleCleanupTime(long staleCleanupTime) {
342 this.staleCleanupTime = staleCleanupTime;
345 public long getCfgReplayEndTime() {
346 return cfgReplayEndTime;
349 public void setCfgReplayEndTime(long cfgReplayEndTime) {
350 this.cfgReplayEndTime = cfgReplayEndTime;
353 public TransactionHistory getBgpUpdatesHistory() {
354 return bgpUpdatesHistory;
357 public long getCfgReplayStartTime() {
358 return cfgReplayStartTime;
361 public void setCfgReplayStartTime(long cfgReplayStartTime) {
362 this.cfgReplayStartTime = cfgReplayStartTime;
365 public long getStaleEndTime() {
369 public void setStaleEndTime(long staleEndTime) {
370 this.staleEndTime = staleEndTime;
373 public long getStaleStartTime() {
374 return staleStartTime;
377 public void setStaleStartTime(long staleStartTime) {
378 this.staleStartTime = staleStartTime;
381 private Object createListener(Class<?> cls) {
383 Constructor<?> ctor = cls.getConstructor(BgpConfigurationManager.class);
384 return ctor.newInstance(this);
385 } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException
387 LOG.error("Failed to create listener object", e);
392 private void registerCallbacks() {
393 for (Class<?> reactor : REACTORS) {
394 Object obj = createListener(reactor);
396 AsyncDataTreeChangeListenerBase dcl = (AsyncDataTreeChangeListenerBase) obj;
397 dcl.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
403 @SuppressWarnings("checkstyle:IllegalCatch")
405 public void close() {
408 if (bgpThriftService != null) {
409 bgpThriftService.stop();
410 bgpThriftService = null;
413 if (isBgpConnected()) {
414 //disconnect the CONFIG SERVER port (which was )opened during I was Owner
415 bgpRouter.disconnect();
418 if (candidateRegistration != null) {
419 candidateRegistration.close();
422 entityListenerRegistration.close();
424 listeners.forEach(l -> {
427 } catch (Exception e) {
428 LOG.warn("Error closing {}", l ,e);
432 LOG.info("{} close", getClass().getSimpleName());
435 private String getProperty(String var, String def) {
436 String property = bundleContext.getProperty(var);
437 return property == null ? def : property;
440 private EntityOwnershipCandidateRegistration registerEntityCandidate(
441 final EntityOwnershipService entityOwnershipService) {
443 return entityOwnershipService.registerCandidate(
444 new Entity(BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME));
445 } catch (CandidateAlreadyRegisteredException e) {
446 LOG.error("failed to register bgp entity", e);
451 private EntityOwnershipListenerRegistration registerEntityListener(
452 final EntityOwnershipService entityOwnershipService) {
453 return entityOwnershipService.registerListener(BGP_ENTITY_TYPE_FOR_OWNERSHIP, ownershipChange -> {
454 LOG.info("entity owner change event fired: {}", ownershipChange);
456 if (ownershipChange.getState() == EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED) {
457 LOG.info("This PL is the Owner");
458 if (bgpThriftService != null) {
459 //opening UPDATE-SERVER port.
460 bgpThriftService.start();
462 LOG.error("I am the owner of BGP entity, but bgpThriftService is not initialized yet");
466 LOG.info("Not owner: hasOwner: {}, isOwner: {}", ownershipChange.getState().hasOwner(),
467 ownershipChange.getState().isOwner());
468 if (bgpThriftService != null && bgpThriftService.isBgpThriftServiceStarted()) {
469 //close the bgp Thrift Update-SERVER port opened on non-Entity Owner
470 bgpThriftService.stop();
472 if (isBgpConnected()) {
473 //disconnect the CONFIG SERVER port (which was )opened during I was Owner
474 bgpRouter.disconnect();
480 public boolean isBGPEntityOwner() {
481 if (entityOwnershipUtils == null) {
482 LOG.error("entityOwnershipUtils is NULL when listener callbacks fired");
485 return entityOwnershipUtils.isEntityOwner(new Entity(BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME), 0, 1);
489 config = getConfig();
493 public class ConfigServerReactor
494 extends AsyncDataTreeChangeListenerBase<ConfigServer, ConfigServerReactor>
495 implements ClusteredDataTreeChangeListener<ConfigServer> {
496 private static final String YANG_OBJ = "config-server ";
498 public ConfigServerReactor() {
499 super(ConfigServer.class, ConfigServerReactor.class);
503 protected void add(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
504 LOG.trace("received bgp connect config host {}", val.getHost().getValue());
505 if (!isBGPEntityOwner()) {
511 } catch (InterruptedException e) {
514 LOG.debug("issueing bgp router connect to host {}", val.getHost().getValue());
515 bgpRouter.configServerUpdated();
516 synchronized (BgpConfigurationManager.this) {
517 boolean res = bgpRouter.connect(val.getHost().getValue(),
518 val.getPort().intValue());
520 LOG.error(YANG_OBJ + "Add failed; " + ADD_WARN);
523 VtyshCli.setHostAddr(val.getHost().getValue());
524 ClearBgpCli.setHostAddr(val.getHost().getValue());
528 protected ConfigServerReactor getDataTreeChangeListener() {
529 return ConfigServerReactor.this;
533 protected InstanceIdentifier<ConfigServer> getWildCardPath() {
534 return InstanceIdentifier.create(Bgp.class).child(ConfigServer.class);
538 protected void remove(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
539 LOG.trace("received bgp disconnect");
540 if (!isBGPEntityOwner()) {
544 bgpRouter.configServerUpdated();
546 synchronized (BgpConfigurationManager.this) {
547 if (bgp_as_num != 0) {
549 bgpRouter.stopBgp(bgp_as_num);
550 stopBgpCountersTask();
552 } catch (TException | BgpRouterException e) {
553 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
556 LOG.debug("bgp as-id is null while removing config-server");
558 bgpRouter.disconnect();
563 protected void update(InstanceIdentifier<ConfigServer> iid,
564 ConfigServer oldval, ConfigServer newval) {
565 LOG.trace("received bgp Connection update");
566 if (!isBGPEntityOwner()) {
569 LOG.error(YANG_OBJ + UPD_WARN);
573 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
574 justification = "https://github.com/spotbugs/spotbugs/issues/811")
575 private BgpRouter getClient(String yangObj) {
576 if (bgpRouter == null || !bgpRouter.isBgpConnected()) {
577 LOG.warn("{}: configuration received when BGP is inactive", yangObj);
583 public class AsIdReactor
584 extends AsyncDataTreeChangeListenerBase<AsId, AsIdReactor>
585 implements ClusteredDataTreeChangeListener<AsId> {
587 private static final String YANG_OBJ = "as-id ";
589 public AsIdReactor() {
590 super(AsId.class, AsIdReactor.class);
594 protected void add(InstanceIdentifier<AsId> iid, AsId val) {
595 LOG.error("received bgp add asid {}", val);
596 if (!isBGPEntityOwner()) {
599 LOG.debug("received add router config asNum {}", val.getLocalAs());
600 bgp_as_num = val.getLocalAs().longValue();
601 synchronized (BgpConfigurationManager.this) {
602 BgpRouter br = getClient(YANG_OBJ);
604 LOG.debug("{} Unable to process add for asNum {}; {} {}", YANG_OBJ, val.getLocalAs(),
605 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
610 startBgpCountersTask();
611 startBgpAlarmsTask();
616 protected AsIdReactor getDataTreeChangeListener() {
617 return AsIdReactor.this;
621 protected InstanceIdentifier<AsId> getWildCardPath() {
622 return InstanceIdentifier.create(Bgp.class).child(AsId.class);
626 protected void remove(InstanceIdentifier<AsId> iid, AsId val) {
627 LOG.error("received delete router config asNum {}", val.getLocalAs());
628 if (!isBGPEntityOwner()) {
631 synchronized (BgpConfigurationManager.this) {
632 long asNum = val.getLocalAs().toJava();
633 BgpRouter br = getClient(YANG_OBJ);
636 LOG.debug("{} Unable to process remove for asNum {}; {} {}", YANG_OBJ, asNum,
637 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
642 } catch (TException | BgpRouterException e) {
643 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
646 stopBgpCountersTask();
649 Bgp conf = getConfig();
651 LOG.error("Config Null while removing the as-id");
654 LOG.debug("Removing external routes from FIB");
655 deleteExternalFibRoutes();
656 List<Neighbors> nbrs = conf.getNeighbors();
657 if (nbrs != null && nbrs.size() > 0) {
658 LOG.error("Tring to remove the as-id when neighbor config is already present");
659 for (Neighbors nbr : nbrs) {
660 LOG.debug("Removing Neighbor {} from Data store", nbr.getAddress().getValue());
661 delNeighbor(nbr.getAddress().getValue());
668 protected void update(InstanceIdentifier<AsId> iid,
669 AsId oldval, AsId newval) {
670 if (!isBGPEntityOwner()) {
673 LOG.error(YANG_OBJ + UPD_WARN);
677 public class GracefulRestartReactor
678 extends AsyncDataTreeChangeListenerBase<GracefulRestart, GracefulRestartReactor>
679 implements ClusteredDataTreeChangeListener<GracefulRestart> {
681 private static final String YANG_OBJ = "graceful-restart ";
683 public GracefulRestartReactor() {
684 super(GracefulRestart.class, GracefulRestartReactor.class);
688 protected void add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
689 if (!isBGPEntityOwner()) {
692 synchronized (BgpConfigurationManager.this) {
693 int stalePathTime = val.getStalepathTime().intValue();
694 BgpRouter br = getClient(YANG_OBJ);
696 LOG.error("{} Unable to add stale-path time {}; {} {}", YANG_OBJ, stalePathTime,
697 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
701 br.addGracefulRestart(stalePathTime);
702 } catch (TException | BgpRouterException e) {
703 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
709 protected GracefulRestartReactor getDataTreeChangeListener() {
710 return GracefulRestartReactor.this;
714 protected InstanceIdentifier<GracefulRestart> getWildCardPath() {
715 return InstanceIdentifier.create(Bgp.class).child(GracefulRestart.class);
719 protected void remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
720 if (!isBGPEntityOwner()) {
723 LOG.debug("received delete GracefulRestart config val {}", val.getStalepathTime().intValue());
724 synchronized (BgpConfigurationManager.this) {
725 BgpRouter br = getClient(YANG_OBJ);
727 LOG.error("{} Unable to delete stale-path time; {} {}", YANG_OBJ,
728 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
732 br.delGracefulRestart();
733 } catch (TException | BgpRouterException e) {
734 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
740 protected void update(InstanceIdentifier<GracefulRestart> iid,
741 GracefulRestart oldval, GracefulRestart newval) {
742 if (!isBGPEntityOwner()) {
745 LOG.debug("received update GracefulRestart config val {}", newval.getStalepathTime().intValue());
746 synchronized (BgpConfigurationManager.this) {
747 int stalePathTime = newval.getStalepathTime().intValue();
748 BgpRouter br = getClient(YANG_OBJ);
750 LOG.error("{} Unable to update stale-path time to {}; {} {}", YANG_OBJ, stalePathTime,
751 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
755 br.addGracefulRestart(stalePathTime);
756 } catch (TException | BgpRouterException e) {
757 LOG.error("{} update received exception; {}", YANG_OBJ, ADD_WARN, e);
763 public class LoggingReactor
764 extends AsyncDataTreeChangeListenerBase<Logging, LoggingReactor>
765 implements ClusteredDataTreeChangeListener<Logging> {
767 private static final String YANG_OBJ = "logging ";
769 public LoggingReactor() {
770 super(Logging.class, LoggingReactor.class);
774 protected void add(InstanceIdentifier<Logging> iid, Logging val) {
775 if (!isBGPEntityOwner()) {
778 synchronized (BgpConfigurationManager.this) {
779 BgpRouter br = getClient(YANG_OBJ);
781 LOG.error("{} Unable to add logging for qbgp; {} {}", YANG_OBJ,
782 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
786 br.setLogging(val.getFile(), val.getLevel());
787 } catch (TException | BgpRouterException e) {
788 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
794 protected LoggingReactor getDataTreeChangeListener() {
795 return LoggingReactor.this;
799 protected InstanceIdentifier<Logging> getWildCardPath() {
800 return InstanceIdentifier.create(Bgp.class).child(Logging.class);
804 protected void remove(InstanceIdentifier<Logging> iid, Logging val) {
805 if (!isBGPEntityOwner()) {
808 LOG.debug("received remove Logging config val {}", val.getLevel());
809 synchronized (BgpConfigurationManager.this) {
810 BgpRouter br = getClient(YANG_OBJ);
812 LOG.error("{} Unable to remove logging for qbgp; {} {}", YANG_OBJ,
813 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
817 br.setLogging(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
818 } catch (TException | BgpRouterException e) {
819 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
825 protected void update(InstanceIdentifier<Logging> iid,
826 Logging oldval, Logging newval) {
827 if (!isBGPEntityOwner()) {
830 synchronized (BgpConfigurationManager.this) {
831 BgpRouter br = getClient(YANG_OBJ);
833 LOG.error("{} Unable to update logging for qbgp; {} {}", YANG_OBJ,
834 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
838 br.setLogging(newval.getFile(), newval.getLevel());
839 } catch (TException | BgpRouterException e) {
840 LOG.error("{} newval received exception; {}", YANG_OBJ, ADD_WARN, e);
846 public class NeighborsReactor
847 extends AsyncDataTreeChangeListenerBase<Neighbors, NeighborsReactor>
848 implements ClusteredDataTreeChangeListener<Neighbors> {
850 private static final String YANG_OBJ = "neighbors ";
852 public NeighborsReactor() {
853 super(Neighbors.class, NeighborsReactor.class);
857 protected void add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
858 if (!isBGPEntityOwner()) {
861 LOG.debug("received add Neighbors config val {}", val.getAddress().getValue());
862 synchronized (BgpConfigurationManager.this) {
863 String peerIp = val.getAddress().getValue();
864 long as = val.getRemoteAs().toJava();
865 final String md5Secret = extractMd5Secret(val);
866 BgpRouter br = getClient(YANG_OBJ);
868 LOG.debug("{} Unable to process add for peer {} as {}; {} {}", YANG_OBJ, peerIp, as,
869 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
873 //itmProvider.buildTunnelsToDCGW(new IpAddress(peerIp.toCharArray()));
874 br.addNeighbor(peerIp, as, md5Secret);
876 } catch (TException | BgpRouterException e) {
877 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
883 protected NeighborsReactor getDataTreeChangeListener() {
884 return NeighborsReactor.this;
888 protected InstanceIdentifier<Neighbors> getWildCardPath() {
889 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class);
893 protected void remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
894 if (!isBGPEntityOwner()) {
897 LOG.debug("received remove Neighbors config val {}", val.getAddress().getValue());
898 synchronized (BgpConfigurationManager.this) {
899 String peerIp = val.getAddress().getValue();
900 BgpRouter br = getClient(YANG_OBJ);
902 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
903 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
907 //itmProvider.deleteTunnelsToDCGW(new IpAddress(val.getAddress().getValue().toCharArray()));
908 br.delNeighbor(peerIp);
909 } catch (TException | BgpRouterException e) {
910 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
913 final BgpAlarms bgpAlarms = getBgpAlarms();
914 if (bgpAlarms != null) {
915 bgpAlarms.clearBgpNbrDownAlarm(peerIp);
918 if (bgpUtil.isBfdEnabled()) {
919 final BgpCounters bgpCounters = getBgpCounters();
920 if (bgpCounters != null) {
921 bgpCounters.clearBfdNbrCounters(peerIp);
928 protected void update(InstanceIdentifier<Neighbors> iid,
929 Neighbors oldval, Neighbors newval) {
930 if (!isBGPEntityOwner()) {
933 //purposefully nothing to do.
937 public class EbgpMultihopReactor
938 extends AsyncDataTreeChangeListenerBase<EbgpMultihop, EbgpMultihopReactor>
939 implements ClusteredDataTreeChangeListener<EbgpMultihop> {
941 private static final String YANG_OBJ = "ebgp-multihop ";
943 public EbgpMultihopReactor() {
944 super(EbgpMultihop.class, EbgpMultihopReactor.class);
948 protected void add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
949 if (!isBGPEntityOwner()) {
952 LOG.debug("received add EbgpMultihop config val {}", val.getPeerIp().getValue());
953 synchronized (BgpConfigurationManager.this) {
954 String peerIp = val.getPeerIp().getValue();
955 BgpRouter br = getClient(YANG_OBJ);
957 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
958 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
962 br.addEbgpMultihop(peerIp, val.getNhops().intValue());
963 } catch (TException | BgpRouterException e) {
964 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
970 protected EbgpMultihopReactor getDataTreeChangeListener() {
971 return EbgpMultihopReactor.this;
975 protected InstanceIdentifier<EbgpMultihop> getWildCardPath() {
976 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(EbgpMultihop.class);
980 protected void remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
981 if (!isBGPEntityOwner()) {
984 LOG.debug("received remove EbgpMultihop config val {}", val.getPeerIp().getValue());
985 synchronized (BgpConfigurationManager.this) {
986 String peerIp = val.getPeerIp().getValue();
987 BgpRouter br = getClient(YANG_OBJ);
989 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
990 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
994 br.delEbgpMultihop(peerIp);
995 } catch (TException | BgpRouterException e) {
996 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1002 protected void update(InstanceIdentifier<EbgpMultihop> iid,
1003 EbgpMultihop oldval, EbgpMultihop newval) {
1004 if (!isBGPEntityOwner()) {
1007 LOG.error(YANG_OBJ + UPD_WARN);
1011 public class UpdateSourceReactor
1012 extends AsyncDataTreeChangeListenerBase<UpdateSource, UpdateSourceReactor>
1013 implements ClusteredDataTreeChangeListener<UpdateSource> {
1015 private static final String YANG_OBJ = "update-source ";
1017 public UpdateSourceReactor() {
1018 super(UpdateSource.class, UpdateSourceReactor.class);
1022 protected void add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
1023 if (!isBGPEntityOwner()) {
1026 LOG.debug("received add UpdateSource config val {}", val.getSourceIp().getValue());
1027 synchronized (BgpConfigurationManager.this) {
1028 String peerIp = val.getPeerIp().getValue();
1029 BgpRouter br = getClient(YANG_OBJ);
1031 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
1032 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1036 br.addUpdateSource(peerIp, val.getSourceIp().getValue());
1037 } catch (TException | BgpRouterException e) {
1038 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1044 protected UpdateSourceReactor getDataTreeChangeListener() {
1045 return UpdateSourceReactor.this;
1049 protected InstanceIdentifier<UpdateSource> getWildCardPath() {
1050 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(UpdateSource.class);
1054 protected void remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
1055 if (!isBGPEntityOwner()) {
1058 LOG.debug("received remove UpdateSource config val {}", val.getSourceIp().getValue());
1059 synchronized (BgpConfigurationManager.this) {
1060 String peerIp = val.getPeerIp().getValue();
1061 BgpRouter br = getClient(YANG_OBJ);
1063 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
1064 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1068 br.delUpdateSource(peerIp);
1069 } catch (TException | BgpRouterException e) {
1070 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1076 protected void update(InstanceIdentifier<UpdateSource> iid,
1077 UpdateSource oldval, UpdateSource newval) {
1078 if (!isBGPEntityOwner()) {
1081 LOG.error(YANG_OBJ + UPD_WARN);
1085 public class AddressFamiliesReactor
1086 extends AsyncDataTreeChangeListenerBase<AddressFamilies, AddressFamiliesReactor>
1087 implements ClusteredDataTreeChangeListener<AddressFamilies> {
1089 private static final String YANG_OBJ = "address-families ";
1091 public AddressFamiliesReactor() {
1092 super(AddressFamilies.class, AddressFamiliesReactor.class);
1096 protected void add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
1097 if (!isBGPEntityOwner()) {
1100 LOG.debug("received add AddressFamilies config val {}", val.getPeerIp().getValue());
1101 synchronized (BgpConfigurationManager.this) {
1102 String peerIp = val.getPeerIp().getValue();
1103 BgpRouter br = getClient(YANG_OBJ);
1105 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
1106 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1109 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
1110 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
1112 br.addAddressFamily(peerIp, afi, safi);
1113 } catch (TException | BgpRouterException e) {
1114 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1120 protected AddressFamiliesReactor getDataTreeChangeListener() {
1121 return AddressFamiliesReactor.this;
1125 protected InstanceIdentifier<AddressFamilies> getWildCardPath() {
1126 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(AddressFamilies.class);
1130 protected void remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
1131 if (!isBGPEntityOwner()) {
1134 LOG.debug("received remove AddressFamilies config val {}", val.getPeerIp().getValue());
1135 synchronized (BgpConfigurationManager.this) {
1136 String peerIp = val.getPeerIp().getValue();
1137 BgpRouter br = getClient(YANG_OBJ);
1139 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
1140 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1143 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
1144 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
1146 br.delAddressFamily(peerIp, afi, safi);
1147 } catch (TException | BgpRouterException e) {
1148 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1154 protected void update(InstanceIdentifier<AddressFamilies> iid,
1155 AddressFamilies oldval, AddressFamilies newval) {
1156 if (!isBGPEntityOwner()) {
1159 LOG.error(YANG_OBJ + UPD_WARN);
1163 public class NetworksReactor
1164 extends AsyncDataTreeChangeListenerBase<Networks, NetworksReactor>
1165 implements ClusteredDataTreeChangeListener<Networks> {
1167 private static final String YANG_OBJ = "networks ";
1169 public NetworksReactor() {
1170 super(Networks.class, NetworksReactor.class);
1174 public NetworksReactor getDataTreeChangeListener() {
1175 return NetworksReactor.this;
1179 protected void add(InstanceIdentifier<Networks> iid, Networks val) {
1180 if (!isBGPEntityOwner()) {
1183 LOG.debug("received add Networks config val {}", val.getPrefixLen());
1184 synchronized (BgpConfigurationManager.this) {
1185 String rd = val.getRd();
1186 String pfxlen = val.getPrefixLen();
1187 String nh = val.getNexthop().getValue();
1188 BgpRouter br = getClient(YANG_OBJ);
1190 LOG.debug("{} Unable to process add for rd {} prefix {} nexthop {}; {} {}", YANG_OBJ, rd, pfxlen,
1191 nh, BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1194 Long label = val.getLabel().toJava();
1195 int lbl = label == null ? qbgpConstants.LBL_NO_LABEL
1197 int l3vni = val.getL3vni() == null ? qbgpConstants.LBL_NO_LABEL
1198 : val.getL3vni().intValue();
1199 int l2vni = val.getL2vni() == null ? qbgpConstants.LBL_NO_LABEL
1200 : val.getL2vni().intValue();
1202 BgpControlPlaneType protocolType = val.getBgpControlPlaneType();
1203 int ethernetTag = val.getEthtag().intValue();
1204 String esi = val.getEsi();
1205 String macaddress = val.getMacaddress();
1206 EncapType encapType = val.getEncapType();
1207 String routerMac = val.getRoutermac();
1210 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, l2vni, BgpUtil.convertToThriftProtocolType(protocolType),
1211 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
1212 } catch (TException | BgpRouterException e) {
1213 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1219 protected InstanceIdentifier<Networks> getWildCardPath() {
1220 return InstanceIdentifier.create(Bgp.class).child(Networks.class);
1224 protected void remove(InstanceIdentifier<Networks> iid, Networks val) {
1225 if (!isBGPEntityOwner()) {
1228 LOG.debug("received remove Networks config val {}", val.getPrefixLen());
1229 synchronized (BgpConfigurationManager.this) {
1230 String rd = val.getRd();
1231 String pfxlen = val.getPrefixLen();
1232 BgpRouter br = getClient(YANG_OBJ);
1234 LOG.debug("{} Unable to process remove for rd {} prefix {}; {} {}", YANG_OBJ, rd, pfxlen,
1235 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1238 Long label = val.getLabel().toJava();
1239 int lbl = label == null ? 0 : label.intValue();
1240 if (rd == null && lbl > 0) {
1241 //LU prefix is being deleted.
1242 rd = Integer.toString(lbl);
1245 br.delPrefix(rd, pfxlen);
1246 } catch (TException | BgpRouterException e) {
1247 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1252 /**get the value AFI from a prefix as "x.x.x.x/x".
1254 * @param pfxlen the prefix to get an afi
1255 * @return the afi value as you are need
1257 public int testValueAFI(String pfxlen) {
1258 int afiNew = af_afi.AFI_IP.getValue();
1260 String ipOnly = pfxlen.substring(0, pfxlen.lastIndexOf("/"));
1261 java.net.Inet6Address.getByName(ipOnly);
1262 afiNew = af_afi.AFI_IPV6.getValue();
1263 } catch (java.net.UnknownHostException e) {
1264 //ce n'est pas de l'ipv6
1271 protected void update(final InstanceIdentifier<Networks> iid,
1272 final Networks oldval, final Networks newval) {
1273 if (!isBGPEntityOwner()) {
1276 if (oldval.equals(newval)) {
1277 //Update: OLD and New values are same, no need to trigger remove/add.
1278 LOG.debug("received Updated for the same OLD and New values. RD: {}, Prefix: {}, Label: {}, NH: {}",
1279 oldval.getRd(), oldval.getPrefixLen(), oldval.getLabel(), oldval.getNexthop());
1282 LOG.debug("update networks old val RD: {}, Prefix: {}, Label: {}, NH: {} "
1283 + "new val RD: {}, Prefix: {}, Label: {}, NH: {}",
1284 oldval.getRd(), oldval.getPrefixLen(), oldval.getLabel(), oldval.getNexthop(),
1285 newval.getRd(), newval.getPrefixLen(), newval.getLabel(), newval.getNexthop());
1286 remove(iid, oldval);
1291 static Timer timer = new Timer();
1293 public class VrfsReactor
1294 extends AsyncDataTreeChangeListenerBase<Vrfs, VrfsReactor>
1295 implements ClusteredDataTreeChangeListener<Vrfs> {
1297 private static final String YANG_OBJ = "vrfs ";
1299 public VrfsReactor() {
1300 super(Vrfs.class, VrfsReactor.class);
1304 protected void add(InstanceIdentifier<Vrfs> iid, Vrfs vrfs) {
1305 if (!isBGPEntityOwner()) {
1308 LOG.debug("received add Vrfs config value {}", vrfs.getRd());
1309 synchronized (BgpConfigurationManager.this) {
1310 String rd = vrfs.getRd();
1311 BgpRouter br = getClient(YANG_OBJ);
1313 LOG.debug("{} Unable to process add for rd {}; {} {}", YANG_OBJ, rd,
1314 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1318 List<AddressFamiliesVrf> vrfAddrFamilyList = vrfs.getAddressFamiliesVrf();
1319 for (AddressFamiliesVrf vrfAddrFamily : vrfAddrFamilyList) {
1320 /*add to br the new vrfs arguments*/
1321 br.addVrf(BgpUtil.getLayerType(vrfAddrFamily), rd, vrfs.getImportRts(),
1322 vrfs.getExportRts(), vrfAddrFamily.getAfi().toJava(), vrfAddrFamily.getSafi().toJava());
1324 /*add to br the vrfs contained in mapNewAdFamily*/
1325 List<AddressFamiliesVrf> vrfAddrFamilyListFromMap = mapNewAdFamily.get(rd);
1326 if (vrfAddrFamilyListFromMap == null) {
1330 for (AddressFamiliesVrf adf : vrfAddrFamilyListFromMap) {
1331 if (vrfAddrFamilyList.contains(adf)) {
1332 mapNewAdFamily.remove(rd);
1333 } else if (adf != null) {
1335 br.addVrf(BgpUtil.getLayerType(adf), rd, vrfs.getImportRts(),
1336 vrfs.getExportRts(), adf.getAfi().toJava(), adf.getSafi().toJava());
1337 // remove AddressFamiliesVrf which was already added to BGP
1338 vrfAddrFamilyListFromMap.remove(adf);
1339 if (vrfAddrFamilyListFromMap.isEmpty()) {
1340 // remove Vrf entry from temp mapNewAdFamily if all its AddressFamiliesVrf was
1342 mapNewAdFamily.remove(rd);
1346 } catch (TException | BgpRouterException e) {
1347 LOG.error("{} get {}, Add received exception", YANG_OBJ, ADD_WARN, e);
1353 protected VrfsReactor getDataTreeChangeListener() {
1354 return VrfsReactor.this;
1358 protected InstanceIdentifier<Vrfs> getWildCardPath() {
1359 return InstanceIdentifier.create(Bgp.class).child(Vrfs.class);
1363 protected void remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
1364 if (!isBGPEntityOwner()) {
1367 LOG.debug("received remove Vrfs config val {}", val.getRd());
1368 synchronized (BgpConfigurationManager.this) {
1369 String rd = val.getRd();
1370 BgpRouter br = getClient(YANG_OBJ);
1372 LOG.debug("{} Unable to process remove for rd {}; {} {}", YANG_OBJ, rd,
1373 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1377 List<AddressFamiliesVrf> adf = mapNewAdFamily.get(rd);
1378 adf = adf != null ? adf : new ArrayList<>();
1379 for (AddressFamiliesVrf s : val.getAddressFamiliesVrf()) {
1380 br.delVrf(rd, s.getAfi().toJava(), s.getSafi().toJava());
1381 adf.remove(s);// remove in the map the vrf in waiting for advertise quagga
1383 if (adf.isEmpty()) {
1384 mapNewAdFamily.remove(rd);
1386 } catch (TException | BgpRouterException e) {
1387 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1393 protected void update(InstanceIdentifier<Vrfs> iid,
1394 Vrfs oldval, Vrfs newval) {
1395 if (oldval != null && newval != null) {
1396 LOG.debug("received update Vrfs config val {}, VRFS: Update getting triggered for VRFS rd {}",
1397 newval.getRd(), oldval.getRd());
1399 LOG.debug("received update Vrfs config val {}, from old vrf {}",
1402 if (!isBGPEntityOwner()) {
1406 List<AddressFamiliesVrf> adFamilyVrfToDel = new ArrayList<>();
1407 List<AddressFamiliesVrf> adFamilyVrfToAdd = new ArrayList<>();
1408 List<AddressFamiliesVrf> oldlistAdFamilies = new ArrayList<>();
1409 List<AddressFamiliesVrf> newlistAdFamilies = new ArrayList<>();
1410 if (oldval != null) {
1411 oldlistAdFamilies = oldval.getAddressFamiliesVrf() == null
1412 ? new ArrayList<>() : oldval.getAddressFamiliesVrf();
1414 if (newval != null) {
1415 newlistAdFamilies = newval.getAddressFamiliesVrf() == null
1416 ? new ArrayList<>() : newval.getAddressFamiliesVrf();
1418 /*find old AddressFamily to remove from new configuration*/
1419 for (AddressFamiliesVrf adVrf : oldlistAdFamilies) {
1420 if (!newlistAdFamilies.contains(adVrf)) {
1421 adFamilyVrfToDel.add(adVrf);
1424 /*find new AddressFamily to add to unexisting configuration*/
1425 for (AddressFamiliesVrf adVrf : newlistAdFamilies) {
1426 if (!oldlistAdFamilies.contains(adVrf)) {
1427 adFamilyVrfToAdd.add(adVrf);
1430 String rd = newval != null ? newval.getRd() : null;
1432 BgpRouter br = getClient(YANG_OBJ);
1434 LOG.debug("{} Unable to process add for rd {}; {} {}", YANG_OBJ, rd,
1435 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1439 for (AddressFamiliesVrf adfvrf : adFamilyVrfToAdd) {
1441 LOG.debug("call addVRf rd {} afi {} safi {}", rd, adfvrf.getAfi(), adfvrf.getSafi());
1442 br.addVrf(BgpUtil.getLayerType(adfvrf), rd, newval.getImportRts(),
1443 newval.getExportRts(),adfvrf.getAfi().toJava(), adfvrf.getSafi().toJava());
1444 } catch (TException | BgpRouterException e) {
1445 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1449 for (AddressFamiliesVrf adfToDel : adFamilyVrfToDel) {
1451 LOG.debug("call delVRf rd {} afi {} safi {}", rd, adfToDel.getAfi(), adfToDel.getSafi());
1452 br.delVrf(rd, adfToDel.getAfi().toJava(), adfToDel.getSafi().toJava());
1453 } catch (TException | BgpRouterException e) {
1454 LOG.error("{} delVrf received exception; {}", YANG_OBJ, ADD_WARN, e);
1461 public class BgpReactor
1462 extends AsyncDataTreeChangeListenerBase<Bgp, BgpReactor>
1463 implements ClusteredDataTreeChangeListener<Bgp> {
1465 private static final String YANG_OBJ = "Bgp ";
1467 public BgpReactor() {
1468 super(Bgp.class, BgpReactor.class);
1473 protected void add(InstanceIdentifier<Bgp> iid, Bgp val) {
1474 LOG.debug("received add Bgp config");
1478 } catch (InterruptedException e) {
1481 synchronized (BgpConfigurationManager.this) {
1483 if (!isBGPEntityOwner()) {
1490 protected BgpReactor getDataTreeChangeListener() {
1491 return BgpReactor.this;
1495 protected InstanceIdentifier<Bgp> getWildCardPath() {
1496 return InstanceIdentifier.create(Bgp.class);
1500 protected void remove(InstanceIdentifier<Bgp> iid, Bgp val) {
1501 if (!isBGPEntityOwner()) {
1504 LOG.debug("received remove Bgp config");
1510 protected void update(InstanceIdentifier<Bgp> iid,
1511 Bgp oldval, Bgp newval) {
1512 if (!isBGPEntityOwner()) {
1520 @SuppressWarnings("deprecation")
1521 public class MultipathReactor
1522 extends AsyncDataTreeChangeListenerBase<Multipath, MultipathReactor>
1523 implements ClusteredDataTreeChangeListener<Multipath> {
1525 private static final String YANG_OBJ = "multipath ";
1527 public MultipathReactor() {
1528 super(Multipath.class, MultipathReactor.class);
1533 protected MultipathReactor getDataTreeChangeListener() {
1534 return MultipathReactor.this;
1538 protected InstanceIdentifier<Multipath> getWildCardPath() {
1539 return InstanceIdentifier.create(Bgp.class).child(Multipath.class);
1543 protected void remove(InstanceIdentifier<Multipath> iid, Multipath val) {
1544 executor.execute(new MultipathStatusChange(val));
1548 protected void update(InstanceIdentifier<Multipath> iid, Multipath oldval, Multipath newval) {
1549 executor.execute(new MultipathStatusChange(newval));
1553 protected void add(InstanceIdentifier<Multipath> key, Multipath dataObjectModification) {
1554 executor.execute(new MultipathStatusChange(dataObjectModification));
1557 class MultipathStatusChange implements Runnable {
1559 Multipath multipath;
1561 MultipathStatusChange(Multipath multipath) {
1562 this.multipath = multipath;
1567 if (isBGPEntityOwner()) {
1568 synchronized (BgpConfigurationManager.this) {
1570 BgpRouter br = getClient(YANG_OBJ);
1573 af_afi afi = af_afi.findByValue(multipath.getAfi().intValue());
1574 af_safi safi = af_safi.findByValue(multipath.getSafi().intValue());
1577 if (multipath.isMultipathEnabled()) {
1578 br.enableMultipath(afi, safi);
1580 br.disableMultipath(afi, safi);
1582 } catch (TException | BgpRouterException e) {
1583 LOG.error("{} received exception", YANG_OBJ, e);
1593 public void close() {
1598 @SuppressWarnings("deprecation")
1599 public class VrfMaxpathReactor
1600 extends AsyncDataTreeChangeListenerBase<VrfMaxpath, VrfMaxpathReactor>
1601 implements ClusteredDataTreeChangeListener<VrfMaxpath> {
1603 private static final String YANG_OBJ = "vrfMaxpath ";
1605 public VrfMaxpathReactor() {
1606 super(VrfMaxpath.class, VrfMaxpathReactor.class);
1611 protected VrfMaxpathReactor getDataTreeChangeListener() {
1612 return VrfMaxpathReactor.this;
1616 protected InstanceIdentifier<VrfMaxpath> getWildCardPath() {
1617 return InstanceIdentifier.create(Bgp.class).child(VrfMaxpath.class);
1620 class VrfMaxPathConfigurator implements Runnable {
1622 VrfMaxpath vrfMaxpathVal;
1624 VrfMaxPathConfigurator(VrfMaxpath vrfMaxPathVal) {
1625 this.vrfMaxpathVal = vrfMaxPathVal;
1630 if (isBGPEntityOwner()) {
1631 synchronized (BgpConfigurationManager.this) {
1632 BgpRouter br = getClient(YANG_OBJ);
1635 br.multipaths(vrfMaxpathVal.getRd(), vrfMaxpathVal.getMaxpaths().toJava());
1636 LOG.debug("Maxpath for vrf {} is {}", vrfMaxpathVal.getRd(),
1637 vrfMaxpathVal.getMaxpaths());
1638 } catch (TException | BgpRouterException e) {
1639 LOG.error("{} received exception", YANG_OBJ, e);
1648 protected void remove(InstanceIdentifier<VrfMaxpath> iid, VrfMaxpath vrfMaxPathVal) {
1649 if (isBGPEntityOwner()) {
1650 synchronized (BgpConfigurationManager.this) {
1651 BgpRouter br = getClient(YANG_OBJ);
1654 br.multipaths(vrfMaxPathVal.getRd(), BgpConstants.BGP_DEFAULT_MULTIPATH);
1655 LOG.debug("Del Maxpath for vrf: {} ", vrfMaxPathVal.getRd());
1656 } catch (TException | BgpRouterException e) {
1657 LOG.error(YANG_OBJ + " del received exception:", e);
1665 protected void update(InstanceIdentifier<VrfMaxpath> iid,
1666 VrfMaxpath oldval, VrfMaxpath newval) {
1667 if (!Objects.equals(oldval.getMaxpaths(), newval.getMaxpaths())) {
1668 executor.execute(new VrfMaxPathConfigurator(newval));
1673 protected void add(InstanceIdentifier<VrfMaxpath> instanceIdentifier, VrfMaxpath vrfMaxpathVal) {
1674 executor.execute(new VrfMaxPathConfigurator(vrfMaxpathVal));
1678 public void close() {
1683 public class BfdConfigReactor
1684 extends AsyncDataTreeChangeListenerBase<BfdConfig, BfdConfigReactor>
1685 implements ClusteredDataTreeChangeListener<BfdConfig> {
1687 private static final String YANG_OBJ = "BfdConfig ";
1689 public BfdConfigReactor() {
1690 super(BfdConfig.class, BfdConfigReactor.class);
1694 protected void add(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
1695 if (!isBGPEntityOwner()) {
1698 BgpRouter br = getClient(YANG_OBJ);
1699 LOG.debug("received bfd config: bfd enabled {} min-rx {} min-tx {} detect-mul {} mhop {}",
1700 val.isBfdEnabled(), val.getMinRx(), val.getMinTx(),
1701 val.getDetectMult(), val.isMultihop());
1703 LOG.debug(YANG_OBJ + "{} Unable to process add {}",
1704 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1707 if (val.isBfdEnabled() == false) {
1708 LOG.debug("BFD not enabled. Ignoring the config add");
1711 int minRx = val.getMinRx().intValue();
1712 int minTx = val.getMinTx().intValue();
1713 int detectMult = val.getDetectMult().intValue();
1714 boolean multiHop = val.isMultihop();
1716 br.addBfd(detectMult, minRx, minTx,multiHop);
1717 } catch (TException | BgpRouterException e) {
1718 LOG.error("{} get {}, Add received exception;", YANG_OBJ, ADD_WARN, e);
1723 protected BfdConfigReactor getDataTreeChangeListener() {
1724 return BfdConfigReactor.this;
1728 protected InstanceIdentifier<BfdConfig> getWildCardPath() {
1729 return InstanceIdentifier.create(BfdConfig.class);
1733 protected void remove(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
1734 if (!isBGPEntityOwner()) {
1737 LOG.debug("received bfd config removal");
1738 BgpRouter br = getClient(YANG_OBJ);
1740 LOG.debug("{} Unable to process del {} {}", YANG_OBJ,
1741 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1746 } catch (TException | BgpRouterException e) {
1747 LOG.error("{} get {}, Del received exception;", YANG_OBJ, ADD_WARN, e);
1753 protected void update(InstanceIdentifier<BfdConfig> iid,
1754 BfdConfig oldval, BfdConfig newval) {
1755 LOG.debug("received bfd config: updated oldval bfd enabled {}"
1756 + "min-rx {} min-tx {} detect-mul {} mhop {}",
1757 oldval.isBfdEnabled(), oldval.getMinRx(), oldval.getMinTx(),
1758 oldval.getDetectMult(), oldval.isMultihop());
1759 LOG.debug("received bfd config: updated newval bfd enabled {}"
1760 + "min-rx {} min-tx {} detect-mul {} mhop {}",
1761 newval.isBfdEnabled(), newval.getMinRx(), newval.getMinTx(),
1762 newval.getDetectMult(), newval.isMultihop());
1763 if (oldval.isBfdEnabled()) {
1764 LOG.debug("deleting bfd config on an update");
1765 remove(iid, oldval);
1767 LOG.debug("adding bfd config on an update");
1773 public boolean isIpAvailable(String odlip) {
1776 if (odlip != null) {
1777 if ("127.0.0.1".equals(odlip)) {
1780 Enumeration<NetworkInterface> networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces();
1781 while (networkInterfaceEnumeration.hasMoreElements()) {
1782 NetworkInterface networkInterface = networkInterfaceEnumeration.nextElement();
1783 Enumeration<InetAddress> inetAddressEnumeration = networkInterface.getInetAddresses();
1784 while (inetAddressEnumeration.hasMoreElements()) {
1785 InetAddress inetAddress = inetAddressEnumeration.nextElement();
1786 if (odlip.equals(inetAddress.getHostAddress())) {
1792 } catch (SocketException e) {
1798 public long getStalePathtime(int defValue, AsId asId) {
1801 spt = getConfig().getGracefulRestart().getStalepathTime().toJava();
1802 } catch (NullPointerException e) {
1804 spt = asId.getStalepathTime().toJava();
1805 LOG.trace("BGP config/Stale-path time is not set using graceful");
1806 } catch (NullPointerException ignore) {
1807 LOG.trace("BGP AS id is not set using graceful");
1812 LOG.trace("BGP config/Stale-path time is not set using graceful/start-bgp");
1818 public static boolean isValidConfigBgpHostPort(String bgpHost, int bgpPort) {
1819 if (!bgpHost.equals(DEF_CHOST)) {
1826 public synchronized void bgpRestarted() {
1828 * If there a thread which in the process of stale cleanup, cancel it
1829 * and start a new thread (to avoid processing same again).
1831 if (previousReplayJobInProgress()) {
1832 cancelPreviousReplayJob();
1834 Runnable task = () -> {
1836 LOG.info("running bgp replay task ");
1837 if (get() == null) {
1838 String host = getConfigHost();
1839 int port = getConfigPort();
1840 LOG.info("connecting to bgp host {} ", host);
1841 bgpRouter.connect(host, port);
1842 LOG.info("no config to push in bgp replay task ");
1845 setStaleStartTime(System.currentTimeMillis());
1846 LOG.info("started creating stale fibDSWriter map ");
1847 createStaleFibMap();
1848 setStaleEndTime(System.currentTimeMillis());
1849 LOG.info("took {} msecs for stale fibDSWriter map creation ", getStaleEndTime() - getStaleStartTime());
1850 LOG.info("started bgp config replay ");
1851 setCfgReplayStartTime(System.currentTimeMillis());
1852 boolean replaySucceded = replay();
1853 setCfgReplayEndTime(System.currentTimeMillis());
1854 LOG.info("took {} msecs for bgp replay ", getCfgReplayEndTime() - getCfgReplayStartTime());
1855 if (replaySucceded) {
1856 long routeSyncTime = getStalePathtime(BGP_RESTART_ROUTE_SYNC_SEC, config.getAsId());
1857 setStaleCleanupTime(routeSyncTime);
1858 LOG.error("starting the stale cleanup timer: {} seconds", routeSyncTime);
1859 routeCleanupFuture = executor.schedule(new RouteCleanup(), routeSyncTime, TimeUnit.SECONDS);
1861 LOG.error("skipping stale cleanup, may be due to exception while replay");
1862 staledFibEntriesMap.clear();
1864 } catch (InterruptedException | TimeoutException | ExecutionException eCancel) {
1865 LOG.error("Stale Cleanup Task Cancelled", eCancel);
1868 lastReplayJobFt = executor.submit(task);
1871 private boolean previousReplayJobInProgress() {
1872 return ((lastReplayJobFt != null && !lastReplayJobFt.isDone())
1873 || (routeCleanupFuture != null && !routeCleanupFuture.isDone()));
1876 private void cancelPreviousReplayJob() {
1878 LOG.error("cancelling already running bgp replay task");
1879 if (lastReplayJobFt != null) {
1880 lastReplayJobFt.cancel(true);
1881 lastReplayJobFt = null;
1882 staledFibEntriesMap.clear();
1884 if (routeCleanupFuture != null) {
1885 routeCleanupFuture.cancel(true);
1886 routeCleanupFuture = null;
1887 staledFibEntriesMap.clear();
1890 } catch (InterruptedException e) {
1891 LOG.error("Failed to cancel previous replay job ", e);
1895 private void doRouteSync() {
1896 LOG.error("Starting BGP route sync");
1898 bgpRouter.initRibSync(bgpSyncHandle);
1899 } catch (BgpRouterException e) {
1900 LOG.error("Route sync aborted, exception when initializing", e);
1903 while (bgpSyncHandle.getState() != BgpSyncHandle.DONE) {
1904 for (af_afi afi : af_afi.values()) {
1905 Routes routes = null;
1907 routes = bgpRouter.doRibSync(bgpSyncHandle, afi);
1908 } catch (TException | BgpRouterException e) {
1909 LOG.error("Route sync aborted, exception when syncing", e);
1912 Iterator<Update> updates = routes.getUpdatesIterator();
1913 while (updates.hasNext()) {
1914 Update update = updates.next();
1915 String rd = update.getRd();
1916 String nexthop = update.getNexthop();
1918 // TODO: decide correct label here
1919 int label = update.getL3label();
1920 int l2label = update.getL2label();
1922 String prefix = update.getPrefix();
1923 int plen = update.getPrefixlen();
1926 // TODO: protocol type will not be available in "update"
1927 // use "rd" to query vrf table and obtain the protocol_type.
1928 // Currently using PROTOCOL_EVPN as default.
1930 protocol_type.PROTOCOL_L3VPN,
1935 update.getMacaddress(),
1936 Uint32.valueOf(label),
1937 Uint32.valueOf(l2label),
1938 update.getRoutermac(),
1944 LOG.error("Ending BGP route-sync");
1945 bgpRouter.endRibSync(bgpSyncHandle);
1946 } catch (BgpRouterException e) {
1951 public void addTepToElanDS(String rd, String tepIp, String mac, Uint32 l2vni) {
1952 boolean needUpdate = addToRt2TepMap(rd, tepIp, mac, l2vni);
1954 LOG.info("Adding tepIp {} with RD {} to ELan DS", tepIp, rd);
1955 bgpUtil.addTepToElanInstance(rd, tepIp);
1957 LOG.debug("Skipping the Elan update for RT2 from tep {} rd {}", tepIp, rd);
1961 public void deleteTepfromElanDS(String rd, String tepIp, String mac) {
1962 boolean needUpdate = deleteFromRt2TepMap(rd, tepIp, mac);
1964 LOG.info("Deleting tepIp {} with RD {} to ELan DS", tepIp, rd);
1965 bgpUtil.deleteTepFromElanInstance(rd, tepIp);
1967 LOG.debug("Skipping the Elan update for RT2 withdraw from tep {} rd {}", tepIp, rd);
1971 /* onUpdatePushRoute
1972 * Get Stale fibDSWriter map, and compare current route/fibDSWriter entry.
1973 * - Entry compare shall include NextHop, Label.
1974 * - If entry matches: delete from STALE Map. NO Change to FIB Config DS.
1975 * - If entry not found, add to FIB Config DS.
1976 * - If entry found, but either Label/NextHop doesn't match.
1977 * - Update FIB Config DS with modified values.
1978 * - delete from Stale Map.
1981 public void onUpdatePushRoute(protocol_type protocolType, String rd, String prefix, int plen, String nextHop,
1982 String macaddress, Uint32 label, Uint32 l2label, String routermac, af_afi afi) {
1983 PrefixUpdateEvent prefixUpdateEvent = new PrefixUpdateEvent(protocolType,rd,prefix,plen,nextHop,
1984 macaddress,label,l2label,routermac,afi);
1985 bgpUpdatesHistory.addToHistory(TransactionType.ADD, prefixUpdateEvent);
1986 boolean addroute = false;
1987 boolean macupdate = false;
1988 Uint32 l3vni = Uint32.ZERO;
1989 VrfEntry.EncapType encapType = VrfEntry.EncapType.Mplsgre;
1990 if (protocolType.equals(protocol_type.PROTOCOL_EVPN)) {
1991 encapType = VrfEntry.EncapType.Vxlan;
1992 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = bgpUtil.getVpnInstanceOpData(rd);
1993 if (vpnInstanceOpDataEntry != null) {
1994 if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
1995 LOG.info("Got RT2 route for RD {} l3label {} l2label {} from tep {} with mac {} remote RD {}",
1996 vpnInstanceOpDataEntry.getVpnInstanceName(), label, l2label, nextHop, macaddress, rd);
1997 addTepToElanDS(rd, nextHop, macaddress, l2label);
2000 l3vni = vpnInstanceOpDataEntry.getL3vni();
2003 LOG.error("No corresponding vpn instance found for rd {}. Aborting.", rd);
2008 if (!staledFibEntriesMap.isEmpty()) {
2009 // restart Scenario, as MAP is not empty.
2010 Map<String, Uint32> map = staledFibEntriesMap.get(rd);
2012 String prefixNextHop = appendNextHopToPrefix(prefix + "/" + plen, nextHop);
2013 Uint32 labelInStaleMap = map.get(prefixNextHop);
2014 if (null == labelInStaleMap) {
2015 // New Entry, which happened to be added during restart.
2018 map.remove(prefixNextHop);
2019 if (isRouteModified(label, labelInStaleMap)) {
2020 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
2021 // Existing entry, where in Label got modified during restart
2026 LOG.debug("rd {} map is null while processing prefix {} ", rd, prefix);
2030 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
2034 LOG.info("ADD: Adding Mac Fib entry rd {} mac{} nexthop {} l2vni {}", rd, macaddress, nextHop, l2label);
2035 fibDSWriter.addMacEntryToDS(rd, macaddress, prefix, Collections.singletonList(nextHop),
2036 encapType, l2label, routermac, RouteOrigin.BGP);
2037 LOG.info("ADD: Added Mac Fib entry rd {} prefix {} nexthop {} label {}", rd, macaddress, nextHop, l2label);
2038 } else if (addroute) {
2039 LOG.info("ADD: Adding Fib entry rd {} prefix {} nexthop {} label {} afi {}",
2040 rd, prefix, nextHop, label, afi);
2041 // TODO: modify addFibEntryToDS signature
2042 List<String> nextHopList = Collections.singletonList(nextHop);
2043 fibDSWriter.addFibEntryToDS(rd, prefix + "/" + plen, nextHopList, encapType, label, l3vni,
2044 routermac, RouteOrigin.BGP);
2045 LOG.info("ADD: Added Fib entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, label);
2046 String vpnName = bgpUtil.getVpnNameFromRd(rd);
2047 if (vpnName != null) {
2048 vpnLinkService.leakRouteIfNeeded(vpnName, prefix, nextHopList, label, RouteOrigin.BGP,
2049 NwConstants.ADD_FLOW);
2054 public void onUpdateWithdrawRoute(protocol_type protocolType, String rd, String prefix, int plen, String nextHop,
2055 String macaddress) {
2056 PrefixWithdrawEvent prefixWithdrawEvent = new PrefixWithdrawEvent(protocolType,rd,prefix,plen,
2057 nextHop,macaddress);
2058 bgpUpdatesHistory.addToHistory(TransactionType.ADD, prefixWithdrawEvent);
2059 boolean macupdate = false;
2060 if (protocolType.equals(protocol_type.PROTOCOL_EVPN)) {
2061 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = bgpUtil.getVpnInstanceOpData(rd);
2062 if (vpnInstanceOpDataEntry != null) {
2063 Uint32 vni = vpnInstanceOpDataEntry.getL3vni();
2064 if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
2065 LOG.debug("Got RT2 withdraw for RD {} {} from tep {} with mac {} remote RD {}",
2066 vpnInstanceOpDataEntry.getVpnInstanceName(), vni, nextHop, macaddress, rd);
2067 deleteTepfromElanDS(rd, nextHop, macaddress);
2068 LOG.debug("For rd {}. skipping fib update", rd);
2072 LOG.error("No corresponding vpn instance found for rd {}. Aborting.", rd);
2077 LOG.info("Removing Mac Fib entry rd {} mac{} nexthop {} ", rd, macaddress, nextHop);
2078 fibDSWriter.removeMacEntryFromDS(rd, macaddress);
2079 LOG.info("Removed Mac Fib entry rd {} prefix {} nexthop {} ", rd, macaddress, nextHop);
2081 LOG.info("REMOVE: Removing Fib entry rd {} prefix {}", rd, prefix);
2082 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix + "/" + plen, nextHop);
2083 LOG.info("REMOVE: Removed Fib entry rd {} prefix {}", rd, prefix);
2087 //TODO: below function is for testing purpose with cli
2088 public void onUpdateWithdrawRoute(String rd, String prefix, int plen, String nexthop) {
2089 LOG.debug("Route del ** {} ** {}/{} ", rd, prefix, plen);
2090 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix + "/" + plen, nexthop);
2091 String vpnName = bgpUtil.getVpnNameFromRd(rd);
2092 if (vpnName != null) {
2093 vpnLinkService.leakRouteIfNeeded(vpnName, prefix, null /*nextHopList*/, Uint32.ZERO /*INVALID_LABEL*/,
2094 RouteOrigin.BGP, NwConstants.DEL_FLOW);
2098 public void peerDown(String ipAddress, long asNumber) {
2099 List<String> tepIpList = bgpUtil.getDcgwTepConfig(ipAddress);
2100 if (tepIpList == null) {
2101 LOG.error("No Tep IP configured for DCGW {} on a peerDown", ipAddress);
2104 tepIpList.forEach(tepIp -> {
2105 bgpUtil.removeOrUpdateLBGroups(tepIp, NwConstants.MOD_FLOW);
2109 public void peerUp(String ipAddress, long asNumber) {
2110 List<String> tepIpList = bgpUtil.getDcgwTepConfig(ipAddress);
2111 if (tepIpList == null) {
2112 LOG.error("No Tep IP configured for DCGW {} on a peerUp", ipAddress);
2115 tepIpList.forEach(tepIp -> {
2116 bgpUtil.removeOrUpdateLBGroups(tepIp, NwConstants.MOD_FLOW);
2120 private static boolean isRouteModified(Uint32 label, Uint32 labelInStaleMap) {
2121 return labelInStaleMap != null && !labelInStaleMap.equals(label);
2124 static class ReplayNbr {
2126 boolean shouldRetry = false;
2128 public Neighbors getNbr() {
2132 public boolean isShouldRetry() {
2136 public void setShouldRetry(boolean retryNbr) {
2137 this.shouldRetry = retryNbr;
2140 ReplayNbr(Neighbors nbr, boolean shouldRetry) {
2142 this.shouldRetry = shouldRetry;
2146 private static boolean replayNbrConfig(List<Neighbors> neighbors, BgpRouter br) {
2147 if (neighbors == null || neighbors.isEmpty()) {
2148 LOG.error("Replaying nbr configuration, received NULL list ");
2152 List<ReplayNbr> replayNbrList = new ArrayList<>();
2153 for (Neighbors nbr : neighbors) {
2155 replayNbrList.add(new ReplayNbr(nbr, true));
2158 final int numberOfNbrRetries = 3;
2159 RetryOnException nbrRetry = new RetryOnException(numberOfNbrRetries);
2161 for (ReplayNbr replayNbr : replayNbrList) {
2162 if (!replayNbr.isShouldRetry()) {
2165 boolean replayDone = false;
2166 LOG.debug("Replaying addNbr {}", replayNbr.getNbr().getAddress().getValue());
2169 final String md5password = extractMd5Secret(replayNbr.getNbr());
2170 br.addNeighbor(replayNbr.getNbr().getAddress().getValue(),
2171 replayNbr.getNbr().getRemoteAs().longValue(), md5password);
2173 } catch (TApplicationException tae) {
2174 LOG.debug("Replaying addNbr {}, tapplicationexception: ",
2175 replayNbr.getNbr().getAddress().getValue(), tae);
2176 if (tae.getType() == BgpRouterException.BGP_ERR_PEER_EXISTS) {
2177 LOG.debug("Replaying addNbr Neighbor already present");
2180 LOG.error("Replaying addNbr {}, exception: ", replayNbr.getNbr().getAddress().getValue(), tae);
2182 } catch (TException | BgpRouterException eNbr) {
2183 LOG.debug("Replaying addNbr {}, exception: ", replayNbr.getNbr().getAddress().getValue(), eNbr);
2186 LOG.debug("Replay addNbr {} successful", replayNbr.getNbr().getAddress().getValue());
2188 //Update Source handling
2189 UpdateSource us = replayNbr.getNbr().getUpdateSource();
2191 LOG.debug("Replaying updatesource {} to peer {}", us.getSourceIp().getValue(),
2192 us.getPeerIp().getValue());
2194 br.addUpdateSource(us.getPeerIp().getValue(),
2195 us.getSourceIp().getValue());
2196 } catch (TException | BgpRouterException eUs) {
2197 LOG.debug("Replaying UpdateSource for Nbr {}, exception:",
2198 replayNbr.getNbr().getAddress().getValue(), eUs);
2200 LOG.debug("Replay updatesource {} successful", us.getSourceIp().getValue());
2203 EbgpMultihop en = replayNbr.getNbr().getEbgpMultihop();
2206 br.addEbgpMultihop(en.getPeerIp().getValue(),
2207 en.getNhops().intValue());
2208 } catch (TException | BgpRouterException eEbgpMhop) {
2209 LOG.debug("Replaying EbgpMultihop for Nbr {}, exception: ",
2210 replayNbr.getNbr().getAddress().getValue(), eEbgpMhop);
2215 List<AddressFamilies> afs = replayNbr.getNbr().getAddressFamilies();
2217 for (AddressFamilies af : afs) {
2218 af_afi afi = af_afi.findByValue(af.getAfi().intValue());
2219 af_safi safi = af_safi.findByValue(af.getSafi().intValue());
2221 br.addAddressFamily(af.getPeerIp().getValue(), afi, safi);
2222 } catch (TException | BgpRouterException eAFs) {
2223 LOG.debug("Replaying AddressFamily for Nbr {}, exception:",
2224 replayNbr.getNbr().getAddress().getValue(), eAFs);
2228 //replay is success --> no need to replay this nbr in next iteration.
2229 replayNbr.setShouldRetry(replayDone ? false : true);
2231 } while (nbrRetry.decrementAndRetry());
2232 boolean replaySuccess = true;
2233 for (ReplayNbr replayNbr : replayNbrList) {
2234 replaySuccess = replaySuccess && !replayNbr.isShouldRetry();
2235 if (replaySuccess == false) {
2236 LOG.error("replayNbrConfig: will be cancelling stale cleanup, cfg nbr: {} Failed:",
2237 replayNbr.getNbr().getAddress().getValue());
2240 return replaySuccess;
2243 public String getConfigHost() {
2244 if (config == null) {
2247 ConfigServer ts = config.getConfigServer();
2248 return ts == null ? hostStartup : ts.getHost().getValue();
2251 public int getConfigPort() {
2252 if (config == null) {
2253 return Integer.parseInt(portStartup);
2255 ConfigServer ts = config.getConfigServer();
2256 return ts == null ? Integer.parseInt(portStartup) :
2257 ts.getPort().intValue();
2260 public Bgp getConfig() {
2261 AtomicInteger bgpDSretryCount = new AtomicInteger(DS_RETRY_COUNT);
2262 while (0 != bgpDSretryCount.decrementAndGet()) {
2264 return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
2265 InstanceIdentifier.create(Bgp.class)).orNull();
2266 } catch (ReadFailedException e) {
2267 //Config DS may not be up, so sleep for 1 second and retry
2268 LOG.debug("failed to get bgp config, may be DS is yet in consistent state(?)", e);
2270 Thread.sleep(WAIT_TIME_BETWEEN_EACH_TRY_MILLIS);
2271 } catch (InterruptedException timerEx) {
2272 LOG.debug("WAIT_TIME_BETWEEN_EACH_TRY_MILLIS, Timer got interrupted while waiting for"
2273 + "config DS availability", timerEx);
2277 LOG.error("failed to get bgp config");
2281 @SuppressWarnings("checkstyle:IllegalCatch")
2282 public synchronized boolean replay() throws InterruptedException, TimeoutException, ExecutionException {
2283 boolean replaySucceded = true;
2284 boolean doRouteSync = false;
2285 String host = getConfigHost();
2286 int port = getConfigPort();
2287 LOG.error("connecting to bgp host {} ", host);
2288 boolean res = bgpRouter.connect(host, port);
2290 LOG.error("Cannot connect to BGP config server at {} {}", host, port);
2291 return replaySucceded;
2293 config = getConfig();
2294 if (config == null) {
2295 LOG.error("bgp config is empty nothing to push to bgp");
2296 return replaySucceded;
2298 BgpRouter br = bgpRouter;
2299 AsId asId = config.getAsId();
2301 LOG.error("bgp as-id is null");
2302 return replaySucceded;
2304 long asNum = asId.getLocalAs().toJava();
2305 IpAddress routerId = asId.getRouterId();
2306 String rid = routerId == null ? "" : routerId.stringValue();
2307 int stalepathTime = (int) getStalePathtime(bgpGrRestartTime, config.getAsId());
2308 boolean announceFbit = true;
2309 boolean replayDone = false;
2310 final int numberOfStartBgpRetries = 3;
2311 RetryOnException startBgpRetry = new RetryOnException(numberOfStartBgpRetries);
2314 LOG.debug("Replaying BGPConfig ");
2315 br.startBgp(asNum, rid, bgpKaTime, bgpHoldTime, stalepathTime, announceFbit);
2316 LOG.debug("Replay BGPConfig successful");
2319 } catch (BgpRouterException bre) {
2320 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
2321 LOG.debug("Starting the routesync for exception", bre);
2322 startBgpRetry.errorOccured();
2323 if (!startBgpRetry.shouldRetry()) {
2328 LOG.error("Replay: startBgp() received exception error {} : ",
2329 bre.getErrorCode(), bre);
2330 startBgpRetry.errorOccured();
2332 } catch (TApplicationException tae) {
2333 if (tae.getType() == BgpRouterException.BGP_ERR_ACTIVE) {
2334 LOG.debug("Starting the routesync for exception", tae);
2335 startBgpRetry.errorOccured();
2336 if (!startBgpRetry.shouldRetry()) {
2340 } else if (tae.getType() == BgpRouterException.BGP_ERR_COMMON_FAILURE) {
2341 LOG.debug("Starting the routesync for AS-ID started exception", tae);
2342 startBgpRetry.errorOccured();
2343 if (!startBgpRetry.shouldRetry()) {
2348 LOG.error("Replay: startBgp() received exception type {}: ",
2349 tae.getType(), tae);
2350 startBgpRetry.errorOccured();
2352 } catch (Exception e) {
2353 //not unusual. We may have restarted & BGP is already on
2354 LOG.error("Replay:startBgp() received exception: ", e);
2355 startBgpRetry.errorOccured();
2357 } while (startBgpRetry.shouldRetry());
2359 replaySucceded = replayDone;
2361 startBgpCountersTask();
2362 startBgpAlarmsTask();
2365 * commenting this due to a bug with QBGP. Will uncomment once QBGP fix is done.
2366 * This wont have any functional impacts
2369 // br.delayEOR(delayEorSeconds);
2370 //} catch (TException | BgpRouterException e) {
2371 // LOG.error("Replay: delayEOR() number of seconds to wait for EOR from ODL:", e);
2374 BfdConfig bfdConfig = bgpUtil.getBfdConfig();
2375 if (bfdConfig != null) {
2376 if (bfdConfig.isBfdEnabled()) {
2377 LOG.debug("Replaying bfd config min-rx {} min-tx {} detect-mul {} mhop {}",
2378 bfdConfig.getMinRx(), bfdConfig.getMinTx(),
2379 bfdConfig.getDetectMult(), bfdConfig.isMultihop());
2381 br.addBfd(bfdConfig.getDetectMult().intValue(), bfdConfig.getMinRx().intValue(),
2382 bfdConfig.getMinTx().intValue(), bfdConfig.isMultihop());
2383 } catch (TApplicationException tae) {
2384 if (tae.getType() == BgpRouterException.BGP_ERR_PEER_EXISTS) {
2385 LOG.debug("Replay:addBfd() received exception", tae);
2387 LOG.error("Replay:addBfd() received exception", tae);
2389 } catch (TException | BgpRouterException e) {
2390 LOG.error("Replay:addBfd() received exception", e);
2395 List<Neighbors> neighbors = config.getNeighbors();
2396 if (neighbors != null) {
2397 LOG.error("configuring existing Neighbors present for replay total neighbors {}", neighbors.size());
2398 boolean neighborConfigReplayResult = replayNbrConfig(neighbors, br);
2399 if (neighborConfigReplayResult == false) {
2400 replaySucceded = false;
2403 LOG.error("no Neighbors present for replay config ");
2406 Logging logging = config.getLogging();
2407 if (logging != null) {
2409 br.setLogging(logging.getFile(), logging.getLevel());
2410 } catch (TException | BgpRouterException e) {
2411 LOG.error("Replay:setLogging() received exception", e);
2415 GracefulRestart gracefulRestart = config.getGracefulRestart();
2416 bgpGrRestartTime = ((gracefulRestart != null)
2417 ? gracefulRestart.getStalepathTime().intValue() : bgpGrRestartTime);
2419 br.addGracefulRestart(bgpGrRestartTime);
2420 } catch (Exception e) {
2421 LOG.error("Replay:addGr() received exception: ", e);
2423 List<Vrfs> vrfs = config.getVrfs();
2425 vrfs = new ArrayList<>();
2427 for (Vrfs vrf : vrfs) {
2428 for (AddressFamiliesVrf adf : vrf.getAddressFamiliesVrf()) {
2430 br.addVrf(BgpUtil.getLayerType(adf), vrf.getRd(), vrf.getImportRts(),
2431 vrf.getExportRts(), adf.getAfi().toJava(), adf.getSafi().toJava());
2432 } catch (TException | BgpRouterException e) {
2433 LOG.error("Replay:addVrf() received exception", e);
2438 List<Networks> ln = config.getNetworks();
2440 for (Networks net : ln) {
2441 String rd = net.getRd();
2442 String pfxlen = net.getPrefixLen();
2443 String nh = net.getNexthop().getValue();
2444 Long label = net.getLabel().toJava();
2445 int lbl = label == null ? 0 : label.intValue();
2446 int l3vni = net.getL3vni() == null ? 0 : net.getL3vni().intValue();
2447 int l2vni = net.getL2vni() == null ? 0 : net.getL2vni().intValue();
2448 if (rd == null && lbl > 0) {
2449 //LU prefix is being deleted.
2450 rd = Integer.toString(lbl);
2453 BgpControlPlaneType protocolType = net.getBgpControlPlaneType();
2454 int ethernetTag = net.getEthtag().intValue();
2455 String esi = net.getEsi();
2456 String macaddress = net.getMacaddress();
2457 EncapType encapType = net.getEncapType();
2458 String routerMac = net.getRoutermac();
2461 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, l2vni,
2462 BgpUtil.convertToThriftProtocolType(protocolType),
2463 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
2464 } catch (TException | BgpRouterException e) {
2465 LOG.error("Replay:addPfx() received exception", e);
2471 List<Multipath> multipaths = config.getMultipath();
2473 if (multipaths != null) {
2474 for (Multipath multipath : multipaths) {
2475 if (multipath != null) {
2476 af_afi afi = af_afi.findByValue(multipath.getAfi().intValue());
2477 af_safi safi = af_safi.findByValue(multipath.getSafi().intValue());
2480 if (multipath.isMultipathEnabled()) {
2481 br.enableMultipath(afi, safi);
2483 br.disableMultipath(afi, safi);
2485 } catch (TException | BgpRouterException e) {
2486 LOG.info("Replay:multipaths() received exception", e);
2491 List<VrfMaxpath> vrfMaxpaths = config.getVrfMaxpath();
2492 if (vrfMaxpaths != null) {
2493 for (VrfMaxpath vrfMaxpath : vrfMaxpaths) {
2495 br.multipaths(vrfMaxpath.getRd(), vrfMaxpath.getMaxpaths().toJava());
2496 } catch (TException | BgpRouterException e) {
2497 LOG.info("Replay:vrfMaxPath() received exception", e);
2502 //send End of Rib Marker to Qthriftd.
2503 final int numberOfEORRetries = 3;
2504 RetryOnException eorRetry = new RetryOnException(numberOfEORRetries);
2508 LOG.debug("Replay sendEOR() successful");
2510 } catch (Exception e) {
2511 eorRetry.errorOccured();
2512 LOG.error("Replay:sedEOR() received exception:", e);
2514 } while (eorRetry.shouldRetry());
2517 LOG.debug("starting route sync for Thrift BGP_ERR_COMMON_FAILURE exception "
2518 + "happened earlier");
2522 return replaySucceded;
2525 private <T extends DataObject> void update(InstanceIdentifier<T> iid, T dto) {
2526 bgpUtil.update(iid, dto);
2529 private <T extends DataObject> void delete(InstanceIdentifier<T> iid) {
2530 bgpUtil.delete(iid);
2533 public void startConfig(String bgpHost, int thriftPort) {
2534 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
2535 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
2536 InstanceIdentifier<ConfigServer> iid = iib.build();
2537 Ipv4Address ipAddr = new Ipv4Address(bgpHost);
2538 ConfigServer dto = new ConfigServerBuilder().setHost(ipAddr)
2539 .setPort((long) thriftPort).build();
2543 public void startBgp(long as, String routerId, int spt, boolean fbit) {
2544 IpAddress rid = routerId == null ? null : IpAddressBuilder.getDefaultInstance(routerId);
2545 Long staleTime = (long) spt;
2546 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
2547 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
2548 InstanceIdentifier<AsId> iid = iib.build();
2549 AsId dto = new AsIdBuilder().setLocalAs(as)
2551 .setStalepathTime(staleTime)
2552 .setAnnounceFbit(fbit).build();
2556 public void startBfd(long detectMult, long minRx, long minTx, boolean multiHop) {
2557 InstanceIdentifier.InstanceIdentifierBuilder<BfdConfig> iib =
2558 InstanceIdentifier.builder(BfdConfig.class);
2559 InstanceIdentifier<BfdConfig> iid = iib.build();
2560 BfdConfig dto = new BfdConfigBuilder()
2561 .setBfdEnabled(true)
2562 .setMultihop(multiHop)
2565 .setDetectMult(detectMult)
2570 public void addDcgwTep(String dcgwIp, String tepIp) {
2571 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2572 InstanceIdentifier.builder(Bgp.class)
2573 .child(DcgwTepList.class)
2574 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2575 InstanceIdentifier<DcgwTep> iid = iib.build();
2576 ArrayList<String> tepList = new ArrayList<String>();
2578 DcgwTep dto = new DcgwTepBuilder().setDcGwIp(dcgwIp).setTepIps(tepList)
2581 bgpUtil.removeOrUpdateLBGroups(tepIp,NwConstants.MOD_FLOW);
2584 public void addLogging(String fileName, String logLevel) {
2585 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
2586 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
2587 InstanceIdentifier<Logging> iid = iib.build();
2588 Logging dto = new LoggingBuilder().setFile(fileName)
2589 .setLevel(logLevel).build();
2593 public void addGracefulRestart(int staleTime) {
2594 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
2595 InstanceIdentifier.builder(Bgp.class).child(GracefulRestart.class);
2596 InstanceIdentifier<GracefulRestart> iid = iib.build();
2597 GracefulRestart dto = new GracefulRestartBuilder()
2598 .setStalepathTime((long) staleTime).build();
2602 public void addNeighbor(
2603 String nbrIp, long remoteAs, @Nullable final TcpMd5SignaturePasswordType md5Secret) {
2604 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2605 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
2606 InstanceIdentifier.builder(Bgp.class)
2607 .child(Neighbors.class, new NeighborsKey(nbrAddr));
2608 InstanceIdentifier<Neighbors> iid = iib.build();
2609 TcpSecurityOption tcpSecOption = null;
2610 if (md5Secret != null) {
2611 tcpSecOption = new TcpMd5SignatureOptionBuilder().setTcpMd5SignaturePassword(md5Secret).build();
2612 } // else let tcpSecOption be null
2613 Neighbors dto = new NeighborsBuilder().setAddress(nbrAddr)
2614 .setRemoteAs(remoteAs).setTcpSecurityOption(tcpSecOption).build();
2616 } // public addNeighbor(nbrIp, remoteAs, md5Secret)
2618 public void addUpdateSource(String nbrIp, String srcIp) {
2619 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2620 Ipv4Address srcAddr = new Ipv4Address(srcIp);
2621 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
2622 InstanceIdentifier.builder(Bgp.class)
2623 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2624 .child(UpdateSource.class);
2625 InstanceIdentifier<UpdateSource> iid = iib.build();
2626 UpdateSource dto = new UpdateSourceBuilder().setPeerIp(nbrAddr)
2627 .setSourceIp(srcAddr).build();
2631 public void addEbgpMultihop(String nbrIp, int hops) {
2632 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2633 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
2634 InstanceIdentifier.builder(Bgp.class)
2635 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2636 .child(EbgpMultihop.class);
2637 InstanceIdentifier<EbgpMultihop> iid = iib.build();
2638 EbgpMultihop dto = new EbgpMultihopBuilder().setPeerIp(nbrAddr)
2639 .setNhops((long) hops).build();
2643 public void addAddressFamily(String nbrIp, int afi, int safi) {
2644 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2645 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
2646 InstanceIdentifier.builder(Bgp.class)
2647 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2648 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
2649 InstanceIdentifier<AddressFamilies> iid = iib.build();
2650 AddressFamilies dto = new AddressFamiliesBuilder().setPeerIp(nbrAddr)
2651 .setAfi((long) afi).setSafi((long) safi).build();
2655 public void addPrefix(String rd, String macAddress, String pfx, List<String> nhList,
2656 VrfEntry.EncapType encapType, Uint32 lbl, Uint32 l3vni, Uint32 l2vni, String gatewayMac) {
2657 for (String nh : nhList) {
2658 Ipv4Address nexthop = nh != null ? new Ipv4Address(nh) : null;
2660 InstanceIdentifier<Networks> iid = InstanceIdentifier.builder(Bgp.class)
2661 .child(Networks.class, new NetworksKey(pfx, rd)).build();
2662 NetworksBuilder networksBuilder = new NetworksBuilder().setRd(rd).setPrefixLen(pfx).setNexthop(nexthop)
2663 .setLabel(label).setEthtag(BgpConstants.DEFAULT_ETH_TAG);
2664 buildVpnEncapSpecificInfo(networksBuilder, encapType, label, l3vni, l2vni, macAddress, gatewayMac);
2665 update(iid, networksBuilder.build());
2669 private static void buildVpnEncapSpecificInfo(NetworksBuilder builder, VrfEntry.EncapType encapType, Uint32 label,
2670 Uint32 l3vni, Uint32 l2vni, String macAddress, String gatewayMac) {
2671 if (encapType.equals(VrfEntry.EncapType.Mplsgre)) {
2672 builder.setLabel(label).setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLL3VPN)
2673 .setEncapType(EncapType.GRE);
2675 builder.setL3vni(l3vni).setL2vni(l2vni).setMacaddress(macAddress).setRoutermac(gatewayMac)
2676 .setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLEVPN).setEncapType(EncapType.VXLAN);
2680 // TODO: add LayerType as arg - supports command
2681 public void addVrf(String rd, List<String> irts, List<String> erts, AddressFamily addressFamily) {
2682 Vrfs vrf = bgpUtil.getVrfFromRd(rd);
2683 List<AddressFamiliesVrf> adfList = new ArrayList<>(1);
2685 adfList = vrf.getAddressFamiliesVrf();
2687 AddressFamiliesVrfBuilder adfBuilder = new AddressFamiliesVrfBuilder();
2688 if (addressFamily.equals(AddressFamily.IPV4)) {
2689 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2690 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2691 } else if (addressFamily.equals(AddressFamily.IPV6)) {
2692 adfBuilder.setAfi((long) af_afi.AFI_IPV6.getValue());
2693 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2694 } else if (addressFamily.equals(AddressFamily.L2VPN)) {
2695 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2696 adfBuilder.setSafi((long) af_safi.SAFI_EVPN.getValue());
2698 AddressFamiliesVrf adf = adfBuilder.build();
2700 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib = InstanceIdentifier.builder(Bgp.class)
2701 .child(Vrfs.class, new VrfsKey(rd));
2702 InstanceIdentifier<Vrfs> iid = iib.build();
2703 Vrfs dto = new VrfsBuilder().setRd(rd).setImportRts(irts)
2704 .setExportRts(erts).setAddressFamiliesVrf(adfList).build();
2706 List<AddressFamiliesVrf> listAdFamilies = mapNewAdFamily.get(rd);
2707 if (listAdFamilies != null) {
2708 listAdFamilies.add(adf);
2710 mapNewAdFamily.put(rd, adfList);
2714 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
2715 } catch (TransactionCommitFailedException e) {
2716 LOG.error("Error adding VRF to datastore", e);
2717 throw new RuntimeException(e);
2720 // enable multipath by default in all VRFs
2721 setMultipaths(rd, BgpConstants.BGP_DEFAULT_MULTIPATH);
2724 public void stopConfig() {
2725 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
2726 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
2727 InstanceIdentifier<ConfigServer> iid = iib.build();
2731 public void stopBgp() {
2732 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
2733 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
2734 InstanceIdentifier<AsId> iid = iib.build();
2738 public void stopBfd() {
2739 InstanceIdentifier.InstanceIdentifierBuilder<BfdConfig> iib =
2740 InstanceIdentifier.builder(BfdConfig.class);
2741 InstanceIdentifier<BfdConfig> iid = iib.build();
2745 public void delDcgwTep(String dcgwIp, String tepIp) {
2746 if (tepIp == null) {
2747 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2748 InstanceIdentifier.builder(Bgp.class)
2749 .child(DcgwTepList.class)
2750 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2751 InstanceIdentifier<DcgwTep> iid = iib.build();
2754 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2755 InstanceIdentifier.builder(Bgp.class)
2756 .child(DcgwTepList.class)
2757 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2758 InstanceIdentifier<DcgwTep> iid = iib.build();
2759 List<String> tepIpList = bgpUtil.getDcgwTepConfig(dcgwIp);
2760 if (tepIpList == null) {
2761 LOG.error("No Tep IP configured for DCGW {} on deleting the dcgwtep", dcgwIp);
2764 List<String> newTepIpList = new ArrayList<String>();
2765 tepIpList.forEach(tep -> {
2766 if (!tep.equals(tepIp)) {
2767 newTepIpList.add(tep);
2770 DcgwTep dto = new DcgwTepBuilder().setDcGwIp(dcgwIp).setTepIps(newTepIpList)
2773 SingleTransactionDataBroker.syncWrite(dataBroker,
2774 LogicalDatastoreType.CONFIGURATION, iid, dto);
2775 } catch (TransactionCommitFailedException e) {
2776 LOG.error("delDcgwTep: Error deleting DCGW Tep", e);
2777 throw new RuntimeException(e);
2782 public void delLogging() {
2783 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
2784 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
2785 InstanceIdentifier<Logging> iid = iib.build();
2789 public void delGracefulRestart() {
2790 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
2791 InstanceIdentifier.builder(Bgp.class)
2792 .child(GracefulRestart.class);
2793 InstanceIdentifier<GracefulRestart> iid = iib.build();
2797 public void delNeighbor(String nbrIp) {
2798 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2799 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
2800 InstanceIdentifier.builder(Bgp.class)
2801 .child(Neighbors.class, new NeighborsKey(nbrAddr));
2802 InstanceIdentifier<Neighbors> iid = iib.build();
2806 public void delUpdateSource(String nbrIp) {
2807 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2808 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
2809 InstanceIdentifier.builder(Bgp.class)
2810 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2811 .child(UpdateSource.class);
2812 InstanceIdentifier<UpdateSource> iid = iib.build();
2816 public void delEbgpMultihop(String nbrIp) {
2817 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2818 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
2819 InstanceIdentifier.builder(Bgp.class)
2820 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2821 .child(EbgpMultihop.class);
2822 InstanceIdentifier<EbgpMultihop> iid = iib.build();
2826 public void delAddressFamily(String nbrIp, int afi, int safi) {
2827 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2828 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
2829 InstanceIdentifier.builder(Bgp.class)
2830 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2831 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
2832 InstanceIdentifier<AddressFamilies> iid = iib.build();
2836 public void delPrefix(String rd, String pfx) {
2837 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
2838 InstanceIdentifier.builder(Bgp.class)
2839 .child(Networks.class, new NetworksKey(pfx, rd));
2840 InstanceIdentifier<Networks> iid = iib.build();
2844 public boolean delVrf(String rd, AddressFamily addressFamily) {
2845 if (addressFamily == null) {
2846 LOG.error("delVrf: vrf {}, addressFamily invalid", rd);
2850 AddressFamiliesVrfBuilder adfBuilder = new AddressFamiliesVrfBuilder();
2851 if (addressFamily.equals(AddressFamily.IPV4)) {
2852 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2853 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2854 } else if (addressFamily.equals(AddressFamily.IPV6)) {
2855 adfBuilder.setAfi((long) af_afi.AFI_IPV6.getValue());
2856 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2857 } else if (addressFamily.equals(AddressFamily.L2VPN)) {
2858 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2859 adfBuilder.setSafi((long) af_safi.SAFI_EVPN.getValue());
2861 LOG.debug("delVrf: Received Delete VRF : rd:{}, address family: {} {}", rd,
2862 adfBuilder.getAfi(), adfBuilder.getSafi());
2864 Vrfs vrfOriginal = bgpUtil.getVrfFromRd(rd);
2865 if (vrfOriginal == null) {
2866 LOG.error("delVrf: no vrf with existing rd {}. step aborted", rd);
2870 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
2871 InstanceIdentifier.builder(Bgp.class)
2872 .child(Vrfs.class, new VrfsKey(rd));
2874 InstanceIdentifier<Vrfs> iid = iib.build();
2876 @SuppressWarnings("static-access")
2877 InstanceIdentifier<Bgp> iid6 = iid.builder(Bgp.class).build()
2878 .child(Multipath.class, new MultipathKey(adfBuilder.getAfi(), adfBuilder.getSafi())).create(Bgp.class);
2879 InstanceIdentifierBuilder<Vrfs> iib3 = iid6.child(Vrfs.class, new VrfsKey(rd)).builder();
2880 InstanceIdentifier<Vrfs> iidFinal = iib3.build();
2882 //** update or delete the vrfs with the rest of AddressFamilies already present in the last list
2883 AddressFamiliesVrf adfToDel = adfBuilder.build();
2884 List<AddressFamiliesVrf> adfListOriginal = vrfOriginal.getAddressFamiliesVrf() == null
2885 ? new ArrayList<>() : vrfOriginal.getAddressFamiliesVrf();
2886 List<AddressFamiliesVrf> adfListToRemoveFromOriginal = new ArrayList<>();
2887 adfListOriginal.forEach(adf -> {
2888 if (adf.equals(adfToDel)) {
2889 adfListToRemoveFromOriginal.add(adfToDel);
2893 for (AddressFamiliesVrf adfToRemove : adfListToRemoveFromOriginal) {
2894 adfListOriginal.remove(adfToRemove);
2896 SingleTransactionDataBroker.syncWrite(dataBroker,
2897 LogicalDatastoreType.CONFIGURATION, iid, vrfOriginal);
2898 } catch (TransactionCommitFailedException e) {
2899 LOG.error("delVrf: Error updating VRF to datastore", e);
2900 throw new RuntimeException(e);
2903 if (adfListOriginal.isEmpty()) {
2904 LOG.debug("delVrf: delete iid: {}", iidFinal);
2908 // not all is removed
2912 public void setMultipathStatus(af_afi afi, af_safi safi, boolean enable) {
2913 long lafi = afi.getValue();
2914 long lsafi = safi.getValue();
2916 InstanceIdentifier.InstanceIdentifierBuilder<Multipath> iib =
2919 .child(Multipath.class,
2920 new MultipathKey(Long.valueOf(afi.getValue()), Long.valueOf(safi.getValue())));
2922 Multipath dto = new MultipathBuilder().setAfi(lafi).setSafi(lsafi).setMultipathEnabled(enable).build();
2923 update(iib.build(), dto);
2926 public void setMultipaths(String rd, int maxpath) {
2927 InstanceIdentifier.InstanceIdentifierBuilder<VrfMaxpath> iib =
2930 .child(VrfMaxpath.class, new VrfMaxpathKey(rd));
2932 VrfMaxpath dto = new VrfMaxpathBuilder().setRd(rd).setMaxpaths(maxpath).build();
2933 update(iib.build(), dto);
2936 public void delMultipaths(String rd) {
2937 InstanceIdentifier.InstanceIdentifierBuilder<VrfMaxpath> iib =
2938 InstanceIdentifier.builder(Bgp.class)
2939 .child(VrfMaxpath.class, new VrfMaxpathKey(rd));
2940 InstanceIdentifier<VrfMaxpath> iid = iib.build();
2945 * Remove Stale Marked Routes after timer expiry.
2947 private class RouteCleanup implements Callable<Integer> {
2950 public Integer call() {
2953 if (staledFibEntriesMap.isEmpty()) {
2954 LOG.info("BGP: RouteCleanup timertask tirggered but STALED FIB MAP is EMPTY");
2956 for (String rd : staledFibEntriesMap.keySet()) {
2957 if (Thread.interrupted()) {
2960 Map<String, Uint32> map = staledFibEntriesMap.get(rd);
2962 for (String key : map.keySet()) {
2963 if (Thread.interrupted()) {
2966 String prefix = extractPrefix(key);
2967 String nextHop = extractNextHop(key);
2969 LOG.debug("BGP: RouteCleanup deletePrefix called for : rd:{}, prefix{}, nextHop:{}",
2970 rd, prefix, nextHop);
2971 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix, nextHop);
2977 staledFibEntriesMap.clear();
2979 LOG.error("cleared {} stale routes after bgp restart", totalCleared);
2985 * BGP restart scenario, ODL-BGP manager was/is running.
2986 * On re-sync notification, Get a copy of FIB database.
2988 public void createStaleFibMap() {
2989 totalStaledCount = 0;
2991 staledFibEntriesMap.clear();
2992 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
2994 Optional<FibEntries> fibEntries = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2995 LogicalDatastoreType.CONFIGURATION, id);
2996 if (fibEntries.isPresent()) {
2997 List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
2998 for (VrfTables vrfTable : staleVrfTables) {
2999 Map<String, Uint32> staleFibEntMap = new HashMap<>();
3000 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
3001 if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
3002 //Stale marking and cleanup is only meant for the routes learned through BGP.
3005 if (Thread.interrupted()) {
3009 //Create MAP from staleVrfTables.
3010 vrfEntry.getRoutePaths()
3012 routePath -> staleFibEntMap.put(
3013 appendNextHopToPrefix(vrfEntry.getDestPrefix(),
3014 routePath.getNexthopAddress()), routePath.getLabel()));
3016 staledFibEntriesMap.put(vrfTable.getRouteDistinguisher(), staleFibEntMap);
3019 LOG.error("createStaleFibMap:: FIBentries.class is not present");
3021 } catch (ReadFailedException e) {
3022 LOG.error("createStaleFibMap:: error ", e);
3024 LOG.error("created {} staled entries ", totalStaledCount);
3028 * BGP config remove scenario, Need to remove all the
3029 * external routes from FIB.
3031 public void deleteExternalFibRoutes() {
3032 totalExternalRoutes = 0;
3033 totalExternalMacRoutes = 0;
3035 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
3037 Optional<FibEntries> fibEntries = SingleTransactionDataBroker.syncReadOptional(dataBroker,
3038 LogicalDatastoreType.CONFIGURATION, id);
3039 if (fibEntries.isPresent()) {
3040 if (fibEntries.get().getVrfTables() == null) {
3041 LOG.error("deleteExternalFibRoutes::getVrfTables is null");
3044 List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
3045 for (VrfTables vrfTable : staleVrfTables) {
3046 String rd = vrfTable.getRouteDistinguisher();
3047 if (vrfTable.getVrfEntry() != null) {
3048 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
3049 if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
3050 //route cleanup is only meant for the routes learned through BGP.
3053 totalExternalRoutes++;
3054 fibDSWriter.removeFibEntryFromDS(rd, vrfEntry.getDestPrefix());
3056 } else if (vrfTable.getMacVrfEntry() != null) {
3057 for (MacVrfEntry macEntry : vrfTable.getMacVrfEntry()) {
3058 if (RouteOrigin.value(macEntry.getOrigin()) != RouteOrigin.BGP) {
3059 //route cleanup is only meant for the routes learned through BGP.
3062 totalExternalMacRoutes++;
3063 fibDSWriter.removeMacEntryFromDS(rd, macEntry.getMac());
3068 LOG.error("deleteExternalFibRoutes:: FIBentries.class is not present");
3070 } catch (ReadFailedException e) {
3071 LOG.error("deleteExternalFibRoutes:: error ", e);
3073 LOG.debug("deleted {} fib entries {} mac entries", totalExternalRoutes, totalExternalMacRoutes);
3076 public boolean addToRt2TepMap(String rd, String tepIp, String mac, Uint32 l2vni) {
3077 boolean isFirstMacUpdateFromTep = false;
3078 if (rt2TepMap.containsKey(rd)) {
3079 if (rt2TepMap.get(rd).containsKey(tepIp)) {
3080 LOG.debug("RT2 with mac {} l2vni {} from existing rd {} and tep-ip {}. No Elan DS write required",
3081 mac, l2vni, rd, tepIp);
3082 rt2TepMap.get(rd).get(tepIp).put(mac, l2vni);
3084 LOG.debug("RT2 with mac {} l2vni {} from existing rd {} and new tep-ip {}",
3085 mac, l2vni, rd, tepIp);
3086 isFirstMacUpdateFromTep = true;
3087 Map<String, Uint32> macList = new HashMap<>();
3088 macList.put(mac, l2vni);
3089 rt2TepMap.get(rd).put(tepIp, macList);
3092 LOG.debug("RT2 with mac {} l2vni {} from new rd {} and tep ip {}",
3093 mac, l2vni, rd, tepIp);
3094 isFirstMacUpdateFromTep = true;
3095 Map<String, Uint32> macList = new HashMap<>();
3096 macList.put(mac, l2vni);
3097 Map<String, Map<String, Uint32>> tepIpMacMap = new HashMap<>();
3098 tepIpMacMap.put(tepIp, macList);
3099 rt2TepMap.put(rd, tepIpMacMap);
3101 return isFirstMacUpdateFromTep;
3104 public boolean deleteFromRt2TepMap(String rd, String tepIp, String mac) {
3105 boolean isLastMacUpdateFromTep = false;
3106 LOG.debug("RT2 withdraw with rd {} mac {} tep-ip {} ", rd, mac, tepIp);
3107 if (rt2TepMap.containsKey(rd)) {
3108 if (rt2TepMap.get(rd).containsKey(tepIp)) {
3109 if (rt2TepMap.get(rd).get(tepIp).containsKey(mac)) {
3110 LOG.debug("RT2 Withdraw : Removing the mac {} from Map", mac);
3111 rt2TepMap.get(rd).get(tepIp).remove(mac);
3112 if (rt2TepMap.get(rd).get(tepIp).isEmpty()) {
3113 isLastMacUpdateFromTep = true;
3114 LOG.debug("RT2 Withdraw : Removing the tep-ip {} from Map", tepIp);
3115 rt2TepMap.get(rd).remove(tepIp);
3116 if (rt2TepMap.get(rd).isEmpty()) {
3117 LOG.debug("RT2 Withdraw : Removing the rd {} from Map", rd);
3118 rt2TepMap.remove(rd);
3124 return isLastMacUpdateFromTep;
3127 public Collection<String> getTepIPs(String rd) {
3128 final Map<String, Map<String, Uint32>> tepIpMap = rt2TepMap.get(rd);
3129 return tepIpMap != null ? tepIpMap.keySet() : Collections.emptyList();
3132 public boolean isBgpConnected() {
3133 return (bgpRouter == null) ? false : bgpRouter.isBgpConnected();
3136 public long getLastConnectedTS() {
3137 return (bgpRouter == null) ? 0 : bgpRouter.getLastConnectedTS();
3140 public long getConnectTS() {
3141 return (bgpRouter == null) ? 0 : bgpRouter.getConnectTS();
3144 public long getStartTS() {
3145 return (bgpRouter == null) ? 0 : bgpRouter.getStartTS();
3148 public TTransport getTransport() {
3149 return bgpRouter.getTransport();
3152 public int getTotalStaledCount() {
3153 return totalStaledCount;
3156 public int getTotalCleared() {
3157 return totalCleared;
3160 public BgpCounters getBgpCounters() {
3161 return bgpCountersReference.get();
3164 private void startBgpCountersTask() {
3165 if (getBgpCounters() == null && bgpCountersReference.compareAndSet(null,
3166 new BgpCounters(getBgpSdncMipIp(), metricProvider))) {
3167 bgpCountersTask = executor.scheduleAtFixedRate(bgpCountersReference.get(), 0, 120 * 1000,
3168 TimeUnit.MILLISECONDS);
3169 LOG.info("Bgp Counters task scheduled for every two minutes.");
3171 bgpManager.setQbgpLog(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
3175 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
3176 justification = "https://github.com/spotbugs/spotbugs/issues/811")
3177 private void stopBgpCountersTask() {
3178 final BgpCounters bgpCounters = bgpCountersReference.getAndSet(null);
3179 if (bgpCounters != null) {
3180 bgpCountersTask.cancel(true);
3181 bgpCounters.close();
3185 private void startBgpAlarmsTask() {
3186 if (getBgpAlarms() == null && bgpAlarmsReference.compareAndSet(null, new BgpAlarms(this))) {
3187 bgpAlarmsReference.get().init();
3188 bgpAlarmsTask = executor.scheduleAtFixedRate(bgpAlarmsReference.get(), 0, 60 * 1000, TimeUnit.MILLISECONDS);
3189 LOG.info("Bgp Alarms task scheduled for every minute.");
3191 LOG.trace("Bgp Alarms task already scheduled for every minute.");
3195 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
3196 justification = "https://github.com/spotbugs/spotbugs/issues/811")
3197 private void stopBgpAlarmsTask() {
3198 final BgpAlarms bgpAlarms = bgpAlarmsReference.getAndSet(null);
3199 if (bgpAlarms != null) {
3200 bgpAlarmsTask.cancel(true);
3205 public BgpAlarms getBgpAlarms() {
3206 return bgpAlarmsReference.get();
3209 public void getPeerStatus(String nbrIp, long nbrAsNum) throws
3210 BgpRouterException, TException {
3211 bgpRouter.getPeerStatus(nbrIp, nbrAsNum);
3214 private static String appendNextHopToPrefix(String prefix, String nextHop) {
3215 return prefix + ":" + nextHop;
3218 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
3219 justification = "https://github.com/spotbugs/spotbugs/issues/811")
3220 private static String extractPrefix(String prefixNextHop) {
3221 return prefixNextHop.split(":")[0];
3224 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
3225 justification = "https://github.com/spotbugs/spotbugs/issues/811")
3226 private static String extractNextHop(String prefixNextHop) {
3227 return prefixNextHop.split(":")[1];
3230 private static String extractMd5Secret(final Neighbors val) {
3231 String md5Secret = null;
3232 TcpSecurityOption tcpSecOpt = val.getTcpSecurityOption();
3233 if (tcpSecOpt != null) {
3234 if (tcpSecOpt instanceof TcpMd5SignatureOption) {
3235 md5Secret = ((TcpMd5SignatureOption) tcpSecOpt).getTcpMd5SignaturePassword().getValue();
3236 } else { // unknown TcpSecurityOption
3237 LOG.debug("neighbors Ignored unknown tcp-security-option of peer {}", val.getAddress().getValue());
3241 } // private method extractMd5Secret