2 * Copyright © 2015, 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.netvirt.bgpmanager;
10 import static org.opendaylight.netvirt.bgpmanager.oam.BgpConstants.HISTORY_LIMIT;
11 import static org.opendaylight.netvirt.bgpmanager.oam.BgpConstants.HISTORY_THRESHOLD;
13 import com.google.common.base.Optional;
14 import com.google.common.base.Preconditions;
15 import com.google.common.net.InetAddresses;
16 import com.google.common.util.concurrent.ThreadFactoryBuilder;
17 import io.netty.util.concurrent.GlobalEventExecutor;
18 import java.lang.reflect.Constructor;
19 import java.lang.reflect.InvocationTargetException;
20 import java.net.InetAddress;
21 import java.net.InetSocketAddress;
22 import java.net.NetworkInterface;
23 import java.net.SocketException;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.Enumeration;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
32 import java.util.Objects;
33 import java.util.Timer;
34 import java.util.concurrent.Callable;
35 import java.util.concurrent.ConcurrentHashMap;
36 import java.util.concurrent.CountDownLatch;
37 import java.util.concurrent.ExecutionException;
38 import java.util.concurrent.Executors;
39 import java.util.concurrent.Future;
40 import java.util.concurrent.ScheduledExecutorService;
41 import java.util.concurrent.ScheduledFuture;
42 import java.util.concurrent.TimeUnit;
43 import java.util.concurrent.TimeoutException;
44 import java.util.concurrent.atomic.AtomicInteger;
45 import java.util.concurrent.atomic.AtomicReference;
46 import javax.annotation.PreDestroy;
47 import javax.inject.Inject;
48 import javax.inject.Singleton;
49 import org.apache.thrift.TApplicationException;
50 import org.apache.thrift.TException;
51 import org.apache.thrift.transport.TTransport;
52 import org.eclipse.jdt.annotation.Nullable;
53 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
54 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
55 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
56 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
57 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
58 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
59 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
60 import org.opendaylight.genius.mdsalutil.NwConstants;
61 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
62 import org.opendaylight.infrautils.metrics.MetricProvider;
63 import org.opendaylight.mdsal.eos.binding.api.Entity;
64 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
65 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipListenerRegistration;
66 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
67 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
68 import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
69 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
70 import org.opendaylight.netvirt.bgpmanager.commands.ClearBgpCli;
71 import org.opendaylight.netvirt.bgpmanager.oam.BgpAlarms;
72 import org.opendaylight.netvirt.bgpmanager.oam.BgpConstants;
73 import org.opendaylight.netvirt.bgpmanager.oam.BgpCounters;
74 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouter;
75 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouterException;
76 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpSyncHandle;
77 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Routes;
78 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Update;
79 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
80 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
81 import org.opendaylight.netvirt.bgpmanager.thrift.gen.protocol_type;
82 import org.opendaylight.netvirt.bgpmanager.thrift.gen.qbgpConstants;
83 import org.opendaylight.netvirt.bgpmanager.thrift.server.BgpThriftService;
84 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
85 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.IVpnLinkService;
86 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionHistory;
87 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
88 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfig;
89 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfigBuilder;
90 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.AddressFamily;
91 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
92 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.BgpControlPlaneType;
93 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.EncapType;
94 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.TcpMd5SignaturePasswordType;
95 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsId;
96 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsIdBuilder;
97 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServer;
98 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServerBuilder;
99 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.DcgwTepList;
100 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestart;
101 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestartBuilder;
102 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Logging;
103 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.LoggingBuilder;
104 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Multipath;
105 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.MultipathBuilder;
106 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.MultipathKey;
107 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Neighbors;
108 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsBuilder;
109 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsKey;
110 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Networks;
111 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksBuilder;
112 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksKey;
113 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpath;
114 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpathBuilder;
115 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpathKey;
116 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Vrfs;
117 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsBuilder;
118 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsKey;
119 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTep;
120 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepBuilder;
121 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepKey;
122 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamilies;
123 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesBuilder;
124 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesKey;
125 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihop;
126 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihopBuilder;
127 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSource;
128 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSourceBuilder;
129 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfs.AddressFamiliesVrf;
130 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfs.AddressFamiliesVrfBuilder;
131 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.TcpSecurityOption;
132 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.tcp.security.option.TcpMd5SignatureOption;
133 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.tcp.security.option.TcpMd5SignatureOptionBuilder;
134 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
135 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
136 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
137 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
138 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
139 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.macvrfentries.MacVrfEntry;
140 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
141 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
142 import org.opendaylight.yangtools.yang.binding.DataObject;
143 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
144 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
145 import org.osgi.framework.BundleContext;
146 import org.osgi.util.tracker.ServiceTracker;
147 import org.slf4j.Logger;
148 import org.slf4j.LoggerFactory;
151 public class BgpConfigurationManager {
152 private static final Logger LOG = LoggerFactory.getLogger(BgpConfigurationManager.class);
154 // to have stale FIB map (RD, Prefix)
155 // number of seconds wait for route sync-up between ODL and BGP
156 private static final int BGP_RESTART_ROUTE_SYNC_SEC = 600;
157 private static final String UPDATE_PORT = "bgp.thrift.service.port";
158 private static final String CONFIG_HOST = "vpnservice.bgpspeaker.host.name";
159 private static final String CONFIG_PORT = "vpnservice.bgpspeaker.thrift.port";
160 private static final String DEF_UPORT = "6644";
161 private static final String DEF_CHOST = "255.255.255.255"; // Invalid Host IP
162 private static final String DEF_CPORT = "7644";
163 private static final String DEF_BGP_SDNC_MIP = "127.0.0.1";
164 //vpnservice.bgp.thrift.bgp.mip is the MIP present with ODL. Here we open 6644 port
165 private static final String BGP_SDNC_MIP = "vpnservice.bgp.thrift.bgp.mip";
166 private static final String BGP_GR_RESTART_TIMER_PROPERTY = "vpnservice.bgp.gr.timer";
167 private static final String BGP_KA_TIMER_PROPERTY = "vpnservice.bgp.ka.timer";
168 private static final String BGP_HOLD_TIMER_PROPERTY = "vpnservice.bgp.hold.timer";
169 private static final String BGP_EOR_DELAY_PROPERTY = "vpnservice.bgp.eordelay";
170 private static final int DEF_BGP_KA_TIME = 60;
171 private static final int DEF_BGP_HOLD_TIME = 180;
172 private static final int DEF_BGP_GR_TIME = 4000;
173 private static final int RESTART_DEFAULT_GR = 90;
174 private static final int DS_RETRY_COUNT = 100; //100 retries, each after WAIT_TIME_BETWEEN_EACH_TRY_MILLIS seconds
175 private static final long WAIT_TIME_BETWEEN_EACH_TRY_MILLIS = 1000L; //one second sleep after every retry
176 private static final String BGP_ENTITY_TYPE_FOR_OWNERSHIP = "bgp";
177 private static final String BGP_EOR_DELAY = "vpnservice.bgp.eordelay";
178 private static final String DEF_BGP_EOR_DELAY = "1800";
179 private static final String BGP_ENTITY_NAME = "bgp";
180 private static final String ADD_WARN = "Config store updated; undo with Delete if needed.";
181 private static final String DEL_WARN = "Config store updated; undo with Add if needed.";
182 private static final String UPD_WARN = "Update operation not supported; Config store updated;"
183 + " restore with another Update if needed.";
184 private static long bgp_as_num = 0;
185 private int bgpKaTime = 0;
186 private int bgpHoldTime = 0;
187 private int bgpGrRestartTime = 0;
189 private static final Class<?>[] REACTORS = {
190 ConfigServerReactor.class, AsIdReactor.class,
191 GracefulRestartReactor.class, LoggingReactor.class,
192 NeighborsReactor.class, UpdateSourceReactor.class,
193 EbgpMultihopReactor.class, AddressFamiliesReactor.class,
194 NetworksReactor.class, VrfsReactor.class, BgpReactor.class,
195 MultipathReactor.class, VrfMaxpathReactor.class, BfdConfigReactor.class
198 private IBgpManager bgpManager;
199 private final DataBroker dataBroker;
200 private final FibDSWriter fibDSWriter;
201 private final IVpnLinkService vpnLinkService;
202 private final BundleContext bundleContext;
203 private final BgpUtil bgpUtil;
204 private volatile Bgp config;
205 private final BgpRouter bgpRouter;
206 private final BgpSyncHandle bgpSyncHandle = new BgpSyncHandle();
207 private volatile BgpThriftService bgpThriftService = null;
208 private final int delayEorSeconds;
210 private final CountDownLatch initer = new CountDownLatch(1);
212 private final String hostStartup;
213 private final String portStartup;
215 private final AtomicReference<BgpCounters> bgpCountersReference = new AtomicReference<>();
216 private ScheduledFuture<?> bgpCountersTask;
218 private final AtomicReference<BgpAlarms> bgpAlarmsReference = new AtomicReference<>();
219 private ScheduledFuture<?> bgpAlarmsTask;
221 private Future<?> lastReplayJobFt;
222 private ScheduledFuture<?> routeCleanupFuture;
224 private long staleStartTime;
225 private long staleEndTime;
226 private long cfgReplayStartTime;
227 private long cfgReplayEndTime;
228 private long staleCleanupTime;
229 private int totalStaledCount;
230 private int totalCleared;
231 private int totalExternalRoutes;
232 private int totalExternalMacRoutes;
234 private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(
235 new ThreadFactoryBuilder().setNameFormat("BgpConfigurationManager-%d").setDaemon(true).build());
238 * this map store the new address families to send to quagga. When it is sended you must clear it.
239 * The keys String are rd (route distinguisher).
241 private final ConcurrentHashMap<String, List<AddressFamiliesVrf>> mapNewAdFamily = new ConcurrentHashMap<>();
243 // map<rd, map<prefix/len:nexthop, label>>
244 private final Map<String, Map<String, Long>> staledFibEntriesMap = new ConcurrentHashMap<>();
246 // map<rd, map<tep-ip, map<mac, l2vni>>>
247 private final Map<String, Map<String, Map<String, Long>>> rt2TepMap = new ConcurrentHashMap<>();
249 private final List<AutoCloseable> listeners = new ArrayList<>();
251 private final EntityOwnershipUtils entityOwnershipUtils;
252 private final EntityOwnershipCandidateRegistration candidateRegistration;
253 private final EntityOwnershipListenerRegistration entityListenerRegistration;
254 private final MetricProvider metricProvider;
255 private final TransactionHistory bgpUpdatesHistory;
258 public BgpConfigurationManager(final DataBroker dataBroker,
259 final EntityOwnershipService entityOwnershipService,
260 final FibDSWriter fibDSWriter,
261 final IVpnLinkService vpnLinkSrvce,
262 final BundleContext bundleContext,
263 final BgpUtil bgpUtil,
264 final MetricProvider metricProvider) {
265 this.dataBroker = dataBroker;
266 this.fibDSWriter = fibDSWriter;
267 this.vpnLinkService = vpnLinkSrvce;
268 this.bundleContext = bundleContext;
269 this.bgpUtil = bgpUtil;
270 this.metricProvider = metricProvider;
271 hostStartup = getProperty(CONFIG_HOST, DEF_CHOST);
272 portStartup = getProperty(CONFIG_PORT, DEF_CPORT);
274 Integer.parseInt(getProperty(BGP_KA_TIMER_PROPERTY,
275 Integer.toString(DEF_BGP_KA_TIME)));
277 Integer.parseInt(getProperty(BGP_HOLD_TIMER_PROPERTY,
278 Integer.toString(DEF_BGP_HOLD_TIME)));
280 Integer.parseInt(getProperty(BGP_GR_RESTART_TIMER_PROPERTY,
281 Integer.toString(DEF_BGP_GR_TIME)));
282 LOG.info("ConfigServer at {}:{}", hostStartup, portStartup);
283 VtyshCli.setHostAddr(hostStartup);
284 ClearBgpCli.setHostAddr(hostStartup);
285 bgpUpdatesHistory = new TransactionHistory(HISTORY_LIMIT, HISTORY_THRESHOLD);
286 bgpRouter = BgpRouter.newInstance(this::getConfig, this::isBGPEntityOwner, bgpUpdatesHistory);
287 delayEorSeconds = Integer.parseInt(getProperty(BGP_EOR_DELAY, DEF_BGP_EOR_DELAY));
289 entityOwnershipUtils = new EntityOwnershipUtils(entityOwnershipService);
291 candidateRegistration = registerEntityCandidate(entityOwnershipService);
292 entityListenerRegistration = registerEntityListener(entityOwnershipService);
294 LOG.info("BGP Configuration manager initialized");
297 GlobalEventExecutor.INSTANCE.execute(() -> {
298 ServiceTracker<IBgpManager, ?> tracker = null;
300 tracker = new ServiceTracker<>(bundleContext, IBgpManager.class, null);
302 bgpManager = (IBgpManager) tracker.waitForService(TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES));
303 Preconditions.checkState(bgpManager != null, "IBgpManager service not found");
304 } catch (InterruptedException e) {
305 throw new IllegalStateException("Error retrieving IBgpManager service", e);
307 if (tracker != null) {
312 String updatePort = getProperty(UPDATE_PORT, DEF_UPORT);
313 if (InetAddresses.isInetAddress(getBgpSdncMipIp())) {
314 InetSocketAddress bgpThriftServerSocketAddr = new InetSocketAddress(getBgpSdncMipIp(),
315 Integer.parseInt(updatePort));
316 bgpThriftService = new BgpThriftService(bgpThriftServerSocketAddr, bgpManager, this);
317 if (isBGPEntityOwner()) {
318 //I am EoS owner of BGP, opening bgp thrift UPDATE-SERVER port.
319 LOG.info("BGP Configuration manager initialized: UPDATE-SERVER started");
320 bgpThriftService.start();
322 LOG.info("UPDATE server started :ip:port={}:{}", getBgpSdncMipIp(), updatePort);
324 LOG.error("Failed to init UPDATE server invalid ip:port={}:{}", getBgpSdncMipIp(), updatePort);
328 LOG.info("BgpConfigurationManager initialized. IBgpManager={}", bgpManager);
331 public String getBgpSdncMipIp() {
332 return getProperty(BGP_SDNC_MIP, DEF_BGP_SDNC_MIP);
335 public long getStaleCleanupTime() {
336 return staleCleanupTime;
339 public void setStaleCleanupTime(long staleCleanupTime) {
340 this.staleCleanupTime = staleCleanupTime;
343 public long getCfgReplayEndTime() {
344 return cfgReplayEndTime;
347 public void setCfgReplayEndTime(long cfgReplayEndTime) {
348 this.cfgReplayEndTime = cfgReplayEndTime;
351 public TransactionHistory getBgpUpdatesHistory() {
352 return bgpUpdatesHistory;
355 public long getCfgReplayStartTime() {
356 return cfgReplayStartTime;
359 public void setCfgReplayStartTime(long cfgReplayStartTime) {
360 this.cfgReplayStartTime = cfgReplayStartTime;
363 public long getStaleEndTime() {
367 public void setStaleEndTime(long staleEndTime) {
368 this.staleEndTime = staleEndTime;
371 public long getStaleStartTime() {
372 return staleStartTime;
375 public void setStaleStartTime(long staleStartTime) {
376 this.staleStartTime = staleStartTime;
379 private Object createListener(Class<?> cls) {
381 Constructor<?> ctor = cls.getConstructor(BgpConfigurationManager.class);
382 return ctor.newInstance(this);
383 } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException
385 LOG.error("Failed to create listener object", e);
390 private void registerCallbacks() {
391 for (Class<?> reactor : REACTORS) {
392 Object obj = createListener(reactor);
394 AsyncDataTreeChangeListenerBase dcl = (AsyncDataTreeChangeListenerBase) obj;
395 dcl.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
401 @SuppressWarnings("checkstyle:IllegalCatch")
403 public void close() {
406 if (bgpThriftService != null) {
407 bgpThriftService.stop();
408 bgpThriftService = null;
411 if (isBgpConnected()) {
412 //disconnect the CONFIG SERVER port (which was )opened during I was Owner
413 bgpRouter.disconnect();
416 if (candidateRegistration != null) {
417 candidateRegistration.close();
420 entityListenerRegistration.close();
422 listeners.forEach(l -> {
425 } catch (Exception e) {
426 LOG.warn("Error closing {}", l ,e);
430 LOG.info("{} close", getClass().getSimpleName());
433 private String getProperty(String var, String def) {
434 String property = bundleContext.getProperty(var);
435 return property == null ? def : property;
438 private EntityOwnershipCandidateRegistration registerEntityCandidate(
439 final EntityOwnershipService entityOwnershipService) {
441 return entityOwnershipService.registerCandidate(
442 new Entity(BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME));
443 } catch (CandidateAlreadyRegisteredException e) {
444 LOG.error("failed to register bgp entity", e);
449 private EntityOwnershipListenerRegistration registerEntityListener(
450 final EntityOwnershipService entityOwnershipService) {
451 return entityOwnershipService.registerListener(BGP_ENTITY_TYPE_FOR_OWNERSHIP, ownershipChange -> {
452 LOG.info("entity owner change event fired: {}", ownershipChange);
454 if (ownershipChange.getState() == EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED) {
455 LOG.info("This PL is the Owner");
456 if (bgpThriftService != null) {
457 //opening UPDATE-SERVER port.
458 bgpThriftService.start();
460 LOG.error("I am the owner of BGP entity, but bgpThriftService is not initialized yet");
464 LOG.info("Not owner: hasOwner: {}, isOwner: {}", ownershipChange.getState().hasOwner(),
465 ownershipChange.getState().isOwner());
466 if (bgpThriftService != null && bgpThriftService.isBgpThriftServiceStarted()) {
467 //close the bgp Thrift Update-SERVER port opened on non-Entity Owner
468 bgpThriftService.stop();
470 if (isBgpConnected()) {
471 //disconnect the CONFIG SERVER port (which was )opened during I was Owner
472 bgpRouter.disconnect();
478 public boolean isBGPEntityOwner() {
479 if (entityOwnershipUtils == null) {
480 LOG.error("entityOwnershipUtils is NULL when listener callbacks fired");
483 return entityOwnershipUtils.isEntityOwner(new Entity(BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME), 0, 1);
487 config = getConfig();
491 public class ConfigServerReactor
492 extends AsyncDataTreeChangeListenerBase<ConfigServer, ConfigServerReactor>
493 implements ClusteredDataTreeChangeListener<ConfigServer> {
494 private static final String YANG_OBJ = "config-server ";
496 public ConfigServerReactor() {
497 super(ConfigServer.class, ConfigServerReactor.class);
501 protected void add(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
502 LOG.trace("received bgp connect config host {}", val.getHost().getValue());
503 if (!isBGPEntityOwner()) {
509 } catch (InterruptedException e) {
512 LOG.debug("issueing bgp router connect to host {}", val.getHost().getValue());
513 bgpRouter.configServerUpdated();
514 synchronized (BgpConfigurationManager.this) {
515 boolean res = bgpRouter.connect(val.getHost().getValue(),
516 val.getPort().intValue());
518 LOG.error(YANG_OBJ + "Add failed; " + ADD_WARN);
521 VtyshCli.setHostAddr(val.getHost().getValue());
522 ClearBgpCli.setHostAddr(val.getHost().getValue());
526 protected ConfigServerReactor getDataTreeChangeListener() {
527 return ConfigServerReactor.this;
531 protected InstanceIdentifier<ConfigServer> getWildCardPath() {
532 return InstanceIdentifier.create(Bgp.class).child(ConfigServer.class);
536 protected void remove(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
537 LOG.trace("received bgp disconnect");
538 if (!isBGPEntityOwner()) {
542 bgpRouter.configServerUpdated();
544 synchronized (BgpConfigurationManager.this) {
545 if (bgp_as_num != 0) {
547 bgpRouter.stopBgp(bgp_as_num);
548 stopBgpCountersTask();
550 } catch (TException | BgpRouterException e) {
551 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
554 LOG.debug("bgp as-id is null while removing config-server");
556 bgpRouter.disconnect();
561 protected void update(InstanceIdentifier<ConfigServer> iid,
562 ConfigServer oldval, ConfigServer newval) {
563 LOG.trace("received bgp Connection update");
564 if (!isBGPEntityOwner()) {
567 LOG.error(YANG_OBJ + UPD_WARN);
571 private BgpRouter getClient(String yangObj) {
572 if (bgpRouter == null || !bgpRouter.isBgpConnected()) {
573 LOG.warn("{}: configuration received when BGP is inactive", yangObj);
579 public class AsIdReactor
580 extends AsyncDataTreeChangeListenerBase<AsId, AsIdReactor>
581 implements ClusteredDataTreeChangeListener<AsId> {
583 private static final String YANG_OBJ = "as-id ";
585 public AsIdReactor() {
586 super(AsId.class, AsIdReactor.class);
590 protected void add(InstanceIdentifier<AsId> iid, AsId val) {
591 LOG.error("received bgp add asid {}", val);
592 if (!isBGPEntityOwner()) {
595 LOG.debug("received add router config asNum {}", val.getLocalAs());
596 bgp_as_num = val.getLocalAs().longValue();
597 synchronized (BgpConfigurationManager.this) {
598 BgpRouter br = getClient(YANG_OBJ);
600 LOG.debug("{} Unable to process add for asNum {}; {} {}", YANG_OBJ, val.getLocalAs(),
601 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
606 startBgpCountersTask();
607 startBgpAlarmsTask();
612 protected AsIdReactor getDataTreeChangeListener() {
613 return AsIdReactor.this;
617 protected InstanceIdentifier<AsId> getWildCardPath() {
618 return InstanceIdentifier.create(Bgp.class).child(AsId.class);
622 protected void remove(InstanceIdentifier<AsId> iid, AsId val) {
623 LOG.error("received delete router config asNum {}", val.getLocalAs());
624 if (!isBGPEntityOwner()) {
627 synchronized (BgpConfigurationManager.this) {
628 long asNum = val.getLocalAs();
629 BgpRouter br = getClient(YANG_OBJ);
632 LOG.debug("{} Unable to process remove for asNum {}; {} {}", YANG_OBJ, asNum,
633 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
638 } catch (TException | BgpRouterException e) {
639 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
642 stopBgpCountersTask();
645 Bgp conf = getConfig();
647 LOG.error("Config Null while removing the as-id");
650 LOG.debug("Removing external routes from FIB");
651 deleteExternalFibRoutes();
652 List<Neighbors> nbrs = conf.getNeighbors();
653 if (nbrs != null && nbrs.size() > 0) {
654 LOG.error("Tring to remove the as-id when neighbor config is already present");
655 for (Neighbors nbr : nbrs) {
656 LOG.debug("Removing Neighbor {} from Data store", nbr.getAddress().getValue());
657 delNeighbor(nbr.getAddress().getValue());
664 protected void update(InstanceIdentifier<AsId> iid,
665 AsId oldval, AsId newval) {
666 if (!isBGPEntityOwner()) {
669 LOG.error(YANG_OBJ + UPD_WARN);
673 public class GracefulRestartReactor
674 extends AsyncDataTreeChangeListenerBase<GracefulRestart, GracefulRestartReactor>
675 implements ClusteredDataTreeChangeListener<GracefulRestart> {
677 private static final String YANG_OBJ = "graceful-restart ";
679 public GracefulRestartReactor() {
680 super(GracefulRestart.class, GracefulRestartReactor.class);
684 protected void add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
685 if (!isBGPEntityOwner()) {
688 synchronized (BgpConfigurationManager.this) {
689 int stalePathTime = val.getStalepathTime().intValue();
690 BgpRouter br = getClient(YANG_OBJ);
692 LOG.error("{} Unable to add stale-path time {}; {} {}", YANG_OBJ, stalePathTime,
693 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
697 br.addGracefulRestart(stalePathTime);
698 } catch (TException | BgpRouterException e) {
699 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
705 protected GracefulRestartReactor getDataTreeChangeListener() {
706 return GracefulRestartReactor.this;
710 protected InstanceIdentifier<GracefulRestart> getWildCardPath() {
711 return InstanceIdentifier.create(Bgp.class).child(GracefulRestart.class);
715 protected void remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
716 if (!isBGPEntityOwner()) {
719 LOG.debug("received delete GracefulRestart config val {}", val.getStalepathTime().intValue());
720 synchronized (BgpConfigurationManager.this) {
721 BgpRouter br = getClient(YANG_OBJ);
723 LOG.error("{} Unable to delete stale-path time; {} {}", YANG_OBJ,
724 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
728 br.delGracefulRestart();
729 } catch (TException | BgpRouterException e) {
730 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
736 protected void update(InstanceIdentifier<GracefulRestart> iid,
737 GracefulRestart oldval, GracefulRestart newval) {
738 if (!isBGPEntityOwner()) {
741 LOG.debug("received update GracefulRestart config val {}", newval.getStalepathTime().intValue());
742 synchronized (BgpConfigurationManager.this) {
743 int stalePathTime = newval.getStalepathTime().intValue();
744 BgpRouter br = getClient(YANG_OBJ);
746 LOG.error("{} Unable to update stale-path time to {}; {} {}", YANG_OBJ, stalePathTime,
747 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
751 br.addGracefulRestart(stalePathTime);
752 } catch (TException | BgpRouterException e) {
753 LOG.error("{} update received exception; {}", YANG_OBJ, ADD_WARN, e);
759 public class LoggingReactor
760 extends AsyncDataTreeChangeListenerBase<Logging, LoggingReactor>
761 implements ClusteredDataTreeChangeListener<Logging> {
763 private static final String YANG_OBJ = "logging ";
765 public LoggingReactor() {
766 super(Logging.class, LoggingReactor.class);
770 protected void add(InstanceIdentifier<Logging> iid, Logging val) {
771 if (!isBGPEntityOwner()) {
774 synchronized (BgpConfigurationManager.this) {
775 BgpRouter br = getClient(YANG_OBJ);
777 LOG.error("{} Unable to add logging for qbgp; {} {}", YANG_OBJ,
778 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
782 br.setLogging(val.getFile(), val.getLevel());
783 } catch (TException | BgpRouterException e) {
784 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
790 protected LoggingReactor getDataTreeChangeListener() {
791 return LoggingReactor.this;
795 protected InstanceIdentifier<Logging> getWildCardPath() {
796 return InstanceIdentifier.create(Bgp.class).child(Logging.class);
800 protected void remove(InstanceIdentifier<Logging> iid, Logging val) {
801 if (!isBGPEntityOwner()) {
804 LOG.debug("received remove Logging config val {}", val.getLevel());
805 synchronized (BgpConfigurationManager.this) {
806 BgpRouter br = getClient(YANG_OBJ);
808 LOG.error("{} Unable to remove logging for qbgp; {} {}", YANG_OBJ,
809 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
813 br.setLogging(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
814 } catch (TException | BgpRouterException e) {
815 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
821 protected void update(InstanceIdentifier<Logging> iid,
822 Logging oldval, Logging newval) {
823 if (!isBGPEntityOwner()) {
826 synchronized (BgpConfigurationManager.this) {
827 BgpRouter br = getClient(YANG_OBJ);
829 LOG.error("{} Unable to update logging for qbgp; {} {}", YANG_OBJ,
830 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
834 br.setLogging(newval.getFile(), newval.getLevel());
835 } catch (TException | BgpRouterException e) {
836 LOG.error("{} newval received exception; {}", YANG_OBJ, ADD_WARN, e);
842 public class NeighborsReactor
843 extends AsyncDataTreeChangeListenerBase<Neighbors, NeighborsReactor>
844 implements ClusteredDataTreeChangeListener<Neighbors> {
846 private static final String YANG_OBJ = "neighbors ";
848 public NeighborsReactor() {
849 super(Neighbors.class, NeighborsReactor.class);
853 protected void add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
854 if (!isBGPEntityOwner()) {
857 LOG.debug("received add Neighbors config val {}", val.getAddress().getValue());
858 synchronized (BgpConfigurationManager.this) {
859 String peerIp = val.getAddress().getValue();
860 long as = val.getRemoteAs();
861 final String md5Secret = extractMd5Secret(val);
862 BgpRouter br = getClient(YANG_OBJ);
864 LOG.debug("{} Unable to process add for peer {} as {}; {} {}", YANG_OBJ, peerIp, as,
865 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
869 //itmProvider.buildTunnelsToDCGW(new IpAddress(peerIp.toCharArray()));
870 br.addNeighbor(peerIp, as, md5Secret);
872 } catch (TException | BgpRouterException e) {
873 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
879 protected NeighborsReactor getDataTreeChangeListener() {
880 return NeighborsReactor.this;
884 protected InstanceIdentifier<Neighbors> getWildCardPath() {
885 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class);
889 protected void remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
890 if (!isBGPEntityOwner()) {
893 LOG.debug("received remove Neighbors config val {}", val.getAddress().getValue());
894 synchronized (BgpConfigurationManager.this) {
895 String peerIp = val.getAddress().getValue();
896 BgpRouter br = getClient(YANG_OBJ);
898 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
899 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
903 //itmProvider.deleteTunnelsToDCGW(new IpAddress(val.getAddress().getValue().toCharArray()));
904 br.delNeighbor(peerIp);
905 } catch (TException | BgpRouterException e) {
906 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
909 final BgpAlarms bgpAlarms = getBgpAlarms();
910 if (bgpAlarms != null) {
911 bgpAlarms.clearBgpNbrDownAlarm(peerIp);
914 if (bgpUtil.isBfdEnabled()) {
915 final BgpCounters bgpCounters = getBgpCounters();
916 if (bgpCounters != null) {
917 bgpCounters.clearBfdNbrCounters(peerIp);
924 protected void update(InstanceIdentifier<Neighbors> iid,
925 Neighbors oldval, Neighbors newval) {
926 if (!isBGPEntityOwner()) {
929 //purposefully nothing to do.
933 public class EbgpMultihopReactor
934 extends AsyncDataTreeChangeListenerBase<EbgpMultihop, EbgpMultihopReactor>
935 implements ClusteredDataTreeChangeListener<EbgpMultihop> {
937 private static final String YANG_OBJ = "ebgp-multihop ";
939 public EbgpMultihopReactor() {
940 super(EbgpMultihop.class, EbgpMultihopReactor.class);
944 protected void add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
945 if (!isBGPEntityOwner()) {
948 LOG.debug("received add EbgpMultihop config val {}", val.getPeerIp().getValue());
949 synchronized (BgpConfigurationManager.this) {
950 String peerIp = val.getPeerIp().getValue();
951 BgpRouter br = getClient(YANG_OBJ);
953 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
954 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
958 br.addEbgpMultihop(peerIp, val.getNhops().intValue());
959 } catch (TException | BgpRouterException e) {
960 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
966 protected EbgpMultihopReactor getDataTreeChangeListener() {
967 return EbgpMultihopReactor.this;
971 protected InstanceIdentifier<EbgpMultihop> getWildCardPath() {
972 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(EbgpMultihop.class);
976 protected void remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
977 if (!isBGPEntityOwner()) {
980 LOG.debug("received remove EbgpMultihop config val {}", val.getPeerIp().getValue());
981 synchronized (BgpConfigurationManager.this) {
982 String peerIp = val.getPeerIp().getValue();
983 BgpRouter br = getClient(YANG_OBJ);
985 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
986 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
990 br.delEbgpMultihop(peerIp);
991 } catch (TException | BgpRouterException e) {
992 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
998 protected void update(InstanceIdentifier<EbgpMultihop> iid,
999 EbgpMultihop oldval, EbgpMultihop newval) {
1000 if (!isBGPEntityOwner()) {
1003 LOG.error(YANG_OBJ + UPD_WARN);
1007 public class UpdateSourceReactor
1008 extends AsyncDataTreeChangeListenerBase<UpdateSource, UpdateSourceReactor>
1009 implements ClusteredDataTreeChangeListener<UpdateSource> {
1011 private static final String YANG_OBJ = "update-source ";
1013 public UpdateSourceReactor() {
1014 super(UpdateSource.class, UpdateSourceReactor.class);
1018 protected void add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
1019 if (!isBGPEntityOwner()) {
1022 LOG.debug("received add UpdateSource config val {}", val.getSourceIp().getValue());
1023 synchronized (BgpConfigurationManager.this) {
1024 String peerIp = val.getPeerIp().getValue();
1025 BgpRouter br = getClient(YANG_OBJ);
1027 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
1028 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1032 br.addUpdateSource(peerIp, val.getSourceIp().getValue());
1033 } catch (TException | BgpRouterException e) {
1034 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1040 protected UpdateSourceReactor getDataTreeChangeListener() {
1041 return UpdateSourceReactor.this;
1045 protected InstanceIdentifier<UpdateSource> getWildCardPath() {
1046 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(UpdateSource.class);
1050 protected void remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
1051 if (!isBGPEntityOwner()) {
1054 LOG.debug("received remove UpdateSource config val {}", val.getSourceIp().getValue());
1055 synchronized (BgpConfigurationManager.this) {
1056 String peerIp = val.getPeerIp().getValue();
1057 BgpRouter br = getClient(YANG_OBJ);
1059 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
1060 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1064 br.delUpdateSource(peerIp);
1065 } catch (TException | BgpRouterException e) {
1066 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1072 protected void update(InstanceIdentifier<UpdateSource> iid,
1073 UpdateSource oldval, UpdateSource newval) {
1074 if (!isBGPEntityOwner()) {
1077 LOG.error(YANG_OBJ + UPD_WARN);
1081 public class AddressFamiliesReactor
1082 extends AsyncDataTreeChangeListenerBase<AddressFamilies, AddressFamiliesReactor>
1083 implements ClusteredDataTreeChangeListener<AddressFamilies> {
1085 private static final String YANG_OBJ = "address-families ";
1087 public AddressFamiliesReactor() {
1088 super(AddressFamilies.class, AddressFamiliesReactor.class);
1092 protected void add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
1093 if (!isBGPEntityOwner()) {
1096 LOG.debug("received add AddressFamilies config val {}", val.getPeerIp().getValue());
1097 synchronized (BgpConfigurationManager.this) {
1098 String peerIp = val.getPeerIp().getValue();
1099 BgpRouter br = getClient(YANG_OBJ);
1101 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
1102 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1105 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
1106 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
1108 br.addAddressFamily(peerIp, afi, safi);
1109 } catch (TException | BgpRouterException e) {
1110 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1116 protected AddressFamiliesReactor getDataTreeChangeListener() {
1117 return AddressFamiliesReactor.this;
1121 protected InstanceIdentifier<AddressFamilies> getWildCardPath() {
1122 return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(AddressFamilies.class);
1126 protected void remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
1127 if (!isBGPEntityOwner()) {
1130 LOG.debug("received remove AddressFamilies config val {}", val.getPeerIp().getValue());
1131 synchronized (BgpConfigurationManager.this) {
1132 String peerIp = val.getPeerIp().getValue();
1133 BgpRouter br = getClient(YANG_OBJ);
1135 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
1136 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1139 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
1140 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
1142 br.delAddressFamily(peerIp, afi, safi);
1143 } catch (TException | BgpRouterException e) {
1144 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1150 protected void update(InstanceIdentifier<AddressFamilies> iid,
1151 AddressFamilies oldval, AddressFamilies newval) {
1152 if (!isBGPEntityOwner()) {
1155 LOG.error(YANG_OBJ + UPD_WARN);
1159 public class NetworksReactor
1160 extends AsyncDataTreeChangeListenerBase<Networks, NetworksReactor>
1161 implements ClusteredDataTreeChangeListener<Networks> {
1163 private static final String YANG_OBJ = "networks ";
1165 public NetworksReactor() {
1166 super(Networks.class, NetworksReactor.class);
1170 public NetworksReactor getDataTreeChangeListener() {
1171 return NetworksReactor.this;
1175 protected void add(InstanceIdentifier<Networks> iid, Networks val) {
1176 if (!isBGPEntityOwner()) {
1179 LOG.debug("received add Networks config val {}", val.getPrefixLen());
1180 synchronized (BgpConfigurationManager.this) {
1181 String rd = val.getRd();
1182 String pfxlen = val.getPrefixLen();
1183 String nh = val.getNexthop().getValue();
1184 BgpRouter br = getClient(YANG_OBJ);
1186 LOG.debug("{} Unable to process add for rd {} prefix {} nexthop {}; {} {}", YANG_OBJ, rd, pfxlen,
1187 nh, BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1190 Long label = val.getLabel();
1191 int lbl = label == null ? qbgpConstants.LBL_NO_LABEL
1193 int l3vni = val.getL3vni() == null ? qbgpConstants.LBL_NO_LABEL
1194 : val.getL3vni().intValue();
1195 int l2vni = val.getL2vni() == null ? qbgpConstants.LBL_NO_LABEL
1196 : val.getL2vni().intValue();
1198 BgpControlPlaneType protocolType = val.getBgpControlPlaneType();
1199 int ethernetTag = val.getEthtag().intValue();
1200 String esi = val.getEsi();
1201 String macaddress = val.getMacaddress();
1202 EncapType encapType = val.getEncapType();
1203 String routerMac = val.getRoutermac();
1206 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, l2vni, BgpUtil.convertToThriftProtocolType(protocolType),
1207 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
1208 } catch (TException | BgpRouterException e) {
1209 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1215 protected InstanceIdentifier<Networks> getWildCardPath() {
1216 return InstanceIdentifier.create(Bgp.class).child(Networks.class);
1220 protected void remove(InstanceIdentifier<Networks> iid, Networks val) {
1221 if (!isBGPEntityOwner()) {
1224 LOG.debug("received remove Networks config val {}", val.getPrefixLen());
1225 synchronized (BgpConfigurationManager.this) {
1226 String rd = val.getRd();
1227 String pfxlen = val.getPrefixLen();
1228 BgpRouter br = getClient(YANG_OBJ);
1230 LOG.debug("{} Unable to process remove for rd {} prefix {}; {} {}", YANG_OBJ, rd, pfxlen,
1231 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1234 Long label = val.getLabel();
1235 int lbl = label == null ? 0 : label.intValue();
1236 if (rd == null && lbl > 0) {
1237 //LU prefix is being deleted.
1238 rd = Integer.toString(lbl);
1241 br.delPrefix(rd, pfxlen);
1242 } catch (TException | BgpRouterException e) {
1243 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1248 /**get the value AFI from a prefix as "x.x.x.x/x".
1250 * @param pfxlen the prefix to get an afi
1251 * @return the afi value as you are need
1253 public int testValueAFI(String pfxlen) {
1254 int afiNew = af_afi.AFI_IP.getValue();
1256 String ipOnly = pfxlen.substring(0, pfxlen.lastIndexOf("/"));
1257 java.net.Inet6Address.getByName(ipOnly);
1258 afiNew = af_afi.AFI_IPV6.getValue();
1259 } catch (java.net.UnknownHostException e) {
1260 //ce n'est pas de l'ipv6
1267 protected void update(final InstanceIdentifier<Networks> iid,
1268 final Networks oldval, final Networks newval) {
1269 if (!isBGPEntityOwner()) {
1272 if (oldval.equals(newval)) {
1273 //Update: OLD and New values are same, no need to trigger remove/add.
1274 LOG.debug("received Updated for the same OLD and New values. RD: {}, Prefix: {}, Label: {}, NH: {}",
1275 oldval.getRd(), oldval.getPrefixLen(), oldval.getLabel(), oldval.getNexthop());
1278 LOG.debug("update networks old val RD: {}, Prefix: {}, Label: {}, NH: {} "
1279 + "new val RD: {}, Prefix: {}, Label: {}, NH: {}",
1280 oldval.getRd(), oldval.getPrefixLen(), oldval.getLabel(), oldval.getNexthop(),
1281 newval.getRd(), newval.getPrefixLen(), newval.getLabel(), newval.getNexthop());
1282 remove(iid, oldval);
1287 static Timer timer = new Timer();
1289 public class VrfsReactor
1290 extends AsyncDataTreeChangeListenerBase<Vrfs, VrfsReactor>
1291 implements ClusteredDataTreeChangeListener<Vrfs> {
1293 private static final String YANG_OBJ = "vrfs ";
1295 public VrfsReactor() {
1296 super(Vrfs.class, VrfsReactor.class);
1300 protected void add(InstanceIdentifier<Vrfs> iid, Vrfs vrfs) {
1301 if (!isBGPEntityOwner()) {
1304 LOG.debug("received add Vrfs config value {}", vrfs.getRd());
1305 synchronized (BgpConfigurationManager.this) {
1306 String rd = vrfs.getRd();
1307 BgpRouter br = getClient(YANG_OBJ);
1309 LOG.debug("{} Unable to process add for rd {}; {} {}", YANG_OBJ, rd,
1310 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1314 List<AddressFamiliesVrf> vrfAddrFamilyList = vrfs.getAddressFamiliesVrf();
1315 for (AddressFamiliesVrf vrfAddrFamily : vrfAddrFamilyList) {
1316 /*add to br the new vrfs arguments*/
1317 br.addVrf(BgpUtil.getLayerType(vrfAddrFamily), rd, vrfs.getImportRts(),
1318 vrfs.getExportRts(), vrfAddrFamily.getAfi(), vrfAddrFamily.getSafi());
1320 /*add to br the vrfs contained in mapNewAdFamily*/
1321 List<AddressFamiliesVrf> vrfAddrFamilyListFromMap = mapNewAdFamily.get(rd);
1322 if (vrfAddrFamilyListFromMap == null) {
1326 for (AddressFamiliesVrf adf : vrfAddrFamilyListFromMap) {
1327 if (vrfAddrFamilyList.contains(adf)) {
1328 mapNewAdFamily.remove(rd);
1329 } else if (adf != null) {
1331 br.addVrf(BgpUtil.getLayerType(adf), rd, vrfs.getImportRts(),
1332 vrfs.getExportRts(), adf.getAfi(), adf.getSafi());
1333 // remove AddressFamiliesVrf which was already added to BGP
1334 vrfAddrFamilyListFromMap.remove(adf);
1335 if (vrfAddrFamilyListFromMap.isEmpty()) {
1336 // remove Vrf entry from temp mapNewAdFamily if all its AddressFamiliesVrf was
1338 mapNewAdFamily.remove(rd);
1342 } catch (TException | BgpRouterException e) {
1343 LOG.error("{} get {}, Add received exception", YANG_OBJ, ADD_WARN, e);
1349 protected VrfsReactor getDataTreeChangeListener() {
1350 return VrfsReactor.this;
1354 protected InstanceIdentifier<Vrfs> getWildCardPath() {
1355 return InstanceIdentifier.create(Bgp.class).child(Vrfs.class);
1359 protected void remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
1360 if (!isBGPEntityOwner()) {
1363 LOG.debug("received remove Vrfs config val {}", val.getRd());
1364 synchronized (BgpConfigurationManager.this) {
1365 String rd = val.getRd();
1366 BgpRouter br = getClient(YANG_OBJ);
1368 LOG.debug("{} Unable to process remove for rd {}; {} {}", YANG_OBJ, rd,
1369 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1373 List<AddressFamiliesVrf> adf = mapNewAdFamily.get(rd);
1374 adf = adf != null ? adf : new ArrayList<>();
1375 for (AddressFamiliesVrf s : val.getAddressFamiliesVrf()) {
1376 br.delVrf(rd, s.getAfi(), s.getSafi());
1377 adf.remove(s);// remove in the map the vrf in waiting for advertise quagga
1379 if (adf.isEmpty()) {
1380 mapNewAdFamily.remove(rd);
1382 } catch (TException | BgpRouterException e) {
1383 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1389 protected void update(InstanceIdentifier<Vrfs> iid,
1390 Vrfs oldval, Vrfs newval) {
1391 if (oldval != null && newval != null) {
1392 LOG.debug("received update Vrfs config val {}, VRFS: Update getting triggered for VRFS rd {}",
1393 newval.getRd(), oldval.getRd());
1395 LOG.debug("received update Vrfs config val {}, from old vrf {}",
1398 if (!isBGPEntityOwner()) {
1402 List<AddressFamiliesVrf> adFamilyVrfToDel = new ArrayList<>();
1403 List<AddressFamiliesVrf> adFamilyVrfToAdd = new ArrayList<>();
1404 List<AddressFamiliesVrf> oldlistAdFamilies = new ArrayList<>();
1405 List<AddressFamiliesVrf> newlistAdFamilies = new ArrayList<>();
1406 if (oldval != null) {
1407 oldlistAdFamilies = oldval.getAddressFamiliesVrf() == null
1408 ? new ArrayList<>() : oldval.getAddressFamiliesVrf();
1410 if (newval != null) {
1411 newlistAdFamilies = newval.getAddressFamiliesVrf() == null
1412 ? new ArrayList<>() : newval.getAddressFamiliesVrf();
1414 /*find old AddressFamily to remove from new configuration*/
1415 for (AddressFamiliesVrf adVrf : oldlistAdFamilies) {
1416 if (!newlistAdFamilies.contains(adVrf)) {
1417 adFamilyVrfToDel.add(adVrf);
1420 /*find new AddressFamily to add to unexisting configuration*/
1421 for (AddressFamiliesVrf adVrf : newlistAdFamilies) {
1422 if (!oldlistAdFamilies.contains(adVrf)) {
1423 adFamilyVrfToAdd.add(adVrf);
1426 String rd = newval != null ? newval.getRd() : null;
1428 BgpRouter br = getClient(YANG_OBJ);
1430 LOG.debug("{} Unable to process add for rd {}; {} {}", YANG_OBJ, rd,
1431 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1435 for (AddressFamiliesVrf adfvrf : adFamilyVrfToAdd) {
1437 LOG.debug("call addVRf rd {} afi {} safi {}", rd, adfvrf.getAfi(), adfvrf.getSafi());
1438 br.addVrf(BgpUtil.getLayerType(adfvrf), rd, newval.getImportRts(),
1439 newval.getExportRts(),adfvrf.getAfi(), adfvrf.getSafi());
1440 } catch (TException | BgpRouterException e) {
1441 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1445 for (AddressFamiliesVrf adfToDel : adFamilyVrfToDel) {
1447 LOG.debug("call delVRf rd {} afi {} safi {}", rd, adfToDel.getAfi(), adfToDel.getSafi());
1448 br.delVrf(rd, adfToDel.getAfi(), adfToDel.getSafi());
1449 } catch (TException | BgpRouterException e) {
1450 LOG.error("{} delVrf received exception; {}", YANG_OBJ, ADD_WARN, e);
1457 public class BgpReactor
1458 extends AsyncDataTreeChangeListenerBase<Bgp, BgpReactor>
1459 implements ClusteredDataTreeChangeListener<Bgp> {
1461 private static final String YANG_OBJ = "Bgp ";
1463 public BgpReactor() {
1464 super(Bgp.class, BgpReactor.class);
1469 protected void add(InstanceIdentifier<Bgp> iid, Bgp val) {
1470 LOG.debug("received add Bgp config");
1474 } catch (InterruptedException e) {
1477 synchronized (BgpConfigurationManager.this) {
1479 if (!isBGPEntityOwner()) {
1486 protected BgpReactor getDataTreeChangeListener() {
1487 return BgpReactor.this;
1491 protected InstanceIdentifier<Bgp> getWildCardPath() {
1492 return InstanceIdentifier.create(Bgp.class);
1496 protected void remove(InstanceIdentifier<Bgp> iid, Bgp val) {
1497 if (!isBGPEntityOwner()) {
1500 LOG.debug("received remove Bgp config");
1506 protected void update(InstanceIdentifier<Bgp> iid,
1507 Bgp oldval, Bgp newval) {
1508 if (!isBGPEntityOwner()) {
1516 @SuppressWarnings("deprecation")
1517 public class MultipathReactor
1518 extends AsyncDataTreeChangeListenerBase<Multipath, MultipathReactor>
1519 implements ClusteredDataTreeChangeListener<Multipath> {
1521 private static final String YANG_OBJ = "multipath ";
1523 public MultipathReactor() {
1524 super(Multipath.class, MultipathReactor.class);
1529 protected MultipathReactor getDataTreeChangeListener() {
1530 return MultipathReactor.this;
1534 protected InstanceIdentifier<Multipath> getWildCardPath() {
1535 return InstanceIdentifier.create(Bgp.class).child(Multipath.class);
1539 protected void remove(InstanceIdentifier<Multipath> iid, Multipath val) {
1540 executor.execute(new MultipathStatusChange(val));
1544 protected void update(InstanceIdentifier<Multipath> iid, Multipath oldval, Multipath newval) {
1545 executor.execute(new MultipathStatusChange(newval));
1549 protected void add(InstanceIdentifier<Multipath> key, Multipath dataObjectModification) {
1550 executor.execute(new MultipathStatusChange(dataObjectModification));
1553 class MultipathStatusChange implements Runnable {
1555 Multipath multipath;
1557 MultipathStatusChange(Multipath multipath) {
1558 this.multipath = multipath;
1563 if (isBGPEntityOwner()) {
1564 synchronized (BgpConfigurationManager.this) {
1566 BgpRouter br = getClient(YANG_OBJ);
1569 af_afi afi = af_afi.findByValue(multipath.getAfi().intValue());
1570 af_safi safi = af_safi.findByValue(multipath.getSafi().intValue());
1573 if (multipath.isMultipathEnabled()) {
1574 br.enableMultipath(afi, safi);
1576 br.disableMultipath(afi, safi);
1578 } catch (TException | BgpRouterException e) {
1579 LOG.error("{} received exception", YANG_OBJ, e);
1589 public void close() {
1594 @SuppressWarnings("deprecation")
1595 public class VrfMaxpathReactor
1596 extends AsyncDataTreeChangeListenerBase<VrfMaxpath, VrfMaxpathReactor>
1597 implements ClusteredDataTreeChangeListener<VrfMaxpath> {
1599 private static final String YANG_OBJ = "vrfMaxpath ";
1601 public VrfMaxpathReactor() {
1602 super(VrfMaxpath.class, VrfMaxpathReactor.class);
1607 protected VrfMaxpathReactor getDataTreeChangeListener() {
1608 return VrfMaxpathReactor.this;
1612 protected InstanceIdentifier<VrfMaxpath> getWildCardPath() {
1613 return InstanceIdentifier.create(Bgp.class).child(VrfMaxpath.class);
1616 class VrfMaxPathConfigurator implements Runnable {
1618 VrfMaxpath vrfMaxpathVal;
1620 VrfMaxPathConfigurator(VrfMaxpath vrfMaxPathVal) {
1621 this.vrfMaxpathVal = vrfMaxPathVal;
1626 if (isBGPEntityOwner()) {
1627 synchronized (BgpConfigurationManager.this) {
1628 BgpRouter br = getClient(YANG_OBJ);
1631 br.multipaths(vrfMaxpathVal.getRd(), vrfMaxpathVal.getMaxpaths());
1632 LOG.debug("Maxpath for vrf {} is {}", vrfMaxpathVal.getRd(),
1633 vrfMaxpathVal.getMaxpaths());
1634 } catch (TException | BgpRouterException e) {
1635 LOG.error("{} received exception", YANG_OBJ, e);
1644 protected void remove(InstanceIdentifier<VrfMaxpath> iid, VrfMaxpath vrfMaxPathVal) {
1645 if (isBGPEntityOwner()) {
1646 synchronized (BgpConfigurationManager.this) {
1647 BgpRouter br = getClient(YANG_OBJ);
1650 br.multipaths(vrfMaxPathVal.getRd(), BgpConstants.BGP_DEFAULT_MULTIPATH);
1651 LOG.debug("Del Maxpath for vrf: {} ", vrfMaxPathVal.getRd());
1652 } catch (TException | BgpRouterException e) {
1653 LOG.error(YANG_OBJ + " del received exception:", e);
1661 protected void update(InstanceIdentifier<VrfMaxpath> iid,
1662 VrfMaxpath oldval, VrfMaxpath newval) {
1663 if (!Objects.equals(oldval.getMaxpaths(), newval.getMaxpaths())) {
1664 executor.execute(new VrfMaxPathConfigurator(newval));
1669 protected void add(InstanceIdentifier<VrfMaxpath> instanceIdentifier, VrfMaxpath vrfMaxpathVal) {
1670 executor.execute(new VrfMaxPathConfigurator(vrfMaxpathVal));
1674 public void close() {
1679 public class BfdConfigReactor
1680 extends AsyncDataTreeChangeListenerBase<BfdConfig, BfdConfigReactor>
1681 implements ClusteredDataTreeChangeListener<BfdConfig> {
1683 private static final String YANG_OBJ = "BfdConfig ";
1685 public BfdConfigReactor() {
1686 super(BfdConfig.class, BfdConfigReactor.class);
1690 protected void add(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
1691 if (!isBGPEntityOwner()) {
1694 BgpRouter br = getClient(YANG_OBJ);
1695 LOG.debug("received bfd config: bfd enabled {} min-rx {} min-tx {} detect-mul {} mhop {}",
1696 val.isBfdEnabled(), val.getMinRx(), val.getMinTx(),
1697 val.getDetectMult(), val.isMultihop());
1699 LOG.debug(YANG_OBJ + "{} Unable to process add {}",
1700 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1703 if (val.isBfdEnabled() == false) {
1704 LOG.debug("BFD not enabled. Ignoring the config add");
1707 int minRx = val.getMinRx().intValue();
1708 int minTx = val.getMinTx().intValue();
1709 int detectMult = val.getDetectMult().intValue();
1710 boolean multiHop = val.isMultihop();
1712 br.addBfd(detectMult, minRx, minTx,multiHop);
1713 } catch (TException | BgpRouterException e) {
1714 LOG.error("{} get {}, Add received exception;", YANG_OBJ, ADD_WARN, e);
1719 protected BfdConfigReactor getDataTreeChangeListener() {
1720 return BfdConfigReactor.this;
1724 protected InstanceIdentifier<BfdConfig> getWildCardPath() {
1725 return InstanceIdentifier.create(BfdConfig.class);
1729 protected void remove(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
1730 if (!isBGPEntityOwner()) {
1733 LOG.debug("received bfd config removal");
1734 BgpRouter br = getClient(YANG_OBJ);
1736 LOG.debug("{} Unable to process del {} {}", YANG_OBJ,
1737 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1742 } catch (TException | BgpRouterException e) {
1743 LOG.error("{} get {}, Del received exception;", YANG_OBJ, ADD_WARN, e);
1749 protected void update(InstanceIdentifier<BfdConfig> iid,
1750 BfdConfig oldval, BfdConfig newval) {
1751 LOG.debug("received bfd config: updated oldval bfd enabled {}"
1752 + "min-rx {} min-tx {} detect-mul {} mhop {}",
1753 oldval.isBfdEnabled(), oldval.getMinRx(), oldval.getMinTx(),
1754 oldval.getDetectMult(), oldval.isMultihop());
1755 LOG.debug("received bfd config: updated newval bfd enabled {}"
1756 + "min-rx {} min-tx {} detect-mul {} mhop {}",
1757 newval.isBfdEnabled(), newval.getMinRx(), newval.getMinTx(),
1758 newval.getDetectMult(), newval.isMultihop());
1759 if (oldval.isBfdEnabled()) {
1760 LOG.debug("deleting bfd config on an update");
1761 remove(iid, oldval);
1763 LOG.debug("adding bfd config on an update");
1769 public boolean isIpAvailable(String odlip) {
1772 if (odlip != null) {
1773 if ("127.0.0.1".equals(odlip)) {
1776 Enumeration<NetworkInterface> networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces();
1777 while (networkInterfaceEnumeration.hasMoreElements()) {
1778 NetworkInterface networkInterface = networkInterfaceEnumeration.nextElement();
1779 Enumeration<InetAddress> inetAddressEnumeration = networkInterface.getInetAddresses();
1780 while (inetAddressEnumeration.hasMoreElements()) {
1781 InetAddress inetAddress = inetAddressEnumeration.nextElement();
1782 if (odlip.equals(inetAddress.getHostAddress())) {
1788 } catch (SocketException e) {
1794 public long getStalePathtime(int defValue, AsId asId) {
1797 spt = getConfig().getGracefulRestart().getStalepathTime();
1798 } catch (NullPointerException e) {
1800 spt = asId.getStalepathTime();
1801 LOG.trace("BGP config/Stale-path time is not set using graceful");
1802 } catch (NullPointerException ignore) {
1803 LOG.trace("BGP AS id is not set using graceful");
1808 LOG.trace("BGP config/Stale-path time is not set using graceful/start-bgp");
1814 public static boolean isValidConfigBgpHostPort(String bgpHost, int bgpPort) {
1815 if (!bgpHost.equals(DEF_CHOST)) {
1822 public synchronized void bgpRestarted() {
1824 * If there a thread which in the process of stale cleanup, cancel it
1825 * and start a new thread (to avoid processing same again).
1827 if (previousReplayJobInProgress()) {
1828 cancelPreviousReplayJob();
1830 Runnable task = () -> {
1832 LOG.info("running bgp replay task ");
1833 if (get() == null) {
1834 String host = getConfigHost();
1835 int port = getConfigPort();
1836 LOG.info("connecting to bgp host {} ", host);
1837 bgpRouter.connect(host, port);
1838 LOG.info("no config to push in bgp replay task ");
1841 setStaleStartTime(System.currentTimeMillis());
1842 LOG.info("started creating stale fibDSWriter map ");
1843 createStaleFibMap();
1844 setStaleEndTime(System.currentTimeMillis());
1845 LOG.info("took {} msecs for stale fibDSWriter map creation ", getStaleEndTime() - getStaleStartTime());
1846 LOG.info("started bgp config replay ");
1847 setCfgReplayStartTime(System.currentTimeMillis());
1848 boolean replaySucceded = replay();
1849 setCfgReplayEndTime(System.currentTimeMillis());
1850 LOG.info("took {} msecs for bgp replay ", getCfgReplayEndTime() - getCfgReplayStartTime());
1851 if (replaySucceded) {
1852 long routeSyncTime = getStalePathtime(BGP_RESTART_ROUTE_SYNC_SEC, config.getAsId());
1853 setStaleCleanupTime(routeSyncTime);
1854 LOG.error("starting the stale cleanup timer: {} seconds", routeSyncTime);
1855 routeCleanupFuture = executor.schedule(new RouteCleanup(), routeSyncTime, TimeUnit.SECONDS);
1857 LOG.error("skipping stale cleanup, may be due to exception while replay");
1858 staledFibEntriesMap.clear();
1860 } catch (InterruptedException | TimeoutException | ExecutionException eCancel) {
1861 LOG.error("Stale Cleanup Task Cancelled", eCancel);
1864 lastReplayJobFt = executor.submit(task);
1867 private boolean previousReplayJobInProgress() {
1868 return ((lastReplayJobFt != null && !lastReplayJobFt.isDone())
1869 || (routeCleanupFuture != null && !routeCleanupFuture.isDone()));
1872 private void cancelPreviousReplayJob() {
1874 LOG.error("cancelling already running bgp replay task");
1875 if (lastReplayJobFt != null) {
1876 lastReplayJobFt.cancel(true);
1877 lastReplayJobFt = null;
1878 staledFibEntriesMap.clear();
1880 if (routeCleanupFuture != null) {
1881 routeCleanupFuture.cancel(true);
1882 routeCleanupFuture = null;
1883 staledFibEntriesMap.clear();
1886 } catch (InterruptedException e) {
1887 LOG.error("Failed to cancel previous replay job ", e);
1891 private void doRouteSync() {
1892 LOG.error("Starting BGP route sync");
1894 bgpRouter.initRibSync(bgpSyncHandle);
1895 } catch (BgpRouterException e) {
1896 LOG.error("Route sync aborted, exception when initializing", e);
1899 while (bgpSyncHandle.getState() != BgpSyncHandle.DONE) {
1900 for (af_afi afi : af_afi.values()) {
1901 Routes routes = null;
1903 routes = bgpRouter.doRibSync(bgpSyncHandle, afi);
1904 } catch (TException | BgpRouterException e) {
1905 LOG.error("Route sync aborted, exception when syncing", e);
1908 Iterator<Update> updates = routes.getUpdatesIterator();
1909 while (updates.hasNext()) {
1910 Update update = updates.next();
1911 String rd = update.getRd();
1912 String nexthop = update.getNexthop();
1914 // TODO: decide correct label here
1915 int label = update.getL3label();
1916 int l2label = update.getL2label();
1918 String prefix = update.getPrefix();
1919 int plen = update.getPrefixlen();
1922 // TODO: protocol type will not be available in "update"
1923 // use "rd" to query vrf table and obtain the protocol_type.
1924 // Currently using PROTOCOL_EVPN as default.
1926 protocol_type.PROTOCOL_L3VPN,
1931 update.getMacaddress(),
1934 update.getRoutermac(),
1940 LOG.error("Ending BGP route-sync");
1941 bgpRouter.endRibSync(bgpSyncHandle);
1942 } catch (BgpRouterException e) {
1947 public void addTepToElanDS(String rd, String tepIp, String mac, Long l2vni) {
1948 boolean needUpdate = addToRt2TepMap(rd, tepIp, mac, l2vni);
1950 LOG.info("Adding tepIp {} with RD {} to ELan DS", tepIp, rd);
1951 bgpUtil.addTepToElanInstance(rd, tepIp);
1953 LOG.debug("Skipping the Elan update for RT2 from tep {} rd {}", tepIp, rd);
1957 public void deleteTepfromElanDS(String rd, String tepIp, String mac) {
1958 boolean needUpdate = deleteFromRt2TepMap(rd, tepIp, mac);
1960 LOG.info("Deleting tepIp {} with RD {} to ELan DS", tepIp, rd);
1961 bgpUtil.deleteTepFromElanInstance(rd, tepIp);
1963 LOG.debug("Skipping the Elan update for RT2 withdraw from tep {} rd {}", tepIp, rd);
1967 /* onUpdatePushRoute
1968 * Get Stale fibDSWriter map, and compare current route/fibDSWriter entry.
1969 * - Entry compare shall include NextHop, Label.
1970 * - If entry matches: delete from STALE Map. NO Change to FIB Config DS.
1971 * - If entry not found, add to FIB Config DS.
1972 * - If entry found, but either Label/NextHop doesn't match.
1973 * - Update FIB Config DS with modified values.
1974 * - delete from Stale Map.
1977 public void onUpdatePushRoute(protocol_type protocolType, String rd, String prefix, int plen, String nextHop,
1978 String macaddress, int label, int l2label, String routermac, af_afi afi) {
1979 PrefixUpdateEvent prefixUpdateEvent = new PrefixUpdateEvent(protocolType,rd,prefix,plen,nextHop,
1980 macaddress,label,l2label,routermac,afi);
1981 bgpUpdatesHistory.addToHistory(TransactionType.ADD, prefixUpdateEvent);
1982 boolean addroute = false;
1983 boolean macupdate = false;
1985 VrfEntry.EncapType encapType = VrfEntry.EncapType.Mplsgre;
1986 if (protocolType.equals(protocol_type.PROTOCOL_EVPN)) {
1987 encapType = VrfEntry.EncapType.Vxlan;
1988 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = bgpUtil.getVpnInstanceOpData(rd);
1989 if (vpnInstanceOpDataEntry != null) {
1990 if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
1991 LOG.info("Got RT2 route for RD {} l3label {} l2label {} from tep {} with mac {} remote RD {}",
1992 vpnInstanceOpDataEntry.getVpnInstanceName(), label, l2label, nextHop, macaddress, rd);
1993 addTepToElanDS(rd, nextHop, macaddress, (long)l2label);
1996 l3vni = vpnInstanceOpDataEntry.getL3vni();
1999 LOG.error("No corresponding vpn instance found for rd {}. Aborting.", rd);
2004 if (!staledFibEntriesMap.isEmpty()) {
2005 // restart Scenario, as MAP is not empty.
2006 Map<String, Long> map = staledFibEntriesMap.get(rd);
2008 String prefixNextHop = appendNextHopToPrefix(prefix + "/" + plen, nextHop);
2009 Long labelInStaleMap = map.get(prefixNextHop);
2010 if (null == labelInStaleMap) {
2011 // New Entry, which happened to be added during restart.
2014 map.remove(prefixNextHop);
2015 if (isRouteModified(label, labelInStaleMap)) {
2016 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
2017 // Existing entry, where in Label got modified during restart
2022 LOG.debug("rd {} map is null while processing prefix {} ", rd, prefix);
2026 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
2030 LOG.info("ADD: Adding Mac Fib entry rd {} mac{} nexthop {} l2vni {}", rd, macaddress, nextHop, l2label);
2031 fibDSWriter.addMacEntryToDS(rd, macaddress, prefix, Collections.singletonList(nextHop),
2032 encapType, l2label, routermac, RouteOrigin.BGP);
2033 LOG.info("ADD: Added Mac Fib entry rd {} prefix {} nexthop {} label {}", rd, macaddress, nextHop, l2label);
2034 } else if (addroute) {
2035 LOG.info("ADD: Adding Fib entry rd {} prefix {} nexthop {} label {} afi {}",
2036 rd, prefix, nextHop, label, afi);
2037 // TODO: modify addFibEntryToDS signature
2038 List<String> nextHopList = Collections.singletonList(nextHop);
2039 fibDSWriter.addFibEntryToDS(rd, prefix + "/" + plen, nextHopList, encapType, label, l3vni,
2040 routermac, RouteOrigin.BGP);
2041 LOG.info("ADD: Added Fib entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, label);
2042 String vpnName = bgpUtil.getVpnNameFromRd(rd);
2043 if (vpnName != null) {
2044 vpnLinkService.leakRouteIfNeeded(vpnName, prefix, nextHopList, label, RouteOrigin.BGP,
2045 NwConstants.ADD_FLOW);
2050 public void onUpdateWithdrawRoute(protocol_type protocolType, String rd, String prefix, int plen, String nextHop,
2051 String macaddress) {
2052 PrefixWithdrawEvent prefixWithdrawEvent = new PrefixWithdrawEvent(protocolType,rd,prefix,plen,
2053 nextHop,macaddress);
2054 bgpUpdatesHistory.addToHistory(TransactionType.ADD, prefixWithdrawEvent);
2056 boolean macupdate = false;
2057 if (protocolType.equals(protocol_type.PROTOCOL_EVPN)) {
2058 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = bgpUtil.getVpnInstanceOpData(rd);
2059 if (vpnInstanceOpDataEntry != null) {
2060 vni = vpnInstanceOpDataEntry.getL3vni();
2061 if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
2062 LOG.debug("Got RT2 withdraw for RD {} {} from tep {} with mac {} remote RD {}",
2063 vpnInstanceOpDataEntry.getVpnInstanceName(), vni, nextHop, macaddress, rd);
2064 deleteTepfromElanDS(rd, nextHop, macaddress);
2065 LOG.debug("For rd {}. skipping fib update", rd);
2069 LOG.error("No corresponding vpn instance found for rd {}. Aborting.", rd);
2074 LOG.info("Removing Mac Fib entry rd {} mac{} nexthop {} ", rd, macaddress, nextHop);
2075 fibDSWriter.removeMacEntryFromDS(rd, macaddress);
2076 LOG.info("Removed Mac Fib entry rd {} prefix {} nexthop {} ", rd, macaddress, nextHop);
2078 LOG.info("REMOVE: Removing Fib entry rd {} prefix {}", rd, prefix);
2079 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix + "/" + plen, nextHop);
2080 LOG.info("REMOVE: Removed Fib entry rd {} prefix {}", rd, prefix);
2084 //TODO: below function is for testing purpose with cli
2085 public void onUpdateWithdrawRoute(String rd, String prefix, int plen, String nexthop) {
2086 LOG.debug("Route del ** {} ** {}/{} ", rd, prefix, plen);
2087 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix + "/" + plen, nexthop);
2088 String vpnName = bgpUtil.getVpnNameFromRd(rd);
2089 if (vpnName != null) {
2090 vpnLinkService.leakRouteIfNeeded(vpnName, prefix, null /*nextHopList*/, 0 /*INVALID_LABEL*/,
2091 RouteOrigin.BGP, NwConstants.DEL_FLOW);
2095 public void peerDown(String ipAddress, long asNumber) {
2096 List<String> tepIpList = bgpUtil.getDcgwTepConfig(ipAddress);
2097 if (tepIpList == null) {
2098 LOG.error("No Tep IP configured for DCGW {} on a peerDown", ipAddress);
2101 tepIpList.forEach(tepIp -> {
2102 bgpUtil.removeOrUpdateLBGroups(tepIp, NwConstants.MOD_FLOW);
2106 public void peerUp(String ipAddress, long asNumber) {
2107 List<String> tepIpList = bgpUtil.getDcgwTepConfig(ipAddress);
2108 if (tepIpList == null) {
2109 LOG.error("No Tep IP configured for DCGW {} on a peerUp", ipAddress);
2112 tepIpList.forEach(tepIp -> {
2113 bgpUtil.removeOrUpdateLBGroups(tepIp, NwConstants.MOD_FLOW);
2117 private static boolean isRouteModified(int label, Long labelInStaleMap) {
2118 return labelInStaleMap != null && !labelInStaleMap.equals(Long.valueOf(label));
2121 static class ReplayNbr {
2123 boolean shouldRetry = false;
2125 public Neighbors getNbr() {
2129 public boolean isShouldRetry() {
2133 public void setShouldRetry(boolean retryNbr) {
2134 this.shouldRetry = retryNbr;
2137 ReplayNbr(Neighbors nbr, boolean shouldRetry) {
2139 this.shouldRetry = shouldRetry;
2143 private static boolean replayNbrConfig(List<Neighbors> neighbors, BgpRouter br) {
2144 if (neighbors == null || neighbors.isEmpty()) {
2145 LOG.error("Replaying nbr configuration, received NULL list ");
2149 List<ReplayNbr> replayNbrList = new ArrayList<>();
2150 for (Neighbors nbr : neighbors) {
2152 replayNbrList.add(new ReplayNbr(nbr, true));
2155 final int numberOfNbrRetries = 3;
2156 RetryOnException nbrRetry = new RetryOnException(numberOfNbrRetries);
2158 for (ReplayNbr replayNbr : replayNbrList) {
2159 if (!replayNbr.isShouldRetry()) {
2162 boolean replayDone = false;
2163 LOG.debug("Replaying addNbr {}", replayNbr.getNbr().getAddress().getValue());
2166 final String md5password = extractMd5Secret(replayNbr.getNbr());
2167 br.addNeighbor(replayNbr.getNbr().getAddress().getValue(),
2168 replayNbr.getNbr().getRemoteAs().longValue(), md5password);
2170 } catch (TApplicationException tae) {
2171 LOG.debug("Replaying addNbr {}, tapplicationexception: ",
2172 replayNbr.getNbr().getAddress().getValue(), tae);
2173 if (tae.getType() == BgpRouterException.BGP_ERR_PEER_EXISTS) {
2174 LOG.debug("Replaying addNbr Neighbor already present");
2177 LOG.error("Replaying addNbr {}, exception: ", replayNbr.getNbr().getAddress().getValue(), tae);
2179 } catch (TException | BgpRouterException eNbr) {
2180 LOG.debug("Replaying addNbr {}, exception: ", replayNbr.getNbr().getAddress().getValue(), eNbr);
2183 LOG.debug("Replay addNbr {} successful", replayNbr.getNbr().getAddress().getValue());
2185 //Update Source handling
2186 UpdateSource us = replayNbr.getNbr().getUpdateSource();
2188 LOG.debug("Replaying updatesource {} to peer {}", us.getSourceIp().getValue(),
2189 us.getPeerIp().getValue());
2191 br.addUpdateSource(us.getPeerIp().getValue(),
2192 us.getSourceIp().getValue());
2193 } catch (TException | BgpRouterException eUs) {
2194 LOG.debug("Replaying UpdateSource for Nbr {}, exception:",
2195 replayNbr.getNbr().getAddress().getValue(), eUs);
2197 LOG.debug("Replay updatesource {} successful", us.getSourceIp().getValue());
2200 EbgpMultihop en = replayNbr.getNbr().getEbgpMultihop();
2203 br.addEbgpMultihop(en.getPeerIp().getValue(),
2204 en.getNhops().intValue());
2205 } catch (TException | BgpRouterException eEbgpMhop) {
2206 LOG.debug("Replaying EbgpMultihop for Nbr {}, exception: ",
2207 replayNbr.getNbr().getAddress().getValue(), eEbgpMhop);
2212 List<AddressFamilies> afs = replayNbr.getNbr().getAddressFamilies();
2214 for (AddressFamilies af : afs) {
2215 af_afi afi = af_afi.findByValue(af.getAfi().intValue());
2216 af_safi safi = af_safi.findByValue(af.getSafi().intValue());
2218 br.addAddressFamily(af.getPeerIp().getValue(), afi, safi);
2219 } catch (TException | BgpRouterException eAFs) {
2220 LOG.debug("Replaying AddressFamily for Nbr {}, exception:",
2221 replayNbr.getNbr().getAddress().getValue(), eAFs);
2225 //replay is success --> no need to replay this nbr in next iteration.
2226 replayNbr.setShouldRetry(replayDone ? false : true);
2228 } while (nbrRetry.decrementAndRetry());
2229 boolean replaySuccess = true;
2230 for (ReplayNbr replayNbr : replayNbrList) {
2231 replaySuccess = replaySuccess && !replayNbr.isShouldRetry();
2232 if (replaySuccess == false) {
2233 LOG.error("replayNbrConfig: will be cancelling stale cleanup, cfg nbr: {} Failed:",
2234 replayNbr.getNbr().getAddress().getValue());
2237 return replaySuccess;
2240 public String getConfigHost() {
2241 if (config == null) {
2244 ConfigServer ts = config.getConfigServer();
2245 return ts == null ? hostStartup : ts.getHost().getValue();
2248 public int getConfigPort() {
2249 if (config == null) {
2250 return Integer.parseInt(portStartup);
2252 ConfigServer ts = config.getConfigServer();
2253 return ts == null ? Integer.parseInt(portStartup) :
2254 ts.getPort().intValue();
2257 public Bgp getConfig() {
2258 AtomicInteger bgpDSretryCount = new AtomicInteger(DS_RETRY_COUNT);
2259 while (0 != bgpDSretryCount.decrementAndGet()) {
2261 return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
2262 InstanceIdentifier.create(Bgp.class)).orNull();
2263 } catch (ReadFailedException e) {
2264 //Config DS may not be up, so sleep for 1 second and retry
2265 LOG.debug("failed to get bgp config, may be DS is yet in consistent state(?)", e);
2267 Thread.sleep(WAIT_TIME_BETWEEN_EACH_TRY_MILLIS);
2268 } catch (InterruptedException timerEx) {
2269 LOG.debug("WAIT_TIME_BETWEEN_EACH_TRY_MILLIS, Timer got interrupted while waiting for"
2270 + "config DS availability", timerEx);
2274 LOG.error("failed to get bgp config");
2278 @SuppressWarnings("checkstyle:IllegalCatch")
2279 public synchronized boolean replay() throws InterruptedException, TimeoutException, ExecutionException {
2280 boolean replaySucceded = true;
2281 boolean doRouteSync = false;
2282 String host = getConfigHost();
2283 int port = getConfigPort();
2284 LOG.error("connecting to bgp host {} ", host);
2285 boolean res = bgpRouter.connect(host, port);
2287 LOG.error("Cannot connect to BGP config server at {} {}", host, port);
2288 return replaySucceded;
2290 config = getConfig();
2291 if (config == null) {
2292 LOG.error("bgp config is empty nothing to push to bgp");
2293 return replaySucceded;
2295 BgpRouter br = bgpRouter;
2296 AsId asId = config.getAsId();
2298 LOG.error("bgp as-id is null");
2299 return replaySucceded;
2301 long asNum = asId.getLocalAs();
2302 IpAddress routerId = asId.getRouterId();
2303 String rid = routerId == null ? "" : routerId.stringValue();
2304 int stalepathTime = (int) getStalePathtime(bgpGrRestartTime, config.getAsId());
2305 boolean announceFbit = true;
2306 boolean replayDone = false;
2307 final int numberOfStartBgpRetries = 3;
2308 RetryOnException startBgpRetry = new RetryOnException(numberOfStartBgpRetries);
2311 LOG.debug("Replaying BGPConfig ");
2312 br.startBgp(asNum, rid, bgpKaTime, bgpHoldTime, stalepathTime, announceFbit);
2313 LOG.debug("Replay BGPConfig successful");
2316 } catch (BgpRouterException bre) {
2317 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
2318 LOG.debug("Starting the routesync for exception", bre);
2319 startBgpRetry.errorOccured();
2320 if (!startBgpRetry.shouldRetry()) {
2325 LOG.error("Replay: startBgp() received exception error {} : ",
2326 bre.getErrorCode(), bre);
2327 startBgpRetry.errorOccured();
2329 } catch (TApplicationException tae) {
2330 if (tae.getType() == BgpRouterException.BGP_ERR_ACTIVE) {
2331 LOG.debug("Starting the routesync for exception", tae);
2332 startBgpRetry.errorOccured();
2333 if (!startBgpRetry.shouldRetry()) {
2337 } else if (tae.getType() == BgpRouterException.BGP_ERR_COMMON_FAILURE) {
2338 LOG.debug("Starting the routesync for AS-ID started exception", tae);
2339 startBgpRetry.errorOccured();
2340 if (!startBgpRetry.shouldRetry()) {
2345 LOG.error("Replay: startBgp() received exception type {}: ",
2346 tae.getType(), tae);
2347 startBgpRetry.errorOccured();
2349 } catch (Exception e) {
2350 //not unusual. We may have restarted & BGP is already on
2351 LOG.error("Replay:startBgp() received exception: ", e);
2352 startBgpRetry.errorOccured();
2354 } while (startBgpRetry.shouldRetry());
2356 replaySucceded = replayDone;
2358 startBgpCountersTask();
2359 startBgpAlarmsTask();
2362 * commenting this due to a bug with QBGP. Will uncomment once QBGP fix is done.
2363 * This wont have any functional impacts
2366 // br.delayEOR(delayEorSeconds);
2367 //} catch (TException | BgpRouterException e) {
2368 // LOG.error("Replay: delayEOR() number of seconds to wait for EOR from ODL:", e);
2371 BfdConfig bfdConfig = bgpUtil.getBfdConfig();
2372 if (bfdConfig != null) {
2373 if (bfdConfig.isBfdEnabled()) {
2374 LOG.debug("Replaying bfd config min-rx {} min-tx {} detect-mul {} mhop {}",
2375 bfdConfig.getMinRx(), bfdConfig.getMinTx(),
2376 bfdConfig.getDetectMult(), bfdConfig.isMultihop());
2378 br.addBfd(bfdConfig.getDetectMult().intValue(), bfdConfig.getMinRx().intValue(),
2379 bfdConfig.getMinTx().intValue(), bfdConfig.isMultihop());
2380 } catch (TApplicationException tae) {
2381 if (tae.getType() == BgpRouterException.BGP_ERR_PEER_EXISTS) {
2382 LOG.debug("Replay:addBfd() received exception", tae);
2384 LOG.error("Replay:addBfd() received exception", tae);
2386 } catch (TException | BgpRouterException e) {
2387 LOG.error("Replay:addBfd() received exception", e);
2392 List<Neighbors> neighbors = config.getNeighbors();
2393 if (neighbors != null) {
2394 LOG.error("configuring existing Neighbors present for replay total neighbors {}", neighbors.size());
2395 boolean neighborConfigReplayResult = replayNbrConfig(neighbors, br);
2396 if (neighborConfigReplayResult == false) {
2397 replaySucceded = false;
2400 LOG.error("no Neighbors present for replay config ");
2403 Logging logging = config.getLogging();
2404 if (logging != null) {
2406 br.setLogging(logging.getFile(), logging.getLevel());
2407 } catch (TException | BgpRouterException e) {
2408 LOG.error("Replay:setLogging() received exception", e);
2412 GracefulRestart gracefulRestart = config.getGracefulRestart();
2413 bgpGrRestartTime = ((gracefulRestart != null)
2414 ? gracefulRestart.getStalepathTime().intValue() : bgpGrRestartTime);
2416 br.addGracefulRestart(bgpGrRestartTime);
2417 } catch (Exception e) {
2418 LOG.error("Replay:addGr() received exception: ", e);
2420 List<Vrfs> vrfs = config.getVrfs();
2422 vrfs = new ArrayList<>();
2424 for (Vrfs vrf : vrfs) {
2425 for (AddressFamiliesVrf adf : vrf.getAddressFamiliesVrf()) {
2427 br.addVrf(BgpUtil.getLayerType(adf), vrf.getRd(), vrf.getImportRts(),
2428 vrf.getExportRts(), adf.getAfi(), adf.getSafi());
2429 } catch (TException | BgpRouterException e) {
2430 LOG.error("Replay:addVrf() received exception", e);
2435 List<Networks> ln = config.getNetworks();
2437 for (Networks net : ln) {
2438 String rd = net.getRd();
2439 String pfxlen = net.getPrefixLen();
2440 String nh = net.getNexthop().getValue();
2441 Long label = net.getLabel();
2442 int lbl = label == null ? 0 : label.intValue();
2443 int l3vni = net.getL3vni() == null ? 0 : net.getL3vni().intValue();
2444 int l2vni = net.getL2vni() == null ? 0 : net.getL2vni().intValue();
2445 if (rd == null && lbl > 0) {
2446 //LU prefix is being deleted.
2447 rd = Integer.toString(lbl);
2450 BgpControlPlaneType protocolType = net.getBgpControlPlaneType();
2451 int ethernetTag = net.getEthtag().intValue();
2452 String esi = net.getEsi();
2453 String macaddress = net.getMacaddress();
2454 EncapType encapType = net.getEncapType();
2455 String routerMac = net.getRoutermac();
2458 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, l2vni,
2459 BgpUtil.convertToThriftProtocolType(protocolType),
2460 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
2461 } catch (TException | BgpRouterException e) {
2462 LOG.error("Replay:addPfx() received exception", e);
2468 List<Multipath> multipaths = config.getMultipath();
2470 if (multipaths != null) {
2471 for (Multipath multipath : multipaths) {
2472 if (multipath != null) {
2473 af_afi afi = af_afi.findByValue(multipath.getAfi().intValue());
2474 af_safi safi = af_safi.findByValue(multipath.getSafi().intValue());
2477 if (multipath.isMultipathEnabled()) {
2478 br.enableMultipath(afi, safi);
2480 br.disableMultipath(afi, safi);
2482 } catch (TException | BgpRouterException e) {
2483 LOG.info("Replay:multipaths() received exception", e);
2488 List<VrfMaxpath> vrfMaxpaths = config.getVrfMaxpath();
2489 if (vrfMaxpaths != null) {
2490 for (VrfMaxpath vrfMaxpath : vrfMaxpaths) {
2492 br.multipaths(vrfMaxpath.getRd(), vrfMaxpath.getMaxpaths());
2493 } catch (TException | BgpRouterException e) {
2494 LOG.info("Replay:vrfMaxPath() received exception", e);
2499 //send End of Rib Marker to Qthriftd.
2500 final int numberOfEORRetries = 3;
2501 RetryOnException eorRetry = new RetryOnException(numberOfEORRetries);
2505 LOG.debug("Replay sendEOR() successful");
2507 } catch (Exception e) {
2508 eorRetry.errorOccured();
2509 LOG.error("Replay:sedEOR() received exception:", e);
2511 } while (eorRetry.shouldRetry());
2514 LOG.debug("starting route sync for Thrift BGP_ERR_COMMON_FAILURE exception "
2515 + "happened earlier");
2519 return replaySucceded;
2522 private <T extends DataObject> void update(InstanceIdentifier<T> iid, T dto) {
2523 bgpUtil.update(iid, dto);
2526 private <T extends DataObject> void delete(InstanceIdentifier<T> iid) {
2527 bgpUtil.delete(iid);
2530 public void startConfig(String bgpHost, int thriftPort) {
2531 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
2532 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
2533 InstanceIdentifier<ConfigServer> iid = iib.build();
2534 Ipv4Address ipAddr = new Ipv4Address(bgpHost);
2535 ConfigServer dto = new ConfigServerBuilder().setHost(ipAddr)
2536 .setPort((long) thriftPort).build();
2540 public void startBgp(long as, String routerId, int spt, boolean fbit) {
2541 IpAddress rid = routerId == null ? null : IpAddressBuilder.getDefaultInstance(routerId);
2542 Long staleTime = (long) spt;
2543 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
2544 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
2545 InstanceIdentifier<AsId> iid = iib.build();
2546 AsId dto = new AsIdBuilder().setLocalAs(as)
2548 .setStalepathTime(staleTime)
2549 .setAnnounceFbit(fbit).build();
2553 public void startBfd(long detectMult, long minRx, long minTx, boolean multiHop) {
2554 InstanceIdentifier.InstanceIdentifierBuilder<BfdConfig> iib =
2555 InstanceIdentifier.builder(BfdConfig.class);
2556 InstanceIdentifier<BfdConfig> iid = iib.build();
2557 BfdConfig dto = new BfdConfigBuilder()
2558 .setBfdEnabled(true)
2559 .setMultihop(multiHop)
2562 .setDetectMult(detectMult)
2567 public void addDcgwTep(String dcgwIp, String tepIp) {
2568 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2569 InstanceIdentifier.builder(Bgp.class)
2570 .child(DcgwTepList.class)
2571 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2572 InstanceIdentifier<DcgwTep> iid = iib.build();
2573 ArrayList<String> tepList = new ArrayList<String>();
2575 DcgwTep dto = new DcgwTepBuilder().setDcGwIp(dcgwIp).setTepIps(tepList)
2578 bgpUtil.removeOrUpdateLBGroups(tepIp,NwConstants.MOD_FLOW);
2581 public void addLogging(String fileName, String logLevel) {
2582 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
2583 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
2584 InstanceIdentifier<Logging> iid = iib.build();
2585 Logging dto = new LoggingBuilder().setFile(fileName)
2586 .setLevel(logLevel).build();
2590 public void addGracefulRestart(int staleTime) {
2591 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
2592 InstanceIdentifier.builder(Bgp.class).child(GracefulRestart.class);
2593 InstanceIdentifier<GracefulRestart> iid = iib.build();
2594 GracefulRestart dto = new GracefulRestartBuilder()
2595 .setStalepathTime((long) staleTime).build();
2599 public void addNeighbor(
2600 String nbrIp, long remoteAs, @Nullable final TcpMd5SignaturePasswordType md5Secret) {
2601 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2602 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
2603 InstanceIdentifier.builder(Bgp.class)
2604 .child(Neighbors.class, new NeighborsKey(nbrAddr));
2605 InstanceIdentifier<Neighbors> iid = iib.build();
2606 TcpSecurityOption tcpSecOption = null;
2607 if (md5Secret != null) {
2608 tcpSecOption = new TcpMd5SignatureOptionBuilder().setTcpMd5SignaturePassword(md5Secret).build();
2609 } // else let tcpSecOption be null
2610 Neighbors dto = new NeighborsBuilder().setAddress(nbrAddr)
2611 .setRemoteAs(remoteAs).setTcpSecurityOption(tcpSecOption).build();
2613 } // public addNeighbor(nbrIp, remoteAs, md5Secret)
2615 public void addUpdateSource(String nbrIp, String srcIp) {
2616 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2617 Ipv4Address srcAddr = new Ipv4Address(srcIp);
2618 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
2619 InstanceIdentifier.builder(Bgp.class)
2620 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2621 .child(UpdateSource.class);
2622 InstanceIdentifier<UpdateSource> iid = iib.build();
2623 UpdateSource dto = new UpdateSourceBuilder().setPeerIp(nbrAddr)
2624 .setSourceIp(srcAddr).build();
2628 public void addEbgpMultihop(String nbrIp, int hops) {
2629 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2630 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
2631 InstanceIdentifier.builder(Bgp.class)
2632 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2633 .child(EbgpMultihop.class);
2634 InstanceIdentifier<EbgpMultihop> iid = iib.build();
2635 EbgpMultihop dto = new EbgpMultihopBuilder().setPeerIp(nbrAddr)
2636 .setNhops((long) hops).build();
2640 public void addAddressFamily(String nbrIp, int afi, int safi) {
2641 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2642 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
2643 InstanceIdentifier.builder(Bgp.class)
2644 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2645 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
2646 InstanceIdentifier<AddressFamilies> iid = iib.build();
2647 AddressFamilies dto = new AddressFamiliesBuilder().setPeerIp(nbrAddr)
2648 .setAfi((long) afi).setSafi((long) safi).build();
2652 public void addPrefix(String rd, String macAddress, String pfx, List<String> nhList,
2653 VrfEntry.EncapType encapType, long lbl, long l3vni, long l2vni, String gatewayMac) {
2654 for (String nh : nhList) {
2655 Ipv4Address nexthop = nh != null ? new Ipv4Address(nh) : null;
2657 InstanceIdentifier<Networks> iid = InstanceIdentifier.builder(Bgp.class)
2658 .child(Networks.class, new NetworksKey(pfx, rd)).build();
2659 NetworksBuilder networksBuilder = new NetworksBuilder().setRd(rd).setPrefixLen(pfx).setNexthop(nexthop)
2660 .setLabel(label).setEthtag(BgpConstants.DEFAULT_ETH_TAG);
2661 buildVpnEncapSpecificInfo(networksBuilder, encapType, label, l3vni, l2vni, macAddress, gatewayMac);
2662 update(iid, networksBuilder.build());
2666 private static void buildVpnEncapSpecificInfo(NetworksBuilder builder, VrfEntry.EncapType encapType, long label,
2667 long l3vni, long l2vni, String macAddress, String gatewayMac) {
2668 if (encapType.equals(VrfEntry.EncapType.Mplsgre)) {
2669 builder.setLabel(label).setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLL3VPN)
2670 .setEncapType(EncapType.GRE);
2672 builder.setL3vni(l3vni).setL2vni(l2vni).setMacaddress(macAddress).setRoutermac(gatewayMac)
2673 .setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLEVPN).setEncapType(EncapType.VXLAN);
2677 // TODO: add LayerType as arg - supports command
2678 public void addVrf(String rd, List<String> irts, List<String> erts, AddressFamily addressFamily) {
2679 Vrfs vrf = bgpUtil.getVrfFromRd(rd);
2680 List<AddressFamiliesVrf> adfList = new ArrayList<>(1);
2682 adfList = vrf.getAddressFamiliesVrf();
2684 AddressFamiliesVrfBuilder adfBuilder = new AddressFamiliesVrfBuilder();
2685 if (addressFamily.equals(AddressFamily.IPV4)) {
2686 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2687 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2688 } else if (addressFamily.equals(AddressFamily.IPV6)) {
2689 adfBuilder.setAfi((long) af_afi.AFI_IPV6.getValue());
2690 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2691 } else if (addressFamily.equals(AddressFamily.L2VPN)) {
2692 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2693 adfBuilder.setSafi((long) af_safi.SAFI_EVPN.getValue());
2695 AddressFamiliesVrf adf = adfBuilder.build();
2697 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib = InstanceIdentifier.builder(Bgp.class)
2698 .child(Vrfs.class, new VrfsKey(rd));
2699 InstanceIdentifier<Vrfs> iid = iib.build();
2700 Vrfs dto = new VrfsBuilder().setRd(rd).setImportRts(irts)
2701 .setExportRts(erts).setAddressFamiliesVrf(adfList).build();
2703 List<AddressFamiliesVrf> listAdFamilies = mapNewAdFamily.get(rd);
2704 if (listAdFamilies != null) {
2705 listAdFamilies.add(adf);
2707 mapNewAdFamily.put(rd, adfList);
2711 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
2712 } catch (TransactionCommitFailedException e) {
2713 LOG.error("Error adding VRF to datastore", e);
2714 throw new RuntimeException(e);
2717 // enable multipath by default in all VRFs
2718 setMultipaths(rd, BgpConstants.BGP_DEFAULT_MULTIPATH);
2721 public void stopConfig() {
2722 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
2723 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
2724 InstanceIdentifier<ConfigServer> iid = iib.build();
2728 public void stopBgp() {
2729 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
2730 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
2731 InstanceIdentifier<AsId> iid = iib.build();
2735 public void stopBfd() {
2736 InstanceIdentifier.InstanceIdentifierBuilder<BfdConfig> iib =
2737 InstanceIdentifier.builder(BfdConfig.class);
2738 InstanceIdentifier<BfdConfig> iid = iib.build();
2742 public void delDcgwTep(String dcgwIp, String tepIp) {
2743 if (tepIp == null) {
2744 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2745 InstanceIdentifier.builder(Bgp.class)
2746 .child(DcgwTepList.class)
2747 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2748 InstanceIdentifier<DcgwTep> iid = iib.build();
2751 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2752 InstanceIdentifier.builder(Bgp.class)
2753 .child(DcgwTepList.class)
2754 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2755 InstanceIdentifier<DcgwTep> iid = iib.build();
2756 List<String> tepIpList = bgpUtil.getDcgwTepConfig(dcgwIp);
2757 if (tepIpList == null) {
2758 LOG.error("No Tep IP configured for DCGW {} on deleting the dcgwtep", dcgwIp);
2761 List<String> newTepIpList = new ArrayList<String>();
2762 tepIpList.forEach(tep -> {
2763 if (!tep.equals(tepIp)) {
2764 newTepIpList.add(tep);
2767 DcgwTep dto = new DcgwTepBuilder().setDcGwIp(dcgwIp).setTepIps(newTepIpList)
2770 SingleTransactionDataBroker.syncWrite(dataBroker,
2771 LogicalDatastoreType.CONFIGURATION, iid, dto);
2772 } catch (TransactionCommitFailedException e) {
2773 LOG.error("delDcgwTep: Error deleting DCGW Tep", e);
2774 throw new RuntimeException(e);
2779 public void delLogging() {
2780 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
2781 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
2782 InstanceIdentifier<Logging> iid = iib.build();
2786 public void delGracefulRestart() {
2787 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
2788 InstanceIdentifier.builder(Bgp.class)
2789 .child(GracefulRestart.class);
2790 InstanceIdentifier<GracefulRestart> iid = iib.build();
2794 public void delNeighbor(String nbrIp) {
2795 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2796 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
2797 InstanceIdentifier.builder(Bgp.class)
2798 .child(Neighbors.class, new NeighborsKey(nbrAddr));
2799 InstanceIdentifier<Neighbors> iid = iib.build();
2803 public void delUpdateSource(String nbrIp) {
2804 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2805 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
2806 InstanceIdentifier.builder(Bgp.class)
2807 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2808 .child(UpdateSource.class);
2809 InstanceIdentifier<UpdateSource> iid = iib.build();
2813 public void delEbgpMultihop(String nbrIp) {
2814 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2815 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
2816 InstanceIdentifier.builder(Bgp.class)
2817 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2818 .child(EbgpMultihop.class);
2819 InstanceIdentifier<EbgpMultihop> iid = iib.build();
2823 public void delAddressFamily(String nbrIp, int afi, int safi) {
2824 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2825 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
2826 InstanceIdentifier.builder(Bgp.class)
2827 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2828 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
2829 InstanceIdentifier<AddressFamilies> iid = iib.build();
2833 public void delPrefix(String rd, String pfx) {
2834 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
2835 InstanceIdentifier.builder(Bgp.class)
2836 .child(Networks.class, new NetworksKey(pfx, rd));
2837 InstanceIdentifier<Networks> iid = iib.build();
2841 public boolean delVrf(String rd, AddressFamily addressFamily) {
2842 if (addressFamily == null) {
2843 LOG.error("delVrf: vrf {}, addressFamily invalid", rd);
2847 AddressFamiliesVrfBuilder adfBuilder = new AddressFamiliesVrfBuilder();
2848 if (addressFamily.equals(AddressFamily.IPV4)) {
2849 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2850 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2851 } else if (addressFamily.equals(AddressFamily.IPV6)) {
2852 adfBuilder.setAfi((long) af_afi.AFI_IPV6.getValue());
2853 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2854 } else if (addressFamily.equals(AddressFamily.L2VPN)) {
2855 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2856 adfBuilder.setSafi((long) af_safi.SAFI_EVPN.getValue());
2858 LOG.debug("delVrf: Received Delete VRF : rd:{}, address family: {} {}", rd,
2859 adfBuilder.getAfi(), adfBuilder.getSafi());
2861 Vrfs vrfOriginal = bgpUtil.getVrfFromRd(rd);
2862 if (vrfOriginal == null) {
2863 LOG.error("delVrf: no vrf with existing rd {}. step aborted", rd);
2867 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
2868 InstanceIdentifier.builder(Bgp.class)
2869 .child(Vrfs.class, new VrfsKey(rd));
2871 InstanceIdentifier<Vrfs> iid = iib.build();
2873 @SuppressWarnings("static-access")
2874 InstanceIdentifier<Bgp> iid6 = iid.builder(Bgp.class).build()
2875 .child(Multipath.class, new MultipathKey(adfBuilder.getAfi(), adfBuilder.getSafi())).create(Bgp.class);
2876 InstanceIdentifierBuilder<Vrfs> iib3 = iid6.child(Vrfs.class, new VrfsKey(rd)).builder();
2877 InstanceIdentifier<Vrfs> iidFinal = iib3.build();
2879 //** update or delete the vrfs with the rest of AddressFamilies already present in the last list
2880 AddressFamiliesVrf adfToDel = adfBuilder.build();
2881 List<AddressFamiliesVrf> adfListOriginal = vrfOriginal.getAddressFamiliesVrf() == null
2882 ? new ArrayList<>() : vrfOriginal.getAddressFamiliesVrf();
2883 List<AddressFamiliesVrf> adfListToRemoveFromOriginal = new ArrayList<>();
2884 adfListOriginal.forEach(adf -> {
2885 if (adf.equals(adfToDel)) {
2886 adfListToRemoveFromOriginal.add(adfToDel);
2890 for (AddressFamiliesVrf adfToRemove : adfListToRemoveFromOriginal) {
2891 adfListOriginal.remove(adfToRemove);
2893 SingleTransactionDataBroker.syncWrite(dataBroker,
2894 LogicalDatastoreType.CONFIGURATION, iid, vrfOriginal);
2895 } catch (TransactionCommitFailedException e) {
2896 LOG.error("delVrf: Error updating VRF to datastore", e);
2897 throw new RuntimeException(e);
2900 if (adfListOriginal.isEmpty()) {
2901 LOG.debug("delVrf: delete iid: {}", iidFinal);
2905 // not all is removed
2909 public void setMultipathStatus(af_afi afi, af_safi safi, boolean enable) {
2910 long lafi = afi.getValue();
2911 long lsafi = safi.getValue();
2913 InstanceIdentifier.InstanceIdentifierBuilder<Multipath> iib =
2916 .child(Multipath.class,
2917 new MultipathKey(Long.valueOf(afi.getValue()), Long.valueOf(safi.getValue())));
2919 Multipath dto = new MultipathBuilder().setAfi(lafi).setSafi(lsafi).setMultipathEnabled(enable).build();
2920 update(iib.build(), dto);
2923 public void setMultipaths(String rd, int maxpath) {
2924 InstanceIdentifier.InstanceIdentifierBuilder<VrfMaxpath> iib =
2927 .child(VrfMaxpath.class, new VrfMaxpathKey(rd));
2929 VrfMaxpath dto = new VrfMaxpathBuilder().setRd(rd).setMaxpaths(maxpath).build();
2930 update(iib.build(), dto);
2933 public void delMultipaths(String rd) {
2934 InstanceIdentifier.InstanceIdentifierBuilder<VrfMaxpath> iib =
2935 InstanceIdentifier.builder(Bgp.class)
2936 .child(VrfMaxpath.class, new VrfMaxpathKey(rd));
2937 InstanceIdentifier<VrfMaxpath> iid = iib.build();
2942 * Remove Stale Marked Routes after timer expiry.
2944 private class RouteCleanup implements Callable<Integer> {
2947 public Integer call() {
2950 if (staledFibEntriesMap.isEmpty()) {
2951 LOG.info("BGP: RouteCleanup timertask tirggered but STALED FIB MAP is EMPTY");
2953 for (String rd : staledFibEntriesMap.keySet()) {
2954 if (Thread.interrupted()) {
2957 Map<String, Long> map = staledFibEntriesMap.get(rd);
2959 for (String key : map.keySet()) {
2960 if (Thread.interrupted()) {
2963 String prefix = extractPrefix(key);
2964 String nextHop = extractNextHop(key);
2966 LOG.debug("BGP: RouteCleanup deletePrefix called for : rd:{}, prefix{}, nextHop:{}",
2967 rd, prefix, nextHop);
2968 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix, nextHop);
2974 staledFibEntriesMap.clear();
2976 LOG.error("cleared {} stale routes after bgp restart", totalCleared);
2982 * BGP restart scenario, ODL-BGP manager was/is running.
2983 * On re-sync notification, Get a copy of FIB database.
2985 public void createStaleFibMap() {
2986 totalStaledCount = 0;
2988 staledFibEntriesMap.clear();
2989 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
2991 Optional<FibEntries> fibEntries = SingleTransactionDataBroker.syncReadOptional(dataBroker,
2992 LogicalDatastoreType.CONFIGURATION, id);
2993 if (fibEntries.isPresent()) {
2994 List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
2995 for (VrfTables vrfTable : staleVrfTables) {
2996 Map<String, Long> staleFibEntMap = new HashMap<>();
2997 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
2998 if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
2999 //Stale marking and cleanup is only meant for the routes learned through BGP.
3002 if (Thread.interrupted()) {
3006 //Create MAP from staleVrfTables.
3007 vrfEntry.getRoutePaths()
3009 routePath -> staleFibEntMap.put(
3010 appendNextHopToPrefix(vrfEntry.getDestPrefix(),
3011 routePath.getNexthopAddress()), routePath.getLabel()));
3013 staledFibEntriesMap.put(vrfTable.getRouteDistinguisher(), staleFibEntMap);
3016 LOG.error("createStaleFibMap:: FIBentries.class is not present");
3018 } catch (ReadFailedException e) {
3019 LOG.error("createStaleFibMap:: error ", e);
3021 LOG.error("created {} staled entries ", totalStaledCount);
3025 * BGP config remove scenario, Need to remove all the
3026 * external routes from FIB.
3028 public void deleteExternalFibRoutes() {
3029 totalExternalRoutes = 0;
3030 totalExternalMacRoutes = 0;
3032 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
3034 Optional<FibEntries> fibEntries = SingleTransactionDataBroker.syncReadOptional(dataBroker,
3035 LogicalDatastoreType.CONFIGURATION, id);
3036 if (fibEntries.isPresent()) {
3037 if (fibEntries.get().getVrfTables() == null) {
3038 LOG.error("deleteExternalFibRoutes::getVrfTables is null");
3041 List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
3042 for (VrfTables vrfTable : staleVrfTables) {
3043 String rd = vrfTable.getRouteDistinguisher();
3044 if (vrfTable.getVrfEntry() != null) {
3045 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
3046 if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
3047 //route cleanup is only meant for the routes learned through BGP.
3050 totalExternalRoutes++;
3051 fibDSWriter.removeFibEntryFromDS(rd, vrfEntry.getDestPrefix());
3053 } else if (vrfTable.getMacVrfEntry() != null) {
3054 for (MacVrfEntry macEntry : vrfTable.getMacVrfEntry()) {
3055 if (RouteOrigin.value(macEntry.getOrigin()) != RouteOrigin.BGP) {
3056 //route cleanup is only meant for the routes learned through BGP.
3059 totalExternalMacRoutes++;
3060 fibDSWriter.removeMacEntryFromDS(rd, macEntry.getMac());
3065 LOG.error("deleteExternalFibRoutes:: FIBentries.class is not present");
3067 } catch (ReadFailedException e) {
3068 LOG.error("deleteExternalFibRoutes:: error ", e);
3070 LOG.debug("deleted {} fib entries {} mac entries", totalExternalRoutes, totalExternalMacRoutes);
3073 public boolean addToRt2TepMap(String rd, String tepIp, String mac, Long l2vni) {
3074 boolean isFirstMacUpdateFromTep = false;
3075 if (rt2TepMap.containsKey(rd)) {
3076 if (rt2TepMap.get(rd).containsKey(tepIp)) {
3077 LOG.debug("RT2 with mac {} l2vni {} from existing rd {} and tep-ip {}. No Elan DS write required",
3078 mac, l2vni, rd, tepIp);
3079 rt2TepMap.get(rd).get(tepIp).put(mac, l2vni);
3081 LOG.debug("RT2 with mac {} l2vni {} from existing rd {} and new tep-ip {}",
3082 mac, l2vni, rd, tepIp);
3083 isFirstMacUpdateFromTep = true;
3084 Map<String, Long> macList = new HashMap<>();
3085 macList.put(mac, l2vni);
3086 rt2TepMap.get(rd).put(tepIp, macList);
3089 LOG.debug("RT2 with mac {} l2vni {} from new rd {} and tep ip {}",
3090 mac, l2vni, rd, tepIp);
3091 isFirstMacUpdateFromTep = true;
3092 Map<String, Long> macList = new HashMap<>();
3093 macList.put(mac, l2vni);
3094 Map<String, Map<String, Long>> tepIpMacMap = new HashMap<>();
3095 tepIpMacMap.put(tepIp, macList);
3096 rt2TepMap.put(rd, tepIpMacMap);
3098 return isFirstMacUpdateFromTep;
3101 public boolean deleteFromRt2TepMap(String rd, String tepIp, String mac) {
3102 boolean isLastMacUpdateFromTep = false;
3103 LOG.debug("RT2 withdraw with rd {} mac {} tep-ip {} ", rd, mac, tepIp);
3104 if (rt2TepMap.containsKey(rd)) {
3105 if (rt2TepMap.get(rd).containsKey(tepIp)) {
3106 if (rt2TepMap.get(rd).get(tepIp).containsKey(mac)) {
3107 LOG.debug("RT2 Withdraw : Removing the mac {} from Map", mac);
3108 rt2TepMap.get(rd).get(tepIp).remove(mac);
3109 if (rt2TepMap.get(rd).get(tepIp).isEmpty()) {
3110 isLastMacUpdateFromTep = true;
3111 LOG.debug("RT2 Withdraw : Removing the tep-ip {} from Map", tepIp);
3112 rt2TepMap.get(rd).remove(tepIp);
3113 if (rt2TepMap.get(rd).isEmpty()) {
3114 LOG.debug("RT2 Withdraw : Removing the rd {} from Map", rd);
3115 rt2TepMap.remove(rd);
3121 return isLastMacUpdateFromTep;
3124 public Collection<String> getTepIPs(String rd) {
3125 final Map<String, Map<String, Long>> tepIpMap = rt2TepMap.get(rd);
3126 return tepIpMap != null ? tepIpMap.keySet() : Collections.emptyList();
3129 public boolean isBgpConnected() {
3130 return (bgpRouter == null) ? false : bgpRouter.isBgpConnected();
3133 public long getLastConnectedTS() {
3134 return (bgpRouter == null) ? 0 : bgpRouter.getLastConnectedTS();
3137 public long getConnectTS() {
3138 return (bgpRouter == null) ? 0 : bgpRouter.getConnectTS();
3141 public long getStartTS() {
3142 return (bgpRouter == null) ? 0 : bgpRouter.getStartTS();
3145 public TTransport getTransport() {
3146 return bgpRouter.getTransport();
3149 public int getTotalStaledCount() {
3150 return totalStaledCount;
3153 public int getTotalCleared() {
3154 return totalCleared;
3157 public BgpCounters getBgpCounters() {
3158 return bgpCountersReference.get();
3161 private void startBgpCountersTask() {
3162 if (getBgpCounters() == null && bgpCountersReference.compareAndSet(null,
3163 new BgpCounters(getBgpSdncMipIp(), metricProvider))) {
3164 bgpCountersTask = executor.scheduleAtFixedRate(bgpCountersReference.get(), 0, 120 * 1000,
3165 TimeUnit.MILLISECONDS);
3166 LOG.info("Bgp Counters task scheduled for every two minutes.");
3168 bgpManager.setQbgpLog(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
3172 private void stopBgpCountersTask() {
3173 final BgpCounters bgpCounters = bgpCountersReference.getAndSet(null);
3174 if (bgpCounters != null) {
3175 bgpCountersTask.cancel(true);
3176 bgpCounters.close();
3180 private void startBgpAlarmsTask() {
3181 if (getBgpAlarms() == null && bgpAlarmsReference.compareAndSet(null, new BgpAlarms(this))) {
3182 bgpAlarmsReference.get().init();
3183 bgpAlarmsTask = executor.scheduleAtFixedRate(bgpAlarmsReference.get(), 0, 60 * 1000, TimeUnit.MILLISECONDS);
3184 LOG.info("Bgp Alarms task scheduled for every minute.");
3186 LOG.trace("Bgp Alarms task already scheduled for every minute.");
3190 private void stopBgpAlarmsTask() {
3191 final BgpAlarms bgpAlarms = bgpAlarmsReference.getAndSet(null);
3192 if (bgpAlarms != null) {
3193 bgpAlarmsTask.cancel(true);
3198 public BgpAlarms getBgpAlarms() {
3199 return bgpAlarmsReference.get();
3202 public void getPeerStatus(String nbrIp, long nbrAsNum) throws
3203 BgpRouterException, TException {
3204 bgpRouter.getPeerStatus(nbrIp, nbrAsNum);
3207 private static String appendNextHopToPrefix(String prefix, String nextHop) {
3208 return prefix + ":" + nextHop;
3211 private static String extractPrefix(String prefixNextHop) {
3212 return prefixNextHop.split(":")[0];
3215 private static String extractNextHop(String prefixNextHop) {
3216 return prefixNextHop.split(":")[1];
3219 private static String extractMd5Secret(final Neighbors val) {
3220 String md5Secret = null;
3221 TcpSecurityOption tcpSecOpt = val.getTcpSecurityOption();
3222 if (tcpSecOpt != null) {
3223 if (tcpSecOpt instanceof TcpMd5SignatureOption) {
3224 md5Secret = ((TcpMd5SignatureOption) tcpSecOpt).getTcpMd5SignaturePassword().getValue();
3225 } else { // unknown TcpSecurityOption
3226 LOG.debug("neighbors Ignored unknown tcp-security-option of peer {}", val.getAddress().getValue());
3230 } // private method extractMd5Secret