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;
12 import java.util.Objects;
13 import java.util.Optional;
14 import java.util.concurrent.ExecutionException;
15 import org.opendaylight.genius.infra.Datastore.Configuration;
16 import org.opendaylight.genius.infra.TypedReadWriteTransaction;
17 import org.opendaylight.genius.infra.TypedWriteTransaction;
18 import org.opendaylight.genius.itm.globals.ITMConstants;
19 import org.opendaylight.genius.itm.impl.ItmUtils;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.config.rev160406.ItmConfig;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.ExternalTunnelList;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.DPNTEPsInfo;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.TunnelEndPoints;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.dpn.endpoints.dpn.teps.info.tunnel.end.points.TzMembership;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.external.tunnel.list.ExternalTunnel;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.TransportZones;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZone;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.TransportZoneKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.DeviceVteps;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rev160406.transport.zones.transport.zone.Vteps;
35 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
36 import org.opendaylight.yangtools.yang.common.Uint64;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
40 public final class ItmExternalTunnelDeleteWorker {
41 private static final Logger LOG = LoggerFactory.getLogger(ItmExternalTunnelDeleteWorker.class);
43 private ItmExternalTunnelDeleteWorker() {
47 public static void deleteTunnels(Collection<DPNTEPsInfo> dpnTepsList, Collection<DPNTEPsInfo> meshedDpnList,
48 IpAddress extIp, Class<? extends TunnelTypeBase> tunType,
49 TypedWriteTransaction<Configuration> tx) {
50 LOG.trace(" Delete Tunnels towards DC Gateway with Ip {}", extIp);
51 if (dpnTepsList == null || dpnTepsList.isEmpty()) {
52 LOG.debug("no vtep to delete");
55 for (DPNTEPsInfo teps : dpnTepsList) {
56 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
57 // The membership in the listener will always be 1, to get the actual membership
59 List<TzMembership> originalTzMembership = ItmUtils.getOriginalTzMembership(firstEndPt,
60 teps.getDPNID(), meshedDpnList);
61 if (originalTzMembership.size() == 1) {
62 String interfaceName = firstEndPt.getInterfaceName();
63 String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(interfaceName,
64 firstEndPt.getIpAddress().stringValue(), extIp.stringValue(), tunType.getName());
65 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkInterfaceName);
66 tx.delete(trunkIdentifier);
67 ItmUtils.ITM_CACHE.removeInterface(trunkInterfaceName);
69 InstanceIdentifier<ExternalTunnel> path =
70 InstanceIdentifier.create(ExternalTunnelList.class).child(ExternalTunnel.class,
71 ItmUtils.getExternalTunnelKey(extIp.stringValue(), teps.getDPNID().toString(), tunType));
73 LOG.debug("Deleting tunnel towards DC gateway, Tunnel interface name {} ", trunkInterfaceName);
74 ItmUtils.ITM_CACHE.removeExternalTunnel(trunkInterfaceName);
75 // Release the Ids for the trunk interface Name
76 ItmUtils.releaseIdForTrunkInterfaceName(interfaceName,
77 firstEndPt.getIpAddress().stringValue(), extIp.stringValue(), tunType.getName());
82 public static void deleteTunnels(Collection<DPNTEPsInfo> dpnTepsList, IpAddress extIp,
83 Class<? extends TunnelTypeBase> tunType, TypedWriteTransaction<Configuration> tx) {
84 LOG.trace(" Delete Tunnels towards DC Gateway with Ip {}", extIp);
86 if (dpnTepsList == null || dpnTepsList.isEmpty()) {
87 LOG.debug("no vtep to delete");
90 for (DPNTEPsInfo teps : dpnTepsList) {
91 TunnelEndPoints firstEndPt = teps.getTunnelEndPoints().get(0);
92 String interfaceName = firstEndPt.getInterfaceName();
93 String trunkInterfaceName = ItmUtils.getTrunkInterfaceName(interfaceName,
94 firstEndPt.getIpAddress().stringValue(), extIp.stringValue(), tunType.getName());
95 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(trunkInterfaceName);
96 tx.delete(trunkIdentifier);
97 ItmUtils.ITM_CACHE.removeInterface(trunkInterfaceName);
99 InstanceIdentifier<ExternalTunnel> path =
100 InstanceIdentifier.create(ExternalTunnelList.class).child(ExternalTunnel.class,
101 ItmUtils.getExternalTunnelKey(extIp.stringValue(), teps.getDPNID().toString(), tunType));
103 LOG.debug("Deleting tunnel towards DC gateway, Tunnel interface name {} ", trunkInterfaceName);
104 ItmUtils.ITM_CACHE.removeExternalTunnel(trunkInterfaceName);
105 // Release the Ids for the trunk interface Name
106 ItmUtils.releaseIdForTrunkInterfaceName(interfaceName,
107 firstEndPt.getIpAddress().stringValue(), extIp.stringValue(), tunType.getName());
111 public static void deleteHwVtepsTunnels(List<DPNTEPsInfo> delDpnList, List<HwVtep> cfgdHwVteps,
112 TransportZone originalTZone, TypedReadWriteTransaction<Configuration> tx,
113 ItmConfig itmConfig) throws ExecutionException, InterruptedException {
114 if (delDpnList != null || cfgdHwVteps != null) {
115 tunnelsDeletion(delDpnList, cfgdHwVteps, originalTZone, tx, itmConfig);
119 private static void tunnelsDeletion(List<DPNTEPsInfo> cfgdDpnList, List<HwVtep> cfgdhwVteps,
120 TransportZone originalTZone, TypedReadWriteTransaction<Configuration> tx,
121 ItmConfig itmConfig) throws ExecutionException, InterruptedException {
122 if (cfgdDpnList != null) {
123 for (DPNTEPsInfo dpn : cfgdDpnList) {
124 if (dpn.getTunnelEndPoints() != null) {
125 for (TunnelEndPoints srcTep : dpn.getTunnelEndPoints()) {
126 for (TzMembership zone : srcTep.nonnullTzMembership()) {
127 deleteTunnelsInTransportZone(zone.getZoneName(), dpn, srcTep, cfgdhwVteps, tx);
134 if (cfgdhwVteps != null && !cfgdhwVteps.isEmpty()) {
135 for (HwVtep hwTep : cfgdhwVteps) {
136 LOG.trace("processing hwTep from list {}", hwTep);
137 for (HwVtep hwTepRemote : cfgdhwVteps) {
138 if (!hwTep.getHwIp().equals(hwTepRemote.getHwIp())) {
139 deleteTrunksTorTor(hwTep.getTopoId(), hwTep.getNodeId(), hwTep.getHwIp(),
140 hwTepRemote.getTopoId(), hwTepRemote.getNodeId(), hwTepRemote.getHwIp(),
141 TunnelTypeVxlan.class, tx);
144 // do we need to check tunnel type?
145 if (originalTZone.getDeviceVteps() != null) {
146 for (DeviceVteps hwVtepDS : originalTZone.getDeviceVteps()) {
147 LOG.trace("hwtepDS exists {}", hwVtepDS);
148 // do i need to check node-id?
149 // for mlag case and non-m-lag case, isnt it enough to just check ipaddress?
150 if (Objects.equals(hwVtepDS.getIpAddress(), hwTep.getHwIp())) {
151 continue;// dont delete tunnels with self
154 LOG.trace("deleting tor-tor {} and {}", hwTep, hwVtepDS);
155 deleteTrunksTorTor(hwTep.getTopoId(), hwTep.getNodeId(), hwTep.getHwIp(),
156 hwVtepDS.getTopologyId(), hwVtepDS.getNodeId(), hwVtepDS.getIpAddress(),
157 originalTZone.getTunnelType(), tx);
160 if (originalTZone.getVteps() != null) {
162 String portName = itmConfig.getPortname() == null ? ITMConstants.DUMMY_PORT
163 : itmConfig.getPortname();
164 int vlanId = itmConfig.getVlanId() != null ? itmConfig.getVlanId().toJava()
165 : ITMConstants.DUMMY_VLANID;
167 for (Vteps vtep : originalTZone.getVteps()) {
169 LOG.trace("deleting tor-css-tor {} and {}", hwTep, vtep);
170 String parentIf = ItmUtils.getInterfaceName(vtep.getDpnId(), portName, vlanId);
171 deleteTrunksOvsTor(vtep.getDpnId(), parentIf,
172 vtep.getIpAddress(), hwTep.getTopoId(), hwTep.getNodeId(), hwTep.getHwIp(),
173 originalTZone.getTunnelType(), tx);
180 private static void deleteTunnelsInTransportZone(String zoneName, DPNTEPsInfo dpn, TunnelEndPoints srcTep,
181 List<HwVtep> cfgdhwVteps, TypedReadWriteTransaction<Configuration> tx)
182 throws InterruptedException, ExecutionException {
183 InstanceIdentifier<TransportZone> tzonePath = InstanceIdentifier.builder(TransportZones.class)
184 .child(TransportZone.class, new TransportZoneKey(zoneName)).build();
185 Optional<TransportZone> tz = tx.read(tzonePath).get();
186 if (tz.isPresent()) {
187 TransportZone tzone = tz.get();
188 // do we need to check tunnel type?
189 if (tzone.getDeviceVteps() != null) {
190 for (DeviceVteps hwVtepDS : tzone.getDeviceVteps()) {
192 deleteTrunksOvsTor(dpn.getDPNID(), srcTep.getInterfaceName(),
193 srcTep.getIpAddress(), hwVtepDS.getTopologyId(), hwVtepDS.getNodeId(),
194 hwVtepDS.getIpAddress(), tzone.getTunnelType(), tx);
198 if (cfgdhwVteps != null && !cfgdhwVteps.isEmpty()) {
199 for (HwVtep hwVtep : cfgdhwVteps) {
200 deleteTrunksOvsTor(dpn.getDPNID(), srcTep.getInterfaceName(),
201 srcTep.getIpAddress(), hwVtep.getTopoId(), hwVtep.getNodeId(), hwVtep.getHwIp(),
202 TunnelTypeVxlan.class, tx);
208 private static void deleteTrunksOvsTor(Uint64 dpnid, String interfaceName, IpAddress cssIpAddress,
209 String topologyId, String nodeId, IpAddress hwIpAddress, Class<? extends TunnelTypeBase> tunType,
210 TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
212 if (trunkExists(dpnid.toString(), nodeId, tunType, tx)) {
213 LOG.trace("deleting tunnel from {} to {} ", dpnid.toString(), nodeId);
214 String parentIf = interfaceName;
215 String fwdTrunkIf = ItmUtils.getTrunkInterfaceName(parentIf,
216 cssIpAddress.stringValue(), hwIpAddress.stringValue(), tunType.getName());
217 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(fwdTrunkIf);
218 tx.delete(trunkIdentifier);
220 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
221 .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(nodeId, dpnid.toString(), tunType));
224 LOG.trace(" trunk from {} to {} already deleted", dpnid.toString(), nodeId);
227 if (trunkExists(nodeId, dpnid.toString(), tunType, tx)) {
228 LOG.trace("deleting tunnel from {} to {} ", nodeId, dpnid.toString());
230 String parentIf = ItmUtils.getHwParentIf(topologyId, nodeId);
231 String revTrunkIf = ItmUtils.getTrunkInterfaceName(parentIf,
232 hwIpAddress.stringValue(), cssIpAddress.stringValue(), tunType.getName());
233 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(revTrunkIf);
234 tx.delete(trunkIdentifier);
236 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
237 .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(dpnid.toString(), nodeId, tunType));
240 LOG.trace(" trunk from {} to {} already deleted", nodeId, dpnid.toString());
244 private static void deleteTrunksTorTor(String topologyId1, String nodeId1, IpAddress hwIpAddress1,
245 String topologyId2, String nodeId2, IpAddress hwIpAddress2, Class<? extends TunnelTypeBase> tunType,
246 TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
248 if (trunkExists(nodeId1, nodeId2, tunType, tx)) {
249 LOG.trace("deleting tunnel from {} to {} ", nodeId1, nodeId2);
250 String parentIf = ItmUtils.getHwParentIf(topologyId1, nodeId1);
251 String fwdTrunkIf = ItmUtils.getTrunkInterfaceName(parentIf,
252 hwIpAddress1.stringValue(), hwIpAddress2.stringValue(), tunType.getName());
253 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(fwdTrunkIf);
254 tx.delete(trunkIdentifier);
256 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
257 .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(nodeId2, nodeId1, tunType));
260 LOG.trace(" trunk from {} to {} already deleted", nodeId1, nodeId2);
263 if (trunkExists(nodeId2, nodeId1, tunType, tx)) {
264 LOG.trace("deleting tunnel from {} to {} ", nodeId2, nodeId1);
266 String parentIf = ItmUtils.getHwParentIf(topologyId2, nodeId2);
267 String revTrunkIf = ItmUtils.getTrunkInterfaceName(parentIf,
268 hwIpAddress2.stringValue(), hwIpAddress1.stringValue(), tunType.getName());
269 InstanceIdentifier<Interface> trunkIdentifier = ItmUtils.buildId(revTrunkIf);
270 tx.delete(trunkIdentifier);
272 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
273 .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(nodeId1, nodeId2, tunType));
276 LOG.trace(" trunk from {} to {} already deleted", nodeId2, nodeId1);
280 private static boolean trunkExists(String srcDpnOrNode, String dstDpnOrNode,
281 Class<? extends TunnelTypeBase> tunType,
282 TypedReadWriteTransaction<Configuration> tx)
283 throws ExecutionException, InterruptedException {
284 InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
285 .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(dstDpnOrNode, srcDpnOrNode, tunType));
286 return tx.exists(path).get();