Convert itm-impl to use mdsal-binding-util
[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.Map;
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.itm.globals.ITMConstants;
18 import org.opendaylight.genius.itm.impl.ItmUtils;
19 import org.opendaylight.mdsal.binding.util.Datastore.Configuration;
20 import org.opendaylight.mdsal.binding.util.TypedReadWriteTransaction;
21 import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
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;
42
43 public final class ItmExternalTunnelDeleteWorker {
44     private static final Logger LOG = LoggerFactory.getLogger(ItmExternalTunnelDeleteWorker.class);
45
46     private ItmExternalTunnelDeleteWorker() {
47
48     }
49
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");
56             return;
57         }
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
61             // read from the DS
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);
71
72                 InstanceIdentifier<ExternalTunnel> path =
73                         InstanceIdentifier.create(ExternalTunnelList.class).child(ExternalTunnel.class,
74                                ItmUtils.getExternalTunnelKey(extIp.stringValue(), teps.getDPNID().toString(), tunType));
75                 tx.delete(path);
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());
81             }
82         }
83     }
84
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);
88
89         if (dpnTepsList == null || dpnTepsList.isEmpty()) {
90             LOG.debug("no vtep to delete");
91             return;
92         }
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);
101
102             InstanceIdentifier<ExternalTunnel> path =
103                     InstanceIdentifier.create(ExternalTunnelList.class).child(ExternalTunnel.class,
104                             ItmUtils.getExternalTunnelKey(extIp.stringValue(), teps.getDPNID().toString(), tunType));
105             tx.delete(path);
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());
111         }
112     }
113
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);
119         }
120     }
121
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);
131                         }
132                     }
133                 }
134             }
135         }
136
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);
145                     }
146                 }
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
155                         }
156                         // TOR-TOR
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);
161                     }
162                 }
163                 if (originalTZone.getVteps() != null) {
164
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;
169
170                     for (Vteps vtep : originalTZone.getVteps().values()) {
171                         // TOR-OVS
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);
177                     }
178                 }
179             }
180         }
181     }
182
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()) {
194                     // OVS-TOR-OVS
195                     deleteTrunksOvsTor(dpn.getDPNID(), srcTep.getInterfaceName(),
196                             srcTep.getIpAddress(), hwVtepDS.getTopologyId(), hwVtepDS.getNodeId(),
197                             hwVtepDS.getIpAddress(), tzone.getTunnelType(), tx);
198                 }
199             }
200
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);
206                 }
207             }
208         }
209     }
210
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 {
214         // OVS-TOR
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);
222
223             InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
224                     .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(nodeId, dpnid.toString(), tunType));
225             tx.delete(path);
226         } else {
227             LOG.trace(" trunk from {} to {} already deleted", dpnid.toString(), nodeId);
228         }
229         // TOR-OVS
230         if (trunkExists(nodeId, dpnid.toString(), tunType, tx)) {
231             LOG.trace("deleting tunnel from {} to {} ", nodeId, dpnid.toString());
232
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);
238
239             InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
240                     .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(dpnid.toString(), nodeId, tunType));
241             tx.delete(path);
242         } else {
243             LOG.trace(" trunk from {} to {} already deleted", nodeId, dpnid.toString());
244         }
245     }
246
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 {
250         // TOR1-TOR2
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);
258
259             InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
260                     .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(nodeId2, nodeId1, tunType));
261             tx.delete(path);
262         } else {
263             LOG.trace(" trunk from {} to {} already deleted", nodeId1, nodeId2);
264         }
265         // TOR2-TOR1
266         if (trunkExists(nodeId2, nodeId1, tunType, tx)) {
267             LOG.trace("deleting tunnel from {} to {} ", nodeId2, nodeId1);
268
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);
274
275             InstanceIdentifier<ExternalTunnel> path = InstanceIdentifier.create(ExternalTunnelList.class)
276                     .child(ExternalTunnel.class, ItmUtils.getExternalTunnelKey(nodeId1, nodeId2, tunType));
277             tx.delete(path);
278         } else {
279             LOG.trace(" trunk from {} to {} already deleted", nodeId2, nodeId1);
280         }
281     }
282
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();
290     }
291 }