eafc097d75e66540985580845dd165ee3577cac0
[genius.git] / itm / itm-impl / src / main / java / org / opendaylight / genius / itm / confighelpers / ItmExternalTunnelDeleteWorker.java
1 /*
2  * Copyright (c) 2016, 2017 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.genius.itm.confighelpers;
9
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;
39
40 public final class ItmExternalTunnelDeleteWorker {
41     private static final Logger LOG = LoggerFactory.getLogger(ItmExternalTunnelDeleteWorker.class);
42
43     private ItmExternalTunnelDeleteWorker() {
44
45     }
46
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");
53             return;
54         }
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
58             // read from the DS
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);
68
69                 InstanceIdentifier<ExternalTunnel> path =
70                         InstanceIdentifier.create(ExternalTunnelList.class).child(ExternalTunnel.class,
71                                ItmUtils.getExternalTunnelKey(extIp.stringValue(), teps.getDPNID().toString(), tunType));
72                 tx.delete(path);
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());
78             }
79         }
80     }
81
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);
85
86         if (dpnTepsList == null || dpnTepsList.isEmpty()) {
87             LOG.debug("no vtep to delete");
88             return;
89         }
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);
98
99             InstanceIdentifier<ExternalTunnel> path =
100                     InstanceIdentifier.create(ExternalTunnelList.class).child(ExternalTunnel.class,
101                             ItmUtils.getExternalTunnelKey(extIp.stringValue(), teps.getDPNID().toString(), tunType));
102             tx.delete(path);
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());
108         }
109     }
110
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);
116         }
117     }
118
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);
128                         }
129                     }
130                 }
131             }
132         }
133
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);
142                     }
143                 }
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
152                         }
153                         // TOR-TOR
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);
158                     }
159                 }
160                 if (originalTZone.getVteps() != null) {
161
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;
166
167                     for (Vteps vtep : originalTZone.getVteps()) {
168                         // TOR-OVS
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);
174                     }
175                 }
176             }
177         }
178     }
179
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()) {
191                     // OVS-TOR-OVS
192                     deleteTrunksOvsTor(dpn.getDPNID(), srcTep.getInterfaceName(),
193                             srcTep.getIpAddress(), hwVtepDS.getTopologyId(), hwVtepDS.getNodeId(),
194                             hwVtepDS.getIpAddress(), tzone.getTunnelType(), tx);
195                 }
196             }
197
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);
203                 }
204             }
205         }
206     }
207
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 {
211         // OVS-TOR
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);
219
220             InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
221                     .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(nodeId, dpnid.toString(), tunType));
222             tx.delete(path);
223         } else {
224             LOG.trace(" trunk from {} to {} already deleted", dpnid.toString(), nodeId);
225         }
226         // TOR-OVS
227         if (trunkExists(nodeId, dpnid.toString(), tunType, tx)) {
228             LOG.trace("deleting tunnel from {} to {} ", nodeId, dpnid.toString());
229
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);
235
236             InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
237                     .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(dpnid.toString(), nodeId, tunType));
238             tx.delete(path);
239         } else {
240             LOG.trace(" trunk from {} to {} already deleted", nodeId, dpnid.toString());
241         }
242     }
243
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 {
247         // TOR1-TOR2
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);
255
256             InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
257                     .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(nodeId2, nodeId1, tunType));
258             tx.delete(path);
259         } else {
260             LOG.trace(" trunk from {} to {} already deleted", nodeId1, nodeId2);
261         }
262         // TOR2-TOR1
263         if (trunkExists(nodeId2, nodeId1, tunType, tx)) {
264             LOG.trace("deleting tunnel from {} to {} ", nodeId2, nodeId1);
265
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);
271
272             InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
273                     .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(nodeId1, nodeId2, tunType));
274             tx.delete(path);
275         } else {
276             LOG.trace(" trunk from {} to {} already deleted", nodeId2, nodeId1);
277         }
278     }
279
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();
287     }
288 }