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.Futures;
17 import com.google.common.util.concurrent.ListenableFuture;
18 import com.google.common.util.concurrent.ThreadFactoryBuilder;
19 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
20 import io.netty.util.concurrent.GlobalEventExecutor;
21 import java.lang.reflect.Constructor;
22 import java.lang.reflect.InvocationTargetException;
23 import java.net.InetAddress;
24 import java.net.InetSocketAddress;
25 import java.net.NetworkInterface;
26 import java.net.SocketException;
27 import java.util.ArrayList;
28 import java.util.Collection;
29 import java.util.Collections;
30 import java.util.Enumeration;
31 import java.util.HashMap;
32 import java.util.Iterator;
33 import java.util.List;
35 import java.util.Objects;
36 import java.util.Timer;
37 import java.util.concurrent.Callable;
38 import java.util.concurrent.ConcurrentHashMap;
39 import java.util.concurrent.CountDownLatch;
40 import java.util.concurrent.ExecutionException;
41 import java.util.concurrent.Executors;
42 import java.util.concurrent.Future;
43 import java.util.concurrent.ScheduledExecutorService;
44 import java.util.concurrent.ScheduledFuture;
45 import java.util.concurrent.TimeUnit;
46 import java.util.concurrent.TimeoutException;
47 import java.util.concurrent.atomic.AtomicBoolean;
48 import java.util.concurrent.atomic.AtomicInteger;
49 import java.util.concurrent.atomic.AtomicReference;
50 import javax.annotation.PreDestroy;
51 import javax.inject.Inject;
52 import javax.inject.Singleton;
53 import org.apache.thrift.TApplicationException;
54 import org.apache.thrift.TException;
55 import org.apache.thrift.transport.TTransport;
56 import org.eclipse.jdt.annotation.Nullable;
57 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
58 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
59 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
60 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
61 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
62 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
63 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
64 import org.opendaylight.genius.mdsalutil.NwConstants;
65 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
66 import org.opendaylight.infrautils.metrics.MetricProvider;
67 import org.opendaylight.mdsal.eos.binding.api.Entity;
68 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
69 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipListenerRegistration;
70 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
71 import org.opendaylight.mdsal.eos.common.api.CandidateAlreadyRegisteredException;
72 import org.opendaylight.mdsal.eos.common.api.EntityOwnershipChangeState;
73 import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
74 import org.opendaylight.netvirt.bgpmanager.commands.ClearBgpCli;
75 import org.opendaylight.netvirt.bgpmanager.oam.BgpAlarms;
76 import org.opendaylight.netvirt.bgpmanager.oam.BgpConstants;
77 import org.opendaylight.netvirt.bgpmanager.oam.BgpCounters;
78 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouter;
79 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpRouterException;
80 import org.opendaylight.netvirt.bgpmanager.thrift.client.BgpSyncHandle;
81 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Routes;
82 import org.opendaylight.netvirt.bgpmanager.thrift.gen.Update;
83 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_afi;
84 import org.opendaylight.netvirt.bgpmanager.thrift.gen.af_safi;
85 import org.opendaylight.netvirt.bgpmanager.thrift.gen.protocol_type;
86 import org.opendaylight.netvirt.bgpmanager.thrift.gen.qbgpConstants;
87 import org.opendaylight.netvirt.bgpmanager.thrift.server.BgpThriftService;
88 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
89 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.IVpnLinkService;
90 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionHistory;
91 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
92 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfig;
93 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfigBuilder;
94 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.AddressFamily;
95 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
96 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.BgpControlPlaneType;
97 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.EbgpService;
98 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.EncapType;
99 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.InitiateEorInput;
100 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.InitiateEorOutput;
101 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.InitiateEorOutputBuilder;
102 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.TcpMd5SignaturePasswordType;
103 //import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.*;
104 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsId;
105 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsIdBuilder;
106 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServer;
107 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServerBuilder;
108 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.DcgwTepList;
109 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestart;
110 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestartBuilder;
111 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Logging;
112 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.LoggingBuilder;
113 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.MultipathContainer;
114 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsContainer;
115 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksContainer;
116 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpathContainer;
117 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsContainer;
118 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTep;
119 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepBuilder;
120 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepKey;
121 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.multipathcontainer.Multipath;
122 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.multipathcontainer.MultipathBuilder;
123 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.multipathcontainer.MultipathKey;
124 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.Neighbors;
125 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.NeighborsBuilder;
126 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.NeighborsKey;
127 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.AddressFamilies;
128 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.AddressFamiliesBuilder;
129 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.AddressFamiliesKey;
130 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.EbgpMultihop;
131 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.EbgpMultihopBuilder;
132 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.UpdateSource;
133 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.UpdateSourceBuilder;
134 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.networkscontainer.Networks;
135 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.networkscontainer.NetworksBuilder;
136 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.networkscontainer.NetworksKey;
137 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfmaxpathcontainer.VrfMaxpath;
138 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfmaxpathcontainer.VrfMaxpathBuilder;
139 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfmaxpathcontainer.VrfMaxpathKey;
140 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.Vrfs;
141 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.VrfsBuilder;
142 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.VrfsKey;
143 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.vrfs.AddressFamiliesVrf;
144 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.vrfs.AddressFamiliesVrfBuilder;
145 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.TcpSecurityOption;
146 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.tcp.security.option.TcpMd5SignatureOption;
147 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.tcp.security.option.TcpMd5SignatureOptionBuilder;
148 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
149 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressBuilder;
150 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
151 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
152 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
153 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.macvrfentries.MacVrfEntry;
154 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
155 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
156 import org.opendaylight.yangtools.yang.binding.DataObject;
157 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
158 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
159 import org.opendaylight.yangtools.yang.common.RpcError;
160 import org.opendaylight.yangtools.yang.common.RpcResult;
161 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
162 import org.opendaylight.yangtools.yang.common.Uint32;
163 import org.osgi.framework.BundleContext;
164 import org.osgi.util.tracker.ServiceTracker;
165 import org.slf4j.Logger;
166 import org.slf4j.LoggerFactory;
169 public class BgpConfigurationManager implements EbgpService {
170 private static final Logger LOG = LoggerFactory.getLogger(BgpConfigurationManager.class);
172 // to have stale FIB map (RD, Prefix)
173 // number of seconds wait for route sync-up between ODL and BGP
174 private static final int BGP_RESTART_ROUTE_SYNC_SEC = 600;
175 private static final String UPDATE_PORT = "bgp.thrift.service.port";
176 private static final String CONFIG_HOST = "vpnservice.bgpspeaker.host.name";
177 private static final String CONFIG_PORT = "vpnservice.bgpspeaker.thrift.port";
178 private static final String DEF_UPORT = "6644";
179 private static final String DEF_CHOST = "255.255.255.255"; // Invalid Host IP
180 private static final String DEF_CPORT = "7644";
181 private static final String DEF_BGP_SDNC_MIP = "127.0.0.1";
182 //vpnservice.bgp.thrift.bgp.mip is the MIP present with ODL. Here we open 6644 port
183 private static final String BGP_SDNC_MIP = "vpnservice.bgp.thrift.bgp.mip";
184 private static final String BGP_GR_RESTART_TIMER_PROPERTY = "vpnservice.bgp.gr.timer";
185 private static final String BGP_KA_TIMER_PROPERTY = "vpnservice.bgp.ka.timer";
186 private static final String BGP_HOLD_TIMER_PROPERTY = "vpnservice.bgp.hold.timer";
187 private static final String BGP_EOR_DELAY_PROPERTY = "vpnservice.bgp.eordelay";
188 private static final int DEF_BGP_KA_TIME = 60;
189 private static final int DEF_BGP_HOLD_TIME = 180;
190 private static final int DEF_BGP_GR_TIME = 4000;
191 private static final int RESTART_DEFAULT_GR = 90;
192 private static final int DS_RETRY_COUNT = 100; //100 retries, each after WAIT_TIME_BETWEEN_EACH_TRY_MILLIS seconds
193 private static final long WAIT_TIME_BETWEEN_EACH_TRY_MILLIS = 1000L; //one second sleep after every retry
194 private static final String BGP_ENTITY_TYPE_FOR_OWNERSHIP = "bgp";
195 private static final String BGP_EOR_DELAY = "vpnservice.bgp.eordelay";
196 private static final String DEF_BGP_EOR_DELAY = "1800";
197 private static final String BGP_ENTITY_NAME = "bgp";
198 private static final String ADD_WARN = "Config store updated; undo with Delete if needed.";
199 private static final String DEL_WARN = "Config store updated; undo with Add if needed.";
200 private static final String UPD_WARN = "Update operation not supported; Config store updated;"
201 + " restore with another Update if needed.";
202 private static long bgp_as_num = 0;
203 private int bgpKaTime = 0;
204 private int bgpHoldTime = 0;
205 private int bgpGrRestartTime = 0;
207 private static final Class<?>[] REACTORS = {
208 ConfigServerReactor.class, AsIdReactor.class,
209 GracefulRestartReactor.class, LoggingReactor.class,
210 NeighborsReactor.class, UpdateSourceReactor.class,
211 EbgpMultihopReactor.class, AddressFamiliesReactor.class,
212 NetworksReactor.class, VrfsReactor.class, BgpReactor.class,
213 MultipathReactor.class, VrfMaxpathReactor.class, BfdConfigReactor.class
216 private IBgpManager bgpManager;
217 private final DataBroker dataBroker;
218 private final FibDSWriter fibDSWriter;
219 private final IVpnLinkService vpnLinkService;
220 private final BundleContext bundleContext;
221 private final BgpUtil bgpUtil;
222 private volatile Bgp config;
223 private final BgpRouter bgpRouter;
224 private final BgpSyncHandle bgpSyncHandle = new BgpSyncHandle();
225 private volatile BgpThriftService bgpThriftService = null;
226 private final int delayEorSeconds;
228 private final CountDownLatch initer = new CountDownLatch(1);
230 private final String hostStartup;
231 private final String portStartup;
233 private final AtomicReference<BgpCounters> bgpCountersReference = new AtomicReference<>();
234 private ScheduledFuture<?> bgpCountersTask;
236 private final AtomicReference<BgpAlarms> bgpAlarmsReference = new AtomicReference<>();
237 private ScheduledFuture<?> bgpAlarmsTask;
239 private Future<?> lastReplayJobFt;
240 private ScheduledFuture<?> routeCleanupFuture;
242 private long staleStartTime;
243 private long staleEndTime;
244 private long cfgReplayStartTime;
245 private long cfgReplayEndTime;
246 private long staleCleanupTime;
247 private int totalStaledCount;
248 private int totalCleared;
249 private int totalExternalRoutes;
250 private int totalExternalMacRoutes;
252 private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(
253 new ThreadFactoryBuilder().setNameFormat("bgp-config-%d").setDaemon(true).build());
256 * this map store the new address families to send to quagga. When it is sended you must clear it.
257 * The keys String are rd (route distinguisher).
259 private final ConcurrentHashMap<String, List<AddressFamiliesVrf>> mapNewAdFamily = new ConcurrentHashMap<>();
261 // map<rd, map<prefix/len:nexthop, label>>
262 private final Map<String, Map<String, Uint32>> staledFibEntriesMap = new ConcurrentHashMap<>();
264 // map<rd, map<tep-ip, map<mac, l2vni>>>
265 private final Map<String, Map<String, Map<String, Uint32>>> rt2TepMap = new ConcurrentHashMap<>();
267 private final List<AutoCloseable> listeners = new ArrayList<>();
269 private final EntityOwnershipUtils entityOwnershipUtils;
270 private final EntityOwnershipCandidateRegistration candidateRegistration;
271 private final EntityOwnershipListenerRegistration entityListenerRegistration;
272 private final MetricProvider metricProvider;
273 private final TransactionHistory bgpUpdatesHistory;
275 private volatile AtomicBoolean eorSupressedDuetoUpgradeFlag = new AtomicBoolean(false);
278 public BgpConfigurationManager(final DataBroker dataBroker,
279 final EntityOwnershipService entityOwnershipService,
280 final FibDSWriter fibDSWriter,
281 final IVpnLinkService vpnLinkSrvce,
282 final BundleContext bundleContext,
283 final BgpUtil bgpUtil,
284 final MetricProvider metricProvider) {
285 this.dataBroker = dataBroker;
286 this.fibDSWriter = fibDSWriter;
287 this.vpnLinkService = vpnLinkSrvce;
288 this.bundleContext = bundleContext;
289 this.bgpUtil = bgpUtil;
290 this.metricProvider = metricProvider;
291 hostStartup = getProperty(CONFIG_HOST, DEF_CHOST);
292 portStartup = getProperty(CONFIG_PORT, DEF_CPORT);
294 Integer.parseInt(getProperty(BGP_KA_TIMER_PROPERTY,
295 Integer.toString(DEF_BGP_KA_TIME)));
297 Integer.parseInt(getProperty(BGP_HOLD_TIMER_PROPERTY,
298 Integer.toString(DEF_BGP_HOLD_TIME)));
300 Integer.parseInt(getProperty(BGP_GR_RESTART_TIMER_PROPERTY,
301 Integer.toString(DEF_BGP_GR_TIME)));
302 LOG.info("ConfigServer at {}:{}", hostStartup, portStartup);
303 VtyshCli.setHostAddr(hostStartup);
304 ClearBgpCli.setHostAddr(hostStartup);
305 bgpUpdatesHistory = new TransactionHistory(HISTORY_LIMIT, HISTORY_THRESHOLD);
306 bgpRouter = BgpRouter.newInstance(this::getConfig, this::isBGPEntityOwner, bgpUpdatesHistory);
307 delayEorSeconds = Integer.parseInt(getProperty(BGP_EOR_DELAY, DEF_BGP_EOR_DELAY));
309 entityOwnershipUtils = new EntityOwnershipUtils(entityOwnershipService);
311 candidateRegistration = registerEntityCandidate(entityOwnershipService);
312 entityListenerRegistration = registerEntityListener(entityOwnershipService);
314 LOG.info("BGP Configuration manager initialized");
317 GlobalEventExecutor.INSTANCE.execute(() -> {
318 ServiceTracker<IBgpManager, ?> tracker = null;
320 tracker = new ServiceTracker<>(bundleContext, IBgpManager.class, null);
322 bgpManager = (IBgpManager) tracker.waitForService(TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES));
323 Preconditions.checkState(bgpManager != null, "IBgpManager service not found");
324 } catch (InterruptedException e) {
325 throw new IllegalStateException("Error retrieving IBgpManager service", e);
327 if (tracker != null) {
332 String updatePort = getProperty(UPDATE_PORT, DEF_UPORT);
333 if (InetAddresses.isInetAddress(getBgpSdncMipIp())) {
334 InetSocketAddress bgpThriftServerSocketAddr = new InetSocketAddress(getBgpSdncMipIp(),
335 Integer.parseInt(updatePort));
336 bgpThriftService = new BgpThriftService(bgpThriftServerSocketAddr, bgpManager, this);
337 if (isBGPEntityOwner()) {
338 //I am EoS owner of BGP, opening bgp thrift UPDATE-SERVER port.
339 LOG.info("BGP Configuration manager initialized: UPDATE-SERVER started");
340 bgpThriftService.start();
342 LOG.info("UPDATE server started :ip:port={}:{}", getBgpSdncMipIp(), updatePort);
344 LOG.error("Failed to init UPDATE server invalid ip:port={}:{}", getBgpSdncMipIp(), updatePort);
348 LOG.info("BgpConfigurationManager initialized. IBgpManager={}", bgpManager);
351 public String getBgpSdncMipIp() {
352 return getProperty(BGP_SDNC_MIP, DEF_BGP_SDNC_MIP);
355 public long getStaleCleanupTime() {
356 return staleCleanupTime;
359 public void setStaleCleanupTime(long staleCleanupTime) {
360 this.staleCleanupTime = staleCleanupTime;
363 public long getCfgReplayEndTime() {
364 return cfgReplayEndTime;
367 public void setCfgReplayEndTime(long cfgReplayEndTime) {
368 this.cfgReplayEndTime = cfgReplayEndTime;
371 public TransactionHistory getBgpUpdatesHistory() {
372 return bgpUpdatesHistory;
375 public long getCfgReplayStartTime() {
376 return cfgReplayStartTime;
379 public void setCfgReplayStartTime(long cfgReplayStartTime) {
380 this.cfgReplayStartTime = cfgReplayStartTime;
383 public long getStaleEndTime() {
387 public void setStaleEndTime(long staleEndTime) {
388 this.staleEndTime = staleEndTime;
391 public long getStaleStartTime() {
392 return staleStartTime;
395 public void setStaleStartTime(long staleStartTime) {
396 this.staleStartTime = staleStartTime;
399 private Object createListener(Class<?> cls) {
401 Constructor<?> ctor = cls.getConstructor(BgpConfigurationManager.class);
402 return ctor.newInstance(this);
403 } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException
405 LOG.error("Failed to create listener object", e);
410 private void registerCallbacks() {
411 for (Class<?> reactor : REACTORS) {
412 Object obj = createListener(reactor);
414 AsyncDataTreeChangeListenerBase dcl = (AsyncDataTreeChangeListenerBase) obj;
415 dcl.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
421 @SuppressWarnings("checkstyle:IllegalCatch")
423 public void close() {
426 if (bgpThriftService != null) {
427 bgpThriftService.stop();
428 bgpThriftService = null;
431 if (isBgpConnected()) {
432 //disconnect the CONFIG SERVER port (which was )opened during I was Owner
433 bgpRouter.disconnect();
436 if (candidateRegistration != null) {
437 candidateRegistration.close();
440 entityListenerRegistration.close();
442 listeners.forEach(l -> {
445 } catch (Exception e) {
446 LOG.warn("Error closing {}", l ,e);
450 LOG.info("{} close", getClass().getSimpleName());
453 private String getProperty(String var, String def) {
454 String property = bundleContext.getProperty(var);
455 return property == null ? def : property;
458 private EntityOwnershipCandidateRegistration registerEntityCandidate(
459 final EntityOwnershipService entityOwnershipService) {
461 return entityOwnershipService.registerCandidate(
462 new Entity(BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME));
463 } catch (CandidateAlreadyRegisteredException e) {
464 LOG.error("failed to register bgp entity", e);
469 private EntityOwnershipListenerRegistration registerEntityListener(
470 final EntityOwnershipService entityOwnershipService) {
471 return entityOwnershipService.registerListener(BGP_ENTITY_TYPE_FOR_OWNERSHIP, ownershipChange -> {
472 LOG.info("entity owner change event fired: {}", ownershipChange);
474 if (ownershipChange.getState() == EntityOwnershipChangeState.LOCAL_OWNERSHIP_GRANTED) {
475 LOG.info("This PL is the Owner");
476 if (bgpThriftService != null) {
477 //opening UPDATE-SERVER port.
478 bgpThriftService.start();
480 LOG.error("I am the owner of BGP entity, but bgpThriftService is not initialized yet");
484 LOG.info("Not owner: hasOwner: {}, isOwner: {}", ownershipChange.getState().hasOwner(),
485 ownershipChange.getState().isOwner());
486 if (bgpThriftService != null && bgpThriftService.isBgpThriftServiceStarted()) {
487 //close the bgp Thrift Update-SERVER port opened on non-Entity Owner
488 bgpThriftService.stop();
490 if (isBgpConnected()) {
491 //disconnect the CONFIG SERVER port (which was )opened during I was Owner
492 bgpRouter.disconnect();
498 public boolean isBGPEntityOwner() {
499 if (entityOwnershipUtils == null) {
500 LOG.error("entityOwnershipUtils is NULL when listener callbacks fired");
503 return entityOwnershipUtils.isEntityOwner(new Entity(BGP_ENTITY_TYPE_FOR_OWNERSHIP, BGP_ENTITY_NAME), 0, 1);
507 config = getConfig();
511 public class ConfigServerReactor
512 extends AsyncDataTreeChangeListenerBase<ConfigServer, ConfigServerReactor>
513 implements ClusteredDataTreeChangeListener<ConfigServer> {
514 private static final String YANG_OBJ = "config-server ";
516 public ConfigServerReactor() {
517 super(ConfigServer.class, ConfigServerReactor.class);
521 protected void add(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
522 LOG.trace("received bgp connect config host {}", val.getHost().getValue());
523 if (!isBGPEntityOwner()) {
529 } catch (InterruptedException e) {
532 LOG.debug("issueing bgp router connect to host {}", val.getHost().getValue());
533 bgpRouter.configServerUpdated();
534 synchronized (BgpConfigurationManager.this) {
535 boolean res = bgpRouter.connect(val.getHost().getValue(),
536 val.getPort().intValue());
538 LOG.error(YANG_OBJ + "Add failed; " + ADD_WARN);
541 VtyshCli.setHostAddr(val.getHost().getValue());
542 ClearBgpCli.setHostAddr(val.getHost().getValue());
546 protected ConfigServerReactor getDataTreeChangeListener() {
547 return ConfigServerReactor.this;
551 protected InstanceIdentifier<ConfigServer> getWildCardPath() {
552 return InstanceIdentifier.create(Bgp.class).child(ConfigServer.class);
556 protected void remove(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
557 LOG.trace("received bgp disconnect");
558 if (!isBGPEntityOwner()) {
562 bgpRouter.configServerUpdated();
564 synchronized (BgpConfigurationManager.this) {
565 if (bgp_as_num != 0) {
567 bgpRouter.stopBgp(bgp_as_num);
568 stopBgpCountersTask();
570 } catch (TException | BgpRouterException e) {
571 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
574 LOG.debug("bgp as-id is null while removing config-server");
576 bgpRouter.disconnect();
581 protected void update(InstanceIdentifier<ConfigServer> iid,
582 ConfigServer oldval, ConfigServer newval) {
583 LOG.trace("received bgp Connection update");
584 if (!isBGPEntityOwner()) {
587 LOG.error(YANG_OBJ + UPD_WARN);
591 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
592 justification = "https://github.com/spotbugs/spotbugs/issues/811")
593 private BgpRouter getClient(String yangObj) {
594 if (bgpRouter == null || !bgpRouter.isBgpConnected()) {
595 LOG.warn("{}: configuration received when BGP is inactive", yangObj);
601 public class AsIdReactor
602 extends AsyncDataTreeChangeListenerBase<AsId, AsIdReactor>
603 implements ClusteredDataTreeChangeListener<AsId> {
605 private static final String YANG_OBJ = "as-id ";
607 public AsIdReactor() {
608 super(AsId.class, AsIdReactor.class);
612 protected void add(InstanceIdentifier<AsId> iid, AsId val) {
613 LOG.error("received bgp add asid {}", val);
614 if (!isBGPEntityOwner()) {
617 LOG.debug("received add router config asNum {}", val.getLocalAs());
618 bgp_as_num = val.getLocalAs().longValue();
619 synchronized (BgpConfigurationManager.this) {
620 BgpRouter br = getClient(YANG_OBJ);
622 LOG.debug("{} Unable to process add for asNum {}; {} {}", YANG_OBJ, val.getLocalAs(),
623 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
628 startBgpCountersTask();
629 startBgpAlarmsTask();
634 protected AsIdReactor getDataTreeChangeListener() {
635 return AsIdReactor.this;
639 protected InstanceIdentifier<AsId> getWildCardPath() {
640 return InstanceIdentifier.create(Bgp.class).child(AsId.class);
644 protected void remove(InstanceIdentifier<AsId> iid, AsId val) {
645 LOG.error("received delete router config asNum {}", val.getLocalAs());
646 if (!isBGPEntityOwner()) {
649 synchronized (BgpConfigurationManager.this) {
650 long asNum = val.getLocalAs().toJava();
651 BgpRouter br = getClient(YANG_OBJ);
654 LOG.debug("{} Unable to process remove for asNum {}; {} {}", YANG_OBJ, asNum,
655 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
660 } catch (TException | BgpRouterException e) {
661 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
664 stopBgpCountersTask();
667 Bgp conf = getConfig();
669 LOG.error("Config Null while removing the as-id");
672 LOG.debug("Removing external routes from FIB");
673 deleteExternalFibRoutes();
674 List<Neighbors> nbrs = conf.getNeighborsContainer().getNeighbors();
675 if (nbrs != null && nbrs.size() > 0) {
676 LOG.error("Tring to remove the as-id when neighbor config is already present");
677 for (Neighbors nbr : nbrs) {
678 LOG.debug("Removing Neighbor {} from Data store", nbr.getAddress().getValue());
679 delNeighbor(nbr.getAddress().getValue());
686 protected void update(InstanceIdentifier<AsId> iid,
687 AsId oldval, AsId newval) {
688 if (!isBGPEntityOwner()) {
691 LOG.error(YANG_OBJ + UPD_WARN);
695 public class GracefulRestartReactor
696 extends AsyncDataTreeChangeListenerBase<GracefulRestart, GracefulRestartReactor>
697 implements ClusteredDataTreeChangeListener<GracefulRestart> {
699 private static final String YANG_OBJ = "graceful-restart ";
701 public GracefulRestartReactor() {
702 super(GracefulRestart.class, GracefulRestartReactor.class);
706 protected void add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
707 if (!isBGPEntityOwner()) {
710 synchronized (BgpConfigurationManager.this) {
711 int stalePathTime = val.getStalepathTime().intValue();
712 BgpRouter br = getClient(YANG_OBJ);
714 LOG.error("{} Unable to add stale-path time {}; {} {}", YANG_OBJ, stalePathTime,
715 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
719 br.addGracefulRestart(stalePathTime);
720 } catch (TException | BgpRouterException e) {
721 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
727 protected GracefulRestartReactor getDataTreeChangeListener() {
728 return GracefulRestartReactor.this;
732 protected InstanceIdentifier<GracefulRestart> getWildCardPath() {
733 return InstanceIdentifier.create(Bgp.class).child(GracefulRestart.class);
737 protected void remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
738 if (!isBGPEntityOwner()) {
741 LOG.debug("received delete GracefulRestart config val {}", val.getStalepathTime().intValue());
742 synchronized (BgpConfigurationManager.this) {
743 BgpRouter br = getClient(YANG_OBJ);
745 LOG.error("{} Unable to delete stale-path time; {} {}", YANG_OBJ,
746 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
750 br.delGracefulRestart();
751 } catch (TException | BgpRouterException e) {
752 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
758 protected void update(InstanceIdentifier<GracefulRestart> iid,
759 GracefulRestart oldval, GracefulRestart newval) {
760 if (!isBGPEntityOwner()) {
763 LOG.debug("received update GracefulRestart config val {}", newval.getStalepathTime().intValue());
764 synchronized (BgpConfigurationManager.this) {
765 int stalePathTime = newval.getStalepathTime().intValue();
766 BgpRouter br = getClient(YANG_OBJ);
768 LOG.error("{} Unable to update stale-path time to {}; {} {}", YANG_OBJ, stalePathTime,
769 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
773 br.addGracefulRestart(stalePathTime);
774 } catch (TException | BgpRouterException e) {
775 LOG.error("{} update received exception; {}", YANG_OBJ, ADD_WARN, e);
781 public class LoggingReactor
782 extends AsyncDataTreeChangeListenerBase<Logging, LoggingReactor>
783 implements ClusteredDataTreeChangeListener<Logging> {
785 private static final String YANG_OBJ = "logging ";
787 public LoggingReactor() {
788 super(Logging.class, LoggingReactor.class);
792 protected void add(InstanceIdentifier<Logging> iid, Logging val) {
793 if (!isBGPEntityOwner()) {
796 synchronized (BgpConfigurationManager.this) {
797 BgpRouter br = getClient(YANG_OBJ);
799 LOG.error("{} Unable to add logging for qbgp; {} {}", YANG_OBJ,
800 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
804 br.setLogging(val.getFile(), val.getLevel());
805 } catch (TException | BgpRouterException e) {
806 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
812 protected LoggingReactor getDataTreeChangeListener() {
813 return LoggingReactor.this;
817 protected InstanceIdentifier<Logging> getWildCardPath() {
818 return InstanceIdentifier.create(Bgp.class).child(Logging.class);
822 protected void remove(InstanceIdentifier<Logging> iid, Logging val) {
823 if (!isBGPEntityOwner()) {
826 LOG.debug("received remove Logging config val {}", val.getLevel());
827 synchronized (BgpConfigurationManager.this) {
828 BgpRouter br = getClient(YANG_OBJ);
830 LOG.error("{} Unable to remove logging for qbgp; {} {}", YANG_OBJ,
831 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
835 br.setLogging(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
836 } catch (TException | BgpRouterException e) {
837 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
843 protected void update(InstanceIdentifier<Logging> iid,
844 Logging oldval, Logging newval) {
845 if (!isBGPEntityOwner()) {
848 synchronized (BgpConfigurationManager.this) {
849 BgpRouter br = getClient(YANG_OBJ);
851 LOG.error("{} Unable to update logging for qbgp; {} {}", YANG_OBJ,
852 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
856 br.setLogging(newval.getFile(), newval.getLevel());
857 } catch (TException | BgpRouterException e) {
858 LOG.error("{} newval received exception; {}", YANG_OBJ, ADD_WARN, e);
864 public class NeighborsReactor
865 extends AsyncDataTreeChangeListenerBase<Neighbors, NeighborsReactor>
866 implements ClusteredDataTreeChangeListener<Neighbors> {
868 private static final String YANG_OBJ = "neighbors ";
870 public NeighborsReactor() {
871 super(Neighbors.class, NeighborsReactor.class);
875 protected void add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
876 if (!isBGPEntityOwner()) {
879 LOG.debug("received add Neighbors config val {}", val.getAddress().getValue());
880 synchronized (BgpConfigurationManager.this) {
881 String peerIp = val.getAddress().getValue();
882 long as = val.getRemoteAs().toJava();
883 final String md5Secret = extractMd5Secret(val);
884 BgpRouter br = getClient(YANG_OBJ);
886 LOG.debug("{} Unable to process add for peer {} as {}; {} {}", YANG_OBJ, peerIp, as,
887 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
891 //itmProvider.buildTunnelsToDCGW(new IpAddress(peerIp.toCharArray()));
892 br.addNeighbor(peerIp, as, md5Secret);
894 } catch (TException | BgpRouterException e) {
895 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
901 protected NeighborsReactor getDataTreeChangeListener() {
902 return NeighborsReactor.this;
906 protected InstanceIdentifier<Neighbors> getWildCardPath() {
907 return InstanceIdentifier.create(Bgp.class).child(NeighborsContainer.class).child(Neighbors.class);
911 protected void remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
912 if (!isBGPEntityOwner()) {
915 LOG.debug("received remove Neighbors config val {}", val.getAddress().getValue());
916 synchronized (BgpConfigurationManager.this) {
917 String peerIp = val.getAddress().getValue();
918 BgpRouter br = getClient(YANG_OBJ);
920 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
921 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
925 //itmProvider.deleteTunnelsToDCGW(new IpAddress(val.getAddress().getValue().toCharArray()));
926 br.delNeighbor(peerIp);
927 } catch (TException | BgpRouterException e) {
928 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
931 final BgpAlarms bgpAlarms = getBgpAlarms();
932 if (bgpAlarms != null) {
933 bgpAlarms.clearBgpNbrDownAlarm(peerIp);
936 if (bgpUtil.isBfdEnabled()) {
937 final BgpCounters bgpCounters = getBgpCounters();
938 if (bgpCounters != null) {
939 bgpCounters.clearBfdNbrCounters(peerIp);
946 protected void update(InstanceIdentifier<Neighbors> iid,
947 Neighbors oldval, Neighbors newval) {
948 if (!isBGPEntityOwner()) {
951 //purposefully nothing to do.
955 public class EbgpMultihopReactor
956 extends AsyncDataTreeChangeListenerBase<EbgpMultihop, EbgpMultihopReactor>
957 implements ClusteredDataTreeChangeListener<EbgpMultihop> {
959 private static final String YANG_OBJ = "ebgp-multihop ";
961 public EbgpMultihopReactor() {
962 super(EbgpMultihop.class, EbgpMultihopReactor.class);
966 protected void add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
967 if (!isBGPEntityOwner()) {
970 LOG.debug("received add EbgpMultihop config val {}", val.getPeerIp().getValue());
971 synchronized (BgpConfigurationManager.this) {
972 String peerIp = val.getPeerIp().getValue();
973 BgpRouter br = getClient(YANG_OBJ);
975 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
976 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
980 br.addEbgpMultihop(peerIp, val.getNhops().intValue());
981 } catch (TException | BgpRouterException e) {
982 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
988 protected EbgpMultihopReactor getDataTreeChangeListener() {
989 return EbgpMultihopReactor.this;
993 protected InstanceIdentifier<EbgpMultihop> getWildCardPath() {
994 return InstanceIdentifier.create(Bgp.class).child(NeighborsContainer.class).child(Neighbors.class)
995 .child(EbgpMultihop.class);
999 protected void remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
1000 if (!isBGPEntityOwner()) {
1003 LOG.debug("received remove EbgpMultihop config val {}", val.getPeerIp().getValue());
1004 synchronized (BgpConfigurationManager.this) {
1005 String peerIp = val.getPeerIp().getValue();
1006 BgpRouter br = getClient(YANG_OBJ);
1008 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
1009 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1013 br.delEbgpMultihop(peerIp);
1014 } catch (TException | BgpRouterException e) {
1015 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1021 protected void update(InstanceIdentifier<EbgpMultihop> iid,
1022 EbgpMultihop oldval, EbgpMultihop newval) {
1023 if (!isBGPEntityOwner()) {
1026 LOG.error(YANG_OBJ + UPD_WARN);
1030 public class UpdateSourceReactor
1031 extends AsyncDataTreeChangeListenerBase<UpdateSource, UpdateSourceReactor>
1032 implements ClusteredDataTreeChangeListener<UpdateSource> {
1034 private static final String YANG_OBJ = "update-source ";
1036 public UpdateSourceReactor() {
1037 super(UpdateSource.class, UpdateSourceReactor.class);
1041 protected void add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
1042 if (!isBGPEntityOwner()) {
1045 LOG.debug("received add UpdateSource config val {}", val.getSourceIp().getValue());
1046 synchronized (BgpConfigurationManager.this) {
1047 String peerIp = val.getPeerIp().getValue();
1048 BgpRouter br = getClient(YANG_OBJ);
1050 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
1051 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1055 br.addUpdateSource(peerIp, val.getSourceIp().getValue());
1056 } catch (TException | BgpRouterException e) {
1057 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1063 protected UpdateSourceReactor getDataTreeChangeListener() {
1064 return UpdateSourceReactor.this;
1068 protected InstanceIdentifier<UpdateSource> getWildCardPath() {
1069 return InstanceIdentifier.create(Bgp.class).child(NeighborsContainer.class).child(Neighbors.class)
1070 .child(UpdateSource.class);
1074 protected void remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
1075 if (!isBGPEntityOwner()) {
1078 LOG.debug("received remove UpdateSource config val {}", val.getSourceIp().getValue());
1079 synchronized (BgpConfigurationManager.this) {
1080 String peerIp = val.getPeerIp().getValue();
1081 BgpRouter br = getClient(YANG_OBJ);
1083 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
1084 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1088 br.delUpdateSource(peerIp);
1089 } catch (TException | BgpRouterException e) {
1090 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1096 protected void update(InstanceIdentifier<UpdateSource> iid,
1097 UpdateSource oldval, UpdateSource newval) {
1098 if (!isBGPEntityOwner()) {
1101 LOG.error(YANG_OBJ + UPD_WARN);
1105 public class AddressFamiliesReactor
1106 extends AsyncDataTreeChangeListenerBase<AddressFamilies, AddressFamiliesReactor>
1107 implements ClusteredDataTreeChangeListener<AddressFamilies> {
1109 private static final String YANG_OBJ = "address-families ";
1111 public AddressFamiliesReactor() {
1112 super(AddressFamilies.class, AddressFamiliesReactor.class);
1116 protected void add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
1117 if (!isBGPEntityOwner()) {
1120 LOG.debug("received add AddressFamilies config val {}", val.getPeerIp().getValue());
1121 synchronized (BgpConfigurationManager.this) {
1122 String peerIp = val.getPeerIp().getValue();
1123 BgpRouter br = getClient(YANG_OBJ);
1125 LOG.debug("{} Unable to process add for peer {}; {} {}", YANG_OBJ, peerIp,
1126 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1129 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
1130 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
1132 br.addAddressFamily(peerIp, afi, safi);
1133 } catch (TException | BgpRouterException e) {
1134 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1140 protected AddressFamiliesReactor getDataTreeChangeListener() {
1141 return AddressFamiliesReactor.this;
1145 protected InstanceIdentifier<AddressFamilies> getWildCardPath() {
1146 return InstanceIdentifier.create(Bgp.class).child(NeighborsContainer.class).child(Neighbors.class)
1147 .child(AddressFamilies.class);
1151 protected void remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
1152 if (!isBGPEntityOwner()) {
1155 LOG.debug("received remove AddressFamilies config val {}", val.getPeerIp().getValue());
1156 synchronized (BgpConfigurationManager.this) {
1157 String peerIp = val.getPeerIp().getValue();
1158 BgpRouter br = getClient(YANG_OBJ);
1160 LOG.debug("{} Unable to process remove for peer {}; {} {}", YANG_OBJ, peerIp,
1161 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1164 af_afi afi = af_afi.findByValue(val.getAfi().intValue());
1165 af_safi safi = af_safi.findByValue(val.getSafi().intValue());
1167 br.delAddressFamily(peerIp, afi, safi);
1168 } catch (TException | BgpRouterException e) {
1169 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1175 protected void update(InstanceIdentifier<AddressFamilies> iid,
1176 AddressFamilies oldval, AddressFamilies newval) {
1177 if (!isBGPEntityOwner()) {
1180 LOG.error(YANG_OBJ + UPD_WARN);
1184 public class NetworksReactor
1185 extends AsyncDataTreeChangeListenerBase<Networks, NetworksReactor>
1186 implements ClusteredDataTreeChangeListener<Networks> {
1188 private static final String YANG_OBJ = "networks ";
1190 public NetworksReactor() {
1191 super(Networks.class, NetworksReactor.class);
1195 public NetworksReactor getDataTreeChangeListener() {
1196 return NetworksReactor.this;
1200 protected void add(InstanceIdentifier<Networks> iid, Networks val) {
1201 if (!isBGPEntityOwner()) {
1204 LOG.debug("received add Networks config val {}", val.getPrefixLen());
1205 synchronized (BgpConfigurationManager.this) {
1206 String rd = val.getRd();
1207 String pfxlen = val.getPrefixLen();
1208 String nh = val.getNexthop().getValue();
1209 BgpRouter br = getClient(YANG_OBJ);
1211 LOG.debug("{} Unable to process add for rd {} prefix {} nexthop {}; {} {}", YANG_OBJ, rd, pfxlen,
1212 nh, BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1215 Long label = val.getLabel().toJava();
1216 int lbl = label == null ? qbgpConstants.LBL_NO_LABEL
1218 int l3vni = val.getL3vni() == null ? qbgpConstants.LBL_NO_LABEL
1219 : val.getL3vni().intValue();
1220 int l2vni = val.getL2vni() == null ? qbgpConstants.LBL_NO_LABEL
1221 : val.getL2vni().intValue();
1223 BgpControlPlaneType protocolType = val.getBgpControlPlaneType();
1224 int ethernetTag = val.getEthtag().intValue();
1225 String esi = val.getEsi();
1226 String macaddress = val.getMacaddress();
1227 EncapType encapType = val.getEncapType();
1228 String routerMac = val.getRoutermac();
1231 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, l2vni, BgpUtil.convertToThriftProtocolType(protocolType),
1232 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
1233 } catch (TException | BgpRouterException e) {
1234 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1240 protected InstanceIdentifier<Networks> getWildCardPath() {
1241 return InstanceIdentifier.create(Bgp.class).child(NetworksContainer.class).child(Networks.class);
1245 protected void remove(InstanceIdentifier<Networks> iid, Networks val) {
1246 if (!isBGPEntityOwner()) {
1249 LOG.debug("received remove Networks config val {}", val.getPrefixLen());
1250 synchronized (BgpConfigurationManager.this) {
1251 String rd = val.getRd();
1252 String pfxlen = val.getPrefixLen();
1253 BgpRouter br = getClient(YANG_OBJ);
1255 LOG.debug("{} Unable to process remove for rd {} prefix {}; {} {}", YANG_OBJ, rd, pfxlen,
1256 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1259 Long label = val.getLabel().toJava();
1260 int lbl = label == null ? 0 : label.intValue();
1261 if (rd == null && lbl > 0) {
1262 //LU prefix is being deleted.
1263 rd = Integer.toString(lbl);
1266 br.delPrefix(rd, pfxlen);
1267 } catch (TException | BgpRouterException e) {
1268 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1273 /**get the value AFI from a prefix as "x.x.x.x/x".
1275 * @param pfxlen the prefix to get an afi
1276 * @return the afi value as you are need
1278 public int testValueAFI(String pfxlen) {
1279 int afiNew = af_afi.AFI_IP.getValue();
1281 String ipOnly = pfxlen.substring(0, pfxlen.lastIndexOf("/"));
1282 java.net.Inet6Address.getByName(ipOnly);
1283 afiNew = af_afi.AFI_IPV6.getValue();
1284 } catch (java.net.UnknownHostException e) {
1285 //ce n'est pas de l'ipv6
1292 protected void update(final InstanceIdentifier<Networks> iid,
1293 final Networks oldval, final Networks newval) {
1294 if (!isBGPEntityOwner()) {
1297 if (oldval.equals(newval)) {
1298 //Update: OLD and New values are same, no need to trigger remove/add.
1299 LOG.debug("received Updated for the same OLD and New values. RD: {}, Prefix: {}, Label: {}, NH: {}",
1300 oldval.getRd(), oldval.getPrefixLen(), oldval.getLabel(), oldval.getNexthop());
1303 LOG.debug("update networks old val RD: {}, Prefix: {}, Label: {}, NH: {} "
1304 + "new val RD: {}, Prefix: {}, Label: {}, NH: {}",
1305 oldval.getRd(), oldval.getPrefixLen(), oldval.getLabel(), oldval.getNexthop(),
1306 newval.getRd(), newval.getPrefixLen(), newval.getLabel(), newval.getNexthop());
1307 remove(iid, oldval);
1312 static Timer timer = new Timer();
1314 public class VrfsReactor
1315 extends AsyncDataTreeChangeListenerBase<Vrfs, VrfsReactor>
1316 implements ClusteredDataTreeChangeListener<Vrfs> {
1318 private static final String YANG_OBJ = "vrfs ";
1320 public VrfsReactor() {
1321 super(Vrfs.class, VrfsReactor.class);
1325 protected void add(InstanceIdentifier<Vrfs> iid, Vrfs vrfs) {
1326 if (!isBGPEntityOwner()) {
1329 LOG.debug("received add Vrfs config value {}", vrfs.getRd());
1330 synchronized (BgpConfigurationManager.this) {
1331 String rd = vrfs.getRd();
1332 BgpRouter br = getClient(YANG_OBJ);
1334 LOG.debug("{} Unable to process add for rd {}; {} {}", YANG_OBJ, rd,
1335 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1339 List<AddressFamiliesVrf> vrfAddrFamilyList = vrfs.getAddressFamiliesVrf();
1340 for (AddressFamiliesVrf vrfAddrFamily : vrfAddrFamilyList) {
1341 /*add to br the new vrfs arguments*/
1342 br.addVrf(BgpUtil.getLayerType(vrfAddrFamily), rd, vrfs.getImportRts(),
1343 vrfs.getExportRts(), vrfAddrFamily.getAfi().toJava(), vrfAddrFamily.getSafi().toJava());
1345 /*add to br the vrfs contained in mapNewAdFamily*/
1346 List<AddressFamiliesVrf> vrfAddrFamilyListFromMap = mapNewAdFamily.get(rd);
1347 if (vrfAddrFamilyListFromMap == null) {
1351 for (AddressFamiliesVrf adf : vrfAddrFamilyListFromMap) {
1352 if (vrfAddrFamilyList.contains(adf)) {
1353 mapNewAdFamily.remove(rd);
1354 } else if (adf != null) {
1356 br.addVrf(BgpUtil.getLayerType(adf), rd, vrfs.getImportRts(),
1357 vrfs.getExportRts(), adf.getAfi().toJava(), adf.getSafi().toJava());
1358 // remove AddressFamiliesVrf which was already added to BGP
1359 vrfAddrFamilyListFromMap.remove(adf);
1360 if (vrfAddrFamilyListFromMap.isEmpty()) {
1361 // remove Vrf entry from temp mapNewAdFamily if all its AddressFamiliesVrf was
1363 mapNewAdFamily.remove(rd);
1367 } catch (TException | BgpRouterException e) {
1368 LOG.error("{} get {}, Add received exception", YANG_OBJ, ADD_WARN, e);
1374 protected VrfsReactor getDataTreeChangeListener() {
1375 return VrfsReactor.this;
1379 protected InstanceIdentifier<Vrfs> getWildCardPath() {
1380 return InstanceIdentifier.create(Bgp.class).child(VrfsContainer.class).child(Vrfs.class);
1384 protected void remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
1385 if (!isBGPEntityOwner()) {
1388 LOG.debug("received remove Vrfs config val {}", val.getRd());
1389 synchronized (BgpConfigurationManager.this) {
1390 String rd = val.getRd();
1391 BgpRouter br = getClient(YANG_OBJ);
1393 LOG.debug("{} Unable to process remove for rd {}; {} {}", YANG_OBJ, rd,
1394 BgpRouterException.BGP_ERR_NOT_INITED, DEL_WARN);
1398 List<AddressFamiliesVrf> adf = mapNewAdFamily.get(rd);
1399 adf = adf != null ? adf : new ArrayList<>();
1400 for (AddressFamiliesVrf s : val.getAddressFamiliesVrf()) {
1401 br.delVrf(rd, s.getAfi().toJava(), s.getSafi().toJava());
1402 adf.remove(s);// remove in the map the vrf in waiting for advertise quagga
1404 if (adf.isEmpty()) {
1405 mapNewAdFamily.remove(rd);
1407 } catch (TException | BgpRouterException e) {
1408 LOG.error("{} Delete received exception; {}", YANG_OBJ, DEL_WARN, e);
1414 protected void update(InstanceIdentifier<Vrfs> iid,
1415 Vrfs oldval, Vrfs newval) {
1416 if (oldval != null && newval != null) {
1417 LOG.debug("received update Vrfs config val {}, VRFS: Update getting triggered for VRFS rd {}",
1418 newval.getRd(), oldval.getRd());
1420 LOG.debug("received update Vrfs config val {}, from old vrf {}",
1423 if (!isBGPEntityOwner()) {
1427 List<AddressFamiliesVrf> adFamilyVrfToDel = new ArrayList<>();
1428 List<AddressFamiliesVrf> adFamilyVrfToAdd = new ArrayList<>();
1429 List<AddressFamiliesVrf> oldlistAdFamilies = new ArrayList<>();
1430 List<AddressFamiliesVrf> newlistAdFamilies = new ArrayList<>();
1431 if (oldval != null) {
1432 oldlistAdFamilies = oldval.getAddressFamiliesVrf() == null
1433 ? new ArrayList<>() : oldval.getAddressFamiliesVrf();
1435 if (newval != null) {
1436 newlistAdFamilies = newval.getAddressFamiliesVrf() == null
1437 ? new ArrayList<>() : newval.getAddressFamiliesVrf();
1439 /*find old AddressFamily to remove from new configuration*/
1440 for (AddressFamiliesVrf adVrf : oldlistAdFamilies) {
1441 if (!newlistAdFamilies.contains(adVrf)) {
1442 adFamilyVrfToDel.add(adVrf);
1445 /*find new AddressFamily to add to unexisting configuration*/
1446 for (AddressFamiliesVrf adVrf : newlistAdFamilies) {
1447 if (!oldlistAdFamilies.contains(adVrf)) {
1448 adFamilyVrfToAdd.add(adVrf);
1451 String rd = newval != null ? newval.getRd() : null;
1453 BgpRouter br = getClient(YANG_OBJ);
1455 LOG.debug("{} Unable to process add for rd {}; {} {}", YANG_OBJ, rd,
1456 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1460 for (AddressFamiliesVrf adfvrf : adFamilyVrfToAdd) {
1462 LOG.debug("call addVRf rd {} afi {} safi {}", rd, adfvrf.getAfi(), adfvrf.getSafi());
1463 br.addVrf(BgpUtil.getLayerType(adfvrf), rd, newval.getImportRts(),
1464 newval.getExportRts(),adfvrf.getAfi().toJava(), adfvrf.getSafi().toJava());
1465 } catch (TException | BgpRouterException e) {
1466 LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
1470 for (AddressFamiliesVrf adfToDel : adFamilyVrfToDel) {
1472 LOG.debug("call delVRf rd {} afi {} safi {}", rd, adfToDel.getAfi(), adfToDel.getSafi());
1473 br.delVrf(rd, adfToDel.getAfi().toJava(), adfToDel.getSafi().toJava());
1474 } catch (TException | BgpRouterException e) {
1475 LOG.error("{} delVrf received exception; {}", YANG_OBJ, ADD_WARN, e);
1482 public class BgpReactor
1483 extends AsyncDataTreeChangeListenerBase<Bgp, BgpReactor>
1484 implements ClusteredDataTreeChangeListener<Bgp> {
1486 private static final String YANG_OBJ = "Bgp ";
1488 public BgpReactor() {
1489 super(Bgp.class, BgpReactor.class);
1494 protected void add(InstanceIdentifier<Bgp> iid, Bgp val) {
1495 LOG.debug("received add Bgp config");
1499 } catch (InterruptedException e) {
1502 synchronized (BgpConfigurationManager.this) {
1504 if (!isBGPEntityOwner()) {
1511 protected BgpReactor getDataTreeChangeListener() {
1512 return BgpReactor.this;
1516 protected InstanceIdentifier<Bgp> getWildCardPath() {
1517 return InstanceIdentifier.create(Bgp.class);
1521 protected void remove(InstanceIdentifier<Bgp> iid, Bgp val) {
1522 if (!isBGPEntityOwner()) {
1525 LOG.debug("received remove Bgp config");
1531 protected void update(InstanceIdentifier<Bgp> iid,
1532 Bgp oldval, Bgp newval) {
1533 if (!isBGPEntityOwner()) {
1541 @SuppressWarnings("deprecation")
1542 public class MultipathReactor
1543 extends AsyncDataTreeChangeListenerBase<Multipath, MultipathReactor>
1544 implements ClusteredDataTreeChangeListener<Multipath> {
1546 private static final String YANG_OBJ = "multipath ";
1548 public MultipathReactor() {
1549 super(Multipath.class, MultipathReactor.class);
1554 protected MultipathReactor getDataTreeChangeListener() {
1555 return MultipathReactor.this;
1559 protected InstanceIdentifier<Multipath> getWildCardPath() {
1560 return InstanceIdentifier.create(Bgp.class).child(MultipathContainer.class).child(Multipath.class);
1564 protected void remove(InstanceIdentifier<Multipath> iid, Multipath val) {
1565 executor.execute(new MultipathStatusChange(val));
1569 protected void update(InstanceIdentifier<Multipath> iid, Multipath oldval, Multipath newval) {
1570 executor.execute(new MultipathStatusChange(newval));
1574 protected void add(InstanceIdentifier<Multipath> key, Multipath dataObjectModification) {
1575 executor.execute(new MultipathStatusChange(dataObjectModification));
1578 class MultipathStatusChange implements Runnable {
1580 Multipath multipath;
1582 MultipathStatusChange(Multipath multipath) {
1583 this.multipath = multipath;
1588 if (isBGPEntityOwner()) {
1589 synchronized (BgpConfigurationManager.this) {
1591 BgpRouter br = getClient(YANG_OBJ);
1594 af_afi afi = af_afi.findByValue(multipath.getAfi().intValue());
1595 af_safi safi = af_safi.findByValue(multipath.getSafi().intValue());
1598 if (multipath.isMultipathEnabled()) {
1599 br.enableMultipath(afi, safi);
1601 br.disableMultipath(afi, safi);
1603 } catch (TException | BgpRouterException e) {
1604 LOG.error("{} received exception", YANG_OBJ, e);
1614 public void close() {
1619 @SuppressWarnings("deprecation")
1620 public class VrfMaxpathReactor
1621 extends AsyncDataTreeChangeListenerBase<VrfMaxpath, VrfMaxpathReactor>
1622 implements ClusteredDataTreeChangeListener<VrfMaxpath> {
1624 private static final String YANG_OBJ = "vrfMaxpath ";
1626 public VrfMaxpathReactor() {
1627 super(VrfMaxpath.class, VrfMaxpathReactor.class);
1632 protected VrfMaxpathReactor getDataTreeChangeListener() {
1633 return VrfMaxpathReactor.this;
1637 protected InstanceIdentifier<VrfMaxpath> getWildCardPath() {
1638 return InstanceIdentifier.create(Bgp.class).child(VrfMaxpathContainer.class).child(VrfMaxpath.class);
1641 class VrfMaxPathConfigurator implements Runnable {
1643 VrfMaxpath vrfMaxpathVal;
1645 VrfMaxPathConfigurator(VrfMaxpath vrfMaxPathVal) {
1646 this.vrfMaxpathVal = vrfMaxPathVal;
1651 if (isBGPEntityOwner()) {
1652 synchronized (BgpConfigurationManager.this) {
1653 BgpRouter br = getClient(YANG_OBJ);
1656 br.multipaths(vrfMaxpathVal.getRd(), vrfMaxpathVal.getMaxpaths().toJava());
1657 LOG.debug("Maxpath for vrf {} is {}", vrfMaxpathVal.getRd(),
1658 vrfMaxpathVal.getMaxpaths());
1659 } catch (TException | BgpRouterException e) {
1660 LOG.error("{} received exception", YANG_OBJ, e);
1669 protected void remove(InstanceIdentifier<VrfMaxpath> iid, VrfMaxpath vrfMaxPathVal) {
1670 if (isBGPEntityOwner()) {
1671 synchronized (BgpConfigurationManager.this) {
1672 BgpRouter br = getClient(YANG_OBJ);
1675 br.multipaths(vrfMaxPathVal.getRd(), BgpConstants.BGP_DEFAULT_MULTIPATH);
1676 LOG.debug("Del Maxpath for vrf: {} ", vrfMaxPathVal.getRd());
1677 } catch (TException | BgpRouterException e) {
1678 LOG.error(YANG_OBJ + " del received exception:", e);
1686 protected void update(InstanceIdentifier<VrfMaxpath> iid,
1687 VrfMaxpath oldval, VrfMaxpath newval) {
1688 if (!Objects.equals(oldval.getMaxpaths(), newval.getMaxpaths())) {
1689 executor.execute(new VrfMaxPathConfigurator(newval));
1694 protected void add(InstanceIdentifier<VrfMaxpath> instanceIdentifier, VrfMaxpath vrfMaxpathVal) {
1695 executor.execute(new VrfMaxPathConfigurator(vrfMaxpathVal));
1699 public void close() {
1704 public class BfdConfigReactor
1705 extends AsyncDataTreeChangeListenerBase<BfdConfig, BfdConfigReactor>
1706 implements ClusteredDataTreeChangeListener<BfdConfig> {
1708 private static final String YANG_OBJ = "BfdConfig ";
1710 public BfdConfigReactor() {
1711 super(BfdConfig.class, BfdConfigReactor.class);
1715 protected void add(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
1716 if (!isBGPEntityOwner()) {
1719 BgpRouter br = getClient(YANG_OBJ);
1720 LOG.debug("received bfd config: bfd enabled {} min-rx {} min-tx {} detect-mul {} mhop {}",
1721 val.isBfdEnabled(), val.getMinRx(), val.getMinTx(),
1722 val.getDetectMult(), val.isMultihop());
1724 LOG.debug(YANG_OBJ + "{} Unable to process add {}",
1725 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1728 if (val.isBfdEnabled() == false) {
1729 LOG.debug("BFD not enabled. Ignoring the config add");
1732 int minRx = val.getMinRx().intValue();
1733 int minTx = val.getMinTx().intValue();
1734 int detectMult = val.getDetectMult().intValue();
1735 boolean multiHop = val.isMultihop();
1737 br.addBfd(detectMult, minRx, minTx,multiHop);
1738 } catch (TException | BgpRouterException e) {
1739 LOG.error("{} get {}, Add received exception;", YANG_OBJ, ADD_WARN, e);
1744 protected BfdConfigReactor getDataTreeChangeListener() {
1745 return BfdConfigReactor.this;
1749 protected InstanceIdentifier<BfdConfig> getWildCardPath() {
1750 return InstanceIdentifier.create(BfdConfig.class);
1754 protected void remove(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
1755 if (!isBGPEntityOwner()) {
1758 LOG.debug("received bfd config removal");
1759 BgpRouter br = getClient(YANG_OBJ);
1761 LOG.debug("{} Unable to process del {} {}", YANG_OBJ,
1762 BgpRouterException.BGP_ERR_NOT_INITED, ADD_WARN);
1767 } catch (TException | BgpRouterException e) {
1768 LOG.error("{} get {}, Del received exception;", YANG_OBJ, ADD_WARN, e);
1774 protected void update(InstanceIdentifier<BfdConfig> iid,
1775 BfdConfig oldval, BfdConfig newval) {
1776 LOG.debug("received bfd config: updated oldval bfd enabled {}"
1777 + "min-rx {} min-tx {} detect-mul {} mhop {}",
1778 oldval.isBfdEnabled(), oldval.getMinRx(), oldval.getMinTx(),
1779 oldval.getDetectMult(), oldval.isMultihop());
1780 LOG.debug("received bfd config: updated newval bfd enabled {}"
1781 + "min-rx {} min-tx {} detect-mul {} mhop {}",
1782 newval.isBfdEnabled(), newval.getMinRx(), newval.getMinTx(),
1783 newval.getDetectMult(), newval.isMultihop());
1784 if (oldval.isBfdEnabled()) {
1785 LOG.debug("deleting bfd config on an update");
1786 remove(iid, oldval);
1788 LOG.debug("adding bfd config on an update");
1794 public boolean isIpAvailable(String odlip) {
1797 if (odlip != null) {
1798 if ("127.0.0.1".equals(odlip)) {
1801 Enumeration<NetworkInterface> networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces();
1802 while (networkInterfaceEnumeration.hasMoreElements()) {
1803 NetworkInterface networkInterface = networkInterfaceEnumeration.nextElement();
1804 Enumeration<InetAddress> inetAddressEnumeration = networkInterface.getInetAddresses();
1805 while (inetAddressEnumeration.hasMoreElements()) {
1806 InetAddress inetAddress = inetAddressEnumeration.nextElement();
1807 if (odlip.equals(inetAddress.getHostAddress())) {
1813 } catch (SocketException e) {
1819 public long getStalePathtime(int defValue, AsId asId) {
1822 spt = getConfig().getGracefulRestart().getStalepathTime().toJava();
1823 } catch (NullPointerException e) {
1825 spt = asId.getStalepathTime().toJava();
1826 LOG.trace("BGP config/Stale-path time is not set using graceful");
1827 } catch (NullPointerException ignore) {
1828 LOG.trace("BGP AS id is not set using graceful");
1833 LOG.trace("BGP config/Stale-path time is not set using graceful/start-bgp");
1839 public static boolean isValidConfigBgpHostPort(String bgpHost, int bgpPort) {
1840 if (!bgpHost.equals(DEF_CHOST)) {
1847 public synchronized void bgpRestarted() {
1849 * If there a thread which in the process of stale cleanup, cancel it
1850 * and start a new thread (to avoid processing same again).
1852 if (previousReplayJobInProgress()) {
1853 cancelPreviousReplayJob();
1855 Runnable task = () -> {
1857 LOG.info("running bgp replay task ");
1858 if (get() == null) {
1859 String host = getConfigHost();
1860 int port = getConfigPort();
1861 LOG.info("connecting to bgp host {} ", host);
1862 bgpRouter.connect(host, port);
1863 LOG.info("no config to push in bgp replay task ");
1866 setStaleStartTime(System.currentTimeMillis());
1867 LOG.info("started creating stale fibDSWriter map ");
1868 createStaleFibMap();
1869 setStaleEndTime(System.currentTimeMillis());
1870 LOG.info("took {} msecs for stale fibDSWriter map creation ", getStaleEndTime() - getStaleStartTime());
1871 LOG.info("started bgp config replay ");
1872 setCfgReplayStartTime(System.currentTimeMillis());
1873 boolean replaySucceded = replay();
1874 setCfgReplayEndTime(System.currentTimeMillis());
1875 LOG.info("took {} msecs for bgp replay ", getCfgReplayEndTime() - getCfgReplayStartTime());
1876 if (replaySucceded) {
1877 long routeSyncTime = getStalePathtime(BGP_RESTART_ROUTE_SYNC_SEC, config.getAsId());
1878 setStaleCleanupTime(routeSyncTime);
1879 LOG.error("starting the stale cleanup timer: {} seconds", routeSyncTime);
1880 routeCleanupFuture = executor.schedule(new RouteCleanup(), routeSyncTime, TimeUnit.SECONDS);
1882 LOG.error("skipping stale cleanup, may be due to exception while replay");
1883 staledFibEntriesMap.clear();
1885 } catch (InterruptedException | TimeoutException | ExecutionException eCancel) {
1886 LOG.error("Stale Cleanup Task Cancelled", eCancel);
1889 lastReplayJobFt = executor.submit(task);
1892 private boolean previousReplayJobInProgress() {
1893 return ((lastReplayJobFt != null && !lastReplayJobFt.isDone())
1894 || (routeCleanupFuture != null && !routeCleanupFuture.isDone()));
1897 private void cancelPreviousReplayJob() {
1899 LOG.error("cancelling already running bgp replay task");
1900 if (lastReplayJobFt != null) {
1901 lastReplayJobFt.cancel(true);
1902 lastReplayJobFt = null;
1903 staledFibEntriesMap.clear();
1905 if (routeCleanupFuture != null) {
1906 routeCleanupFuture.cancel(true);
1907 routeCleanupFuture = null;
1908 staledFibEntriesMap.clear();
1911 } catch (InterruptedException e) {
1912 LOG.error("Failed to cancel previous replay job ", e);
1916 private void doRouteSync() {
1917 LOG.error("Starting BGP route sync");
1919 bgpRouter.initRibSync(bgpSyncHandle);
1920 } catch (BgpRouterException e) {
1921 LOG.error("Route sync aborted, exception when initializing", e);
1924 while (bgpSyncHandle.getState() != BgpSyncHandle.DONE) {
1925 for (af_afi afi : af_afi.values()) {
1926 Routes routes = null;
1928 routes = bgpRouter.doRibSync(bgpSyncHandle, afi);
1929 } catch (TException | BgpRouterException e) {
1930 LOG.error("Route sync aborted, exception when syncing", e);
1933 Iterator<Update> updates = routes.getUpdatesIterator();
1934 while (updates.hasNext()) {
1935 Update update = updates.next();
1936 String rd = update.getRd();
1937 String nexthop = update.getNexthop();
1939 // TODO: decide correct label here
1940 int label = update.getL3label();
1941 int l2label = update.getL2label();
1943 String prefix = update.getPrefix();
1944 int plen = update.getPrefixlen();
1947 // TODO: protocol type will not be available in "update"
1948 // use "rd" to query vrf table and obtain the protocol_type.
1949 // Currently using PROTOCOL_EVPN as default.
1951 protocol_type.PROTOCOL_L3VPN,
1956 update.getMacaddress(),
1957 Uint32.valueOf(label),
1958 Uint32.valueOf(l2label),
1959 update.getRoutermac(),
1965 LOG.error("Ending BGP route-sync");
1966 bgpRouter.endRibSync(bgpSyncHandle);
1967 } catch (BgpRouterException e) {
1972 public void addTepToElanDS(String rd, String tepIp, String mac, Uint32 l2vni) {
1973 boolean needUpdate = addToRt2TepMap(rd, tepIp, mac, l2vni);
1975 LOG.info("Adding tepIp {} with RD {} to ELan DS", tepIp, rd);
1976 bgpUtil.addTepToElanInstance(rd, tepIp);
1978 LOG.debug("Skipping the Elan update for RT2 from tep {} rd {}", tepIp, rd);
1982 public void deleteTepfromElanDS(String rd, String tepIp, String mac) {
1983 boolean needUpdate = deleteFromRt2TepMap(rd, tepIp, mac);
1985 LOG.info("Deleting tepIp {} with RD {} to ELan DS", tepIp, rd);
1986 bgpUtil.deleteTepFromElanInstance(rd, tepIp);
1988 LOG.debug("Skipping the Elan update for RT2 withdraw from tep {} rd {}", tepIp, rd);
1992 /* onUpdatePushRoute
1993 * Get Stale fibDSWriter map, and compare current route/fibDSWriter entry.
1994 * - Entry compare shall include NextHop, Label.
1995 * - If entry matches: delete from STALE Map. NO Change to FIB Config DS.
1996 * - If entry not found, add to FIB Config DS.
1997 * - If entry found, but either Label/NextHop doesn't match.
1998 * - Update FIB Config DS with modified values.
1999 * - delete from Stale Map.
2002 public void onUpdatePushRoute(protocol_type protocolType, String rd, String prefix, int plen, String nextHop,
2003 String macaddress, Uint32 label, Uint32 l2label, String routermac, af_afi afi) {
2004 PrefixUpdateEvent prefixUpdateEvent = new PrefixUpdateEvent(protocolType,rd,prefix,plen,nextHop,
2005 macaddress,label,l2label,routermac,afi);
2006 bgpUpdatesHistory.addToHistory(TransactionType.ADD, prefixUpdateEvent);
2007 boolean addroute = false;
2008 boolean macupdate = false;
2009 Uint32 l3vni = Uint32.ZERO;
2010 VrfEntry.EncapType encapType = VrfEntry.EncapType.Mplsgre;
2011 if (protocolType.equals(protocol_type.PROTOCOL_EVPN)) {
2012 encapType = VrfEntry.EncapType.Vxlan;
2013 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = bgpUtil.getVpnInstanceOpData(rd);
2014 if (vpnInstanceOpDataEntry != null) {
2015 if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
2016 LOG.info("Got RT2 route for RD {} l3label {} l2label {} from tep {} with mac {} remote RD {}",
2017 vpnInstanceOpDataEntry.getVpnInstanceName(), label, l2label, nextHop, macaddress, rd);
2018 addTepToElanDS(rd, nextHop, macaddress, l2label);
2021 l3vni = vpnInstanceOpDataEntry.getL3vni();
2024 LOG.error("No corresponding vpn instance found for rd {}. Aborting.", rd);
2029 if (!staledFibEntriesMap.isEmpty()) {
2030 // restart Scenario, as MAP is not empty.
2031 Map<String, Uint32> map = staledFibEntriesMap.get(rd);
2033 String prefixNextHop = appendNextHopToPrefix(prefix + "/" + plen, nextHop);
2034 Uint32 labelInStaleMap = map.get(prefixNextHop);
2035 if (null == labelInStaleMap) {
2036 // New Entry, which happened to be added during restart.
2039 map.remove(prefixNextHop);
2040 if (isRouteModified(label, labelInStaleMap)) {
2041 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
2042 // Existing entry, where in Label got modified during restart
2047 LOG.debug("rd {} map is null while processing prefix {} ", rd, prefix);
2051 LOG.debug("Route add ** {} ** {}/{} ** {} ** {} ", rd, prefix, plen, nextHop, label);
2055 LOG.info("ADD: Adding Mac Fib entry rd {} mac{} nexthop {} l2vni {}", rd, macaddress, nextHop, l2label);
2056 fibDSWriter.addMacEntryToDS(rd, macaddress, prefix, Collections.singletonList(nextHop),
2057 encapType, l2label, routermac, RouteOrigin.BGP);
2058 LOG.info("ADD: Added Mac Fib entry rd {} prefix {} nexthop {} label {}", rd, macaddress, nextHop, l2label);
2059 } else if (addroute) {
2060 LOG.info("ADD: Adding Fib entry rd {} prefix {} nexthop {} label {} afi {}",
2061 rd, prefix, nextHop, label, afi);
2062 // TODO: modify addFibEntryToDS signature
2063 List<String> nextHopList = Collections.singletonList(nextHop);
2064 fibDSWriter.addFibEntryToDS(rd, prefix + "/" + plen, nextHopList, encapType, label, l3vni,
2065 routermac, RouteOrigin.BGP);
2066 LOG.info("ADD: Added Fib entry rd {} prefix {} nexthop {} label {}", rd, prefix, nextHop, label);
2067 String vpnName = bgpUtil.getVpnNameFromRd(rd);
2068 if (vpnName != null) {
2069 vpnLinkService.leakRouteIfNeeded(vpnName, prefix, nextHopList, label, RouteOrigin.BGP,
2070 NwConstants.ADD_FLOW);
2075 public void onUpdateWithdrawRoute(protocol_type protocolType, String rd, String prefix, int plen, String nextHop,
2076 String macaddress) {
2077 PrefixWithdrawEvent prefixWithdrawEvent = new PrefixWithdrawEvent(protocolType,rd,prefix,plen,
2078 nextHop,macaddress);
2079 bgpUpdatesHistory.addToHistory(TransactionType.ADD, prefixWithdrawEvent);
2080 boolean macupdate = false;
2081 if (protocolType.equals(protocol_type.PROTOCOL_EVPN)) {
2082 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = bgpUtil.getVpnInstanceOpData(rd);
2083 if (vpnInstanceOpDataEntry != null) {
2084 Uint32 vni = vpnInstanceOpDataEntry.getL3vni();
2085 if (vpnInstanceOpDataEntry.getType() == VpnInstanceOpDataEntry.Type.L2) {
2086 LOG.debug("Got RT2 withdraw for RD {} {} from tep {} with mac {} remote RD {}",
2087 vpnInstanceOpDataEntry.getVpnInstanceName(), vni, nextHop, macaddress, rd);
2088 deleteTepfromElanDS(rd, nextHop, macaddress);
2089 LOG.debug("For rd {}. skipping fib update", rd);
2093 LOG.error("No corresponding vpn instance found for rd {}. Aborting.", rd);
2098 LOG.info("Removing Mac Fib entry rd {} mac{} nexthop {} ", rd, macaddress, nextHop);
2099 fibDSWriter.removeMacEntryFromDS(rd, macaddress);
2100 LOG.info("Removed Mac Fib entry rd {} prefix {} nexthop {} ", rd, macaddress, nextHop);
2102 LOG.info("REMOVE: Removing Fib entry rd {} prefix {}", rd, prefix);
2103 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix + "/" + plen, nextHop);
2104 LOG.info("REMOVE: Removed Fib entry rd {} prefix {}", rd, prefix);
2108 //TODO: below function is for testing purpose with cli
2109 public void onUpdateWithdrawRoute(String rd, String prefix, int plen, String nexthop) {
2110 LOG.debug("Route del ** {} ** {}/{} ", rd, prefix, plen);
2111 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix + "/" + plen, nexthop);
2112 String vpnName = bgpUtil.getVpnNameFromRd(rd);
2113 if (vpnName != null) {
2114 vpnLinkService.leakRouteIfNeeded(vpnName, prefix, null /*nextHopList*/, Uint32.ZERO /*INVALID_LABEL*/,
2115 RouteOrigin.BGP, NwConstants.DEL_FLOW);
2119 public void peerDown(String ipAddress, long asNumber) {
2120 PeerDownEvent peerDownEvent = new PeerDownEvent(ipAddress,asNumber);
2121 bgpUpdatesHistory.addToHistory(TransactionType.ADD, peerDownEvent);
2122 List<String> tepIpList = bgpUtil.getDcgwTepConfig(ipAddress);
2123 if (tepIpList == null) {
2124 LOG.error("No Tep IP configured for DCGW {} on a peerDown", ipAddress);
2127 tepIpList.forEach(tepIp -> {
2128 bgpUtil.removeOrUpdateLBGroups(tepIp, NwConstants.MOD_FLOW);
2132 public void peerUp(String ipAddress, long asNumber) {
2133 PeerUpEvent peerUpEvent = new PeerUpEvent(ipAddress,asNumber);
2134 bgpUpdatesHistory.addToHistory(TransactionType.ADD, peerUpEvent);
2135 List<String> tepIpList = bgpUtil.getDcgwTepConfig(ipAddress);
2136 if (tepIpList == null) {
2137 LOG.error("No Tep IP configured for DCGW {} on a peerUp", ipAddress);
2140 tepIpList.forEach(tepIp -> {
2141 bgpUtil.removeOrUpdateLBGroups(tepIp, NwConstants.MOD_FLOW);
2145 private static boolean isRouteModified(Uint32 label, Uint32 labelInStaleMap) {
2146 return labelInStaleMap != null && !labelInStaleMap.equals(label);
2149 static class ReplayNbr {
2151 boolean shouldRetry = false;
2153 public Neighbors getNbr() {
2157 public boolean isShouldRetry() {
2161 public void setShouldRetry(boolean retryNbr) {
2162 this.shouldRetry = retryNbr;
2165 ReplayNbr(Neighbors nbr, boolean shouldRetry) {
2167 this.shouldRetry = shouldRetry;
2171 private static boolean replayNbrConfig(List<Neighbors> neighbors, BgpRouter br) {
2172 if (neighbors == null || neighbors.isEmpty()) {
2173 LOG.error("Replaying nbr configuration, received NULL list ");
2177 List<ReplayNbr> replayNbrList = new ArrayList<>();
2178 for (Neighbors nbr : neighbors) {
2180 replayNbrList.add(new ReplayNbr(nbr, true));
2183 final int numberOfNbrRetries = 3;
2184 RetryOnException nbrRetry = new RetryOnException(numberOfNbrRetries);
2186 for (ReplayNbr replayNbr : replayNbrList) {
2187 if (!replayNbr.isShouldRetry()) {
2190 boolean replayDone = false;
2191 LOG.debug("Replaying addNbr {}", replayNbr.getNbr().getAddress().getValue());
2194 final String md5password = extractMd5Secret(replayNbr.getNbr());
2195 br.addNeighbor(replayNbr.getNbr().getAddress().getValue(),
2196 replayNbr.getNbr().getRemoteAs().longValue(), md5password);
2198 } catch (TApplicationException tae) {
2199 LOG.debug("Replaying addNbr {}, tapplicationexception: ",
2200 replayNbr.getNbr().getAddress().getValue(), tae);
2201 if (tae.getType() == BgpRouterException.BGP_ERR_PEER_EXISTS) {
2202 LOG.debug("Replaying addNbr Neighbor already present");
2205 LOG.error("Replaying addNbr {}, exception: ", replayNbr.getNbr().getAddress().getValue(), tae);
2207 } catch (TException | BgpRouterException eNbr) {
2208 LOG.debug("Replaying addNbr {}, exception: ", replayNbr.getNbr().getAddress().getValue(), eNbr);
2211 LOG.debug("Replay addNbr {} successful", replayNbr.getNbr().getAddress().getValue());
2213 //Update Source handling
2214 UpdateSource us = replayNbr.getNbr().getUpdateSource();
2216 LOG.debug("Replaying updatesource {} to peer {}", us.getSourceIp().getValue(),
2217 us.getPeerIp().getValue());
2219 br.addUpdateSource(us.getPeerIp().getValue(),
2220 us.getSourceIp().getValue());
2221 } catch (TException | BgpRouterException eUs) {
2222 LOG.debug("Replaying UpdateSource for Nbr {}, exception:",
2223 replayNbr.getNbr().getAddress().getValue(), eUs);
2225 LOG.debug("Replay updatesource {} successful", us.getSourceIp().getValue());
2228 EbgpMultihop en = replayNbr.getNbr().getEbgpMultihop();
2231 br.addEbgpMultihop(en.getPeerIp().getValue(),
2232 en.getNhops().intValue());
2233 } catch (TException | BgpRouterException eEbgpMhop) {
2234 LOG.debug("Replaying EbgpMultihop for Nbr {}, exception: ",
2235 replayNbr.getNbr().getAddress().getValue(), eEbgpMhop);
2240 List<AddressFamilies> afs = replayNbr.getNbr().getAddressFamilies();
2242 for (AddressFamilies af : afs) {
2243 af_afi afi = af_afi.findByValue(af.getAfi().intValue());
2244 af_safi safi = af_safi.findByValue(af.getSafi().intValue());
2246 br.addAddressFamily(af.getPeerIp().getValue(), afi, safi);
2247 } catch (TException | BgpRouterException eAFs) {
2248 LOG.debug("Replaying AddressFamily for Nbr {}, exception:",
2249 replayNbr.getNbr().getAddress().getValue(), eAFs);
2253 //replay is success --> no need to replay this nbr in next iteration.
2254 replayNbr.setShouldRetry(replayDone ? false : true);
2256 } while (nbrRetry.decrementAndRetry());
2257 boolean replaySuccess = true;
2258 for (ReplayNbr replayNbr : replayNbrList) {
2259 replaySuccess = replaySuccess && !replayNbr.isShouldRetry();
2260 if (replaySuccess == false) {
2261 LOG.error("replayNbrConfig: will be cancelling stale cleanup, cfg nbr: {} Failed:",
2262 replayNbr.getNbr().getAddress().getValue());
2265 return replaySuccess;
2268 public String getConfigHost() {
2269 if (config == null) {
2272 ConfigServer ts = config.getConfigServer();
2273 return ts == null ? hostStartup : ts.getHost().getValue();
2276 public int getConfigPort() {
2277 if (config == null) {
2278 return Integer.parseInt(portStartup);
2280 ConfigServer ts = config.getConfigServer();
2281 return ts == null ? Integer.parseInt(portStartup) :
2282 ts.getPort().intValue();
2285 public Bgp getConfig() {
2286 AtomicInteger bgpDSretryCount = new AtomicInteger(DS_RETRY_COUNT);
2287 while (0 != bgpDSretryCount.decrementAndGet()) {
2289 return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
2290 InstanceIdentifier.create(Bgp.class)).orNull();
2291 } catch (ReadFailedException e) {
2292 //Config DS may not be up, so sleep for 1 second and retry
2293 LOG.debug("failed to get bgp config, may be DS is yet in consistent state(?)", e);
2295 Thread.sleep(WAIT_TIME_BETWEEN_EACH_TRY_MILLIS);
2296 } catch (InterruptedException timerEx) {
2297 LOG.debug("WAIT_TIME_BETWEEN_EACH_TRY_MILLIS, Timer got interrupted while waiting for"
2298 + "config DS availability", timerEx);
2302 LOG.error("failed to get bgp config");
2306 @SuppressWarnings("checkstyle:IllegalCatch")
2307 public synchronized boolean replay() throws InterruptedException, TimeoutException, ExecutionException {
2308 boolean replaySucceded = true;
2309 boolean doRouteSync = false;
2310 String host = getConfigHost();
2311 int port = getConfigPort();
2312 LOG.error("connecting to bgp host {} ", host);
2313 boolean res = bgpRouter.connect(host, port);
2315 LOG.error("Cannot connect to BGP config server at {} {}", host, port);
2316 return replaySucceded;
2318 config = getConfig();
2319 if (config == null) {
2320 LOG.error("bgp config is empty nothing to push to bgp");
2321 return replaySucceded;
2323 BgpRouter br = bgpRouter;
2324 AsId asId = config.getAsId();
2326 LOG.error("bgp as-id is null");
2327 return replaySucceded;
2329 long asNum = asId.getLocalAs().toJava();
2330 IpAddress routerId = asId.getRouterId();
2331 String rid = routerId == null ? "" : routerId.stringValue();
2332 int stalepathTime = (int) getStalePathtime(bgpGrRestartTime, config.getAsId());
2333 boolean announceFbit = true;
2334 boolean replayDone = false;
2335 final int numberOfStartBgpRetries = 3;
2336 RetryOnException startBgpRetry = new RetryOnException(numberOfStartBgpRetries);
2339 LOG.debug("Replaying BGPConfig ");
2340 br.startBgp(asNum, rid, bgpKaTime, bgpHoldTime, stalepathTime, announceFbit);
2341 LOG.debug("Replay BGPConfig successful");
2344 } catch (BgpRouterException bre) {
2345 if (bre.getErrorCode() == BgpRouterException.BGP_ERR_ACTIVE) {
2346 LOG.debug("Starting the routesync for exception", bre);
2347 startBgpRetry.errorOccured();
2348 if (!startBgpRetry.shouldRetry()) {
2353 LOG.error("Replay: startBgp() received exception error {} : ",
2354 bre.getErrorCode(), bre);
2355 startBgpRetry.errorOccured();
2357 } catch (TApplicationException tae) {
2358 if (tae.getType() == BgpRouterException.BGP_ERR_ACTIVE) {
2359 LOG.debug("Starting the routesync for exception", tae);
2360 startBgpRetry.errorOccured();
2361 if (!startBgpRetry.shouldRetry()) {
2365 } else if (tae.getType() == BgpRouterException.BGP_ERR_COMMON_FAILURE) {
2366 LOG.debug("Starting the routesync for AS-ID started exception", tae);
2367 startBgpRetry.errorOccured();
2368 if (!startBgpRetry.shouldRetry()) {
2373 LOG.error("Replay: startBgp() received exception type {}: ",
2374 tae.getType(), tae);
2375 startBgpRetry.errorOccured();
2377 } catch (Exception e) {
2378 //not unusual. We may have restarted & BGP is already on
2379 LOG.error("Replay:startBgp() received exception: ", e);
2380 startBgpRetry.errorOccured();
2382 } while (startBgpRetry.shouldRetry());
2384 replaySucceded = replayDone;
2386 startBgpCountersTask();
2387 startBgpAlarmsTask();
2390 * commenting this due to a bug with QBGP. Will uncomment once QBGP fix is done.
2391 * This wont have any functional impacts
2394 // br.delayEOR(delayEorSeconds);
2395 //} catch (TException | BgpRouterException e) {
2396 // LOG.error("Replay: delayEOR() number of seconds to wait for EOR from ODL:", e);
2399 BfdConfig bfdConfig = bgpUtil.getBfdConfig();
2400 if (bfdConfig != null) {
2401 if (bfdConfig.isBfdEnabled()) {
2402 LOG.debug("Replaying bfd config min-rx {} min-tx {} detect-mul {} mhop {}",
2403 bfdConfig.getMinRx(), bfdConfig.getMinTx(),
2404 bfdConfig.getDetectMult(), bfdConfig.isMultihop());
2406 br.addBfd(bfdConfig.getDetectMult().intValue(), bfdConfig.getMinRx().intValue(),
2407 bfdConfig.getMinTx().intValue(), bfdConfig.isMultihop());
2408 } catch (TApplicationException tae) {
2409 if (tae.getType() == BgpRouterException.BGP_ERR_PEER_EXISTS) {
2410 LOG.debug("Replay:addBfd() received exception", tae);
2412 LOG.error("Replay:addBfd() received exception", tae);
2414 } catch (TException | BgpRouterException e) {
2415 LOG.error("Replay:addBfd() received exception", e);
2420 List<Neighbors> neighbors = config.getNeighborsContainer().getNeighbors();
2421 if (neighbors != null) {
2422 LOG.error("configuring existing Neighbors present for replay total neighbors {}", neighbors.size());
2423 boolean neighborConfigReplayResult = replayNbrConfig(neighbors, br);
2424 if (neighborConfigReplayResult == false) {
2425 replaySucceded = false;
2428 LOG.error("no Neighbors present for replay config ");
2431 Logging logging = config.getLogging();
2432 if (logging != null) {
2434 br.setLogging(logging.getFile(), logging.getLevel());
2435 } catch (TException | BgpRouterException e) {
2436 LOG.error("Replay:setLogging() received exception", e);
2440 GracefulRestart gracefulRestart = config.getGracefulRestart();
2441 bgpGrRestartTime = ((gracefulRestart != null)
2442 ? gracefulRestart.getStalepathTime().intValue() : bgpGrRestartTime);
2444 br.addGracefulRestart(bgpGrRestartTime);
2445 } catch (Exception e) {
2446 LOG.error("Replay:addGr() received exception: ", e);
2448 List<Vrfs> vrfs = config.getVrfsContainer().getVrfs();
2450 vrfs = new ArrayList<>();
2452 for (Vrfs vrf : vrfs) {
2453 for (AddressFamiliesVrf adf : vrf.getAddressFamiliesVrf()) {
2455 br.addVrf(BgpUtil.getLayerType(adf), vrf.getRd(), vrf.getImportRts(),
2456 vrf.getExportRts(), adf.getAfi().toJava(), adf.getSafi().toJava());
2457 } catch (TException | BgpRouterException e) {
2458 LOG.error("Replay:addVrf() received exception", e);
2463 List<Networks> ln = config.getNetworksContainer().getNetworks();
2465 for (Networks net : ln) {
2466 String rd = net.getRd();
2467 String pfxlen = net.getPrefixLen();
2468 String nh = net.getNexthop().getValue();
2469 Long label = net.getLabel().toJava();
2470 int lbl = label == null ? 0 : label.intValue();
2471 int l3vni = net.getL3vni() == null ? 0 : net.getL3vni().intValue();
2472 int l2vni = net.getL2vni() == null ? 0 : net.getL2vni().intValue();
2473 if (rd == null && lbl > 0) {
2474 //LU prefix is being deleted.
2475 rd = Integer.toString(lbl);
2478 BgpControlPlaneType protocolType = net.getBgpControlPlaneType();
2479 int ethernetTag = net.getEthtag().intValue();
2480 String esi = net.getEsi();
2481 String macaddress = net.getMacaddress();
2482 EncapType encapType = net.getEncapType();
2483 String routerMac = net.getRoutermac();
2486 br.addPrefix(rd, pfxlen, nh, lbl, l3vni, l2vni,
2487 BgpUtil.convertToThriftProtocolType(protocolType),
2488 ethernetTag, esi, macaddress, BgpUtil.convertToThriftEncapType(encapType), routerMac);
2489 } catch (TException | BgpRouterException e) {
2490 LOG.error("Replay:addPfx() received exception", e);
2496 List<Multipath> multipaths = config.getMultipathContainer().getMultipath();
2498 if (multipaths != null) {
2499 for (Multipath multipath : multipaths) {
2500 if (multipath != null) {
2501 af_afi afi = af_afi.findByValue(multipath.getAfi().intValue());
2502 af_safi safi = af_safi.findByValue(multipath.getSafi().intValue());
2505 if (multipath.isMultipathEnabled()) {
2506 br.enableMultipath(afi, safi);
2508 br.disableMultipath(afi, safi);
2510 } catch (TException | BgpRouterException e) {
2511 LOG.info("Replay:multipaths() received exception", e);
2516 List<VrfMaxpath> vrfMaxpaths = config.getVrfMaxpathContainer().getVrfMaxpath();
2517 if (vrfMaxpaths != null) {
2518 for (VrfMaxpath vrfMaxpath : vrfMaxpaths) {
2520 br.multipaths(vrfMaxpath.getRd(), vrfMaxpath.getMaxpaths().toJava());
2521 } catch (TException | BgpRouterException e) {
2522 LOG.info("Replay:vrfMaxPath() received exception", e);
2527 //send End of Rib Marker to Qthriftd.
2528 final int numberOfEORRetries = 3;
2529 RetryOnException eorRetry = new RetryOnException(numberOfEORRetries);
2533 LOG.debug("Replay sendEOR() successful");
2535 } catch (Exception e) {
2536 eorRetry.errorOccured();
2537 LOG.error("Replay:sedEOR() received exception:", e);
2539 } while (eorRetry.shouldRetry());
2542 LOG.debug("starting route sync for Thrift BGP_ERR_COMMON_FAILURE exception "
2543 + "happened earlier");
2547 return replaySucceded;
2550 private <T extends DataObject> void update(InstanceIdentifier<T> iid, T dto) {
2551 bgpUtil.update(iid, dto);
2554 private <T extends DataObject> void delete(InstanceIdentifier<T> iid) {
2555 bgpUtil.delete(iid);
2558 public void startConfig(String bgpHost, int thriftPort) {
2559 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
2560 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
2561 InstanceIdentifier<ConfigServer> iid = iib.build();
2562 Ipv4Address ipAddr = new Ipv4Address(bgpHost);
2563 ConfigServer dto = new ConfigServerBuilder().setHost(ipAddr)
2564 .setPort((long) thriftPort).build();
2568 public void startBgp(long as, String routerId, int spt, boolean fbit) {
2569 IpAddress rid = routerId == null ? null : IpAddressBuilder.getDefaultInstance(routerId);
2570 Long staleTime = (long) spt;
2571 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
2572 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
2573 InstanceIdentifier<AsId> iid = iib.build();
2574 AsId dto = new AsIdBuilder().setLocalAs(as)
2576 .setStalepathTime(staleTime)
2577 .setAnnounceFbit(fbit).build();
2581 public void startBfd(long detectMult, long minRx, long minTx, boolean multiHop) {
2582 InstanceIdentifier.InstanceIdentifierBuilder<BfdConfig> iib =
2583 InstanceIdentifier.builder(BfdConfig.class);
2584 InstanceIdentifier<BfdConfig> iid = iib.build();
2585 BfdConfig dto = new BfdConfigBuilder()
2586 .setBfdEnabled(true)
2587 .setMultihop(multiHop)
2590 .setDetectMult(detectMult)
2595 public void addDcgwTep(String dcgwIp, String tepIp) {
2596 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2597 InstanceIdentifier.builder(Bgp.class)
2598 .child(DcgwTepList.class)
2599 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2600 InstanceIdentifier<DcgwTep> iid = iib.build();
2601 ArrayList<String> tepList = new ArrayList<String>();
2603 DcgwTep dto = new DcgwTepBuilder().setDcGwIp(dcgwIp).setTepIps(tepList)
2606 bgpUtil.removeOrUpdateLBGroups(tepIp,NwConstants.MOD_FLOW);
2609 public void addLogging(String fileName, String logLevel) {
2610 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
2611 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
2612 InstanceIdentifier<Logging> iid = iib.build();
2613 Logging dto = new LoggingBuilder().setFile(fileName)
2614 .setLevel(logLevel).build();
2618 public void addGracefulRestart(int staleTime) {
2619 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
2620 InstanceIdentifier.builder(Bgp.class).child(GracefulRestart.class);
2621 InstanceIdentifier<GracefulRestart> iid = iib.build();
2622 GracefulRestart dto = new GracefulRestartBuilder()
2623 .setStalepathTime((long) staleTime).build();
2627 public void addNeighbor(
2628 String nbrIp, long remoteAs, @Nullable final TcpMd5SignaturePasswordType md5Secret) {
2629 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2630 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
2631 InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
2632 .child(Neighbors.class, new NeighborsKey(nbrAddr));
2633 InstanceIdentifier<Neighbors> iid = iib.build();
2634 TcpSecurityOption tcpSecOption = null;
2635 if (md5Secret != null) {
2636 tcpSecOption = new TcpMd5SignatureOptionBuilder().setTcpMd5SignaturePassword(md5Secret).build();
2637 } // else let tcpSecOption be null
2638 Neighbors dto = new NeighborsBuilder().setAddress(nbrAddr)
2639 .setRemoteAs(remoteAs).setTcpSecurityOption(tcpSecOption).build();
2641 } // public addNeighbor(nbrIp, remoteAs, md5Secret)
2643 public void addUpdateSource(String nbrIp, String srcIp) {
2644 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2645 Ipv4Address srcAddr = new Ipv4Address(srcIp);
2646 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
2647 InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
2648 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2649 .child(UpdateSource.class);
2650 InstanceIdentifier<UpdateSource> iid = iib.build();
2651 UpdateSource dto = new UpdateSourceBuilder().setPeerIp(nbrAddr)
2652 .setSourceIp(srcAddr).build();
2656 public void addEbgpMultihop(String nbrIp, int hops) {
2657 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2658 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
2659 InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
2660 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2661 .child(EbgpMultihop.class);
2662 InstanceIdentifier<EbgpMultihop> iid = iib.build();
2663 EbgpMultihop dto = new EbgpMultihopBuilder().setPeerIp(nbrAddr)
2664 .setNhops((long) hops).build();
2668 public void addAddressFamily(String nbrIp, int afi, int safi) {
2669 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2670 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
2671 InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
2672 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2673 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
2674 InstanceIdentifier<AddressFamilies> iid = iib.build();
2675 AddressFamilies dto = new AddressFamiliesBuilder().setPeerIp(nbrAddr)
2676 .setAfi((long) afi).setSafi((long) safi).build();
2680 public void addPrefix(String rd, String macAddress, String pfx, List<String> nhList,
2681 VrfEntry.EncapType encapType, Uint32 lbl, Uint32 l3vni, Uint32 l2vni, String gatewayMac) {
2682 for (String nh : nhList) {
2683 Ipv4Address nexthop = nh != null ? new Ipv4Address(nh) : null;
2685 InstanceIdentifier<Networks> iid = InstanceIdentifier.builder(Bgp.class)
2686 .child(NetworksContainer.class)
2687 .child(Networks.class, new NetworksKey(pfx, rd)).build();
2688 NetworksBuilder networksBuilder = new NetworksBuilder().setRd(rd).setPrefixLen(pfx).setNexthop(nexthop)
2689 .setLabel(label).setEthtag(BgpConstants.DEFAULT_ETH_TAG);
2690 buildVpnEncapSpecificInfo(networksBuilder, encapType, label, l3vni, l2vni, macAddress, gatewayMac);
2691 update(iid, networksBuilder.build());
2695 private static void buildVpnEncapSpecificInfo(NetworksBuilder builder, VrfEntry.EncapType encapType, Uint32 label,
2696 Uint32 l3vni, Uint32 l2vni, String macAddress, String gatewayMac) {
2697 if (encapType.equals(VrfEntry.EncapType.Mplsgre)) {
2698 builder.setLabel(label).setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLL3VPN)
2699 .setEncapType(EncapType.GRE);
2701 builder.setL3vni(l3vni).setL2vni(l2vni).setMacaddress(macAddress).setRoutermac(gatewayMac)
2702 .setBgpControlPlaneType(BgpControlPlaneType.PROTOCOLEVPN).setEncapType(EncapType.VXLAN);
2706 // TODO: add LayerType as arg - supports command
2707 public void addVrf(String rd, List<String> irts, List<String> erts, AddressFamily addressFamily) {
2708 Vrfs vrf = bgpUtil.getVrfFromRd(rd);
2709 List<AddressFamiliesVrf> adfList = new ArrayList<>(1);
2711 adfList = vrf.getAddressFamiliesVrf();
2713 AddressFamiliesVrfBuilder adfBuilder = new AddressFamiliesVrfBuilder();
2714 if (addressFamily.equals(AddressFamily.IPV4)) {
2715 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2716 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2717 } else if (addressFamily.equals(AddressFamily.IPV6)) {
2718 adfBuilder.setAfi((long) af_afi.AFI_IPV6.getValue());
2719 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2720 } else if (addressFamily.equals(AddressFamily.L2VPN)) {
2721 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2722 adfBuilder.setSafi((long) af_safi.SAFI_EVPN.getValue());
2724 AddressFamiliesVrf adf = adfBuilder.build();
2726 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib = InstanceIdentifier.builder(Bgp.class)
2727 .child(VrfsContainer.class)
2728 .child(Vrfs.class, new VrfsKey(rd));
2729 InstanceIdentifier<Vrfs> iid = iib.build();
2730 Vrfs dto = new VrfsBuilder().setRd(rd).setImportRts(irts)
2731 .setExportRts(erts).setAddressFamiliesVrf(adfList).build();
2733 List<AddressFamiliesVrf> listAdFamilies = mapNewAdFamily.get(rd);
2734 if (listAdFamilies != null) {
2735 listAdFamilies.add(adf);
2737 mapNewAdFamily.put(rd, adfList);
2741 SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, iid, dto);
2742 } catch (TransactionCommitFailedException e) {
2743 LOG.error("Error adding VRF to datastore", e);
2744 throw new RuntimeException(e);
2747 // enable multipath by default in all VRFs
2748 setMultipaths(rd, BgpConstants.BGP_DEFAULT_MULTIPATH);
2751 public void stopConfig() {
2752 InstanceIdentifier.InstanceIdentifierBuilder<ConfigServer> iib =
2753 InstanceIdentifier.builder(Bgp.class).child(ConfigServer.class);
2754 InstanceIdentifier<ConfigServer> iid = iib.build();
2758 public void stopBgp() {
2759 InstanceIdentifier.InstanceIdentifierBuilder<AsId> iib =
2760 InstanceIdentifier.builder(Bgp.class).child(AsId.class);
2761 InstanceIdentifier<AsId> iid = iib.build();
2765 public void stopBfd() {
2766 InstanceIdentifier.InstanceIdentifierBuilder<BfdConfig> iib =
2767 InstanceIdentifier.builder(BfdConfig.class);
2768 InstanceIdentifier<BfdConfig> iid = iib.build();
2772 public void delDcgwTep(String dcgwIp, String tepIp) {
2773 if (tepIp == null) {
2774 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2775 InstanceIdentifier.builder(Bgp.class)
2776 .child(DcgwTepList.class)
2777 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2778 InstanceIdentifier<DcgwTep> iid = iib.build();
2781 InstanceIdentifier.InstanceIdentifierBuilder<DcgwTep> iib =
2782 InstanceIdentifier.builder(Bgp.class)
2783 .child(DcgwTepList.class)
2784 .child(DcgwTep.class, new DcgwTepKey(dcgwIp));
2785 InstanceIdentifier<DcgwTep> iid = iib.build();
2786 List<String> tepIpList = bgpUtil.getDcgwTepConfig(dcgwIp);
2787 if (tepIpList == null) {
2788 LOG.error("No Tep IP configured for DCGW {} on deleting the dcgwtep", dcgwIp);
2791 List<String> newTepIpList = new ArrayList<String>();
2792 tepIpList.forEach(tep -> {
2793 if (!tep.equals(tepIp)) {
2794 newTepIpList.add(tep);
2797 DcgwTep dto = new DcgwTepBuilder().setDcGwIp(dcgwIp).setTepIps(newTepIpList)
2800 SingleTransactionDataBroker.syncWrite(dataBroker,
2801 LogicalDatastoreType.CONFIGURATION, iid, dto);
2802 } catch (TransactionCommitFailedException e) {
2803 LOG.error("delDcgwTep: Error deleting DCGW Tep", e);
2804 throw new RuntimeException(e);
2809 public void delLogging() {
2810 InstanceIdentifier.InstanceIdentifierBuilder<Logging> iib =
2811 InstanceIdentifier.builder(Bgp.class).child(Logging.class);
2812 InstanceIdentifier<Logging> iid = iib.build();
2816 public void delGracefulRestart() {
2817 InstanceIdentifier.InstanceIdentifierBuilder<GracefulRestart> iib =
2818 InstanceIdentifier.builder(Bgp.class)
2819 .child(GracefulRestart.class);
2820 InstanceIdentifier<GracefulRestart> iid = iib.build();
2824 public void delNeighbor(String nbrIp) {
2825 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2826 InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
2827 InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
2828 .child(Neighbors.class, new NeighborsKey(nbrAddr));
2829 InstanceIdentifier<Neighbors> iid = iib.build();
2833 public void delUpdateSource(String nbrIp) {
2834 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2835 InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
2836 InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
2837 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2838 .child(UpdateSource.class);
2839 InstanceIdentifier<UpdateSource> iid = iib.build();
2843 public void delEbgpMultihop(String nbrIp) {
2844 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2845 InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
2846 InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
2847 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2848 .child(EbgpMultihop.class);
2849 InstanceIdentifier<EbgpMultihop> iid = iib.build();
2853 public void delAddressFamily(String nbrIp, int afi, int safi) {
2854 Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
2855 InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
2856 InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
2857 .child(Neighbors.class, new NeighborsKey(nbrAddr))
2858 .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
2859 InstanceIdentifier<AddressFamilies> iid = iib.build();
2863 public void delPrefix(String rd, String pfx) {
2864 InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
2865 InstanceIdentifier.builder(Bgp.class).child(NetworksContainer.class)
2866 .child(Networks.class, new NetworksKey(pfx, rd));
2867 InstanceIdentifier<Networks> iid = iib.build();
2871 public boolean delVrf(String rd, AddressFamily addressFamily) {
2872 if (addressFamily == null) {
2873 LOG.error("delVrf: vrf {}, addressFamily invalid", rd);
2877 AddressFamiliesVrfBuilder adfBuilder = new AddressFamiliesVrfBuilder();
2878 if (addressFamily.equals(AddressFamily.IPV4)) {
2879 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2880 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2881 } else if (addressFamily.equals(AddressFamily.IPV6)) {
2882 adfBuilder.setAfi((long) af_afi.AFI_IPV6.getValue());
2883 adfBuilder.setSafi((long) af_safi.SAFI_MPLS_VPN.getValue());
2884 } else if (addressFamily.equals(AddressFamily.L2VPN)) {
2885 adfBuilder.setAfi((long) af_afi.AFI_IP.getValue());
2886 adfBuilder.setSafi((long) af_safi.SAFI_EVPN.getValue());
2888 LOG.debug("delVrf: Received Delete VRF : rd:{}, address family: {} {}", rd,
2889 adfBuilder.getAfi(), adfBuilder.getSafi());
2891 Vrfs vrfOriginal = bgpUtil.getVrfFromRd(rd);
2892 if (vrfOriginal == null) {
2893 LOG.error("delVrf: no vrf with existing rd {}. step aborted", rd);
2897 InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
2898 InstanceIdentifier.builder(Bgp.class).child(VrfsContainer.class)
2899 .child(Vrfs.class, new VrfsKey(rd));
2901 InstanceIdentifier<Vrfs> iid = iib.build();
2903 @SuppressWarnings("static-access")
2904 InstanceIdentifier<Bgp> iid6 = iid.builder(Bgp.class).build()
2905 .child(MultipathContainer.class)
2906 .child(Multipath.class, new MultipathKey(adfBuilder.getAfi(), adfBuilder.getSafi())).create(Bgp.class);
2907 InstanceIdentifierBuilder<Vrfs> iib3 =
2908 iid6.child(VrfsContainer.class).child(Vrfs.class, new VrfsKey(rd)).builder();
2909 InstanceIdentifier<Vrfs> iidFinal = iib3.build();
2911 //** update or delete the vrfs with the rest of AddressFamilies already present in the last list
2912 AddressFamiliesVrf adfToDel = adfBuilder.build();
2913 List<AddressFamiliesVrf> adfListOriginal = new ArrayList<>(vrfOriginal.nonnullAddressFamiliesVrf());
2914 List<AddressFamiliesVrf> adfListToRemoveFromOriginal = new ArrayList<>();
2915 adfListOriginal.forEach(adf -> {
2916 if (adf.equals(adfToDel)) {
2917 adfListToRemoveFromOriginal.add(adfToDel);
2921 for (AddressFamiliesVrf adfToRemove : adfListToRemoveFromOriginal) {
2922 adfListOriginal.remove(adfToRemove);
2924 SingleTransactionDataBroker.syncWrite(dataBroker,
2925 LogicalDatastoreType.CONFIGURATION, iid, vrfOriginal);
2926 } catch (TransactionCommitFailedException e) {
2927 LOG.error("delVrf: Error updating VRF to datastore", e);
2928 throw new RuntimeException(e);
2931 if (adfListOriginal.isEmpty()) {
2932 LOG.debug("delVrf: delete iid: {}", iidFinal);
2936 // not all is removed
2940 public void setMultipathStatus(af_afi afi, af_safi safi, boolean enable) {
2941 long lafi = afi.getValue();
2942 long lsafi = safi.getValue();
2944 InstanceIdentifier.InstanceIdentifierBuilder<Multipath> iib =
2946 .builder(Bgp.class).child(MultipathContainer.class)
2947 .child(Multipath.class,
2948 new MultipathKey(Long.valueOf(afi.getValue()), Long.valueOf(safi.getValue())));
2950 Multipath dto = new MultipathBuilder().setAfi(lafi).setSafi(lsafi).setMultipathEnabled(enable).build();
2951 update(iib.build(), dto);
2954 public void setMultipaths(String rd, int maxpath) {
2955 InstanceIdentifier.InstanceIdentifierBuilder<VrfMaxpath> iib =
2957 .builder(Bgp.class).child(VrfMaxpathContainer.class)
2958 .child(VrfMaxpath.class, new VrfMaxpathKey(rd));
2960 VrfMaxpath dto = new VrfMaxpathBuilder().setRd(rd).setMaxpaths(maxpath).build();
2961 update(iib.build(), dto);
2964 public void delMultipaths(String rd) {
2965 InstanceIdentifier.InstanceIdentifierBuilder<VrfMaxpath> iib =
2966 InstanceIdentifier.builder(Bgp.class).child(VrfMaxpathContainer.class)
2967 .child(VrfMaxpath.class, new VrfMaxpathKey(rd));
2968 InstanceIdentifier<VrfMaxpath> iid = iib.build();
2973 * Remove Stale Marked Routes after timer expiry.
2975 private class RouteCleanup implements Callable<Integer> {
2978 public Integer call() {
2981 if (staledFibEntriesMap.isEmpty()) {
2982 LOG.info("BGP: RouteCleanup timertask tirggered but STALED FIB MAP is EMPTY");
2984 for (String rd : staledFibEntriesMap.keySet()) {
2985 if (Thread.interrupted()) {
2988 Map<String, Uint32> map = staledFibEntriesMap.get(rd);
2990 for (String key : map.keySet()) {
2991 if (Thread.interrupted()) {
2994 String prefix = extractPrefix(key);
2995 String nextHop = extractNextHop(key);
2997 LOG.debug("BGP: RouteCleanup deletePrefix called for : rd:{}, prefix{}, nextHop:{}",
2998 rd, prefix, nextHop);
2999 fibDSWriter.removeOrUpdateFibEntryFromDS(rd, prefix, nextHop);
3005 staledFibEntriesMap.clear();
3007 LOG.error("cleared {} stale routes after bgp restart", totalCleared);
3013 * BGP restart scenario, ODL-BGP manager was/is running.
3014 * On re-sync notification, Get a copy of FIB database.
3016 public void createStaleFibMap() {
3017 totalStaledCount = 0;
3019 staledFibEntriesMap.clear();
3020 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
3022 Optional<FibEntries> fibEntries = SingleTransactionDataBroker.syncReadOptional(dataBroker,
3023 LogicalDatastoreType.CONFIGURATION, id);
3024 if (fibEntries.isPresent()) {
3025 List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
3026 for (VrfTables vrfTable : staleVrfTables) {
3027 Map<String, Uint32> staleFibEntMap = new HashMap<>();
3028 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
3029 if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
3030 //Stale marking and cleanup is only meant for the routes learned through BGP.
3033 if (Thread.interrupted()) {
3037 //Create MAP from staleVrfTables.
3038 vrfEntry.getRoutePaths()
3040 routePath -> staleFibEntMap.put(
3041 appendNextHopToPrefix(vrfEntry.getDestPrefix(),
3042 routePath.getNexthopAddress()), routePath.getLabel()));
3044 staledFibEntriesMap.put(vrfTable.getRouteDistinguisher(), staleFibEntMap);
3047 LOG.error("createStaleFibMap:: FIBentries.class is not present");
3049 } catch (ReadFailedException e) {
3050 LOG.error("createStaleFibMap:: error ", e);
3052 LOG.error("created {} staled entries ", totalStaledCount);
3056 * BGP config remove scenario, Need to remove all the
3057 * external routes from FIB.
3059 public void deleteExternalFibRoutes() {
3060 totalExternalRoutes = 0;
3061 totalExternalMacRoutes = 0;
3063 InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
3065 Optional<FibEntries> fibEntries = SingleTransactionDataBroker.syncReadOptional(dataBroker,
3066 LogicalDatastoreType.CONFIGURATION, id);
3067 if (fibEntries.isPresent()) {
3068 if (fibEntries.get().getVrfTables() == null) {
3069 LOG.error("deleteExternalFibRoutes::getVrfTables is null");
3072 List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
3073 for (VrfTables vrfTable : staleVrfTables) {
3074 String rd = vrfTable.getRouteDistinguisher();
3075 if (vrfTable.getVrfEntry() != null) {
3076 for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
3077 if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
3078 //route cleanup is only meant for the routes learned through BGP.
3081 totalExternalRoutes++;
3082 fibDSWriter.removeFibEntryFromDS(rd, vrfEntry.getDestPrefix());
3084 } else if (vrfTable.getMacVrfEntry() != null) {
3085 for (MacVrfEntry macEntry : vrfTable.getMacVrfEntry()) {
3086 if (RouteOrigin.value(macEntry.getOrigin()) != RouteOrigin.BGP) {
3087 //route cleanup is only meant for the routes learned through BGP.
3090 totalExternalMacRoutes++;
3091 fibDSWriter.removeMacEntryFromDS(rd, macEntry.getMac());
3096 LOG.error("deleteExternalFibRoutes:: FIBentries.class is not present");
3098 } catch (ReadFailedException e) {
3099 LOG.error("deleteExternalFibRoutes:: error ", e);
3101 LOG.debug("deleted {} fib entries {} mac entries", totalExternalRoutes, totalExternalMacRoutes);
3104 public boolean addToRt2TepMap(String rd, String tepIp, String mac, Uint32 l2vni) {
3105 boolean isFirstMacUpdateFromTep = false;
3106 if (rt2TepMap.containsKey(rd)) {
3107 if (rt2TepMap.get(rd).containsKey(tepIp)) {
3108 LOG.debug("RT2 with mac {} l2vni {} from existing rd {} and tep-ip {}. No Elan DS write required",
3109 mac, l2vni, rd, tepIp);
3110 rt2TepMap.get(rd).get(tepIp).put(mac, l2vni);
3112 LOG.debug("RT2 with mac {} l2vni {} from existing rd {} and new tep-ip {}",
3113 mac, l2vni, rd, tepIp);
3114 isFirstMacUpdateFromTep = true;
3115 Map<String, Uint32> macList = new HashMap<>();
3116 macList.put(mac, l2vni);
3117 rt2TepMap.get(rd).put(tepIp, macList);
3120 LOG.debug("RT2 with mac {} l2vni {} from new rd {} and tep ip {}",
3121 mac, l2vni, rd, tepIp);
3122 isFirstMacUpdateFromTep = true;
3123 Map<String, Uint32> macList = new HashMap<>();
3124 macList.put(mac, l2vni);
3125 Map<String, Map<String, Uint32>> tepIpMacMap = new HashMap<>();
3126 tepIpMacMap.put(tepIp, macList);
3127 rt2TepMap.put(rd, tepIpMacMap);
3129 return isFirstMacUpdateFromTep;
3132 public boolean deleteFromRt2TepMap(String rd, String tepIp, String mac) {
3133 boolean isLastMacUpdateFromTep = false;
3134 LOG.debug("RT2 withdraw with rd {} mac {} tep-ip {} ", rd, mac, tepIp);
3135 if (rt2TepMap.containsKey(rd)) {
3136 if (rt2TepMap.get(rd).containsKey(tepIp)) {
3137 if (rt2TepMap.get(rd).get(tepIp).containsKey(mac)) {
3138 LOG.debug("RT2 Withdraw : Removing the mac {} from Map", mac);
3139 rt2TepMap.get(rd).get(tepIp).remove(mac);
3140 if (rt2TepMap.get(rd).get(tepIp).isEmpty()) {
3141 isLastMacUpdateFromTep = true;
3142 LOG.debug("RT2 Withdraw : Removing the tep-ip {} from Map", tepIp);
3143 rt2TepMap.get(rd).remove(tepIp);
3144 if (rt2TepMap.get(rd).isEmpty()) {
3145 LOG.debug("RT2 Withdraw : Removing the rd {} from Map", rd);
3146 rt2TepMap.remove(rd);
3152 return isLastMacUpdateFromTep;
3155 public Collection<String> getTepIPs(String rd) {
3156 final Map<String, Map<String, Uint32>> tepIpMap = rt2TepMap.get(rd);
3157 return tepIpMap != null ? tepIpMap.keySet() : Collections.emptyList();
3160 public boolean isBgpConnected() {
3161 return (bgpRouter == null) ? false : bgpRouter.isBgpConnected();
3164 public long getLastConnectedTS() {
3165 return (bgpRouter == null) ? 0 : bgpRouter.getLastConnectedTS();
3168 public long getConnectTS() {
3169 return (bgpRouter == null) ? 0 : bgpRouter.getConnectTS();
3172 public long getStartTS() {
3173 return (bgpRouter == null) ? 0 : bgpRouter.getStartTS();
3176 public TTransport getTransport() {
3177 return bgpRouter.getTransport();
3180 public int getTotalStaledCount() {
3181 return totalStaledCount;
3184 public int getTotalCleared() {
3185 return totalCleared;
3188 public BgpCounters getBgpCounters() {
3189 return bgpCountersReference.get();
3192 private void startBgpCountersTask() {
3193 if (getBgpCounters() == null && bgpCountersReference.compareAndSet(null,
3194 new BgpCounters(getBgpSdncMipIp(), metricProvider))) {
3195 bgpCountersTask = executor.scheduleAtFixedRate(bgpCountersReference.get(), 0, 120 * 1000,
3196 TimeUnit.MILLISECONDS);
3197 LOG.info("Bgp Counters task scheduled for every two minutes.");
3199 bgpManager.setQbgpLog(BgpConstants.BGP_DEF_LOG_FILE, BgpConstants.BGP_DEF_LOG_LEVEL);
3203 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
3204 justification = "https://github.com/spotbugs/spotbugs/issues/811")
3205 private void stopBgpCountersTask() {
3206 final BgpCounters bgpCounters = bgpCountersReference.getAndSet(null);
3207 if (bgpCounters != null) {
3208 bgpCountersTask.cancel(true);
3209 bgpCounters.close();
3213 private void startBgpAlarmsTask() {
3214 if (getBgpAlarms() == null && bgpAlarmsReference.compareAndSet(null, new BgpAlarms(this))) {
3215 bgpAlarmsReference.get().init();
3216 bgpAlarmsTask = executor.scheduleAtFixedRate(bgpAlarmsReference.get(), 0, 60 * 1000, TimeUnit.MILLISECONDS);
3217 LOG.info("Bgp Alarms task scheduled for every minute.");
3219 LOG.trace("Bgp Alarms task already scheduled for every minute.");
3223 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
3224 justification = "https://github.com/spotbugs/spotbugs/issues/811")
3225 private void stopBgpAlarmsTask() {
3226 final BgpAlarms bgpAlarms = bgpAlarmsReference.getAndSet(null);
3227 if (bgpAlarms != null) {
3228 bgpAlarmsTask.cancel(true);
3233 public BgpAlarms getBgpAlarms() {
3234 return bgpAlarmsReference.get();
3237 public void getPeerStatus(String nbrIp, long nbrAsNum) throws
3238 BgpRouterException, TException {
3239 bgpRouter.getPeerStatus(nbrIp, nbrAsNum);
3242 private static String appendNextHopToPrefix(String prefix, String nextHop) {
3243 return prefix + ":" + nextHop;
3246 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
3247 justification = "https://github.com/spotbugs/spotbugs/issues/811")
3248 private static String extractPrefix(String prefixNextHop) {
3249 return prefixNextHop.split(":")[0];
3252 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
3253 justification = "https://github.com/spotbugs/spotbugs/issues/811")
3254 private static String extractNextHop(String prefixNextHop) {
3255 return prefixNextHop.split(":")[1];
3258 private static String extractMd5Secret(final Neighbors val) {
3259 String md5Secret = null;
3260 TcpSecurityOption tcpSecOpt = val.getTcpSecurityOption();
3261 if (tcpSecOpt != null) {
3262 if (tcpSecOpt instanceof TcpMd5SignatureOption) {
3263 md5Secret = ((TcpMd5SignatureOption) tcpSecOpt).getTcpMd5SignaturePassword().getValue();
3264 } else { // unknown TcpSecurityOption
3265 LOG.debug("neighbors Ignored unknown tcp-security-option of peer {}", val.getAddress().getValue());
3269 } // private method extractMd5Secret
3271 @SuppressWarnings("checkstyle:IllegalCatch")
3273 public ListenableFuture<RpcResult<InitiateEorOutput>> initiateEor(InitiateEorInput input) {
3274 boolean returnError = false;
3276 String neighborIp = null;
3277 if (!isBGPEntityOwner()) {
3278 msg = String.format("RPC triggered in Non-EoS Owner");
3279 return Futures.immediateFuture(
3280 RpcResultBuilder.<InitiateEorOutput>failed().withError(RpcError.ErrorType.APPLICATION,
3283 if (input == null) {
3284 msg = String.format("BGP invalid input for EoR");
3285 LOG.error("Error : {}", msg);
3288 neighborIp = input.getNeighborIp();
3290 if (eorSupressedDuetoUpgradeFlag.get() == false) {
3291 msg = String.format("EoR triggerd by RBU-RPC call before replay"
3292 + "of BGP configuration (or) BGP not restarted");
3293 LOG.error("Error : {}", msg);
3295 if ("ALL".compareToIgnoreCase(neighborIp) == 0) {
3296 //send EoR for all the neighbor
3297 LOG.error("EoR trigger received to ALL neighbors");
3298 final int numberOfEORRetries = 3;
3299 RetryOnException eorRetry = new RetryOnException(numberOfEORRetries);
3302 BgpRouter br = bgpRouter;
3304 LOG.debug("RPC: sendEOR {} successful", br);
3306 } catch (Exception e) {
3307 eorRetry.errorOccured();
3308 LOG.error("Replay:sedEOR() received exception:", e);
3310 } while (eorRetry.shouldRetry());
3311 eorSupressedDuetoUpgradeFlag.set(false);
3312 } else if (InetAddresses.isInetAddress(neighborIp)) {
3313 //send EoR for only one neighbor
3314 msg = String.format("Inidividual neighbors EoR is not supported");
3315 LOG.warn("Error : {}", msg);
3319 msg = String.format("RPC: initiateEor: Invalid input ");
3320 LOG.warn("Error : {}", msg);
3324 return Futures.immediateFuture(
3325 RpcResultBuilder.<InitiateEorOutput>failed().withError(RpcError.ErrorType.APPLICATION,
3328 InitiateEorOutput initiateEorOutput =
3329 new InitiateEorOutputBuilder().setRetVal(0L).build();
3330 return Futures.immediateFuture(RpcResultBuilder.<InitiateEorOutput>success()
3331 .withResult(initiateEorOutput).build());