*/
package org.opendaylight.genius.itm.confighelpers;
+import static java.util.Collections.singletonList;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
import com.google.common.base.Optional;
import com.google.common.util.concurrent.ListenableFuture;
-import java.math.BigInteger;
-import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.Callable;
-
+import java.util.concurrent.ExecutionException;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
+import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
+import org.opendaylight.genius.itm.cache.DpnTepStateCache;
+import org.opendaylight.genius.itm.cache.OfEndPointCache;
+import org.opendaylight.genius.itm.cache.OvsBridgeEntryCache;
+import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
+import org.opendaylight.genius.itm.cache.TunnelStateCache;
+import org.opendaylight.genius.itm.impl.ITMBatchingUtils;
import org.opendaylight.genius.itm.impl.ItmUtils;
+import org.opendaylight.genius.itm.impl.TunnelMonitoringConfig;
+import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
+import org.opendaylight.genius.itm.utils.DpnTepInterfaceInfo;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfTunnel;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.ParentRefsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelMonitoringTypeLldp;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeLogicalGroup;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.OvsBridgeEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.OvsBridgeEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.ovs.bridge.entry.OvsBridgeTunnelEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.ovs.bridge.entry.OvsBridgeTunnelEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntry;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.DpnEndpoints;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPointsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnel;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnel.list.InternalTunnelKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.OperationFailedException;
+import org.opendaylight.yangtools.yang.common.Uint64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ItmInternalTunnelDeleteWorker {
+
private static final Logger LOG = LoggerFactory.getLogger(ItmInternalTunnelDeleteWorker.class) ;
+ private final DataBroker dataBroker;
+ private final ManagedNewTransactionRunner txRunner;
+ private final JobCoordinator jobCoordinator;
+ private final TunnelMonitoringConfig tunnelMonitoringConfig;
+ private final IInterfaceManager interfaceManager;
+ private final DpnTepStateCache dpnTepStateCache;
+ private final OvsBridgeEntryCache ovsBridgeEntryCache;
+ private final OvsBridgeRefEntryCache ovsBridgeRefEntryCache;
+ private final TunnelStateCache tunnelStateCache;
+ private final DirectTunnelUtils directTunnelUtils;
+ private final OfEndPointCache ofEndPointCache;
+ private final ItmConfig itmConfig;
+
+ public ItmInternalTunnelDeleteWorker(DataBroker dataBroker, JobCoordinator jobCoordinator,
+ TunnelMonitoringConfig tunnelMonitoringConfig,
+ IInterfaceManager interfaceManager, DpnTepStateCache dpnTepStateCache,
+ OvsBridgeEntryCache ovsBridgeEntryCache,
+ OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
+ TunnelStateCache tunnelStateCache,
+ DirectTunnelUtils directTunnelUtils,
+ OfEndPointCache ofEndPointCache,
+ ItmConfig itmConfig) {
+ this.dataBroker = dataBroker;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+ this.jobCoordinator = jobCoordinator;
+ this.tunnelMonitoringConfig = tunnelMonitoringConfig;
+ this.interfaceManager = interfaceManager;
+ this.dpnTepStateCache = dpnTepStateCache;
+ this.ovsBridgeEntryCache = ovsBridgeEntryCache;
+ this.ovsBridgeRefEntryCache = ovsBridgeRefEntryCache;
+ this.tunnelStateCache = tunnelStateCache;
+ this.directTunnelUtils = directTunnelUtils;
+ this.ofEndPointCache = ofEndPointCache;
+ this.itmConfig = itmConfig;
+ }
+
@SuppressWarnings("checkstyle:IllegalCatch")
- public static List<ListenableFuture<Void>> deleteTunnels(DataBroker dataBroker, IdManagerService idManagerService,
- IMdsalApiManager mdsalManager,
- List<DPNTEPsInfo> dpnTepsList,
- List<DPNTEPsInfo> meshedDpnList) {
+ public List<ListenableFuture<Void>> deleteTunnels(IMdsalApiManager mdsalManager,
+ Collection<DPNTEPsInfo> dpnTepsList, Collection<DPNTEPsInfo> meshedDpnList) {
LOG.trace("TEPs to be deleted {} " , dpnTepsList);
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
- try {
+ return Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
if (dpnTepsList == null || dpnTepsList.size() == 0) {
LOG.debug("no vtep to delete");
- return futures ;
+ return;
}
if (meshedDpnList == null || meshedDpnList.size() == 0) {
LOG.debug("No Meshed Vteps");
- return futures ;
+ return;
}
for (DPNTEPsInfo srcDpn : dpnTepsList) {
- LOG.trace("Processing srcDpn " + srcDpn);
+ LOG.trace("Processing srcDpn {}", srcDpn);
List<TunnelEndPoints> meshedEndPtCache = ItmUtils.getTEPsForDpn(srcDpn.getDPNID(), meshedDpnList);
if (meshedEndPtCache == null) {
LOG.debug("No Tunnel End Point configured for this DPN {}", srcDpn.getDPNID());
- continue ;
+ continue;
}
- LOG.debug("Entries in meshEndPointCache {} for DPN Id{} ",
- meshedEndPtCache.size(), srcDpn.getDPNID());
- for (TunnelEndPoints srcTep : srcDpn.getTunnelEndPoints()) {
- LOG.trace("Processing srcTep " + srcTep);
- List<TzMembership> srcTZones = srcTep.getTzMembership();
+ LOG.debug("Entries in meshEndPointCache {} for DPN Id{} ", meshedEndPtCache.size(), srcDpn.getDPNID());
+ for (TunnelEndPoints srcTep : srcDpn.nonnullTunnelEndPoints()) {
+ LOG.trace("Processing srcTep {}", srcTep);
+ List<TzMembership> srcTZones = srcTep.nonnullTzMembership();
boolean tepDeleteFlag = false;
// First, take care of tunnel removal, so run through all other DPNS other than srcDpn
// In the tep received from Delete DCN, the membership list will always be 1
// Hence if a tunnel is shared across TZs, compare the original membership list between end points
// to decide if tunnel to be deleted.
for (DPNTEPsInfo dstDpn : meshedDpnList) {
- if (!srcDpn.getDPNID().equals(dstDpn.getDPNID())) {
- for (TunnelEndPoints dstTep : dstDpn.getTunnelEndPoints()) {
- if (!ItmUtils.getIntersection(dstTep.getTzMembership(), srcTZones).isEmpty()) {
+ if (!Objects.equals(srcDpn.getDPNID(), dstDpn.getDPNID())) {
+ for (TunnelEndPoints dstTep : dstDpn.nonnullTunnelEndPoints()) {
+ if (!ItmUtils.getIntersection(dstTep.nonnullTzMembership(), srcTZones).isEmpty()) {
List<TzMembership> originalTzMembership =
ItmUtils.getOriginalTzMembership(srcTep, srcDpn.getDPNID(), meshedDpnList);
- if (ItmUtils.getIntersection(dstTep.getTzMembership(), originalTzMembership).size()
- == 1) {
- if (checkIfTrunkExists(dstDpn.getDPNID(), srcDpn.getDPNID(),
+ if (ItmUtils.getIntersection(dstTep.getTzMembership(),
+ originalTzMembership).size() == 1) {
+ if (interfaceManager.isItmDirectTunnelsEnabled()) {
+ if (checkIfTepInterfaceExists(dstDpn.getDPNID(), srcDpn.getDPNID())) {
+ // remove all trunk interfaces
+ LOG.trace("Invoking removeTrunkInterface between source TEP {} , "
+ + "Destination TEP {} " ,srcTep , dstTep);
+ removeTunnelInterfaceFromOvsdb(tx, srcTep, dstTep, srcDpn.getDPNID(),
+ dstDpn.getDPNID());
+
+ }
+
+ } else {
+ if (checkIfTrunkExists(dstDpn.getDPNID(), srcDpn.getDPNID(),
srcTep.getTunnelType(), dataBroker)) {
- // remove all trunk interfaces
- LOG.trace("Invoking removeTrunkInterface between source TEP {} , "
- + "Destination TEP {} ", srcTep, dstTep);
- removeTrunkInterface(dataBroker, idManagerService, srcTep, dstTep, srcDpn
- .getDPNID(), dstDpn.getDPNID(), writeTransaction, futures);
+ // remove all trunk interfaces
+ LOG.trace("Invoking removeTrunkInterface between source TEP {} , "
+ + "Destination TEP {} ", srcTep, dstTep);
+ removeTrunkInterface(tx, srcTep, dstTep, srcDpn.getDPNID(),
+ dstDpn.getDPNID());
+ }
}
}
}
}
}
}
+
for (DPNTEPsInfo dstDpn : meshedDpnList) {
// Second, take care of Tep TZ membership and identify if tep can be removed
- if (srcDpn.getDPNID().equals(dstDpn.getDPNID())) {
+ if (Objects.equals(srcDpn.getDPNID(), dstDpn.getDPNID())) {
// Same DPN, so remove the TZ membership
- for (TunnelEndPoints dstTep : dstDpn.getTunnelEndPoints()) {
- if (dstTep.getIpAddress().equals(srcTep.getIpAddress())) {
+ for (TunnelEndPoints dstTep : dstDpn.nonnullTunnelEndPoints()) {
+ if (Objects.equals(dstTep.getIpAddress(), srcTep.getIpAddress())) {
// Remove the deleted TZ membership from the TEP
- LOG.debug("Removing TZ list {} from Existing TZ list {} ",
- srcTZones, dstTep.getTzMembership());
+ LOG.debug("Removing TZ list {} from Existing TZ list {} ", srcTZones,
+ dstTep.getTzMembership());
List<TzMembership> updatedList =
ItmUtils.removeTransportZoneMembership(dstTep, srcTZones);
if (updatedList.isEmpty()) {
- LOG.debug(" This TEP can be deleted " + srcTep);
+ LOG.debug(" This TEP can be deleted {}", srcTep);
tepDeleteFlag = true;
} else {
TunnelEndPointsBuilder modifiedTepBld = new TunnelEndPointsBuilder(dstTep);
TunnelEndPoints modifiedTep = modifiedTepBld.build() ;
InstanceIdentifier<TunnelEndPoints> tepPath = InstanceIdentifier
.builder(DpnEndpoints.class)
- .child(DPNTEPsInfo.class, dstDpn.getKey())
- .child(TunnelEndPoints.class, dstTep.getKey()).build();
+ .child(DPNTEPsInfo.class, dstDpn.key())
+ .child(TunnelEndPoints.class, dstTep.key()).build();
LOG.debug(" Store the modified Tep in DS {} ", modifiedTep);
- writeTransaction.put(LogicalDatastoreType.CONFIGURATION, tepPath, modifiedTep);
+ tx.put(tepPath, modifiedTep);
}
}
}
if (tepDeleteFlag) {
// Third, removing vtep / dpn from Tunnels OpDs.
InstanceIdentifier<TunnelEndPoints> tepPath =
- InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, srcDpn.getKey())
- .child(TunnelEndPoints.class, srcTep.getKey()).build();
+ InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, srcDpn.key())
+ .child(TunnelEndPoints.class, srcTep.key()).build();
- LOG.trace("Tep Removal of TEP {} from DPNTEPSINFO CONFIG DS with Key {} "
- + srcTep, srcTep.getKey());
- writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, tepPath);
+ LOG.trace("Tep Removal of TEP {} from DPNTEPSINFO CONFIG DS with Key {} ", srcTep,
+ srcTep.key());
+ tx.delete(tepPath);
// remove the tep from the cache
meshedEndPtCache.remove(srcTep);
Class<? extends TunnelMonitoringTypeBase> monitorProtocol =
- ItmUtils.determineMonitorProtocol(dataBroker);
+ tunnelMonitoringConfig.getMonitorProtocol();
InstanceIdentifier<DPNTEPsInfo> dpnPath =
- InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, srcDpn.getKey())
+ InstanceIdentifier.builder(DpnEndpoints.class).child(DPNTEPsInfo.class, srcDpn.key())
.build();
if (meshedEndPtCache.isEmpty()) {
// remove dpn if no vteps exist on dpn
if (monitorProtocol.isAssignableFrom(TunnelMonitoringTypeLldp.class)) {
LOG.debug("Removing Terminating Service Table Flow ");
- ItmUtils.setUpOrRemoveTerminatingServiceTable(srcDpn.getDPNID(), mdsalManager, false);
+ ItmUtils.removeTerminatingServiceTable(tx, srcDpn.getDPNID(), mdsalManager);
}
- LOG.trace("DPN Removal from DPNTEPSINFO CONFIG DS " + srcDpn.getDPNID());
- writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, dpnPath);
+ LOG.trace("DPN Removal from DPNTEPSINFO CONFIG DS {}", srcDpn.getDPNID());
+ tx.delete(dpnPath);
InstanceIdentifier<DpnEndpoints> tnlContainerPath =
InstanceIdentifier.builder(DpnEndpoints.class).build();
- Optional<DpnEndpoints> containerOptional =
- ItmUtils.read(LogicalDatastoreType.CONFIGURATION,
- tnlContainerPath, dataBroker);
+ Optional<DpnEndpoints> containerOptional = tx.read(tnlContainerPath).get();
// remove container if no DPNs are present
if (containerOptional.isPresent()) {
DpnEndpoints deps = containerOptional.get();
if (deps.getDPNTEPsInfo() == null || deps.getDPNTEPsInfo().isEmpty()) {
LOG.trace("Container Removal from DPNTEPSINFO CONFIG DS");
- writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, tnlContainerPath);
+ tx.delete(tnlContainerPath);
}
}
}
}
+ if (interfaceManager.isItmDirectTunnelsEnabled()) {
+ // SF419 Remove the DPNSTEPs DS
+ LOG.debug("Deleting TEP Interface information from Config datastore with DPNs-Teps "
+ + "for source Dpn {}", srcDpn.getDPNID());
+ // Clean up the DPN TEPs State DS
+ dpnTepStateCache.removeTepFromDpnTepInterfaceConfigDS(srcDpn.getDPNID());
+ }
}
}
- futures.add(writeTransaction.submit());
- } catch (Exception e1) {
- LOG.error("exception while deleting tep", e1);
- }
- return futures ;
+ }));
}
- private static void removeTrunkInterface(DataBroker dataBroker, IdManagerService idManagerService,
- TunnelEndPoints srcTep, TunnelEndPoints dstTep, BigInteger srcDpnId,
- BigInteger dstDpnId, WriteTransaction transaction,
- List<ListenableFuture<Void>> futures) {
- String trunkfwdIfName =
- ItmUtils.getTrunkInterfaceName(idManagerService, srcTep.getInterfaceName(),
- new String(srcTep.getIpAddress().getValue()),
- new String(dstTep.getIpAddress().getValue()),
- srcTep.getTunnelType().getName());
- LOG.trace("Removing forward Trunk Interface " + trunkfwdIfName);
+ private void removeTrunkInterface(TypedWriteTransaction<Configuration> tx, TunnelEndPoints srcTep,
+ TunnelEndPoints dstTep, Uint64 srcDpnId, Uint64 dstDpnId) {
+ String trunkfwdIfName = ItmUtils.getTrunkInterfaceName(srcTep.getInterfaceName(),
+ srcTep.getIpAddress().stringValue(),
+ dstTep.getIpAddress().stringValue(),
+ srcTep.getTunnelType().getName());
+ LOG.trace("Removing forward Trunk Interface {}" , trunkfwdIfName);
InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkfwdIfName);
LOG.debug(" Removing Trunk Interface Name - {} , Id - {} from Config DS ",
trunkfwdIfName, trunkIdentifier) ;
- transaction.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
- ItmUtils.itmCache.removeInterface(trunkfwdIfName);
+ tx.delete(trunkIdentifier);
+ ItmUtils.ITM_CACHE.removeInterface(trunkfwdIfName);
// also update itm-state ds -- Delete the forward tunnel-interface from the tunnel list
InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(TunnelList.class)
.child(InternalTunnel.class, new InternalTunnelKey(dstDpnId, srcDpnId, srcTep.getTunnelType()));
- transaction.delete(LogicalDatastoreType.CONFIGURATION,path) ;
- ItmUtils.itmCache.removeInternalTunnel(trunkfwdIfName);
+ tx.delete(path) ;
+ ItmUtils.ITM_CACHE.removeInternalTunnel(trunkfwdIfName);
// Release the Ids for the forward trunk interface Name
- ItmUtils.releaseIdForTrunkInterfaceName(idManagerService,srcTep.getInterfaceName(),
- new String(srcTep.getIpAddress().getValue()),
- new String(dstTep.getIpAddress().getValue()),
+ ItmUtils.releaseIdForTrunkInterfaceName(srcTep.getInterfaceName(),
+ srcTep.getIpAddress().stringValue(),
+ dstTep.getIpAddress().stringValue(),
srcTep.getTunnelType().getName());
- removeLogicalGroupTunnel(srcDpnId, dstDpnId, dataBroker);
+ removeLogicalGroupTunnel(srcDpnId, dstDpnId);
- String trunkRevIfName = ItmUtils.getTrunkInterfaceName(idManagerService, dstTep.getInterfaceName(),
- new String(dstTep.getIpAddress().getValue()),
- new String(srcTep.getIpAddress().getValue()),
- srcTep.getTunnelType().getName());
- LOG.trace("Removing Reverse Trunk Interface " + trunkRevIfName);
+ String trunkRevIfName = ItmUtils.getTrunkInterfaceName(dstTep.getInterfaceName(),
+ dstTep.getIpAddress().stringValue(),
+ srcTep.getIpAddress().stringValue(),
+ srcTep.getTunnelType().getName());
+ LOG.trace("Removing Reverse Trunk Interface {}", trunkRevIfName);
trunkIdentifier = ItmUtils.buildId(trunkRevIfName);
LOG.debug(" Removing Trunk Interface Name - {} , Id - {} from Config DS ",
trunkRevIfName, trunkIdentifier) ;
- transaction.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
- ItmUtils.itmCache.removeInternalTunnel(trunkRevIfName);
+ tx.delete(trunkIdentifier);
+ ItmUtils.ITM_CACHE.removeInternalTunnel(trunkRevIfName);
// also update itm-state ds -- Delete the reverse tunnel-interface from the tunnel list
path = InstanceIdentifier.create(TunnelList.class)
.child(InternalTunnel.class, new InternalTunnelKey(srcDpnId, dstDpnId, dstTep.getTunnelType()));
- transaction.delete(LogicalDatastoreType.CONFIGURATION,path) ;
+ tx.delete(path) ;
// Release the Ids for the reverse trunk interface Name
- ItmUtils.releaseIdForTrunkInterfaceName(idManagerService, dstTep.getInterfaceName(),
- new String(dstTep.getIpAddress().getValue()),
- new String(srcTep.getIpAddress().getValue()),
+ ItmUtils.releaseIdForTrunkInterfaceName(dstTep.getInterfaceName(),
+ dstTep.getIpAddress().stringValue(),
+ srcTep.getIpAddress().stringValue(),
dstTep.getTunnelType().getName());
- removeLogicalGroupTunnel(dstDpnId, srcDpnId, dataBroker);
+ removeLogicalGroupTunnel(dstDpnId, srcDpnId);
}
- private static boolean checkIfTrunkExists(BigInteger srcDpnId, BigInteger dstDpnId,
+ private static boolean checkIfTrunkExists(Uint64 srcDpnId, Uint64 dstDpnId,
Class<? extends TunnelTypeBase> tunType, DataBroker dataBroker) {
InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(TunnelList.class)
.child(InternalTunnel.class, new InternalTunnelKey(dstDpnId, srcDpnId, tunType));
return ItmUtils.read(LogicalDatastoreType.CONFIGURATION,path, dataBroker).isPresent();
}
- private static void removeLogicalGroupTunnel(BigInteger srcDpnId, BigInteger dstDpnId,
- DataBroker dataBroker) {
+ private void removeLogicalGroupTunnel(Uint64 srcDpnId, Uint64 dstDpnId) {
boolean tunnelAggregationEnabled = ItmTunnelAggregationHelper.isTunnelAggregationEnabled();
if (!tunnelAggregationEnabled) {
return;
}
String logicTunnelName = ItmUtils.getLogicalTunnelGroupName(srcDpnId, dstDpnId);
- DataStoreJobCoordinator coordinator = DataStoreJobCoordinator.getInstance();
ItmTunnelAggregationDeleteWorker addWorker =
new ItmTunnelAggregationDeleteWorker(logicTunnelName, srcDpnId, dstDpnId, dataBroker);
- coordinator.enqueueJob(logicTunnelName, addWorker);
+ jobCoordinator.enqueueJob(logicTunnelName, addWorker);
}
private static class ItmTunnelAggregationDeleteWorker implements Callable<List<ListenableFuture<Void>>> {
private final String logicTunnelName;
- private final BigInteger srcDpnId;
- private final BigInteger dstDpnId;
- private final DataBroker dataBroker;
+ private final Uint64 srcDpnId;
+ private final Uint64 dstDpnId;
+ private final ManagedNewTransactionRunner txRunner;
- ItmTunnelAggregationDeleteWorker(String groupName, BigInteger srcDpnId, BigInteger dstDpnId, DataBroker db) {
+ ItmTunnelAggregationDeleteWorker(String groupName, Uint64 srcDpnId, Uint64 dstDpnId, DataBroker db) {
this.logicTunnelName = groupName;
this.srcDpnId = srcDpnId;
this.dstDpnId = dstDpnId;
- this.dataBroker = db;
+ this.txRunner = new ManagedNewTransactionRunnerImpl(db);
}
@Override
- public List<ListenableFuture<Void>> call() throws Exception {
- List<ListenableFuture<Void>> futures = new ArrayList<>();
- Collection<InternalTunnel> tunnels = ItmUtils.itmCache.getAllInternalTunnel();
- if (tunnels == null) {
- return futures;
- }
+ public List<ListenableFuture<Void>> call() {
+ Collection<InternalTunnel> tunnels = ItmUtils.ITM_CACHE.getAllInternalTunnel();
+
//The logical tunnel interface be removed only when the last tunnel interface on each OVS is deleted
boolean emptyTunnelGroup = true;
boolean foundLogicGroupIface = false;
for (InternalTunnel tunl : tunnels) {
- if (tunl.getSourceDPN().equals(srcDpnId) && tunl.getDestinationDPN().equals(dstDpnId)) {
- if (tunl.getTransportType().isAssignableFrom(TunnelTypeVxlan.class)
+ if (Objects.equals(tunl.getSourceDPN(), srcDpnId) && Objects.equals(tunl.getDestinationDPN(),
+ dstDpnId)) {
+ if (tunl.getTransportType() != null && tunl.getTransportType().isAssignableFrom(
+ TunnelTypeVxlan.class)
&& tunl.getTunnelInterfaceNames() != null && !tunl.getTunnelInterfaceNames().isEmpty()) {
emptyTunnelGroup = false;
break;
- } else if (tunl.getTransportType().isAssignableFrom(TunnelTypeLogicalGroup.class)) {
+ } else if (tunl.getTransportType() != null && tunl.getTransportType().isAssignableFrom(
+ TunnelTypeLogicalGroup.class)) {
foundLogicGroupIface = true;
}
}
}
if (emptyTunnelGroup && foundLogicGroupIface) {
- WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
- LOG.debug("MULTIPLE_VxLAN_TUNNELS: remove the logical tunnel group {} because a last tunnel"
- + " interface on srcDpnId {} dstDpnId {} is removed", logicTunnelName, srcDpnId, dstDpnId);
- InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(logicTunnelName);
- tx.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
- ItmUtils.itmCache.removeInterface(logicTunnelName);
- InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(TunnelList.class)
- .child(InternalTunnel.class,
- new InternalTunnelKey(dstDpnId, srcDpnId, TunnelTypeLogicalGroup.class));
- tx.delete(LogicalDatastoreType.CONFIGURATION, path);
- ItmUtils.itmCache.removeInternalTunnel(logicTunnelName);
- futures.add(tx.submit());
+ return singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+ LOG.debug("MULTIPLE_VxLAN_TUNNELS: remove the logical tunnel group {} because a last tunnel"
+ + " interface on srcDpnId {} dstDpnId {} is removed", logicTunnelName, srcDpnId, dstDpnId);
+ InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(logicTunnelName);
+ tx.delete(LogicalDatastoreType.CONFIGURATION, trunkIdentifier);
+ ItmUtils.ITM_CACHE.removeInterface(logicTunnelName);
+ InstanceIdentifier<InternalTunnel> path = InstanceIdentifier.create(TunnelList.class)
+ .child(InternalTunnel.class,
+ new InternalTunnelKey(dstDpnId, srcDpnId, TunnelTypeLogicalGroup.class));
+ tx.delete(LogicalDatastoreType.CONFIGURATION, path);
+ ItmUtils.ITM_CACHE.removeInternalTunnel(logicTunnelName);
+ }));
} else if (!emptyTunnelGroup) {
LOG.debug("MULTIPLE_VxLAN_TUNNELS: not last tunnel in logical tunnel group {}", logicTunnelName);
}
- return futures;
+ return Collections.emptyList();
+ }
+ }
+
+ private void removeTunnelInterfaceFromOvsdb(TypedReadWriteTransaction<Configuration> tx, TunnelEndPoints srcTep,
+ TunnelEndPoints dstTep, Uint64 srcDpnId, Uint64 dstDpnId) {
+ String trunkfwdIfName = ItmUtils.getTrunkInterfaceName(srcTep.getInterfaceName(),
+ srcTep.getIpAddress().getIpv4Address().getValue(),
+ dstTep.getIpAddress().getIpv4Address().getValue(),
+ srcTep.getTunnelType().getName());
+ LOG.trace("Removing forward Trunk Interface {}", trunkfwdIfName);
+ ParentRefs parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(srcDpnId).build();
+ Interface iface = dpnTepStateCache.getInterfaceFromCache(trunkfwdIfName);
+ // ITM DIRECT TUNNELS -- Call the OVS Worker directly
+ if (iface != null) {
+ try {
+ removeConfiguration(tx, iface, parentRefs);
+ } catch (ExecutionException | InterruptedException | OperationFailedException e) {
+ LOG.error("Cannot Delete Tunnel {} as OVS Bridge Entry is NULL ", iface.getName(), e);
+ }
+ }
+ String trunkRevIfName = ItmUtils.getTrunkInterfaceName(dstTep.getInterfaceName(),
+ dstTep.getIpAddress().getIpv4Address().getValue(),
+ srcTep.getIpAddress().getIpv4Address().getValue(),
+ srcTep.getTunnelType().getName());
+ parentRefs = new ParentRefsBuilder().setDatapathNodeIdentifier(dstDpnId).build();
+ iface = dpnTepStateCache.getInterfaceFromCache(trunkRevIfName);
+
+ if (iface != null) {
+ try {
+ LOG.trace("Removing Reverse Trunk Interface {}", trunkRevIfName);
+ removeConfiguration(tx, iface, parentRefs);
+ } catch (ExecutionException | InterruptedException | OperationFailedException e) {
+ LOG.error("Cannot Delete Tunnel {} as OVS Bridge Entry is NULL ", iface.getName(), e);
+ }
+ }
+ }
+
+ private boolean checkIfTepInterfaceExists(Uint64 srcDpnId, Uint64 dstDpnId) {
+ DpnTepInterfaceInfo dpnTepInterfaceInfo = dpnTepStateCache.getDpnTepInterface(srcDpnId, dstDpnId);
+ if (dpnTepInterfaceInfo != null) {
+ return dpnTepInterfaceInfo.getTunnelName() != null;
+ }
+ return false;
+ }
+
+ private void removeConfiguration(TypedReadWriteTransaction<Configuration> tx, Interface interfaceOld,
+ ParentRefs parentRefs) throws ExecutionException, InterruptedException, OperationFailedException {
+ IfTunnel ifTunnel = interfaceOld.augmentation(IfTunnel.class);
+ if (ifTunnel != null) {
+ // Check if the same transaction can be used across Config and operational shards
+ removeTunnelConfiguration(tx, parentRefs, interfaceOld.getName(), ifTunnel);
+ }
+ }
+
+ private void removeTunnelConfiguration(TypedReadWriteTransaction<Configuration> tx, ParentRefs parentRefs,
+ String interfaceName, IfTunnel ifTunnel)
+ throws ExecutionException, InterruptedException, OperationFailedException {
+
+ LOG.info("removing tunnel configuration for {}", interfaceName);
+ Uint64 dpId = null;
+ if (parentRefs != null) {
+ dpId = parentRefs.getDatapathNodeIdentifier();
+ }
+
+ if (dpId == null) {
+ return;
+ }
+
+ OvsdbBridgeRef ovsdbBridgeRef = getOvsdbBridgeRef(dpId);
+ Optional<OvsBridgeEntry> ovsBridgeEntryOptional = ovsBridgeEntryCache.get(dpId);
+
+ // delete bridge to tunnel interface mappings
+ OvsBridgeEntryKey bridgeEntryKey = new OvsBridgeEntryKey(dpId);
+ InstanceIdentifier<OvsBridgeEntry> bridgeEntryIid =
+ DirectTunnelUtils.getOvsBridgeEntryIdentifier(bridgeEntryKey);
+
+
+ if (ovsBridgeEntryOptional.isPresent()) {
+ List<OvsBridgeTunnelEntry> bridgeTunnelEntries = ovsBridgeEntryOptional.get().nonnullOvsBridgeTunnelEntry();
+
+ if (ovsdbBridgeRef != null) {
+ if (!itmConfig.isUseOfTunnels()) {
+ removeTerminationEndPoint(ovsdbBridgeRef.getValue(), interfaceName);
+ } else if (bridgeTunnelEntries.size() <= 1) {
+ removeTerminationEndPoint(ovsdbBridgeRef.getValue(), ofEndPointCache.get(dpId));
+ ofEndPointCache.remove(dpId);
+ }
+ }
+
+ deleteBridgeInterfaceEntry(bridgeEntryKey, bridgeTunnelEntries, bridgeEntryIid, interfaceName);
+ // IfIndex needs to be removed only during State Clean up not Config
+ }
+
+ directTunnelUtils.deleteTunnelStateEntry(interfaceName);
+ // delete tunnel ingress flow
+ removeTunnelIngressFlow(tx, interfaceName, dpId);
+ directTunnelUtils.removeTunnelEgressFlow(tx, dpId, interfaceName);
+ cleanUpInterfaceWithUnknownState(interfaceName, parentRefs, ifTunnel);
+ directTunnelUtils.removeLportTagInterfaceMap(interfaceName);
+ }
+
+ private OvsdbBridgeRef getOvsdbBridgeRef(Uint64 dpId) throws ReadFailedException {
+ Optional<OvsBridgeRefEntry> ovsBridgeRefEntryOptional = ovsBridgeRefEntryCache.get(dpId);
+ Optional<OvsBridgeEntry> ovsBridgeEntryOptional;
+ OvsdbBridgeRef ovsdbBridgeRef = null;
+ if (ovsBridgeRefEntryOptional.isPresent()) {
+ ovsdbBridgeRef = ovsBridgeRefEntryOptional.get().getOvsBridgeReference();
+ } else {
+ ovsBridgeEntryOptional = ovsBridgeEntryCache.get(dpId);
+ if (ovsBridgeEntryOptional.isPresent()) {
+ ovsdbBridgeRef = ovsBridgeEntryOptional.get().getOvsBridgeReference();
+ }
+ }
+ return ovsdbBridgeRef;
+ }
+
+ private void removeTerminationEndPoint(InstanceIdentifier<?> bridgeIid, String interfaceName) {
+ LOG.debug("removing termination point for {}", interfaceName);
+ InstanceIdentifier<TerminationPoint> tpIid = DirectTunnelUtils.createTerminationPointInstanceIdentifier(
+ InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), interfaceName);
+ ITMBatchingUtils.delete(tpIid, ITMBatchingUtils.EntityType.TOPOLOGY_CONFIG);
+ }
+
+ private void removeTunnelIngressFlow(TypedReadWriteTransaction<Configuration> tx, String interfaceName,
+ Uint64 dpId) throws ExecutionException, InterruptedException {
+ directTunnelUtils.removeTunnelIngressFlow(tx, dpId, interfaceName);
+ }
+
+ // if the node is shutdown, there will be stale interface state entries,
+ // with unknown op-state, clear them.
+ private void cleanUpInterfaceWithUnknownState(String interfaceName, ParentRefs parentRefs, IfTunnel ifTunnel)
+ throws ReadFailedException {
+ Optional<StateTunnelList> stateTunnelList =
+ tunnelStateCache.get(tunnelStateCache.getStateTunnelListIdentifier(interfaceName));
+ if (stateTunnelList.isPresent() && stateTunnelList.get().getOperState() == TunnelOperStatus.Unknown) {
+ String staleInterface = ifTunnel != null ? interfaceName : parentRefs.getParentInterface();
+ LOG.debug("cleaning up parent-interface for {}, since the oper-status is UNKNOWN", interfaceName);
+ directTunnelUtils.deleteTunnelStateEntry(staleInterface);
+ }
+ }
+
+ private void deleteBridgeInterfaceEntry(OvsBridgeEntryKey bridgeEntryKey,
+ List<OvsBridgeTunnelEntry> bridgeTunnelEntries,
+ InstanceIdentifier<OvsBridgeEntry> bridgeEntryIid,
+ String interfaceName) {
+ OvsBridgeTunnelEntryKey bridgeTunnelEntryKey = new OvsBridgeTunnelEntryKey(interfaceName);
+ InstanceIdentifier<OvsBridgeTunnelEntry> bridgeTunnelEntryIid =
+ DirectTunnelUtils.getBridgeTunnelEntryIdentifier(bridgeEntryKey, bridgeTunnelEntryKey);
+ ITMBatchingUtils.delete(bridgeTunnelEntryIid, ITMBatchingUtils.EntityType.DEFAULT_CONFIG);
+ if (bridgeTunnelEntries.size() <= 1) {
+ ITMBatchingUtils.delete(bridgeEntryIid, ITMBatchingUtils.EntityType.DEFAULT_CONFIG);
}
}
}