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