2 * Copyright (c) 2016, 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.genius.itm.confighelpers;
10 import static java.util.Collections.singletonList;
12 import com.google.common.base.Optional;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import java.math.BigInteger;
15 import java.util.Collection;
16 import java.util.Collections;
17 import java.util.List;
18 import java.util.concurrent.Callable;
19 import java.util.concurrent.ExecutionException;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
24 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
25 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
26 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
27 import org.opendaylight.genius.itm.cache.DpnTepStateCache;
28 import org.opendaylight.genius.itm.cache.OvsBridgeEntryCache;
29 import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
30 import org.opendaylight.genius.itm.cache.TunnelStateCache;
31 import org.opendaylight.genius.itm.impl.ITMBatchingUtils;
32 import org.opendaylight.genius.itm.impl.ItmUtils;
33 import org.opendaylight.genius.itm.impl.TunnelMonitoringConfig;
34 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
35 import org.opendaylight.genius.itm.utils.DpnTepInterfaceInfo;
36 import org.opendaylight.genius.mdsalutil.NwConstants;
37 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
38 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeLldp;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.OvsBridgeEntry;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.OvsBridgeEntryKey;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.ovs.bridge.entry.OvsBridgeTunnelEntry;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.ovs.bridge.entry.OvsBridgeTunnelEntryKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntry;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
64 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
65 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
66 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
67 import org.opendaylight.yangtools.yang.common.OperationFailedException;
68 import org.slf4j.Logger;
69 import org.slf4j.LoggerFactory;
71 public class ItmInternalTunnelDeleteWorker {
73 private static final Logger LOG = LoggerFactory.getLogger(ItmInternalTunnelDeleteWorker.class) ;
75 private final DataBroker dataBroker;
76 private final ManagedNewTransactionRunner txRunner;
77 private final JobCoordinator jobCoordinator;
78 private final TunnelMonitoringConfig tunnelMonitoringConfig;
79 private final IInterfaceManager interfaceManager;
80 private final DpnTepStateCache dpnTepStateCache;
81 private final OvsBridgeEntryCache ovsBridgeEntryCache;
82 private final OvsBridgeRefEntryCache ovsBridgeRefEntryCache;
83 private final TunnelStateCache tunnelStateCache;
84 private final DirectTunnelUtils directTunnelUtils;
86 public ItmInternalTunnelDeleteWorker(DataBroker dataBroker, JobCoordinator jobCoordinator,
87 TunnelMonitoringConfig tunnelMonitoringConfig,
88 IInterfaceManager interfaceManager, DpnTepStateCache dpnTepStateCache,
89 OvsBridgeEntryCache ovsBridgeEntryCache,
90 OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
91 TunnelStateCache tunnelStateCache,
92 DirectTunnelUtils directTunnelUtils) {
93 this.dataBroker = dataBroker;
94 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
95 this.jobCoordinator = jobCoordinator;
96 this.tunnelMonitoringConfig = tunnelMonitoringConfig;
97 this.interfaceManager = interfaceManager;
98 this.dpnTepStateCache = dpnTepStateCache;
99 this.ovsBridgeEntryCache = ovsBridgeEntryCache;
100 this.ovsBridgeRefEntryCache = ovsBridgeRefEntryCache;
101 this.tunnelStateCache = tunnelStateCache;
102 this.directTunnelUtils = directTunnelUtils;
105 @SuppressWarnings("checkstyle:IllegalCatch")
106 public List<ListenableFuture<Void>> deleteTunnels(IMdsalApiManager mdsalManager,
107 Collection<DPNTEPsInfo> dpnTepsList, Collection<DPNTEPsInfo> meshedDpnList) {
108 LOG.trace("TEPs to be deleted {} " , dpnTepsList);
109 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(writeTransaction -> {
110 if (dpnTepsList == null || dpnTepsList.size() == 0) {
111 LOG.debug("no vtep to delete");
115 if (meshedDpnList == null || meshedDpnList.size() == 0) {
116 LOG.debug("No Meshed Vteps");
119 for (DPNTEPsInfo srcDpn : dpnTepsList) {
120 LOG.trace("Processing srcDpn {}", srcDpn);
122 List<TunnelEndPoints> meshedEndPtCache = ItmUtils.getTEPsForDpn(srcDpn.getDPNID(), meshedDpnList);
123 if (meshedEndPtCache == null) {
124 LOG.debug("No Tunnel End Point configured for this DPN {}", srcDpn.getDPNID());
127 LOG.debug("Entries in meshEndPointCache {} for DPN Id{} ", meshedEndPtCache.size(), srcDpn.getDPNID());
128 for (TunnelEndPoints srcTep : srcDpn.getTunnelEndPoints()) {
129 LOG.trace("Processing srcTep {}", srcTep);
130 List<TzMembership> srcTZones = srcTep.getTzMembership();
131 boolean tepDeleteFlag = false;
132 // First, take care of tunnel removal, so run through all other DPNS other than srcDpn
133 // In the tep received from Delete DCN, the membership list will always be 1
134 // as the DCN is at transport zone level
135 // Hence if a tunnel is shared across TZs, compare the original membership list between end points
136 // to decide if tunnel to be deleted.
137 for (DPNTEPsInfo dstDpn : meshedDpnList) {
138 if (!srcDpn.getDPNID().equals(dstDpn.getDPNID())) {
139 for (TunnelEndPoints dstTep : dstDpn.getTunnelEndPoints()) {
140 if (!ItmUtils.getIntersection(dstTep.getTzMembership(), srcTZones).isEmpty()) {
141 List<TzMembership> originalTzMembership =
142 ItmUtils.getOriginalTzMembership(srcTep, srcDpn.getDPNID(), meshedDpnList);
143 if (ItmUtils.getIntersection(dstTep.getTzMembership(),
144 originalTzMembership).size() == 1) {
145 if (interfaceManager.isItmDirectTunnelsEnabled()) {
146 if (checkIfTepInterfaceExists(dstDpn.getDPNID(), srcDpn.getDPNID())) {
147 // remove all trunk interfaces
148 LOG.trace("Invoking removeTrunkInterface between source TEP {} , "
149 + "Destination TEP {} " ,srcTep , dstTep);
150 removeTunnelInterfaceFromOvsdb(srcTep, dstTep, srcDpn.getDPNID(),
151 dstDpn.getDPNID(), writeTransaction);
156 if (checkIfTrunkExists(dstDpn.getDPNID(), srcDpn.getDPNID(),
157 srcTep.getTunnelType(), dataBroker)) {
158 // remove all trunk interfaces
159 LOG.trace("Invoking removeTrunkInterface between source TEP {} , "
160 + "Destination TEP {} ", srcTep, dstTep);
161 removeTrunkInterface(srcTep, dstTep, srcDpn.getDPNID(),
162 dstDpn.getDPNID(), writeTransaction);
170 for (DPNTEPsInfo dstDpn : meshedDpnList) {
171 // Second, take care of Tep TZ membership and identify if tep can be removed
172 if (srcDpn.getDPNID().equals(dstDpn.getDPNID())) {
173 // Same DPN, so remove the TZ membership
174 for (TunnelEndPoints dstTep : dstDpn.getTunnelEndPoints()) {
175 if (dstTep.getIpAddress().equals(srcTep.getIpAddress())) {
176 // Remove the deleted TZ membership from the TEP
177 LOG.debug("Removing TZ list {} from Existing TZ list {} ", srcTZones,
178 dstTep.getTzMembership());
179 List<TzMembership> updatedList =
180 ItmUtils.removeTransportZoneMembership(dstTep, srcTZones);
181 if (updatedList.isEmpty()) {
182 LOG.debug(" This TEP can be deleted {}", srcTep);
183 tepDeleteFlag = true;
185 TunnelEndPointsBuilder modifiedTepBld = new TunnelEndPointsBuilder(dstTep);
186 modifiedTepBld.setTzMembership(updatedList);
187 TunnelEndPoints modifiedTep = modifiedTepBld.build() ;
188 InstanceIdentifier<TunnelEndPoints> tepPath = InstanceIdentifier
189 .builder(DpnEndpoints.class)
190 .child(DPNTEPsInfo.class, dstDpn.getKey())
191 .child(TunnelEndPoints.class, dstTep.getKey()).build();
193 LOG.debug(" Store the modified Tep in DS {} ", modifiedTep);
194 writeTransaction.put(LogicalDatastoreType.CONFIGURATION, tepPath, modifiedTep);
201 // Third, removing vtep / dpn from Tunnels OpDs.
202 InstanceIdentifier<TunnelEndPoints> tepPath =
203 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, srcDpn.getKey())
204 .child(TunnelEndPoints.class, srcTep.getKey()).build();
206 LOG.trace("Tep Removal of TEP {} from DPNTEPSINFO CONFIG DS with Key {} ", srcTep,
208 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, tepPath);
209 // remove the tep from the cache
210 meshedEndPtCache.remove(srcTep);
211 Class<? extends TunnelMonitoringTypeBase> monitorProtocol =
212 tunnelMonitoringConfig.getMonitorProtocol();
213 InstanceIdentifier<DPNTEPsInfo> dpnPath =
214 InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, srcDpn.getKey())
217 if (meshedEndPtCache.isEmpty()) {
218 // remove dpn if no vteps exist on dpn
219 if (monitorProtocol.isAssignableFrom(TunnelMonitoringTypeLldp.class)) {
220 LOG.debug("Removing Terminating Service Table Flow ");
221 ItmUtils.setUpOrRemoveTerminatingServiceTable(srcDpn.getDPNID(), mdsalManager, false);
223 LOG.trace("DPN Removal from DPNTEPSINFO CONFIG DS {}", srcDpn.getDPNID());
224 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, dpnPath);
225 InstanceIdentifier<DpnEndpoints> tnlContainerPath =
226 InstanceIdentifier.builder(DpnEndpoints.class).build();
227 Optional<DpnEndpoints> containerOptional =
228 ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
229 tnlContainerPath, dataBroker);
230 // remove container if no DPNs are present
231 if (containerOptional.isPresent()) {
232 DpnEndpoints deps = containerOptional.get();
233 if (deps.getDPNTEPsInfo() == null || deps.getDPNTEPsInfo().isEmpty()) {
234 LOG.trace("Container Removal from DPNTEPSINFO CONFIG DS");
235 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, tnlContainerPath);
240 if (interfaceManager.isItmDirectTunnelsEnabled()) {
241 // SF419 Remove the DPNSTEPs DS
242 LOG.debug("Deleting TEP Interface information from Config datastore with DPNs-Teps "
243 + "for source Dpn {}", srcDpn.getDPNID());
244 // Clean up the DPN TEPs State DS
245 dpnTepStateCache.removeTepFromDpnTepInterfaceConfigDS(srcDpn.getDPNID());
252 private void removeTrunkInterface(TunnelEndPoints srcTep, TunnelEndPoints dstTep,
253 BigInteger srcDpnId, BigInteger dstDpnId, WriteTransaction transaction) {
254 String trunkfwdIfName = ItmUtils.getTrunkInterfaceName(srcTep.getInterfaceName(),
255 new String(srcTep.getIpAddress().getValue()),
256 new String(dstTep.getIpAddress().getValue()),
257 srcTep.getTunnelType().getName());
258 LOG.trace("Removing forward Trunk Interface {}" , trunkfwdIfName);
259 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkfwdIfName);
260 LOG.debug(" Removing Trunk Interface Name - {} , Id - {} from Config DS ",
261 trunkfwdIfName, trunkIdentifier) ;
262 transaction.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
263 ItmUtils.ITM_CACHE.removeInterface(trunkfwdIfName);
264 // also update itm-state ds -- Delete the forward tunnel-interface from the tunnel list
265 InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(TunnelList.class)
266 .child(InternalTunnel.class, new InternalTunnelKey(dstDpnId, srcDpnId, srcTep.getTunnelType()));
267 transaction.delete(LogicalDatastoreType.CONFIGURATION,path) ;
268 ItmUtils.ITM_CACHE.removeInternalTunnel(trunkfwdIfName);
269 // Release the Ids for the forward trunk interface Name
270 ItmUtils.releaseIdForTrunkInterfaceName(srcTep.getInterfaceName(),
271 new String(srcTep.getIpAddress().getValue()),
272 new String(dstTep.getIpAddress().getValue()),
273 srcTep.getTunnelType().getName());
274 removeLogicalGroupTunnel(srcDpnId, dstDpnId);
276 String trunkRevIfName = ItmUtils.getTrunkInterfaceName(dstTep.getInterfaceName(),
277 new String(dstTep.getIpAddress().getValue()),
278 new String(srcTep.getIpAddress().getValue()),
279 srcTep.getTunnelType().getName());
280 LOG.trace("Removing Reverse Trunk Interface {}", trunkRevIfName);
281 trunkIdentifier = ItmUtils.buildId(trunkRevIfName);
282 LOG.debug(" Removing Trunk Interface Name - {} , Id - {} from Config DS ",
283 trunkRevIfName, trunkIdentifier) ;
284 transaction.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
285 ItmUtils.ITM_CACHE.removeInternalTunnel(trunkRevIfName);
286 // also update itm-state ds -- Delete the reverse tunnel-interface from the tunnel list
287 path = InstanceIdentifier.create(TunnelList.class)
288 .child(InternalTunnel.class, new InternalTunnelKey(srcDpnId, dstDpnId, dstTep.getTunnelType()));
289 transaction.delete(LogicalDatastoreType.CONFIGURATION,path) ;
291 // Release the Ids for the reverse trunk interface Name
292 ItmUtils.releaseIdForTrunkInterfaceName(dstTep.getInterfaceName(),
293 new String(dstTep.getIpAddress().getValue()),
294 new String(srcTep.getIpAddress().getValue()),
295 dstTep.getTunnelType().getName());
296 removeLogicalGroupTunnel(dstDpnId, srcDpnId);
299 private static boolean checkIfTrunkExists(BigInteger srcDpnId, BigInteger dstDpnId,
300 Class<? extends TunnelTypeBase> tunType, DataBroker dataBroker) {
301 InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(TunnelList.class)
302 .child(InternalTunnel.class, new InternalTunnelKey(dstDpnId, srcDpnId, tunType));
303 return ItmUtils.read(LogicalDatastoreType.CONFIGURATION,path, dataBroker).isPresent();
306 private void removeLogicalGroupTunnel(BigInteger srcDpnId, BigInteger dstDpnId) {
307 boolean tunnelAggregationEnabled = ItmTunnelAggregationHelper.isTunnelAggregationEnabled();
308 if (!tunnelAggregationEnabled) {
311 String logicTunnelName = ItmUtils.getLogicalTunnelGroupName(srcDpnId, dstDpnId);
312 ItmTunnelAggregationDeleteWorker addWorker =
313 new ItmTunnelAggregationDeleteWorker(logicTunnelName, srcDpnId, dstDpnId, dataBroker);
314 jobCoordinator.enqueueJob(logicTunnelName, addWorker);
317 private static class ItmTunnelAggregationDeleteWorker implements Callable<List<ListenableFuture<Void>>> {
319 private final String logicTunnelName;
320 private final BigInteger srcDpnId;
321 private final BigInteger dstDpnId;
322 private final ManagedNewTransactionRunner txRunner;
324 ItmTunnelAggregationDeleteWorker(String groupName, BigInteger srcDpnId, BigInteger dstDpnId, DataBroker db) {
325 this.logicTunnelName = groupName;
326 this.srcDpnId = srcDpnId;
327 this.dstDpnId = dstDpnId;
328 this.txRunner = new ManagedNewTransactionRunnerImpl(db);
332 public List<ListenableFuture<Void>> call() throws Exception {
333 Collection<InternalTunnel> tunnels = ItmUtils.ITM_CACHE.getAllInternalTunnel();
335 //The logical tunnel interface be removed only when the last tunnel interface on each OVS is deleted
336 boolean emptyTunnelGroup = true;
337 boolean foundLogicGroupIface = false;
338 for (InternalTunnel tunl : tunnels) {
339 if (tunl.getSourceDPN().equals(srcDpnId) && tunl.getDestinationDPN().equals(dstDpnId)) {
340 if (tunl.getTransportType().isAssignableFrom(TunnelTypeVxlan.class)
341 && tunl.getTunnelInterfaceNames() != null && !tunl.getTunnelInterfaceNames().isEmpty()) {
342 emptyTunnelGroup = false;
344 } else if (tunl.getTransportType().isAssignableFrom(TunnelTypeLogicalGroup.class)) {
345 foundLogicGroupIface = true;
349 if (emptyTunnelGroup && foundLogicGroupIface) {
350 return singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
351 LOG.debug("MULTIPLE_VxLAN_TUNNELS: remove the logical tunnel group {} because a last tunnel"
352 + " interface on srcDpnId {} dstDpnId {} is removed", logicTunnelName, srcDpnId, dstDpnId);
353 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(logicTunnelName);
354 tx.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
355 ItmUtils.ITM_CACHE.removeInterface(logicTunnelName);
356 InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(TunnelList.class)
357 .child(InternalTunnel.class,
358 new InternalTunnelKey(dstDpnId, srcDpnId, TunnelTypeLogicalGroup.class));
359 tx.delete(LogicalDatastoreType.CONFIGURATION, path);
360 ItmUtils.ITM_CACHE.removeInternalTunnel(logicTunnelName);
362 } else if (!emptyTunnelGroup) {
363 LOG.debug("MULTIPLE_VxLAN_TUNNELS: not last tunnel in logical tunnel group {}", logicTunnelName);
365 return Collections.emptyList();
369 private void removeTunnelInterfaceFromOvsdb(TunnelEndPoints srcTep, TunnelEndPoints dstTep, BigInteger srcDpnId,
370 BigInteger dstDpnId, WriteTransaction writeTransaction) {
371 String trunkfwdIfName = ItmUtils.getTrunkInterfaceName(srcTep.getInterfaceName(),
372 srcTep.getIpAddress().getIpv4Address().getValue(),
373 dstTep.getIpAddress().getIpv4Address().getValue(),
374 srcTep.getTunnelType().getName());
375 LOG.trace("Removing forward Trunk Interface {}", trunkfwdIfName);
376 ParentRefs parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(srcDpnId).build();
377 Interface iface = dpnTepStateCache.getInterfaceFromCache(trunkfwdIfName);
378 // ITM DIRECT TUNNELS -- Call the OVS Worker directly
381 removeConfiguration(iface, parentRefs, writeTransaction);
382 } catch (ExecutionException | InterruptedException | OperationFailedException e) {
383 LOG.error("Cannot Delete Tunnel {} as OVS Bridge Entry is NULL ", iface.getName(), e);
386 String trunkRevIfName = ItmUtils.getTrunkInterfaceName(dstTep.getInterfaceName(),
387 dstTep.getIpAddress().getIpv4Address().getValue(),
388 srcTep.getIpAddress().getIpv4Address().getValue(),
389 srcTep.getTunnelType().getName());
390 parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(dstDpnId).build();
391 iface = dpnTepStateCache.getInterfaceFromCache(trunkRevIfName);
395 LOG.trace("Removing Reverse Trunk Interface {}", trunkRevIfName);
396 removeConfiguration(iface, parentRefs, writeTransaction);
397 } catch (ExecutionException | InterruptedException | OperationFailedException e) {
398 LOG.error("Cannot Delete Tunnel {} as OVS Bridge Entry is NULL ", iface.getName(), e);
403 private boolean checkIfTepInterfaceExists(BigInteger srcDpnId, BigInteger dstDpnId) {
404 DpnTepInterfaceInfo dpnTepInterfaceInfo = dpnTepStateCache.getDpnTepInterface(srcDpnId,dstDpnId);
405 if (dpnTepInterfaceInfo != null) {
406 if (dpnTepInterfaceInfo.getTunnelName() != null) {
413 private void removeConfiguration(Interface interfaceOld, ParentRefs parentRefs, WriteTransaction
414 writeTransaction) throws ExecutionException, InterruptedException, OperationFailedException {
415 IfTunnel ifTunnel = interfaceOld.getAugmentation(IfTunnel.class);
416 if (ifTunnel != null) {
417 // Check if the same transaction can be used across Config and operational shards
418 removeTunnelConfiguration(parentRefs, interfaceOld.getName(), ifTunnel, writeTransaction);
422 private void removeTunnelConfiguration(ParentRefs parentRefs, String interfaceName, IfTunnel ifTunnel,
423 WriteTransaction transaction)
424 throws ExecutionException, InterruptedException, OperationFailedException {
426 LOG.info("removing tunnel configuration for {}", interfaceName);
427 BigInteger dpId = null;
428 if (parentRefs != null) {
429 dpId = parentRefs.getDatapathNodeIdentifier();
436 Optional<OvsBridgeRefEntry> ovsBridgeRefEntryOptional = ovsBridgeRefEntryCache.get(dpId);
437 Optional<OvsBridgeEntry> ovsBridgeEntryOptional;
438 OvsdbBridgeRef ovsdbBridgeRef = null;
439 if (ovsBridgeRefEntryOptional.isPresent()) {
440 ovsdbBridgeRef = ovsBridgeRefEntryOptional.get().getOvsBridgeReference();
442 ovsBridgeEntryOptional = ovsBridgeEntryCache.get(dpId);
443 if (ovsBridgeEntryOptional.isPresent()) {
444 ovsdbBridgeRef = ovsBridgeEntryOptional.get().getOvsBridgeReference();
448 if (ovsdbBridgeRef != null) {
449 removeTerminationEndPoint(ovsdbBridgeRef.getValue(), interfaceName);
452 // delete tunnel ingress flow
453 removeTunnelIngressFlow(interfaceName, dpId);
455 // delete bridge to tunnel interface mappings
456 OvsBridgeEntryKey bridgeEntryKey = new OvsBridgeEntryKey(dpId);
457 InstanceIdentifier<OvsBridgeEntry> bridgeEntryIid =
458 DirectTunnelUtils.getOvsBridgeEntryIdentifier(bridgeEntryKey);
460 ovsBridgeEntryOptional = ovsBridgeEntryCache.get(dpId);
461 if (ovsBridgeEntryOptional.isPresent()) {
462 List<OvsBridgeTunnelEntry> bridgeTunnelEntries = ovsBridgeEntryOptional.get().getOvsBridgeTunnelEntry();
463 deleteBridgeInterfaceEntry(bridgeEntryKey, bridgeTunnelEntries, bridgeEntryIid, interfaceName);
464 // IfIndex needs to be removed only during State Clean up not Config
465 // TunnelMetaUtils.removeLportTagInterfaceMap(idManager, defaultOperationalShardTransaction, interfaceName);
466 cleanUpInterfaceWithUnknownState(interfaceName, parentRefs, ifTunnel, transaction);
467 directTunnelUtils.removeLportTagInterfaceMap(interfaceName);
471 private void removeTerminationEndPoint(InstanceIdentifier<?> bridgeIid, String interfaceName) {
472 LOG.debug("removing termination point for {}", interfaceName);
473 InstanceIdentifier<TerminationPoint> tpIid = DirectTunnelUtils.createTerminationPointInstanceIdentifier(
474 InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), interfaceName);
475 ITMBatchingUtils.delete(tpIid, ITMBatchingUtils.EntityType.TOPOLOGY_CONFIG);
478 private void removeTunnelIngressFlow(String interfaceName, BigInteger dpId) throws ReadFailedException {
479 long portNo = tunnelStateCache.getNodeConnectorIdFromInterface(interfaceName);
480 DpnTepInterfaceInfo dpnTepInfo = dpnTepStateCache.getTunnelFromCache(interfaceName);
481 directTunnelUtils.makeTunnelIngressFlow(dpnTepInfo, dpId, portNo,interfaceName , -1, NwConstants.DEL_FLOW);
484 // if the node is shutdown, there will be stale interface state entries,
485 // with unknown op-state, clear them.
486 private void cleanUpInterfaceWithUnknownState(String interfaceName, ParentRefs parentRefs, IfTunnel ifTunnel,
487 WriteTransaction transaction) throws ReadFailedException {
488 Optional<StateTunnelList> stateTunnelList =
489 tunnelStateCache.get(tunnelStateCache.getStateTunnelListIdentifier(interfaceName));
490 if (stateTunnelList.isPresent() && stateTunnelList.get().getOperState() == TunnelOperStatus.Unknown) {
491 String staleInterface = ifTunnel != null ? interfaceName : parentRefs.getParentInterface();
492 LOG.debug("cleaning up parent-interface for {}, since the oper-status is UNKNOWN", interfaceName);
493 directTunnelUtils.deleteTunnelStateEntry(staleInterface);
497 private void deleteBridgeInterfaceEntry(OvsBridgeEntryKey bridgeEntryKey,
498 List<OvsBridgeTunnelEntry> bridgeTunnelEntries,
499 InstanceIdentifier<OvsBridgeEntry> bridgeEntryIid,
500 String interfaceName) {
501 OvsBridgeTunnelEntryKey bridgeTunnelEntryKey = new OvsBridgeTunnelEntryKey(interfaceName);
502 InstanceIdentifier<OvsBridgeTunnelEntry> bridgeTunnelEntryIid =
503 DirectTunnelUtils.getBridgeTunnelEntryIdentifier(bridgeEntryKey, bridgeTunnelEntryKey);
504 ITMBatchingUtils.delete(bridgeTunnelEntryIid, ITMBatchingUtils.EntityType.DEFAULT_CONFIG);
505 if (bridgeTunnelEntries.size() <= 1) {
506 ITMBatchingUtils.delete(bridgeEntryIid, ITMBatchingUtils.EntityType.DEFAULT_CONFIG);