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 java.util.Collection;
11 import java.util.List;
13 import java.util.Objects;
14 import java.util.Optional;
15 import java.util.concurrent.ExecutionException;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.opendaylight.genius.infra.Datastore.Configuration;
18 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
19 import org.opendaylight.genius.infra.TypedWriteTransaction;
20 import org.opendaylight.genius.itm.globals.ITMConstants;
21 import org.opendaylight.genius.itm.impl.ItmUtils;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembershipKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.DeviceVteps;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Vteps;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.opendaylight.yangtools.yang.common.Uint64;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
43 public final class ItmExternalTunnelDeleteWorker {
44 private static final Logger LOG = LoggerFactory.getLogger(ItmExternalTunnelDeleteWorker.class);
46 private ItmExternalTunnelDeleteWorker() {
50 public static void deleteTunnels(Collection<DPNTEPsInfo> dpnTepsList, Collection<DPNTEPsInfo> meshedDpnList,
51 IpAddress extIp, Class<? extends TunnelTypeBase> tunType,
52 TypedWriteTransaction<Configuration> tx) {
53 LOG.trace(" Delete Tunnels towards DC Gateway with Ip {}", extIp);
54 if (dpnTepsList == null || dpnTepsList.isEmpty()) {
55 LOG.debug("no vtep to delete");
58 for (DPNTEPsInfo teps : dpnTepsList) {
59 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
60 // The membership in the listener will always be 1, to get the actual membership
62 @NonNull Map<TzMembershipKey, TzMembership> originalTzMembership =
63 ItmUtils.getOriginalTzMembership(firstEndPt, teps.getDPNID(), meshedDpnList);
64 if (originalTzMembership.size() == 1) {
65 String interfaceName = firstEndPt.getInterfaceName();
66 String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(interfaceName,
67 firstEndPt.getIpAddress().stringValue(), extIp.stringValue(), tunType.getName());
68 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkInterfaceName);
69 tx.delete(trunkIdentifier);
70 ItmUtils.ITM_CACHE.removeInterface(trunkInterfaceName);
72 InstanceIdentifier<ExternalTunnel> path =
73 InstanceIdentifier.create(ExternalTunnelList.class).child(ExternalTunnel.class,
74 ItmUtils.getExternalTunnelKey(extIp.stringValue(), teps.getDPNID().toString(), tunType));
76 LOG.debug("Deleting tunnel towards DC gateway, Tunnel interface name {} ", trunkInterfaceName);
77 ItmUtils.ITM_CACHE.removeExternalTunnel(trunkInterfaceName);
78 // Release the Ids for the trunk interface Name
79 ItmUtils.releaseIdForTrunkInterfaceName(interfaceName,
80 firstEndPt.getIpAddress().stringValue(), extIp.stringValue(), tunType.getName());
85 public static void deleteTunnels(Collection<DPNTEPsInfo> dpnTepsList, IpAddress extIp,
86 Class<? extends TunnelTypeBase> tunType, TypedWriteTransaction<Configuration> tx) {
87 LOG.trace(" Delete Tunnels towards DC Gateway with Ip {}", extIp);
89 if (dpnTepsList == null || dpnTepsList.isEmpty()) {
90 LOG.debug("no vtep to delete");
93 for (DPNTEPsInfo teps : dpnTepsList) {
94 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
95 String interfaceName = firstEndPt.getInterfaceName();
96 String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(interfaceName,
97 firstEndPt.getIpAddress().stringValue(), extIp.stringValue(), tunType.getName());
98 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkInterfaceName);
99 tx.delete(trunkIdentifier);
100 ItmUtils.ITM_CACHE.removeInterface(trunkInterfaceName);
102 InstanceIdentifier<ExternalTunnel> path =
103 InstanceIdentifier.create(ExternalTunnelList.class).child(ExternalTunnel.class,
104 ItmUtils.getExternalTunnelKey(extIp.stringValue(), teps.getDPNID().toString(), tunType));
106 LOG.debug("Deleting tunnel towards DC gateway, Tunnel interface name {} ", trunkInterfaceName);
107 ItmUtils.ITM_CACHE.removeExternalTunnel(trunkInterfaceName);
108 // Release the Ids for the trunk interface Name
109 ItmUtils.releaseIdForTrunkInterfaceName(interfaceName,
110 firstEndPt.getIpAddress().stringValue(), extIp.stringValue(), tunType.getName());
114 public static void deleteHwVtepsTunnels(List<DPNTEPsInfo> delDpnList, List<HwVtep> cfgdHwVteps,
115 TransportZone originalTZone, TypedReadWriteTransaction<Configuration> tx,
116 ItmConfig itmConfig) throws ExecutionException, InterruptedException {
117 if (delDpnList != null || cfgdHwVteps != null) {
118 tunnelsDeletion(delDpnList, cfgdHwVteps, originalTZone, tx, itmConfig);
122 private static void tunnelsDeletion(List<DPNTEPsInfo> cfgdDpnList, List<HwVtep> cfgdhwVteps,
123 TransportZone originalTZone, TypedReadWriteTransaction<Configuration> tx,
124 ItmConfig itmConfig) throws ExecutionException, InterruptedException {
125 if (cfgdDpnList != null) {
126 for (DPNTEPsInfo dpn : cfgdDpnList) {
127 if (dpn.getTunnelEndPoints() != null) {
128 for (TunnelEndPoints srcTep : dpn.getTunnelEndPoints()) {
129 for (TzMembership zone : srcTep.nonnullTzMembership().values()) {
130 deleteTunnelsInTransportZone(zone.getZoneName(), dpn, srcTep, cfgdhwVteps, tx);
137 if (cfgdhwVteps != null && !cfgdhwVteps.isEmpty()) {
138 for (HwVtep hwTep : cfgdhwVteps) {
139 LOG.trace("processing hwTep from list {}", hwTep);
140 for (HwVtep hwTepRemote : cfgdhwVteps) {
141 if (!hwTep.getHwIp().equals(hwTepRemote.getHwIp())) {
142 deleteTrunksTorTor(hwTep.getTopoId(), hwTep.getNodeId(), hwTep.getHwIp(),
143 hwTepRemote.getTopoId(), hwTepRemote.getNodeId(), hwTepRemote.getHwIp(),
144 TunnelTypeVxlan.class, tx);
147 // do we need to check tunnel type?
148 if (originalTZone.getDeviceVteps() != null) {
149 for (DeviceVteps hwVtepDS : originalTZone.getDeviceVteps().values()) {
150 LOG.trace("hwtepDS exists {}", hwVtepDS);
151 // do i need to check node-id?
152 // for mlag case and non-m-lag case, isnt it enough to just check ipaddress?
153 if (Objects.equals(hwVtepDS.getIpAddress(), hwTep.getHwIp())) {
154 continue;// dont delete tunnels with self
157 LOG.trace("deleting tor-tor {} and {}", hwTep, hwVtepDS);
158 deleteTrunksTorTor(hwTep.getTopoId(), hwTep.getNodeId(), hwTep.getHwIp(),
159 hwVtepDS.getTopologyId(), hwVtepDS.getNodeId(), hwVtepDS.getIpAddress(),
160 originalTZone.getTunnelType(), tx);
163 if (originalTZone.getVteps() != null) {
165 String portName = itmConfig.getPortname() == null ? ITMConstants.DUMMY_PORT
166 : itmConfig.getPortname();
167 int vlanId = itmConfig.getVlanId() != null ? itmConfig.getVlanId().toJava()
168 : ITMConstants.DUMMY_VLANID;
170 for (Vteps vtep : originalTZone.getVteps().values()) {
172 LOG.trace("deleting tor-css-tor {} and {}", hwTep, vtep);
173 String parentIf = ItmUtils.getInterfaceName(vtep.getDpnId(), portName, vlanId);
174 deleteTrunksOvsTor(vtep.getDpnId(), parentIf,
175 vtep.getIpAddress(), hwTep.getTopoId(), hwTep.getNodeId(), hwTep.getHwIp(),
176 originalTZone.getTunnelType(), tx);
183 private static void deleteTunnelsInTransportZone(String zoneName, DPNTEPsInfo dpn, TunnelEndPoints srcTep,
184 List<HwVtep> cfgdhwVteps, TypedReadWriteTransaction<Configuration> tx)
185 throws InterruptedException, ExecutionException {
186 InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
187 .child(TransportZone.class, new TransportZoneKey(zoneName)).build();
188 Optional<TransportZone> tz = tx.read(tzonePath).get();
189 if (tz.isPresent()) {
190 TransportZone tzone = tz.get();
191 // do we need to check tunnel type?
192 if (tzone.getDeviceVteps() != null) {
193 for (DeviceVteps hwVtepDS : tzone.getDeviceVteps().values()) {
195 deleteTrunksOvsTor(dpn.getDPNID(), srcTep.getInterfaceName(),
196 srcTep.getIpAddress(), hwVtepDS.getTopologyId(), hwVtepDS.getNodeId(),
197 hwVtepDS.getIpAddress(), tzone.getTunnelType(), tx);
201 if (cfgdhwVteps != null && !cfgdhwVteps.isEmpty()) {
202 for (HwVtep hwVtep : cfgdhwVteps) {
203 deleteTrunksOvsTor(dpn.getDPNID(), srcTep.getInterfaceName(),
204 srcTep.getIpAddress(), hwVtep.getTopoId(), hwVtep.getNodeId(), hwVtep.getHwIp(),
205 TunnelTypeVxlan.class, tx);
211 private static void deleteTrunksOvsTor(Uint64 dpnid, String interfaceName, IpAddress cssIpAddress,
212 String topologyId, String nodeId, IpAddress hwIpAddress, Class<? extends TunnelTypeBase> tunType,
213 TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
215 if (trunkExists(dpnid.toString(), nodeId, tunType, tx)) {
216 LOG.trace("deleting tunnel from {} to {} ", dpnid.toString(), nodeId);
217 String parentIf = interfaceName;
218 String fwdTrunkIf = ItmUtils.getTrunkInterfaceName(parentIf,
219 cssIpAddress.stringValue(), hwIpAddress.stringValue(), tunType.getName());
220 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(fwdTrunkIf);
221 tx.delete(trunkIdentifier);
223 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
224 .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(nodeId, dpnid.toString(), tunType));
227 LOG.trace(" trunk from {} to {} already deleted", dpnid.toString(), nodeId);
230 if (trunkExists(nodeId, dpnid.toString(), tunType, tx)) {
231 LOG.trace("deleting tunnel from {} to {} ", nodeId, dpnid.toString());
233 String parentIf = ItmUtils.getHwParentIf(topologyId, nodeId);
234 String revTrunkIf = ItmUtils.getTrunkInterfaceName(parentIf,
235 hwIpAddress.stringValue(), cssIpAddress.stringValue(), tunType.getName());
236 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(revTrunkIf);
237 tx.delete(trunkIdentifier);
239 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
240 .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(dpnid.toString(), nodeId, tunType));
243 LOG.trace(" trunk from {} to {} already deleted", nodeId, dpnid.toString());
247 private static void deleteTrunksTorTor(String topologyId1, String nodeId1, IpAddress hwIpAddress1,
248 String topologyId2, String nodeId2, IpAddress hwIpAddress2, Class<? extends TunnelTypeBase> tunType,
249 TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
251 if (trunkExists(nodeId1, nodeId2, tunType, tx)) {
252 LOG.trace("deleting tunnel from {} to {} ", nodeId1, nodeId2);
253 String parentIf = ItmUtils.getHwParentIf(topologyId1, nodeId1);
254 String fwdTrunkIf = ItmUtils.getTrunkInterfaceName(parentIf,
255 hwIpAddress1.stringValue(), hwIpAddress2.stringValue(), tunType.getName());
256 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(fwdTrunkIf);
257 tx.delete(trunkIdentifier);
259 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
260 .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(nodeId2, nodeId1, tunType));
263 LOG.trace(" trunk from {} to {} already deleted", nodeId1, nodeId2);
266 if (trunkExists(nodeId2, nodeId1, tunType, tx)) {
267 LOG.trace("deleting tunnel from {} to {} ", nodeId2, nodeId1);
269 String parentIf = ItmUtils.getHwParentIf(topologyId2, nodeId2);
270 String revTrunkIf = ItmUtils.getTrunkInterfaceName(parentIf,
271 hwIpAddress2.stringValue(), hwIpAddress1.stringValue(), tunType.getName());
272 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(revTrunkIf);
273 tx.delete(trunkIdentifier);
275 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
276 .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(nodeId1, nodeId2, tunType));
279 LOG.trace(" trunk from {} to {} already deleted", nodeId2, nodeId1);
283 private static boolean trunkExists(String srcDpnOrNode, String dstDpnOrNode,
284 Class<? extends TunnelTypeBase> tunType,
285 TypedReadWriteTransaction<Configuration> tx)
286 throws ExecutionException, InterruptedException {
287 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
288 .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(dstDpnOrNode, srcDpnOrNode, tunType));
289 return tx.exists(path).get();