2 * Copyright (c) 2019 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
9 package org.opendaylight.genius.itm.confighelpers;
11 import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
13 import com.google.common.util.concurrent.ListenableFuture;
14 import java.util.Collection;
15 import java.util.Collections;
16 import java.util.List;
18 import java.util.Optional;
19 import java.util.concurrent.ExecutionException;
20 import java.util.stream.Collectors;
21 import org.opendaylight.genius.cloudscaler.api.TombstonedNodeManager;
22 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
23 import org.opendaylight.genius.itm.cache.OfDpnTepConfigCache;
24 import org.opendaylight.genius.itm.cache.OfTepStateCache;
25 import org.opendaylight.genius.itm.cache.OvsBridgeEntryCache;
26 import org.opendaylight.genius.itm.cache.OvsBridgeRefEntryCache;
27 import org.opendaylight.genius.itm.impl.ITMBatchingUtils;
28 import org.opendaylight.genius.itm.itmdirecttunnels.renderer.ovs.utilities.DirectTunnelUtils;
29 import org.opendaylight.mdsal.binding.api.DataBroker;
30 import org.opendaylight.mdsal.binding.util.Datastore.Configuration;
31 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
32 import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
33 import org.opendaylight.mdsal.binding.util.TypedReadWriteTransaction;
34 import org.opendaylight.mdsal.common.api.ReadFailedException;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.OvsBridgeEntry;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.OvsBridgeEntryKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.ovs.bridge.entry.OvsBridgeTunnelEntry;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.bridge.tunnel.info.ovs.bridge.entry.OvsBridgeTunnelEntryKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.meta.rev171210.ovs.bridge.ref.info.OvsBridgeRefEntry;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelOperStatus;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.tep.config.OfDpnTep;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.of.teps.state.OfTep;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeRef;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
46 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
47 import org.opendaylight.yangtools.yang.common.OperationFailedException;
48 import org.opendaylight.yangtools.yang.common.Uint64;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
52 public class ItmOfTunnelDeleteWorker {
54 private static final Logger LOG = LoggerFactory.getLogger(ItmOfTunnelDeleteWorker.class);
55 private static final Logger EVENT_LOGGER = LoggerFactory.getLogger("GeniusEventLogger");
57 private final ManagedNewTransactionRunner txRunner;
58 private final DataBroker dataBroker;
59 private final OfDpnTepConfigCache ofDpnTepConfigCache;
60 private final TombstonedNodeManager tombstonedNodeManager;
61 private final IInterfaceManager interfaceManager;
62 private final DirectTunnelUtils directTunnelUtils;
63 private final OvsBridgeRefEntryCache ovsBridgeRefEntryCache;
64 private final OvsBridgeEntryCache ovsBridgeEntryCache;
65 private final OfTepStateCache ofTepStateCache;
67 public ItmOfTunnelDeleteWorker(DataBroker dataBroker,
68 OfDpnTepConfigCache ofDpnTepConfigCache,
69 TombstonedNodeManager tombstonedNodeManager,
70 IInterfaceManager interfaceManager,
71 DirectTunnelUtils directTunnelUtils,
72 OvsBridgeRefEntryCache ovsBridgeRefEntryCache,
73 OvsBridgeEntryCache ovsBridgeEntryCache,
74 OfTepStateCache ofTepStateCache) {
75 this.dataBroker = dataBroker;
76 this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
77 this.ofDpnTepConfigCache = ofDpnTepConfigCache;
78 this.tombstonedNodeManager = tombstonedNodeManager;
79 this.interfaceManager = interfaceManager;
80 this.directTunnelUtils = directTunnelUtils;
81 this.ovsBridgeRefEntryCache = ovsBridgeRefEntryCache;
82 this.ovsBridgeEntryCache = ovsBridgeEntryCache;
83 this.ofTepStateCache = ofTepStateCache;
86 @SuppressWarnings("checkstyle:IllegalCatch")
87 public List<? extends ListenableFuture<?>> deleteOfTeps(Collection<OfDpnTep> ofTepsList) {
88 LOG.trace("OFTeps to be deleted {} " , ofTepsList);
89 return Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
90 if (ofTepsList == null || ofTepsList.size() == 0) {
91 LOG.debug("no ofteps to delete");
95 for (OfDpnTep srcDpn : ofTepsList) {
96 LOG.trace("Processing srcDpn {}", srcDpn);
98 Boolean isDpnTombstoned = tombstonedNodeManager.isDpnTombstoned(srcDpn.getSourceDpnId());
100 removeOfTepInterfaceFromOvsdb(srcDpn, tx);
101 if (isDpnTombstoned) {
102 EVENT_LOGGER.debug("OfTep-DeleteWorker, Tombstoned, DpnTep for {} removed",
103 srcDpn.getSourceDpnId());
104 LOG.trace("Removing tunnelState entry for {} while tombstoned is set true",srcDpn.getSourceDpnId());
105 removeOfTepState(srcDpn);
107 LOG.debug("Deleting OFTEP Interface information from Config datastore with DPNs-Tep "
108 + "for source Dpn {}", srcDpn.getSourceDpnId());
109 // Clean up the DPNs TEP State DS
110 DirectTunnelUtils.removeOfTepFromDpnsTepConfigDS(dataBroker, srcDpn.getSourceDpnId());
111 EVENT_LOGGER.debug("OfTep-DeleteWorker, DpnTep for {} removed", srcDpn.getSourceDpnId());
116 private void removeOfTepState(OfDpnTep srcDpn) {
117 LOG.trace("Removing ofTepstate for {} with tomstoned enable", srcDpn.getOfPortName());
118 directTunnelUtils.deleteOfTepStateEntry(srcDpn.getOfPortName());
121 private void removeOfTepInterfaceFromOvsdb(OfDpnTep dpnTep, TypedReadWriteTransaction<Configuration> tx) {
122 LOG.trace("Removing ofTep Interface {}", dpnTep.getOfPortName());
124 removeConfiguration(dpnTep, tx);
125 } catch (ExecutionException | InterruptedException | OperationFailedException e) {
126 LOG.error("Cannot Delete Tunnel {} as OVS Bridge Entry is NULL ", dpnTep.getTunnelType(), e);
130 private void removeConfiguration(OfDpnTep dpnsTep, TypedReadWriteTransaction<Configuration> tx)
131 throws ExecutionException, InterruptedException, OperationFailedException {
132 // Check if the same transaction can be used across Config and operational shards
133 removeTunnelConfiguration(dpnsTep, tx);
136 private void removeTunnelConfiguration(OfDpnTep dpnTep, TypedReadWriteTransaction<Configuration> tx)
137 throws ExecutionException, InterruptedException, OperationFailedException {
139 LOG.info("removing ofTep configuration for {}", dpnTep.getOfPortName());
141 Optional<OvsBridgeRefEntry> ovsBridgeRefEntry = ovsBridgeRefEntryCache.get(dpnTep.getSourceDpnId());
142 Optional<OvsBridgeEntry> ovsBridgeEntryOptional;
143 OvsdbBridgeRef ovsdbBridgeRef = null;
144 if (ovsBridgeRefEntry.isPresent()) {
145 ovsdbBridgeRef = ovsBridgeRefEntry.get().getOvsBridgeReference();
147 ovsBridgeEntryOptional = ovsBridgeEntryCache.get(dpnTep.getSourceDpnId());
148 if (ovsBridgeEntryOptional.isPresent()) {
149 ovsdbBridgeRef = ovsBridgeEntryOptional.get().getOvsBridgeReference();
153 if (ovsdbBridgeRef != null) {
154 removeTerminationEndPoint(ovsdbBridgeRef.getValue(), dpnTep.getOfPortName());
157 // delete tunnel ingress flow
158 removeOfPortIngressFlow(tx, dpnTep.getOfPortName(), dpnTep.getSourceDpnId());
160 // delete bridge to tunnel interface mappings
161 OvsBridgeEntryKey bridgeEntryKey = new OvsBridgeEntryKey(dpnTep.getSourceDpnId());
162 InstanceIdentifier<OvsBridgeEntry> bridgeEntryIid =
163 DirectTunnelUtils.getOvsBridgeEntryIdentifier(bridgeEntryKey);
165 ovsBridgeEntryOptional = ovsBridgeEntryCache.get(dpnTep.getSourceDpnId());
166 if (ovsBridgeEntryOptional.isPresent()) {
167 Map<OvsBridgeTunnelEntryKey, OvsBridgeTunnelEntry> bridgeTunnelEntries = ovsBridgeEntryOptional
168 .get().getOvsBridgeTunnelEntry();
169 deleteBridgeInterfaceEntry(bridgeEntryKey,
170 bridgeTunnelEntries.values().stream().collect(Collectors.toList()),
171 bridgeEntryIid, dpnTep.getOfPortName());
172 // IfIndex needs to be removed only during State Clean up not Config
173 cleanUpOfTepWithUnknownState(dpnTep.getOfPortName(), tx);
174 directTunnelUtils.removeLportTagInterfaceMap(dpnTep.getOfPortName());
178 private void removeTerminationEndPoint(InstanceIdentifier<?> bridgeIid, String ofPortName) {
179 LOG.debug("removing termination point for {}", ofPortName);
180 InstanceIdentifier<TerminationPoint> tpIid = DirectTunnelUtils.createTerminationPointInstanceIdentifier(
181 InstanceIdentifier.keyOf(bridgeIid.firstIdentifierOf(Node.class)), ofPortName);
182 ITMBatchingUtils.delete(tpIid, ITMBatchingUtils.EntityType.TOPOLOGY_CONFIG);
185 private void removeOfPortIngressFlow(TypedReadWriteTransaction<Configuration> tx,
187 Uint64 dpId) throws ExecutionException, InterruptedException {
188 directTunnelUtils.removeTunnelIngressFlow(tx, dpId, ofTepName);
191 private void deleteBridgeInterfaceEntry(OvsBridgeEntryKey bridgeEntryKey,
192 List<OvsBridgeTunnelEntry> bridgeTunnelEntries,
193 InstanceIdentifier<OvsBridgeEntry> bridgeEntryIid,
195 OvsBridgeTunnelEntryKey bridgeTunnelEntryKey = new OvsBridgeTunnelEntryKey(ofTepName);
196 InstanceIdentifier<OvsBridgeTunnelEntry> bridgeTunnelEntryIid =
197 DirectTunnelUtils.getBridgeTunnelEntryIdentifier(bridgeEntryKey, bridgeTunnelEntryKey);
198 ITMBatchingUtils.delete(bridgeTunnelEntryIid, ITMBatchingUtils.EntityType.DEFAULT_CONFIG);
199 if (bridgeTunnelEntries.size() <= 1) {
200 ITMBatchingUtils.delete(bridgeEntryIid, ITMBatchingUtils.EntityType.DEFAULT_CONFIG);
204 // if the node is shutdown, there will be stale ofTep state entries,
205 // with unknown op-state, clear them.
206 private void cleanUpOfTepWithUnknownState(String ofTepName, TypedReadWriteTransaction<Configuration> tx)
207 throws ReadFailedException {
208 Optional<OfTep> ofTepList = ofTepStateCache.get(ofTepName);
209 if (ofTepList.isPresent() && ofTepList.get().getOfTepState() == TunnelOperStatus.Unknown) {
210 LOG.debug("cleaning up dpnTep for {}, since the oper-status is {}", ofTepName,
211 ofTepList.get().getOfTepState());
212 directTunnelUtils.deleteOfTepStateEntry(ofTepName);