2 * Copyright (c) 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.vpnmanager;
10 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
11 import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
12 import static org.opendaylight.mdsal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
14 import com.google.common.util.concurrent.FutureCallback;
15 import com.google.common.util.concurrent.Futures;
16 import com.google.common.util.concurrent.ListenableFuture;
17 import com.google.common.util.concurrent.MoreExecutors;
18 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Collections;
22 import java.util.List;
23 import java.util.Optional;
24 import java.util.concurrent.Callable;
25 import java.util.concurrent.ExecutionException;
26 import java.util.concurrent.locks.ReentrantLock;
27 import javax.annotation.PreDestroy;
28 import javax.inject.Inject;
29 import javax.inject.Singleton;
30 import org.eclipse.jdt.annotation.Nullable;
31 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
32 import org.opendaylight.genius.infra.Datastore.Configuration;
33 import org.opendaylight.genius.infra.Datastore.Operational;
34 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
35 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
36 import org.opendaylight.genius.infra.TypedWriteTransaction;
37 import org.opendaylight.genius.mdsalutil.FlowEntity;
38 import org.opendaylight.genius.mdsalutil.InstructionInfo;
39 import org.opendaylight.genius.mdsalutil.MDSALUtil;
40 import org.opendaylight.genius.mdsalutil.MatchInfo;
41 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
42 import org.opendaylight.genius.mdsalutil.NWUtil;
43 import org.opendaylight.genius.mdsalutil.NwConstants;
44 import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
45 import org.opendaylight.genius.mdsalutil.instructions.InstructionWriteMetadata;
46 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
47 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
48 import org.opendaylight.genius.utils.JvmGlobalLocks;
49 import org.opendaylight.genius.utils.SystemPropertyReader;
50 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
51 import org.opendaylight.infrautils.utils.concurrent.Executors;
52 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
53 import org.opendaylight.mdsal.binding.api.DataBroker;
54 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
55 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
56 import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.DcGatewayIpList;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.dc.gateway.ip.list.DcGatewayIp;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIds;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnTargetsBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTargetBuilder;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTargetKey;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.VpnInstances;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.VpnInstance;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.VpnTargets;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.l3vpn.rev200204.vpn.instances.vpn.instance.vpntargets.VpnTarget;
72 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
73 import org.opendaylight.yangtools.yang.common.Uint32;
74 import org.opendaylight.yangtools.yang.common.Uint64;
75 import org.slf4j.Logger;
76 import org.slf4j.LoggerFactory;
79 public class VpnInstanceListener extends AbstractAsyncDataTreeChangeListener<VpnInstance> {
80 private static final Logger LOG = LoggerFactory.getLogger(VpnInstanceListener.class);
81 private static final String LOGGING_PREFIX_ADD = "VPN-ADD:";
82 private static final String LOGGING_PREFIX_UPDATE = "VPN-UPDATE:";
83 private static final String LOGGING_PREFIX_DELETE = "VPN-REMOVE:";
84 private final DataBroker dataBroker;
85 private final ManagedNewTransactionRunner txRunner;
86 private final IdManagerService idManager;
87 private final VpnInterfaceManager vpnInterfaceManager;
88 private final IFibManager fibManager;
89 private final VpnOpDataSyncer vpnOpDataNotifier;
90 private final IMdsalApiManager mdsalManager;
91 private final JobCoordinator jobCoordinator;
92 private final VpnUtil vpnUtil;
95 public VpnInstanceListener(final DataBroker dataBroker, final IdManagerService idManager,
96 final VpnInterfaceManager vpnInterfaceManager, final IFibManager fibManager,
97 final VpnOpDataSyncer vpnOpDataSyncer, final IMdsalApiManager mdsalManager,
98 final JobCoordinator jobCoordinator, VpnUtil vpnUtil) {
99 super(dataBroker, LogicalDatastoreType.CONFIGURATION,
100 InstanceIdentifier.create(VpnInstances.class).child(VpnInstance.class),
101 Executors.newListeningSingleThreadExecutor("VpnInstanceListener", LOG));
102 this.dataBroker = dataBroker;
103 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
104 this.idManager = idManager;
105 this.vpnInterfaceManager = vpnInterfaceManager;
106 this.fibManager = fibManager;
107 this.vpnOpDataNotifier = vpnOpDataSyncer;
108 this.mdsalManager = mdsalManager;
109 this.jobCoordinator = jobCoordinator;
110 this.vpnUtil = vpnUtil;
114 public void start() {
115 LOG.info("{} start", getClass().getSimpleName());
120 public void close() {
122 Executors.shutdownAndAwaitTermination(getExecutorService());
127 public void remove(InstanceIdentifier<VpnInstance> identifier, VpnInstance del) {
128 LOG.trace("{} : VPN event key: {}, value: {}", LOGGING_PREFIX_DELETE, identifier, del);
129 final String vpnName = del.getVpnInstanceName();
130 Optional<VpnInstanceOpDataEntry> vpnOpValue;
131 String primaryRd = vpnUtil.getVpnRd(vpnName);
132 if (primaryRd == null) {
133 LOG.error("{}, failed to remove VPN: primaryRd is null for vpn {}", LOGGING_PREFIX_DELETE, vpnName);
137 //TODO(vpnteam): Entire code would need refactoring to listen only on the parent object - VPNInstance
139 vpnOpValue = SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL,
140 VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd));
141 } catch (InterruptedException | ExecutionException e) {
142 LOG.error("{}, failed to remove VPN: Exception while retrieving VpnInstanceOpDataEntry for VPN {}. ",
143 LOGGING_PREFIX_DELETE, vpnName, e);
147 if (!vpnOpValue.isPresent()) {
148 LOG.error("{}, failed to remove VPN: Unable to retrieve VpnInstanceOpDataEntry for VPN {}. ",
149 LOGGING_PREFIX_DELETE, vpnName);
152 jobCoordinator.enqueueJob("VPN-" + vpnName, () ->
153 Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx -> {
154 VpnInstanceOpDataEntryBuilder builder = null;
155 InstanceIdentifier<VpnInstanceOpDataEntry> id = null;
156 if (primaryRd != null) {
157 builder = new VpnInstanceOpDataEntryBuilder().setVrfId(primaryRd)
158 .setVpnState(VpnInstanceOpDataEntry.VpnState.PendingDelete);
159 id = VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd);
161 builder = new VpnInstanceOpDataEntryBuilder().setVrfId(vpnName)
162 .setVpnState(VpnInstanceOpDataEntry.VpnState.PendingDelete);
163 id = VpnUtil.getVpnInstanceOpDataIdentifier(vpnName);
165 tx.merge(id, builder.build());
167 LOG.info("{} call: Operational status set to PENDING_DELETE for vpn {} with rd {}",
168 LOGGING_PREFIX_DELETE, vpnName, primaryRd);
169 })), SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
174 public void update(InstanceIdentifier<VpnInstance> identifier,
175 VpnInstance original, VpnInstance update) {
176 LOG.trace("VPN-UPDATE: update: VPN event key: {}, value: {}.", identifier, update);
177 String vpnName = update.getVpnInstanceName();
178 if (original != null && update != null
179 && original.getRouteDistinguisher() != null
180 && update.getRouteDistinguisher() != null
181 && original.getRouteDistinguisher().size()
182 != update.getRouteDistinguisher().size()) {
183 LOG.debug("VPN-UPDATE: VpnInstance:{} updated with new RDs: {} from old RDs: {}", vpnName,
184 update.getRouteDistinguisher(), original.getRouteDistinguisher());
185 vpnUtil.updateVpnInstanceWithRdList(vpnName, update.getRouteDistinguisher());
187 vpnInterfaceManager.updateVpnInterfacesForUnProcessAdjancencies(vpnName);
191 public void add(final InstanceIdentifier<VpnInstance> identifier, final VpnInstance value) {
192 LOG.trace("{} add: Add VPN event key: {}, value: {}", LOGGING_PREFIX_ADD, identifier, value);
193 final String vpnName = value.getVpnInstanceName();
194 jobCoordinator.enqueueJob("VPN-" + vpnName, new AddVpnInstanceWorker(dataBroker, value),
195 SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
198 private class AddVpnInstanceWorker implements Callable<List<? extends ListenableFuture<?>>> {
199 private final Logger log = LoggerFactory.getLogger(AddVpnInstanceWorker.class);
200 VpnInstance vpnInstance;
203 AddVpnInstanceWorker(DataBroker broker,
205 this.broker = broker;
206 this.vpnInstance = value;
210 public List<ListenableFuture<Void>> call() {
211 // If another renderer(for eg : CSS) needs to be supported, check can be performed here
212 // to call the respective helpers.
213 List<ListenableFuture<Void>> futures = new ArrayList<>(2);
214 futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, confTx -> {
215 ListenableFuture<Void> future = txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, operTx ->
216 addVpnInstance(vpnInstance, confTx, operTx));
217 ListenableFutures.addErrorLogging(future, LOG, "{} call: error creating VPN {} rd {}",
218 LOGGING_PREFIX_ADD, vpnInstance.getVpnInstanceName(),
219 vpnInstance.getRouteDistinguisher());
222 Futures.addCallback(Futures.allAsList(futures),
223 new PostAddVpnInstanceWorker(vpnInstance , vpnInstance.getVpnInstanceName()),
224 MoreExecutors.directExecutor());
229 // TODO Clean up the exception handling
230 @SuppressWarnings("checkstyle:IllegalCatch")
231 private void addVpnInstance(VpnInstance value, TypedWriteTransaction<Configuration> writeConfigTxn,
232 TypedWriteTransaction<Operational> writeOperTxn) {
233 if (writeConfigTxn == null) {
234 ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx ->
235 addVpnInstance(value, tx, writeOperTxn)), LOG, "Error adding VPN instance {}", value);
238 if (writeOperTxn == null) {
239 ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(OPERATIONAL, tx ->
240 addVpnInstance(value, writeConfigTxn, tx)), LOG, "Error adding VPN instance {}", value);
243 String vpnInstanceName = value.getVpnInstanceName();
245 Uint32 vpnId = vpnUtil.getUniqueId(VpnConstants.VPN_IDPOOL_NAME, vpnInstanceName);
246 if (vpnId.longValue() == 0) {
247 LOG.error("{} addVpnInstance: Unable to fetch label from Id Manager. Bailing out of adding operational"
248 + " data for Vpn Instance {}", LOGGING_PREFIX_ADD, value.getVpnInstanceName());
251 LOG.info("{} addVpnInstance: VPN Id {} generated for VpnInstanceName {}", LOGGING_PREFIX_ADD, vpnId,
253 String primaryRd = VpnUtil.getPrimaryRd(value);
254 org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance
255 vpnInstanceToVpnId = VpnUtil.getVpnInstanceToVpnId(vpnInstanceName, vpnId, primaryRd);
257 writeConfigTxn.put(VpnOperDsUtils.getVpnInstanceToVpnIdIdentifier(vpnInstanceName),
258 vpnInstanceToVpnId, CREATE_MISSING_PARENTS);
260 VpnIds vpnIdToVpnInstance = VpnUtil.getVpnIdToVpnInstance(vpnId, value.getVpnInstanceName(),
261 primaryRd, VpnUtil.isBgpVpn(vpnInstanceName, primaryRd));
263 writeConfigTxn.put(VpnUtil.getVpnIdToVpnInstanceIdentifier(vpnId), vpnIdToVpnInstance, CREATE_MISSING_PARENTS);
266 String cachedTransType = fibManager.getConfTransType();
267 if (cachedTransType.equals("Invalid")) {
269 fibManager.setConfTransType("L3VPN", "VXLAN");
270 } catch (Exception e) {
271 LOG.error("{} addVpnInstance: Exception caught setting the L3VPN tunnel transportType for vpn {}",
272 LOGGING_PREFIX_ADD, vpnInstanceName, e);
275 LOG.debug("{} addVpnInstance: Configured tunnel transport type for L3VPN {} as {}", LOGGING_PREFIX_ADD,
276 vpnInstanceName, cachedTransType);
278 } catch (Exception e) {
279 LOG.error("{} addVpnInstance: Error when trying to retrieve tunnel transport type for L3VPN {}",
280 LOGGING_PREFIX_ADD, vpnInstanceName, e);
283 VpnInstanceOpDataEntryBuilder builder =
284 new VpnInstanceOpDataEntryBuilder().setVrfId(primaryRd).setVpnId(vpnId)
285 .setVpnInstanceName(vpnInstanceName)
286 .setVpnState(VpnInstanceOpDataEntry.VpnState.Created);
287 if (VpnUtil.isBgpVpn(vpnInstanceName, primaryRd)) {
288 List<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn
289 .instance.op.data.entry.vpntargets.VpnTarget> opVpnTargetList = new ArrayList<>();
290 builder.setBgpvpnType(VpnInstanceOpDataEntry.BgpvpnType.BGPVPNExternal);
291 if (value.getL3vni() != null) {
292 builder.setL3vni(value.getL3vni());
294 if (value.isL2vpn()) {
295 builder.setType(VpnInstanceOpDataEntry.Type.L2);
297 VpnTargets vpnTargets = value.getVpnTargets();
298 if (vpnTargets != null) {
299 List<VpnTarget> vpnTargetList = vpnTargets.getVpnTarget();
300 if (vpnTargetList != null) {
301 for (VpnTarget vpnTarget : vpnTargetList) {
302 VpnTargetBuilder vpnTargetBuilder =
303 new VpnTargetBuilder().withKey(new VpnTargetKey(vpnTarget.key().getVrfRTValue()))
304 .setVrfRTType(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
305 .instance.op.data.vpn.instance.op.data.entry.vpntargets.VpnTarget.VrfRTType
306 .forValue(vpnTarget.getVrfRTType().getIntValue())).setVrfRTValue(
307 vpnTarget.getVrfRTValue());
308 opVpnTargetList.add(vpnTargetBuilder.build());
312 VpnTargetsBuilder vpnTargetsBuilder = new VpnTargetsBuilder().setVpnTarget(opVpnTargetList);
313 builder.setVpnTargets(vpnTargetsBuilder.build());
315 List<String> rds = value.getRouteDistinguisher();
318 builder.setBgpvpnType(VpnInstanceOpDataEntry.BgpvpnType.VPN);
320 writeOperTxn.merge(VpnUtil.getVpnInstanceOpDataIdentifier(primaryRd), builder.build(), CREATE_MISSING_PARENTS);
321 LOG.info("{} addVpnInstance: VpnInstanceOpData populated successfully for vpn {} rd {}", LOGGING_PREFIX_ADD,
322 vpnInstanceName, primaryRd);
325 private class PostAddVpnInstanceWorker implements FutureCallback<List<Void>> {
326 private final Logger log = LoggerFactory.getLogger(PostAddVpnInstanceWorker.class);
327 VpnInstance vpnInstance;
330 PostAddVpnInstanceWorker(VpnInstance vpnInstance, String vpnName) {
331 this.vpnInstance = vpnInstance;
332 this.vpnName = vpnName;
336 * This implies that all the future instances have returned success. -- TODO: Confirm this
339 public void onSuccess(List<Void> voids) {
341 if rd is null, then its either a router vpn instance (or) a vlan external network vpn instance.
342 if rd is non-null, then it is a bgpvpn instance
344 List<String> rd = vpnInstance.getRouteDistinguisher();
345 if (rd == null || addBgpVrf()) {
347 vpnInterfaceManager.vpnInstanceIsReady(vpnName);
349 log.info("{} onSuccess: Vpn Instance Op Data addition for {} successful.", LOGGING_PREFIX_ADD, vpnName);
350 VpnInstanceOpDataEntry vpnInstanceOpDataEntry = vpnUtil.getVpnInstanceOpData(
351 VpnUtil.getPrimaryRd(vpnInstance));
353 // bind service on each tunnel interface
354 //TODO (KIRAN): Add a new listener to handle creation of new DC-GW binding and deletion of existing DC-GW.
355 if (VpnUtil.isL3VpnOverVxLan(vpnInstance.getL3vni())) { //Handled for L3VPN Over VxLAN
356 for (String tunnelInterfaceName: getDcGatewayTunnelInterfaceNameList()) {
357 vpnUtil.bindService(vpnInstance.getVpnInstanceName(), tunnelInterfaceName,
358 true/*isTunnelInterface*/);
362 List<MatchInfo> mkMatches = new ArrayList<>();
363 mkMatches.add(new MatchTunnelId(Uint64.valueOf(vpnInstance.getL3vni())));
365 List<InstructionInfo> instructions =
366 Arrays.asList(new InstructionWriteMetadata(MetaDataUtil.getVpnIdMetadata(vpnInstanceOpDataEntry
367 .getVpnId().toJava()), MetaDataUtil.METADATA_MASK_VRFID),
368 new InstructionGotoTable(NwConstants.L3_GW_MAC_TABLE));
370 for (Uint64 dpnId: NWUtil.getOperativeDPNs(dataBroker)) {
371 String flowRef = getFibFlowRef(dpnId, NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE,
372 vpnName, VpnConstants.DEFAULT_FLOW_PRIORITY);
373 FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpnId,
374 NwConstants.L3VNI_EXTERNAL_TUNNEL_DEMUX_TABLE, flowRef,
375 VpnConstants.DEFAULT_FLOW_PRIORITY, "VxLAN VPN Tunnel Bind Service",
376 0, 0, NwConstants.COOKIE_VM_FIB_TABLE, mkMatches, instructions);
377 mdsalManager.installFlow(dpnId, flowEntity);
379 } catch (ExecutionException | InterruptedException e) {
380 LOG.error("PostAddVpnInstanceWorker: Exception while getting the list of Operative DPNs for Vpn {}",
384 ///////////////////////
388 // TODO Clean up the exception handling
389 @SuppressWarnings("checkstyle:IllegalCatch")
390 private boolean addBgpVrf() {
391 String primaryRd = vpnUtil.getPrimaryRd(vpnName);
392 List<VpnTarget> vpnTargetList = vpnInstance.getVpnTargets().getVpnTarget();
394 if (vpnTargetList == null) {
395 log.error("{} addBgpVrf: vpn target list is empty for vpn {} RD {}", LOGGING_PREFIX_ADD,
396 this.vpnName, primaryRd);
399 // FIXME: separate out to somehow?
400 final ReentrantLock lock = JvmGlobalLocks.getLockForString(vpnName);
403 fibManager.addVrfTable(primaryRd, null);
407 vpnInterfaceManager.handleVpnsExportingRoutes(this.vpnName, primaryRd);
411 private void notifyTask() {
412 vpnOpDataNotifier.notifyVpnOpDataReady(VpnOpDataSyncer.VpnOpDataType.vpnInstanceToId, vpnName);
413 vpnOpDataNotifier.notifyVpnOpDataReady(VpnOpDataSyncer.VpnOpDataType.vpnOpData, vpnName);
417 * This method is used to handle failure callbacks.
418 * If more retry needed, the retrycount is decremented and mainworker is executed again.
419 * After retries completed, rollbackworker is executed.
420 * If rollbackworker fails, this is a double-fault. Double fault is logged and ignored.
424 public void onFailure(Throwable throwable) {
425 log.error("{} onFailure: Job for vpnInstance: {} failed with exception:", LOGGING_PREFIX_ADD, vpnName,
427 vpnInterfaceManager.vpnInstanceFailed(vpnName);
432 protected VpnInstanceOpDataEntry getVpnInstanceOpData(String rd) {
433 InstanceIdentifier<VpnInstanceOpDataEntry> id = VpnUtil.getVpnInstanceOpDataIdentifier(rd);
435 return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.OPERATIONAL,
437 } catch (InterruptedException | ExecutionException e) {
438 throw new RuntimeException("Error reading VPN instance data for " + rd, e);
442 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
443 justification = "https://github.com/spotbugs/spotbugs/issues/811")
444 private List<String> getDcGatewayTunnelInterfaceNameList() {
445 List<String> tunnelInterfaceNameList = new ArrayList<>();
447 InstanceIdentifier<DcGatewayIpList> dcGatewayIpListInstanceIdentifier = InstanceIdentifier
448 .create(DcGatewayIpList.class);
449 Optional<DcGatewayIpList> dcGatewayIpListOptional = SingleTransactionDataBroker.syncReadOptional(
450 dataBroker, LogicalDatastoreType.CONFIGURATION, dcGatewayIpListInstanceIdentifier);
451 if (!dcGatewayIpListOptional.isPresent()) {
452 LOG.info("No DC gateways configured.");
453 return tunnelInterfaceNameList;
455 List<DcGatewayIp> dcGatewayIps = dcGatewayIpListOptional.get().nonnullDcGatewayIp();
456 InstanceIdentifier<ExternalTunnelList> externalTunnelListId = InstanceIdentifier
457 .create(ExternalTunnelList.class);
458 Optional<ExternalTunnelList> externalTunnelListOptional = SingleTransactionDataBroker.syncReadOptional(
459 dataBroker, LogicalDatastoreType.OPERATIONAL, externalTunnelListId);
460 if (externalTunnelListOptional.isPresent()) {
461 List<ExternalTunnel> externalTunnels = externalTunnelListOptional.get().nonnullExternalTunnel();
462 List<String> externalTunnelIpList = new ArrayList<>();
463 for (ExternalTunnel externalTunnel: externalTunnels) {
464 externalTunnelIpList.add(externalTunnel.getDestinationDevice());
466 List<String> dcGatewayIpList = new ArrayList<>();
467 for (DcGatewayIp dcGatewayIp: dcGatewayIps) {
468 dcGatewayIpList.add(dcGatewayIp.getIpAddress().getIpv4Address().toString());
470 // Find all externalTunnelIps present in dcGateWayIpList
471 List<String> externalTunnelIpsInDcGatewayIpList = new ArrayList<>();
472 for (String externalTunnelIp: externalTunnelIpList) {
473 for (String dcGateWayIp: dcGatewayIpList) {
474 if (externalTunnelIp.contentEquals(dcGateWayIp)) {
475 externalTunnelIpsInDcGatewayIpList.add(externalTunnelIp);
479 for (String externalTunnelIpsInDcGatewayIp: externalTunnelIpsInDcGatewayIpList) {
480 for (ExternalTunnel externalTunnel: externalTunnels) {
481 if (externalTunnel.getDestinationDevice().contentEquals(externalTunnelIpsInDcGatewayIp)) {
482 tunnelInterfaceNameList.add(externalTunnel.getTunnelInterfaceName());
488 } catch (InterruptedException | ExecutionException e) {
489 LOG.error("getDcGatewayTunnelInterfaceNameList: Failed to read data store");
491 return tunnelInterfaceNameList;
494 @SuppressFBWarnings(value = "UPM_UNCALLED_PRIVATE_METHOD",
495 justification = "https://github.com/spotbugs/spotbugs/issues/811")
496 private String getFibFlowRef(Uint64 dpnId, short tableId, String vpnName, int priority) {
497 return VpnConstants.FLOWID_PREFIX + dpnId + NwConstants.FLOWID_SEPARATOR + tableId
498 + NwConstants.FLOWID_SEPARATOR + vpnName + NwConstants.FLOWID_SEPARATOR + priority;