Fixup Augmentable and Identifiable methods changing
[netvirt.git] / elanmanager / impl / src / main / java / org / opendaylight / netvirt / elan / l2gw / utils / L2GatewayConnectionUtils.java
1 /*
2  * Copyright (c) 2016 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
9 package org.opendaylight.netvirt.elan.l2gw.utils;
10
11 import static org.opendaylight.netvirt.elan.utils.ElanUtils.isVxlanNetworkOrVxlanSegment;
12
13 import com.google.common.base.Optional;
14 import com.google.common.collect.Lists;
15 import com.google.common.util.concurrent.Futures;
16 import com.google.common.util.concurrent.MoreExecutors;
17 import com.google.common.util.concurrent.SettableFuture;
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.List;
21 import java.util.Set;
22 import java.util.concurrent.CopyOnWriteArrayList;
23 import javax.annotation.Nonnull;
24 import javax.annotation.PreDestroy;
25 import javax.inject.Inject;
26 import javax.inject.Singleton;
27 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
28 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
29 import org.opendaylight.genius.mdsalutil.MDSALUtil;
30 import org.opendaylight.genius.utils.hwvtep.HwvtepNodeHACache;
31 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
32 import org.opendaylight.genius.utils.hwvtep.HwvtepUtils;
33 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
34 import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
35 import org.opendaylight.netvirt.elan.l2gw.ha.listeners.HAOpClusteredListener;
36 import org.opendaylight.netvirt.elan.l2gw.jobs.AssociateHwvtepToElanJob;
37 import org.opendaylight.netvirt.elan.l2gw.jobs.DisAssociateHwvtepFromElanJob;
38 import org.opendaylight.netvirt.elan.l2gw.listeners.HwvtepLogicalSwitchListener;
39 import org.opendaylight.netvirt.elan.l2gw.listeners.LocalUcastMacListener;
40 import org.opendaylight.netvirt.elan.utils.ElanClusterUtils;
41 import org.opendaylight.netvirt.elanmanager.utils.ElanL2GwCacheUtils;
42 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayCache;
43 import org.opendaylight.netvirt.neutronvpn.api.l2gw.L2GatewayDevice;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.Devices;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.L2gatewayConnections;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.connections.attributes.l2gatewayconnections.L2gatewayConnection;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.L2gateways;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gateway;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateways.attributes.l2gateways.L2gatewayKey;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepGlobalAugmentation;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
56 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
57 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
58 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
61
62 @Singleton
63 public class L2GatewayConnectionUtils implements AutoCloseable {
64     private static final Logger LOG = LoggerFactory.getLogger(L2GatewayConnectionUtils.class);
65
66     private final DataBroker broker;
67     private final ElanL2GatewayUtils elanL2GatewayUtils;
68     private final ElanClusterUtils elanClusterUtils;
69     private final ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils;
70     private final JobCoordinator jobCoordinator;
71     private final L2GatewayCache l2GatewayCache;
72     private final ElanInstanceCache elanInstanceCache;
73     private final List<AutoCloseable> closeables = new CopyOnWriteArrayList<>();
74     private final HwvtepNodeHACache hwvtepNodeHACache;
75     private final HAOpClusteredListener haOpClusteredListener;
76
77     @Inject
78     public L2GatewayConnectionUtils(DataBroker dataBroker,
79             ElanClusterUtils elanClusterUtils, ElanL2GatewayUtils elanL2GatewayUtils,
80             JobCoordinator jobCoordinator, ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils,
81             L2GatewayCache l2GatewayCache, HAOpClusteredListener haOpClusteredListener,
82             ElanInstanceCache elanInstanceCache, HwvtepNodeHACache hwvtepNodeHACache) {
83         this.broker = dataBroker;
84         this.elanL2GatewayUtils = elanL2GatewayUtils;
85         this.elanClusterUtils = elanClusterUtils;
86         this.elanL2GatewayMulticastUtils = elanL2GatewayMulticastUtils;
87         this.jobCoordinator = jobCoordinator;
88         this.l2GatewayCache = l2GatewayCache;
89         this.haOpClusteredListener = haOpClusteredListener;
90         this.elanInstanceCache = elanInstanceCache;
91         this.hwvtepNodeHACache = hwvtepNodeHACache;
92     }
93
94     @Override
95     @PreDestroy
96     @SuppressWarnings("checkstyle:IllegalCatch")
97     public void close() {
98         closeables.forEach(c -> {
99             try {
100                 c.close();
101             } catch (Exception e) {
102                 LOG.warn("Error closing {}", c, e);
103             }
104         });
105     }
106
107     public static boolean isGatewayAssociatedToL2Device(L2GatewayDevice l2GwDevice) {
108         return l2GwDevice.getL2GatewayIds().size() > 0;
109     }
110
111     public static L2gateway getNeutronL2gateway(DataBroker broker, Uuid l2GatewayId) {
112         LOG.debug("getNeutronL2gateway for {}", l2GatewayId.getValue());
113         InstanceIdentifier<L2gateway> inst = InstanceIdentifier.create(Neutron.class).child(L2gateways.class)
114                 .child(L2gateway.class, new L2gatewayKey(l2GatewayId));
115         return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, inst).orNull();
116     }
117
118     @Nonnull
119     public static List<L2gateway> getL2gatewayList(DataBroker broker) {
120         InstanceIdentifier<L2gateways> inst = InstanceIdentifier.create(Neutron.class).child(L2gateways.class);
121         return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, inst).toJavaUtil().map(
122                 L2gateways::getL2gateway).orElse(Collections.emptyList());
123     }
124
125     @Nonnull
126     public static List<L2gatewayConnection> getAllL2gatewayConnections(DataBroker broker) {
127         InstanceIdentifier<L2gatewayConnections> inst = InstanceIdentifier.create(Neutron.class)
128                 .child(L2gatewayConnections.class);
129         return MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, inst).toJavaUtil().map(
130                 L2gatewayConnections::getL2gatewayConnection).orElse(Collections.emptyList());
131     }
132
133     /**
134      * Gets the associated l2 gw connections.
135      *
136      * @param broker
137      *            the broker
138      * @param l2GatewayIds
139      *            the l2 gateway ids
140      * @return the associated l2 gw connections
141      */
142     @Nonnull
143     public static List<L2gatewayConnection> getAssociatedL2GwConnections(DataBroker broker, Set<Uuid> l2GatewayIds) {
144         List<L2gatewayConnection> allL2GwConns = getAllL2gatewayConnections(broker);
145         List<L2gatewayConnection> l2GwConnections = new ArrayList<>();
146         for (Uuid l2GatewayId : l2GatewayIds) {
147             for (L2gatewayConnection l2GwConn : allL2GwConns) {
148                 if (l2GwConn.getL2gatewayId().equals(l2GatewayId)) {
149                     l2GwConnections.add(l2GwConn);
150                 }
151             }
152         }
153         return l2GwConnections;
154     }
155
156     /**
157      * Gets the associated l2 gw connections.
158      *
159      * @param broker
160      *            the broker
161      * @param elanName
162      *            the elan Name
163      * @return the associated l2 gw connection with elan
164      */
165     @Nonnull
166     public static List<L2gatewayConnection> getL2GwConnectionsByElanName(DataBroker broker, String elanName) {
167         List<L2gatewayConnection> allL2GwConns = getAllL2gatewayConnections(broker);
168         List<L2gatewayConnection> elanL2GateWayConnections = new ArrayList<>();
169         for (L2gatewayConnection l2GwConn : allL2GwConns) {
170             if (l2GwConn.getNetworkId().getValue().equalsIgnoreCase(elanName)) {
171                 elanL2GateWayConnections.add(l2GwConn);
172             }
173         }
174         return elanL2GateWayConnections;
175     }
176
177     public void addL2GatewayConnection(L2gatewayConnection input) {
178         addL2GatewayConnection(input, null/*deviceName*/, null);
179     }
180
181     public void addL2GatewayConnection(final L2gatewayConnection input,
182                                        final String l2GwDeviceName) {
183         addL2GatewayConnection(input, l2GwDeviceName, null);
184     }
185
186     public void addL2GatewayConnection(final L2gatewayConnection input,
187                                        final String l2GwDeviceName ,
188                                        L2gateway l2Gateway) {
189         LOG.info("Adding L2gateway Connection with ID: {}", input.key().getUuid());
190
191         Uuid networkUuid = input.getNetworkId();
192
193         // Taking cluster reboot scenario , if Elan instance is not available when l2GatewayConnection add events
194         // comes we need to wait for elaninstance to resolve. Hence updating the map with the runnable .
195         // When elanInstance add comes , it look in to the map and run the associated runnable associated with it.
196         ElanInstance elanInstance = elanInstanceCache.get(networkUuid.getValue(),
197             () -> addL2GatewayConnection(input, l2GwDeviceName)).orNull();
198         if (elanInstance == null) {
199             return;
200         }
201
202         if (!isVxlanNetworkOrVxlanSegment(elanInstance)) {
203             LOG.error("Neutron network with id {} is not VxlanNetwork", networkUuid.getValue());
204         } else {
205             Uuid l2GatewayId = input.getL2gatewayId();
206             if (l2Gateway == null) {
207                 l2Gateway = getNeutronL2gateway(broker, l2GatewayId);
208             }
209             if (l2Gateway == null) {
210                 LOG.error("L2Gateway with id {} is not present", l2GatewayId.getValue());
211             } else {
212                 associateHwvtepsToElan(elanInstance, l2Gateway, input, l2GwDeviceName);
213             }
214         }
215     }
216
217     public void deleteL2GatewayConnection(L2gatewayConnection input) {
218         LOG.info("Deleting L2gateway Connection with ID: {}", input.key().getUuid());
219
220         Uuid networkUuid = input.getNetworkId();
221         String elanName = networkUuid.getValue();
222         disAssociateHwvtepsFromElan(elanName, input);
223     }
224
225     private void disAssociateHwvtepsFromElan(String elanName, L2gatewayConnection input) {
226         Integer defaultVlan = input.getSegmentId();
227         List<L2GatewayDevice> l2Devices = ElanL2GwCacheUtils.getAllElanDevicesFromCache();
228         List<Devices> l2gwDevicesToBeDeleted = new ArrayList<>();
229         for (L2GatewayDevice elanL2gwDevice : l2Devices) {
230             if (elanL2gwDevice.getL2GatewayIds().contains(input.key().getUuid())) {
231                 l2gwDevicesToBeDeleted.addAll(elanL2gwDevice.getDevicesForL2gwConnectionId(input.key().getUuid()));
232             }
233         }
234         if (l2gwDevicesToBeDeleted.isEmpty()) {
235             //delete logical switch
236             Uuid l2GatewayId = input.getL2gatewayId();
237             L2gateway l2Gateway = L2GatewayConnectionUtils.getNeutronL2gateway(broker, l2GatewayId);
238             if (l2Gateway == null) {
239                 LOG.error("Failed to find the l2gateway for the connection {}", input.getUuid());
240                 return;
241             } else {
242                 l2gwDevicesToBeDeleted.addAll(l2Gateway.getDevices());
243             }
244         }
245         for (Devices l2Device : l2gwDevicesToBeDeleted) {
246             String l2DeviceName = l2Device.getDeviceName();
247             L2GatewayDevice l2GatewayDevice = l2GatewayCache.get(l2DeviceName);
248             String hwvtepNodeId = l2GatewayDevice.getHwvtepNodeId();
249             boolean isLastL2GwConnDeleted = false;
250             L2GatewayDevice elanL2GwDevice = ElanL2GwCacheUtils.getL2GatewayDeviceFromCache(elanName, hwvtepNodeId);
251             if (elanL2GwDevice != null && isLastL2GwConnBeingDeleted(elanL2GwDevice)) {
252                 // Delete L2 Gateway device from 'ElanL2GwDevice' cache
253                 LOG.debug("Elan L2Gw Conn cache removed for id {}", hwvtepNodeId);
254                 ElanL2GwCacheUtils.removeL2GatewayDeviceFromCache(elanName, hwvtepNodeId);
255                 isLastL2GwConnDeleted = true;
256             } else {
257                 Uuid l2GwConnId = input.key().getUuid();
258                 LOG.debug("Elan L2Gw Conn cache with id {} is being referred by other L2Gw Conns; so only "
259                         + "L2 Gw Conn {} reference is removed", hwvtepNodeId, l2GwConnId);
260                 if (elanL2GwDevice != null) {
261                     elanL2GwDevice.removeL2GatewayId(l2GwConnId);
262                 } else {
263                     isLastL2GwConnDeleted = true;
264                 }
265             }
266
267             DisAssociateHwvtepFromElanJob disAssociateHwvtepToElanJob =
268                     new DisAssociateHwvtepFromElanJob(elanL2GatewayUtils, elanL2GatewayMulticastUtils,
269                             elanL2GwDevice, elanName, () -> elanInstanceCache.get(elanName).orNull(),
270                             l2Device, defaultVlan, hwvtepNodeId, isLastL2GwConnDeleted);
271             elanClusterUtils.runOnlyInOwnerNode(disAssociateHwvtepToElanJob.getJobKey(), "remove l2gw connection job",
272                     disAssociateHwvtepToElanJob);
273         }
274     }
275
276     private void associateHwvtepsToElan(ElanInstance elanInstance,
277             L2gateway l2Gateway, L2gatewayConnection input, String l2GwDeviceName) {
278         String elanName = elanInstance.getElanInstanceName();
279         Integer defaultVlan = input.getSegmentId();
280         Uuid l2GwConnId = input.key().getUuid();
281         List<Devices> l2Devices = l2Gateway.getDevices();
282
283         LOG.trace("Associating ELAN {} with L2Gw Conn Id {} having below L2Gw devices {}", elanName, l2GwConnId,
284                 l2Devices);
285
286         for (Devices l2Device : l2Devices) {
287             String l2DeviceName = l2Device.getDeviceName();
288             // L2gateway can have more than one L2 Gw devices. Configure Logical Switch, VLAN mappings,...
289             // only on the switch which has come up just now and exclude all other devices from
290             // preprovisioning/re-provisioning
291             if (l2GwDeviceName != null && !l2GwDeviceName.equals(l2DeviceName)) {
292                 LOG.debug("Associating Hwvtep to ELAN is not been processed for {}; as only {} got connected now!",
293                         l2DeviceName, l2GwDeviceName);
294                 continue;
295             }
296             L2GatewayDevice l2GatewayDevice = l2GatewayCache.get(l2DeviceName);
297             if (isL2GwDeviceConnected(l2GatewayDevice)) {
298                 NodeId hwvtepNodeId = new NodeId(l2GatewayDevice.getHwvtepNodeId());
299
300                 // Delete pending delete logical switch task if scheduled
301                 elanL2GatewayUtils.cancelDeleteLogicalSwitch(hwvtepNodeId,
302                         ElanL2GatewayUtils.getLogicalSwitchFromElan(elanName));
303
304                 // Add L2 Gateway device to 'ElanL2GwDevice' cache
305                 boolean createLogicalSwitch;
306                 LogicalSwitches logicalSwitch = HwvtepUtils.getLogicalSwitch(broker, LogicalDatastoreType.CONFIGURATION,
307                         hwvtepNodeId, elanName);
308                 if (logicalSwitch == null) {
309                     HwvtepLogicalSwitchListener hwVTEPLogicalSwitchListener = new HwvtepLogicalSwitchListener(
310                             elanInstanceCache, elanL2GatewayUtils, elanClusterUtils, elanL2GatewayMulticastUtils,
311                             this, l2GatewayDevice, elanName, l2Device, defaultVlan, l2GwConnId, hwvtepNodeHACache);
312                     hwVTEPLogicalSwitchListener.registerListener(LogicalDatastoreType.OPERATIONAL, broker);
313                     closeables.add(hwVTEPLogicalSwitchListener);
314                     createLogicalSwitch = true;
315                 } else {
316                     addL2DeviceToElanL2GwCache(elanName, l2GatewayDevice, l2GwConnId, l2Device);
317                     createLogicalSwitch = false;
318                 }
319                 AssociateHwvtepToElanJob associateHwvtepToElanJob = new AssociateHwvtepToElanJob(broker,
320                         elanL2GatewayUtils, elanL2GatewayMulticastUtils, elanInstanceCache, l2GatewayDevice,
321                         elanInstance, l2Device, defaultVlan, createLogicalSwitch);
322
323                 elanClusterUtils.runOnlyInOwnerNode(associateHwvtepToElanJob.getJobKey(),
324                         "create logical switch in hwvtep topo", associateHwvtepToElanJob);
325
326             } else {
327                 LOG.info("L2GwConn create is not handled for device with id {} as it's not connected", l2DeviceName);
328             }
329         }
330     }
331
332     public L2GatewayDevice addL2DeviceToElanL2GwCache(String elanName, L2GatewayDevice l2GatewayDevice, Uuid l2GwConnId,
333             Devices l2Device) {
334         String l2gwDeviceNodeId = l2GatewayDevice.getHwvtepNodeId();
335         L2GatewayDevice elanL2GwDevice = ElanL2GwCacheUtils.getL2GatewayDeviceFromCache(elanName, l2gwDeviceNodeId);
336         if (elanL2GwDevice == null) {
337             elanL2GwDevice = new L2GatewayDevice(l2GatewayDevice.getDeviceName());
338             elanL2GwDevice.setHwvtepNodeId(l2gwDeviceNodeId);
339             elanL2GwDevice.setTunnelIps(l2GatewayDevice.getTunnelIps());
340             ElanL2GwCacheUtils.addL2GatewayDeviceToCache(elanName, elanL2GwDevice);
341             LOG.debug("Elan L2GwConn cache created for hwvtep id {}", l2gwDeviceNodeId);
342         } else {
343             LOG.debug("Elan L2GwConn cache already exists for hwvtep id {}; updating L2GwConn id {} to it",
344                     l2gwDeviceNodeId, l2GwConnId);
345         }
346         elanL2GwDevice.addL2GatewayId(l2GwConnId);
347         elanL2GwDevice.addL2gwConnectionIdToDevice(l2GwConnId, l2Device);
348
349         //incase of cluster reboot scenario southbound device would have added more macs
350         //while odl is down, pull them now
351         readAndCopyLocalUcastMacsToCache(elanName, l2GatewayDevice);
352
353         LOG.trace("Elan L2GwConn cache updated with below details: {}", elanL2GwDevice);
354         return elanL2GwDevice;
355     }
356
357     private static boolean isL2GwDeviceConnected(L2GatewayDevice l2GwDevice) {
358         return l2GwDevice != null && l2GwDevice.getHwvtepNodeId() != null;
359     }
360
361     protected static boolean isLastL2GwConnBeingDeleted(@Nonnull L2GatewayDevice l2GwDevice) {
362         return l2GwDevice.getL2GatewayIds().size() == 1;
363     }
364
365     private void readAndCopyLocalUcastMacsToCache(final String elanName, final L2GatewayDevice l2GatewayDevice) {
366         final InstanceIdentifier<Node> nodeIid = HwvtepSouthboundUtils.createInstanceIdentifier(
367                 new NodeId(l2GatewayDevice.getHwvtepNodeId()));
368         jobCoordinator.enqueueJob(elanName + ":" + l2GatewayDevice.getDeviceName(), () -> {
369             final SettableFuture settableFuture = SettableFuture.create();
370             Futures.addCallback(broker.newReadOnlyTransaction().read(LogicalDatastoreType.OPERATIONAL,
371                     nodeIid), new SettableFutureCallback<Optional<Node>>(settableFuture) {
372                         @Override
373                         public void onSuccess(@Nonnull Optional<Node> resultNode) {
374                             LocalUcastMacListener localUcastMacListener =
375                                     new LocalUcastMacListener(broker, haOpClusteredListener,
376                                             elanL2GatewayUtils, jobCoordinator, elanInstanceCache, hwvtepNodeHACache);
377                             settableFuture.set(resultNode);
378                             Optional<Node> nodeOptional = resultNode;
379                             if (nodeOptional.isPresent()) {
380                                 Node node = nodeOptional.get();
381                                 if (node.augmentation(HwvtepGlobalAugmentation.class) != null) {
382                                     List<LocalUcastMacs> localUcastMacs =
383                                             node.augmentation(HwvtepGlobalAugmentation.class).getLocalUcastMacs();
384                                     if (localUcastMacs == null) {
385                                         return;
386                                     }
387                                     localUcastMacs.stream()
388                                             .filter((mac) -> macBelongsToLogicalSwitch(mac, elanName))
389                                             .forEach((mac) -> {
390                                                 InstanceIdentifier<LocalUcastMacs> macIid = getMacIid(nodeIid, mac);
391                                                 localUcastMacListener.added(macIid, mac);
392                                             });
393                                 }
394                             }
395                         }
396                     }, MoreExecutors.directExecutor());
397             return Lists.newArrayList(settableFuture);
398         } , 5);
399     }
400
401     /**
402      * Gets the associated l2 gw connections.
403      *
404      * @param l2GatewayId the l2 gateway id
405      *
406      * @return the associated l2 gw connections
407      */
408     public List<L2gatewayConnection> getL2GwConnectionsByL2GatewayId(Uuid l2GatewayId) {
409         List<L2gatewayConnection> l2GwConnections = new ArrayList<>();
410         List<L2gatewayConnection> allL2GwConns = getAllL2gatewayConnections(broker);
411         for (L2gatewayConnection l2GwConn : allL2GwConns) {
412             if (l2GwConn.getL2gatewayId().equals(l2GatewayId)) {
413                 l2GwConnections.add(l2GwConn);
414             }
415         }
416         return l2GwConnections;
417     }
418
419     private static boolean macBelongsToLogicalSwitch(LocalUcastMacs mac, String logicalSwitchName) {
420         InstanceIdentifier<LogicalSwitches> iid = (InstanceIdentifier<LogicalSwitches>)
421                 mac.getLogicalSwitchRef().getValue();
422         return iid.firstKeyOf(LogicalSwitches.class).getHwvtepNodeName().getValue().equals(logicalSwitchName);
423     }
424
425     static InstanceIdentifier<LocalUcastMacs> getMacIid(InstanceIdentifier<Node> nodeIid, LocalUcastMacs mac) {
426         return nodeIid.augmentation(HwvtepGlobalAugmentation.class).child(LocalUcastMacs.class, mac.key());
427     }
428 }