2 * Copyright (c) 2016 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.vpnservice.elan.l2gw.utils;
10 import java.math.BigInteger;
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.List;
14 import java.util.Objects;
16 import java.util.Timer;
17 import java.util.TimerTask;
18 import java.util.concurrent.Callable;
19 import java.util.concurrent.ConcurrentHashMap;
20 import java.util.concurrent.ConcurrentMap;
21 import java.util.concurrent.ExecutionException;
22 import java.util.concurrent.Future;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
26 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
27 import org.opendaylight.elanmanager.utils.ElanL2GwCacheUtils;
28 import org.opendaylight.vpnservice.elan.l2gw.jobs.DeleteL2GwDeviceMacsFromElanJob;
29 import org.opendaylight.vpnservice.datastoreutils.DataStoreJobCoordinator;
30 import org.opendaylight.vpnservice.elan.l2gw.jobs.LogicalSwitchDeletedJob;
31 import org.opendaylight.vpnservice.elan.l2gw.listeners.HwvtepPhysicalLocatorListener;
32 import org.opendaylight.vpnservice.elan.utils.ElanClusterUtils;
33 import org.opendaylight.vpnservice.elan.utils.ElanConstants;
34 import org.opendaylight.vpnservice.elan.utils.ElanUtils;
35 import org.opendaylight.vpnservice.interfacemgr.IfmUtil;
36 import org.opendaylight.vpnservice.mdsalutil.MDSALUtil;
37 import org.opendaylight.vpnservice.neutronvpn.api.l2gw.L2GatewayDevice;
38 import org.opendaylight.vpnservice.utils.SystemPropertyReader;
39 import org.opendaylight.vpnservice.utils.hwvtep.HwvtepSouthboundConstants;
40 import org.opendaylight.vpnservice.utils.hwvtep.HwvtepSouthboundUtils;
41 import org.opendaylight.vpnservice.utils.hwvtep.HwvtepUtils;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
43 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
44 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
46 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
47 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.Devices;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchRef;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorRef;
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.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacsKey;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.forwarding.tables.MacTable;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.elan.instances.ElanInstance;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntry;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.IfTunnel;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeBase;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rev150331.TunnelTypeVxlan;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.AddL2GwDeviceInputBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetExternalTunnelInterfaceNameInputBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.GetExternalTunnelInterfaceNameOutput;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.itm.rpcs.rev151217.ItmRpcService;
72 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
73 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
74 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
75 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
76 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
77 import org.opendaylight.yangtools.yang.common.RpcResult;
78 import org.apache.commons.lang3.tuple.Pair;
79 import org.apache.commons.lang3.tuple.ImmutablePair;
80 import org.slf4j.Logger;
81 import org.slf4j.LoggerFactory;
83 import com.google.common.base.Function;
84 import com.google.common.base.Optional;
85 import com.google.common.collect.Lists;
86 import com.google.common.util.concurrent.FutureCallback;
87 import com.google.common.util.concurrent.Futures;
88 import com.google.common.util.concurrent.ListenableFuture;
91 * It gathers a set of utility methods that handle ELAN configuration in external Devices (where external means
92 * "not-CSS". As of now: TORs).
94 * It makes use of HwvtepUtils class located under ovsdb/hwvtepsouthbound project for low-level mdsal operations
99 public class ElanL2GatewayUtils {
100 private static DataBroker broker;
101 private static ItmRpcService itmRpcService;
102 private static DataStoreJobCoordinator dataStoreJobCoordinator;
103 private static Timer LogicalSwitchDeleteJobTimer = new Timer();
104 private static final int LOGICAL_SWITCH_DELETE_DELAY = 120000;
105 private static ConcurrentMap<Pair<NodeId, String>, TimerTask> LogicalSwitchDeletedTasks =
106 new ConcurrentHashMap<Pair<NodeId, String>, TimerTask>();
108 private static final Logger LOG = LoggerFactory.getLogger(ElanL2GatewayUtils.class);
111 * Sets the data broker.
114 * the new data broker
116 public static void setDataBroker(DataBroker dataBroker) {
121 * Sets the itm rpc service.
124 * the new itm rpc service
126 public static void setItmRpcService(ItmRpcService itmRpc) {
127 itmRpcService = itmRpc;
131 * Sets DataStoreJobCoordinator
133 * @param dsJobCoordinator
134 * the new dataStoreJobCoordinator
136 public static void setDataStoreJobCoordinator(DataStoreJobCoordinator dsJobCoordinator) {
137 dataStoreJobCoordinator = dsJobCoordinator;
141 * Installs dpn macs in external device.
142 * first it checks if the physical locator towards this dpn tep is present or not
143 * if the physical locator is present go ahead and add the ucast macs
144 * otherwise update the mcast mac entry to include this dpn tep ip
145 * and schedule the job to put ucast macs once the physical locator is programmed in device
148 * @param lstElanInterfaceNames
149 * the lst Elan interface names
152 * @param externalNodeId
153 * the external node id
155 public static void installDpnMacsInL2gwDevice(String elanName, Set<String> lstElanInterfaceNames,
156 BigInteger dpnId, NodeId externalNodeId) {
157 L2GatewayDevice elanL2GwDevice = ElanL2GwCacheUtils.getL2GatewayDeviceFromCache(elanName,
158 externalNodeId.getValue());
159 if (elanL2GwDevice == null) {
160 LOG.debug("L2 gw device not found in elan cache for device name {}", externalNodeId);
163 IpAddress dpnTepIp = getSourceDpnTepIp(dpnId, externalNodeId);
164 if (dpnTepIp == null) {
165 LOG.warn("Could not install dpn macs in l2gw device , dpnTepIp not found dpn : {} , nodeid : {}",
166 dpnId, externalNodeId);
170 String logicalSwitchName = getLogicalSwitchFromElan(elanName);
171 RemoteMcastMacs remoteMcastMac = readRemoteMcastMac(externalNodeId, logicalSwitchName,
172 LogicalDatastoreType.OPERATIONAL);
173 boolean phyLocAlreadyExists = checkIfPhyLocatorAlreadyExistsInRemoteMcastEntry(externalNodeId, remoteMcastMac,
175 LOG.debug("phyLocAlreadyExists = {} for locator [{}] in remote mcast entry for elan [{}], nodeId [{}]",
176 phyLocAlreadyExists, String.valueOf(dpnTepIp.getValue()), elanName, externalNodeId.getValue());
177 List<PhysAddress> staticMacs = null;
178 staticMacs = getElanDpnMacsFromInterfaces(lstElanInterfaceNames);
180 if (phyLocAlreadyExists) {
181 scheduleAddDpnMacsInExtDevice(elanName, dpnId, staticMacs, elanL2GwDevice);
184 ElanL2GatewayMulticastUtils.scheduleMcastMacUpdateJob(elanName, elanL2GwDevice);
185 scheduleAddDpnMacsInExtDevice(elanName, dpnId, staticMacs, elanL2GwDevice);
189 * gets the macs addresses for elan interfaces
191 * @param lstElanInterfaceNames
192 * the lst elan interface names
195 private static List<PhysAddress> getElanDpnMacsFromInterfaces(Set<String> lstElanInterfaceNames) {
196 List<PhysAddress> result = new ArrayList<>();
197 for (String interfaceName : lstElanInterfaceNames) {
198 ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(interfaceName);
199 if (elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
200 for (MacEntry macEntry : elanInterfaceMac.getMacEntry()) {
201 result.add(macEntry.getMacAddress());
209 * Check if phy locator already exists in remote mcast entry.
213 * @param remoteMcastMac
214 * the remote mcast mac
215 * @param expectedPhyLocatorIp
216 * the expected phy locator ip
217 * @return true, if successful
219 public static boolean checkIfPhyLocatorAlreadyExistsInRemoteMcastEntry(NodeId nodeId,
220 RemoteMcastMacs remoteMcastMac, IpAddress expectedPhyLocatorIp) {
221 if (remoteMcastMac != null) {
222 HwvtepPhysicalLocatorAugmentation expectedPhyLocatorAug = HwvtepSouthboundUtils
223 .createHwvtepPhysicalLocatorAugmentation(String.valueOf(expectedPhyLocatorIp.getValue()));
224 HwvtepPhysicalLocatorRef expectedPhyLocRef = new HwvtepPhysicalLocatorRef(
225 HwvtepSouthboundUtils.createPhysicalLocatorInstanceIdentifier(nodeId, expectedPhyLocatorAug));
226 if (remoteMcastMac.getLocatorSet() != null) {
227 for (LocatorSet locatorSet : remoteMcastMac.getLocatorSet()) {
228 if (locatorSet.getLocatorRef().equals(expectedPhyLocRef)) {
229 LOG.trace("matched phyLocRef: {}", expectedPhyLocRef);
239 * Gets the remote mcast mac.
243 * @param logicalSwitchName
244 * the logical switch name
245 * @param datastoreType
247 * @return the remote mcast mac
249 public static RemoteMcastMacs readRemoteMcastMac(NodeId nodeId, String logicalSwitchName,
250 LogicalDatastoreType datastoreType) {
251 InstanceIdentifier<LogicalSwitches> logicalSwitch = HwvtepSouthboundUtils
252 .createLogicalSwitchesInstanceIdentifier(nodeId, new HwvtepNodeName(logicalSwitchName));
253 RemoteMcastMacsKey remoteMcastMacsKey = new RemoteMcastMacsKey(new HwvtepLogicalSwitchRef(logicalSwitch),
254 new MacAddress(ElanConstants.UNKNOWN_DMAC));
255 RemoteMcastMacs remoteMcastMac = HwvtepUtils.getRemoteMcastMac(broker, datastoreType, nodeId,
257 return remoteMcastMac;
261 * Removes the given MAC Addresses from all the External Devices belonging
262 * to the specified ELAN.
264 * @param elanInstance
266 * @param macAddresses
269 public static void removeMacsFromElanExternalDevices(ElanInstance elanInstance, List<PhysAddress> macAddresses) {
270 ConcurrentMap<String, L2GatewayDevice> elanL2GwDevices = ElanL2GwCacheUtils
271 .getInvolvedL2GwDevices(elanInstance.getElanInstanceName());
272 for (L2GatewayDevice l2GatewayDevice : elanL2GwDevices.values()) {
273 removeRemoteUcastMacsFromExternalDevice(l2GatewayDevice.getHwvtepNodeId(),
274 elanInstance.getElanInstanceName(), macAddresses);
279 * Removes the given MAC Addresses from the specified External Device.
281 * @param deviceNodeId
283 * @param logicalSwitchName
284 * @param macAddresses
286 * @return the listenable future
288 private static ListenableFuture<Void> removeRemoteUcastMacsFromExternalDevice(String deviceNodeId,
289 String logicalSwitchName, List<PhysAddress> macAddresses) {
290 NodeId nodeId = new NodeId(deviceNodeId);
293 List<MacAddress> lstMac = Lists.transform(macAddresses, new Function<PhysAddress, MacAddress>() {
295 public MacAddress apply(PhysAddress physAddress) {
296 return (physAddress != null) ? new MacAddress(physAddress.getValue()) : null;
299 return HwvtepUtils.deleteRemoteUcastMacs(broker, nodeId, logicalSwitchName, lstMac);
302 public static ElanInstance getElanInstanceForUcastLocalMac(LocalUcastMacs localUcastMac) {
303 Optional<LogicalSwitches> lsOpc = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL,
304 (InstanceIdentifier<LogicalSwitches>) localUcastMac.getLogicalSwitchRef().getValue());
305 if (lsOpc.isPresent()) {
306 LogicalSwitches ls = lsOpc.get();
308 // Logical switch name is Elan name
309 String elanName = getElanFromLogicalSwitch(ls.getHwvtepNodeName().getValue());
310 return ElanUtils.getElanInstanceByName(elanName);
312 String macAddress = localUcastMac.getMacEntryKey().getValue();
313 LOG.error("Could not find logical_switch for {} being added/deleted", macAddress);
320 * Install external device local macs in dpn.
324 * @param l2gwDeviceNodeId
325 * the l2gw device node id
329 public static void installL2gwDeviceMacsInDpn(BigInteger dpnId, NodeId l2gwDeviceNodeId, ElanInstance elan) {
330 L2GatewayDevice l2gwDevice = ElanL2GwCacheUtils.getL2GatewayDeviceFromCache(elan.getElanInstanceName(),
331 l2gwDeviceNodeId.getValue());
332 if (l2gwDevice == null) {
333 LOG.debug("L2 gw device not found in elan cache for device name {}", l2gwDeviceNodeId.getValue());
337 installDmacFlowsOnDpn(dpnId, l2gwDevice, elan);
341 * Install dmac flows on dpn.
350 public static void installDmacFlowsOnDpn(BigInteger dpnId, L2GatewayDevice l2gwDevice, ElanInstance elan) {
351 String elanName = elan.getElanInstanceName();
353 List<LocalUcastMacs> l2gwDeviceLocalMacs = l2gwDevice.getUcastLocalMacs();
354 if (l2gwDeviceLocalMacs != null && !l2gwDeviceLocalMacs.isEmpty()) {
355 for (LocalUcastMacs localUcastMac : l2gwDeviceLocalMacs) {
356 //TODO batch these ops
357 ElanUtils.installDmacFlowsToExternalRemoteMac(dpnId, l2gwDevice.getHwvtepNodeId(), elan.getElanTag(),
358 elan.getVni(), localUcastMac.getMacEntryKey().getValue(), elanName);
360 LOG.debug("Installing L2gw device [{}] local macs [size: {}] in dpn [{}] for elan [{}]",
361 l2gwDevice.getHwvtepNodeId(), l2gwDeviceLocalMacs.size(), dpnId, elanName);
366 * Install elan l2gw devices local macs in dpn.
373 public static void installElanL2gwDevicesLocalMacsInDpn(BigInteger dpnId, ElanInstance elan) {
374 ConcurrentMap<String, L2GatewayDevice> elanL2GwDevicesFromCache = ElanL2GwCacheUtils
375 .getInvolvedL2GwDevices(elan.getElanInstanceName());
376 if (elanL2GwDevicesFromCache != null) {
377 for (L2GatewayDevice l2gwDevice : elanL2GwDevicesFromCache.values()) {
378 installDmacFlowsOnDpn(dpnId, l2gwDevice, elan);
381 LOG.debug("No Elan l2 gateway devices in cache for [{}] ", elan.getElanInstanceName());
385 public static void installL2GwUcastMacInElan(final ElanInstance elan,
386 final L2GatewayDevice extL2GwDevice, final String macToBeAdded) {
387 final String extDeviceNodeId = extL2GwDevice.getHwvtepNodeId();
388 final String elanInstanceName = elan.getElanInstanceName();
390 // Retrieve all participating DPNs in this Elan. Populate this MAC in DMAC table.
391 // Looping through all DPNs in order to add/remove mac flows in their DMAC table
392 final List<DpnInterfaces> elanDpns = ElanUtils.getInvolvedDpnsInElan(elanInstanceName);
393 if (elanDpns != null && elanDpns.size() > 0) {
394 String jobKey = elan.getElanInstanceName() + ":" + macToBeAdded;
395 ElanClusterUtils.runOnlyInLeaderNode(jobKey,
396 "install l2gw mcas in dmac table",
397 new Callable<List<ListenableFuture<Void>>>() {
399 public List<ListenableFuture<Void>> call() throws Exception {
400 List<ListenableFuture<Void>> fts = Lists.newArrayList();
401 for (DpnInterfaces elanDpn : elanDpns) {
402 //TODO batch the below call
403 fts.addAll(ElanUtils.installDmacFlowsToExternalRemoteMac(elanDpn.getDpId(),
404 extDeviceNodeId, elan.getElanTag(), elan.getVni(), macToBeAdded,
411 final IpAddress extL2GwDeviceTepIp = extL2GwDevice.getTunnelIp();
412 final List<PhysAddress> macList = new ArrayList<PhysAddress>();
413 macList.add(new PhysAddress(macToBeAdded));
415 String jobKey = "hwvtep:"+elan.getElanInstanceName() + ":" + macToBeAdded;
416 ElanClusterUtils.runOnlyInLeaderNode(jobKey,
417 "install remote ucast macs in l2gw device",
418 new Callable<List<ListenableFuture<Void>>>() {
420 public List<ListenableFuture<Void>> call() throws Exception {
421 ConcurrentMap<String, L2GatewayDevice> elanL2GwDevices =
422 ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanInstanceName);
424 List<ListenableFuture<Void>> fts = Lists.newArrayList();
425 for (L2GatewayDevice otherDevice : elanL2GwDevices.values()) {
426 if (!otherDevice.getHwvtepNodeId().equals(extDeviceNodeId)
427 && !areMLAGDevices(extL2GwDevice, otherDevice)) {
428 final String hwvtepId = otherDevice.getHwvtepNodeId();
429 InstanceIdentifier<Node> iid = HwvtepSouthboundUtils.createInstanceIdentifier(
430 new NodeId(hwvtepId));
431 final String logicalSwitchName = elanInstanceName;
433 ListenableFuture<Void> ft = HwvtepUtils.installUcastMacs(
434 broker, hwvtepId, macList, logicalSwitchName, extL2GwDeviceTepIp);
435 //TODO batch the above call
436 Futures.addCallback(ft, new FutureCallback<Void>() {
438 public void onSuccess(Void noarg) {
439 LOG.trace("Successful in initiating ucast_remote_macs addition" +
440 "related to {} in {}", logicalSwitchName, hwvtepId);
444 public void onFailure(Throwable error) {
445 LOG.error(String.format("Failed adding ucast_remote_macs related to " +
446 "%s in %s", logicalSwitchName, hwvtepId), error);
457 * Un install l2 gw ucast mac from elan.
463 * @param macAddresses
466 public static void unInstallL2GwUcastMacFromElan(final ElanInstance elan, final L2GatewayDevice l2GwDevice,
467 final List<MacAddress> macAddresses) {
468 if (macAddresses == null || macAddresses.isEmpty()) {
471 final String elanName = elan.getElanInstanceName();
473 // Retrieve all participating DPNs in this Elan. Populate this MAC in
474 // DMAC table. Looping through all DPNs in order to add/remove mac flows
475 // in their DMAC table
476 for (final MacAddress mac : macAddresses) {
477 final List<DpnInterfaces> elanDpns = ElanUtils.getInvolvedDpnsInElan(elanName);
478 if (elanDpns != null && !elanDpns.isEmpty()) {
479 String jobKey = elanName + ":" + mac.getValue();
480 ElanClusterUtils.runOnlyInLeaderNode(jobKey, "delete l2gw macs from dmac table",
481 new Callable<List<ListenableFuture<Void>>>() {
483 public List<ListenableFuture<Void>> call() {
484 List<ListenableFuture<Void>> fts = Lists.newArrayList();
485 for (DpnInterfaces elanDpn : elanDpns) {
486 BigInteger dpnId = elanDpn.getDpId();
487 // never batch deletes
488 fts.addAll(ElanUtils.deleteDmacFlowsToExternalMac(elan.getElanTag(), dpnId,
489 l2GwDevice.getHwvtepNodeId(), mac.getValue()));
497 DeleteL2GwDeviceMacsFromElanJob job = new DeleteL2GwDeviceMacsFromElanJob(broker, elanName, l2GwDevice,
499 ElanClusterUtils.runOnlyInLeaderNode(job.getJobKey(), "delete remote ucast macs in l2gw devices", job);
503 * Delete elan l2 gateway devices ucast local macs from dpn.
510 public static void deleteElanL2GwDevicesUcastLocalMacsFromDpn(final String elanName, final BigInteger dpnId) {
511 ConcurrentMap<String, L2GatewayDevice> elanL2GwDevices = ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName);
512 if (elanL2GwDevices == null || elanL2GwDevices.isEmpty()) {
513 LOG.trace("No L2 gateway devices in Elan [{}] cache.", elanName);
516 final ElanInstance elan = ElanUtils.getElanInstanceByName(elanName);
518 LOG.error("Could not find Elan by name: {}", elanName);
521 LOG.info("Deleting Elan [{}] L2GatewayDevices UcastLocalMacs from Dpn [{}]", elanName, dpnId);
523 final Long elanTag = elan.getElanTag();
524 for (final L2GatewayDevice l2GwDevice : elanL2GwDevices.values()) {
525 List<MacAddress> localMacs = getL2GwDeviceLocalMacs(l2GwDevice);
526 if (localMacs != null && !localMacs.isEmpty()) {
527 for (final MacAddress mac : localMacs) {
528 String jobKey = elanName + ":" + mac.getValue();
529 ElanClusterUtils.runOnlyInLeaderNode(jobKey, "delete l2gw macs from dmac table",
530 new Callable<List<ListenableFuture<Void>>>() {
532 public List<ListenableFuture<Void>> call() {
533 List<ListenableFuture<Void>> futures = Lists.newArrayList();
535 futures.addAll(ElanUtils.deleteDmacFlowsToExternalMac(elanTag, dpnId,
536 l2GwDevice.getHwvtepNodeId(), mac.getValue()));
546 * Gets the l2 gw device local macs.
550 * @return the l2 gw device local macs
552 public static List<MacAddress> getL2GwDeviceLocalMacs(L2GatewayDevice l2gwDevice) {
553 List<MacAddress> macs = new ArrayList<>();
554 if (l2gwDevice == null) {
557 List<LocalUcastMacs> lstUcastLocalMacs = l2gwDevice.getUcastLocalMacs();
558 if (lstUcastLocalMacs != null && !lstUcastLocalMacs.isEmpty()) {
559 macs = Lists.transform(lstUcastLocalMacs, new Function<LocalUcastMacs, MacAddress>() {
561 public MacAddress apply(LocalUcastMacs localUcastMac) {
562 return (localUcastMac != null) ? localUcastMac.getMacEntryKey() : null;
570 * Delete elan macs from L2 gateway device.<br>
571 * This includes deleting ELAN mac table entries plus external device
572 * UcastLocalMacs which are part of the same ELAN.
574 * @param l2GatewayDevice
575 * the l2 gateway device
578 * @return the listenable future
580 public static ListenableFuture<Void> deleteElanMacsFromL2GatewayDevice(L2GatewayDevice l2GatewayDevice,
582 List<MacAddress> elanMacTableEntries = getElanMacTableEntries(elanName);
583 List<MacAddress> elanL2GatewayDevicesLocalMacs = getElanL2GatewayDevicesLocalMacs(l2GatewayDevice, elanName);
585 List<MacAddress> lstElanLocalMacs = new ArrayList<>(elanMacTableEntries);
586 lstElanLocalMacs.addAll(elanL2GatewayDevicesLocalMacs);
588 return HwvtepUtils.deleteRemoteUcastMacs(broker, new NodeId(l2GatewayDevice.getHwvtepNodeId()),
589 elanName, lstElanLocalMacs);
593 * Gets the elan mac table entries.
597 * @return the elan mac table entries as list
599 public static List<MacAddress> getElanMacTableEntries(String elanName) {
600 MacTable macTable = ElanUtils.getElanMacTable(elanName);
601 if (macTable == null || macTable.getMacEntry() == null || macTable.getMacEntry().isEmpty()) {
602 LOG.trace("MacTable is empty for elan: {}", elanName);
603 return Collections.emptyList();
605 List<MacAddress> lstMacs = Lists.transform(macTable.getMacEntry(), new Function<MacEntry, MacAddress>() {
607 public MacAddress apply(MacEntry macEntry) {
608 return (macEntry != null) ? new MacAddress(macEntry.getMacAddress().getValue()) : null;
615 * Gets the elan l2 gateway devices local macs.
617 * @param l2GwDeviceToBeExcluded
618 * the l2 gw device to be excluded
621 * @return the elan l2 gateway devices local macs
623 public static List<MacAddress> getElanL2GatewayDevicesLocalMacs(L2GatewayDevice l2GwDeviceToBeExcluded,
625 List<MacAddress> lstL2GatewayDeviceMacs = new ArrayList<>();
627 ConcurrentMap<String, L2GatewayDevice> elanL2GwDevicesFromCache = ElanL2GwCacheUtils
628 .getInvolvedL2GwDevices(elanName);
629 if (elanL2GwDevicesFromCache != null) {
630 for (L2GatewayDevice otherDevice : elanL2GwDevicesFromCache.values()) {
631 if (!otherDevice.getHwvtepNodeId().equals(l2GwDeviceToBeExcluded.getHwvtepNodeId())) {
632 List<LocalUcastMacs> lstUcastLocalMacs = otherDevice.getUcastLocalMacs();
633 if (lstUcastLocalMacs != null) {
634 List<MacAddress> l2GwDeviceMacs = Lists.transform(lstUcastLocalMacs,
635 new Function<LocalUcastMacs, MacAddress>() {
637 public MacAddress apply(LocalUcastMacs localUcastMac) {
638 return (localUcastMac != null) ? localUcastMac.getMacEntryKey() : null;
641 lstL2GatewayDeviceMacs.addAll(l2GwDeviceMacs);
646 return lstL2GatewayDeviceMacs;
650 * Install ELAN macs in L2 Gateway device.<br>
651 * This includes installing ELAN mac table entries plus external device
652 * UcastLocalMacs which are part of the same ELAN.
656 * @param l2GatewayDevice
657 * the l2 gateway device which has to be configured
658 * @return the listenable future
660 public static ListenableFuture<Void> installElanMacsInL2GatewayDevice(String elanName,
661 L2GatewayDevice l2GatewayDevice) {
662 String logicalSwitchName = getLogicalSwitchFromElan(elanName);
663 NodeId hwVtepNodeId = new NodeId(l2GatewayDevice.getHwvtepNodeId());
665 List<RemoteUcastMacs> lstL2GatewayDevicesMacs = getOtherDevicesMacs(elanName,
666 l2GatewayDevice, hwVtepNodeId, logicalSwitchName);
667 List<RemoteUcastMacs> lstElanMacTableEntries = getElanMacTableEntriesMacs(elanName,
668 l2GatewayDevice, hwVtepNodeId, logicalSwitchName);
670 List<RemoteUcastMacs> lstRemoteUcastMacs = new ArrayList<>(lstL2GatewayDevicesMacs);
671 lstRemoteUcastMacs.addAll(lstElanMacTableEntries);
673 ListenableFuture<Void> future = HwvtepUtils.addRemoteUcastMacs(broker, hwVtepNodeId, lstRemoteUcastMacs);
675 LOG.info("Added RemoteUcastMacs entries [{}] in config DS. NodeID: {}, LogicalSwitch: {}",
676 lstRemoteUcastMacs.size(), hwVtepNodeId.getValue(), logicalSwitchName);
681 * Gets the l2 gateway devices ucast local macs as remote ucast macs.
685 * @param l2GatewayDeviceToBeConfigured
686 * the l2 gateway device to be configured
687 * @param hwVtepNodeId
688 * the hw vtep node Id to be configured
689 * @param logicalSwitchName
690 * the logical switch name
691 * @return the l2 gateway devices macs as remote ucast macs
693 public static List<RemoteUcastMacs> getOtherDevicesMacs(String elanName,
694 L2GatewayDevice l2GatewayDeviceToBeConfigured,
695 NodeId hwVtepNodeId, String logicalSwitchName) {
696 List<RemoteUcastMacs> lstRemoteUcastMacs = new ArrayList<RemoteUcastMacs>();
697 ConcurrentMap<String, L2GatewayDevice> elanL2GwDevicesFromCache = ElanL2GwCacheUtils
698 .getInvolvedL2GwDevices(elanName);
700 if (elanL2GwDevicesFromCache != null) {
701 for (L2GatewayDevice otherDevice : elanL2GwDevicesFromCache.values()) {
702 if (l2GatewayDeviceToBeConfigured.getHwvtepNodeId().equals(otherDevice.getHwvtepNodeId())) {
705 if (!areMLAGDevices(l2GatewayDeviceToBeConfigured, otherDevice)) {
706 List<LocalUcastMacs> lstUcastLocalMacs = otherDevice.getUcastLocalMacs();
707 if (lstUcastLocalMacs != null) {
708 for (LocalUcastMacs localUcastMac : lstUcastLocalMacs) {
709 HwvtepPhysicalLocatorAugmentation physLocatorAug = HwvtepSouthboundUtils
710 .createHwvtepPhysicalLocatorAugmentation(
711 String.valueOf(otherDevice.getTunnelIp().getValue()));
712 RemoteUcastMacs remoteUcastMac = HwvtepSouthboundUtils.createRemoteUcastMac(hwVtepNodeId,
713 localUcastMac.getMacEntryKey().getValue(), localUcastMac.getIpaddr(),
714 logicalSwitchName, physLocatorAug);
715 lstRemoteUcastMacs.add(remoteUcastMac);
721 return lstRemoteUcastMacs;
727 * @param l2GatewayDevice
728 * the l2 gateway device
729 * @param otherL2GatewayDevice
730 * the other l2 gateway device
731 * @return true, if both the specified l2 gateway devices are part of same
734 public static boolean areMLAGDevices(L2GatewayDevice l2GatewayDevice, L2GatewayDevice otherL2GatewayDevice) {
735 // If tunnel IPs are same, then it is considered to be part of same MLAG
736 return Objects.equals(l2GatewayDevice.getTunnelIp(), otherL2GatewayDevice.getTunnelIp());
740 * Gets the elan mac table entries as remote ucast macs. <br>
741 * Note: ELAN MAC table only contains internal switches MAC's. It doesn't
742 * contain external device MAC's.
746 * @param l2GatewayDeviceToBeConfigured
747 * the l2 gateway device to be configured
748 * @param hwVtepNodeId
749 * the hw vtep node id
750 * @param logicalSwitchName
751 * the logical switch name
752 * @return the elan mac table entries as remote ucast macs
754 public static List<RemoteUcastMacs> getElanMacTableEntriesMacs(String elanName,
755 L2GatewayDevice l2GatewayDeviceToBeConfigured,
756 NodeId hwVtepNodeId, String logicalSwitchName) {
757 List<RemoteUcastMacs> lstRemoteUcastMacs = new ArrayList<RemoteUcastMacs>();
759 MacTable macTable = ElanUtils.getElanMacTable(elanName);
760 if (macTable == null || macTable.getMacEntry() == null || macTable.getMacEntry().isEmpty()) {
761 LOG.trace("MacTable is empty for elan: {}", elanName);
762 return lstRemoteUcastMacs;
765 for (MacEntry macEntry : macTable.getMacEntry()) {
766 BigInteger dpnId = ElanUtils.getDpidFromInterface(macEntry.getInterface());
768 LOG.error("DPN ID not found for interface {}", macEntry.getInterface());
772 IpAddress dpnTepIp = getSourceDpnTepIp(dpnId, hwVtepNodeId);
773 LOG.trace("Dpn Tep IP: {} for dpnId: {} and nodeId: {}", dpnTepIp, dpnId, hwVtepNodeId.getValue());
774 if (dpnTepIp == null) {
775 LOG.error("TEP IP not found for dpnId {} and nodeId {}", dpnId, hwVtepNodeId.getValue());
778 HwvtepPhysicalLocatorAugmentation physLocatorAug = HwvtepSouthboundUtils
779 .createHwvtepPhysicalLocatorAugmentation(String.valueOf(dpnTepIp.getValue()));
780 // TODO: Query ARP cache to get IP address corresponding to the
782 IpAddress ipAddress = null;
783 RemoteUcastMacs remoteUcastMac = HwvtepSouthboundUtils.createRemoteUcastMac(hwVtepNodeId,
784 macEntry.getMacAddress().getValue(), ipAddress, logicalSwitchName, physLocatorAug);
785 lstRemoteUcastMacs.add(remoteUcastMac);
787 return lstRemoteUcastMacs;
791 * Gets the external tunnel interface name.
797 * @return the external tunnel interface name
799 public static String getExternalTunnelInterfaceName(String sourceNode, String dstNode) {
800 Class<? extends TunnelTypeBase> tunType = TunnelTypeVxlan.class;
801 String tunnelInterfaceName = null;
803 Future<RpcResult<GetExternalTunnelInterfaceNameOutput>> output = itmRpcService
804 .getExternalTunnelInterfaceName(new GetExternalTunnelInterfaceNameInputBuilder()
805 .setSourceNode(sourceNode).setDestinationNode(dstNode).setTunnelType(tunType).build());
807 RpcResult<GetExternalTunnelInterfaceNameOutput> rpcResult = output.get();
808 if (rpcResult.isSuccessful()) {
809 tunnelInterfaceName = rpcResult.getResult().getInterfaceName();
810 LOG.debug("Tunnel interface name: {} for sourceNode: {} and dstNode: {}", tunnelInterfaceName,
811 sourceNode, dstNode);
813 LOG.warn("RPC call to ITM.GetExternalTunnelInterfaceName failed with error: {}",
814 rpcResult.getErrors());
816 } catch (NullPointerException | InterruptedException | ExecutionException e) {
817 LOG.error("Failed to get external tunnel interface name for sourceNode: {} and dstNode: {}: {} ",
818 sourceNode, dstNode, e);
820 return tunnelInterfaceName;
824 * Gets the source dpn tep ip.
828 * @param dstHwVtepNodeId
829 * the dst hw vtep node id
830 * @return the dpn tep ip
832 public static IpAddress getSourceDpnTepIp(BigInteger srcDpnId, NodeId dstHwVtepNodeId) {
833 IpAddress dpnTepIp = null;
834 String tunnelInterfaceName = getExternalTunnelInterfaceName(String.valueOf(srcDpnId),
835 dstHwVtepNodeId.getValue());
836 if (tunnelInterfaceName != null) {
837 Interface tunnelInterface = getInterfaceFromConfigDS(new InterfaceKey(tunnelInterfaceName), broker);
838 if (tunnelInterface != null) {
839 dpnTepIp = tunnelInterface.getAugmentation(IfTunnel.class).getTunnelSource();
841 LOG.warn("Tunnel interface not found for tunnelInterfaceName {}", tunnelInterfaceName);
844 LOG.warn("Tunnel interface name not found for srcDpnId {} and dstHwVtepNodeId {}", srcDpnId,
851 * Update vlan bindings in l2 gateway device.
855 * @param logicalSwitchName
856 * the logical switch name
857 * @param hwVtepDevice
858 * the hardware device
859 * @param defaultVlanId
860 * the default vlan id
861 * @return the listenable future
863 public static ListenableFuture<Void> updateVlanBindingsInL2GatewayDevice(NodeId nodeId, String logicalSwitchName,
864 Devices hwVtepDevice, Integer defaultVlanId) {
865 if (hwVtepDevice == null || hwVtepDevice.getInterfaces() == null || hwVtepDevice.getInterfaces().isEmpty()) {
866 String errMsg = "HwVtepDevice is null or interfaces are empty.";
868 return Futures.immediateFailedFuture(new RuntimeException(errMsg));
871 WriteTransaction transaction = broker.newWriteOnlyTransaction();
872 for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.devices.Interfaces deviceInterface : hwVtepDevice
874 List<VlanBindings> vlanBindings = new ArrayList<>();
875 if (deviceInterface.getSegmentationIds() != null && !deviceInterface.getSegmentationIds().isEmpty()) {
876 for (Integer vlanId : deviceInterface.getSegmentationIds()) {
877 vlanBindings.add(HwvtepSouthboundUtils.createVlanBinding(nodeId, vlanId, logicalSwitchName));
880 // Use defaultVlanId (specified in L2GatewayConnection) if Vlan
881 // ID not specified at interface level.
882 vlanBindings.add(HwvtepSouthboundUtils.createVlanBinding(nodeId, defaultVlanId, logicalSwitchName));
884 HwvtepUtils.mergeVlanBindings(transaction, nodeId, hwVtepDevice.getDeviceName(),
885 deviceInterface.getInterfaceName(), vlanBindings);
887 ListenableFuture<Void> future = transaction.submit();
888 LOG.info("Updated Hwvtep VlanBindings in config DS. NodeID: {}, LogicalSwitch: {}", nodeId.getValue(),
894 * Delete vlan bindings from l2 gateway device.
898 * @param hwVtepDevice
900 * @param defaultVlanId
901 * the default vlan id
902 * @return the listenable future
904 public static ListenableFuture<Void> deleteVlanBindingsFromL2GatewayDevice(NodeId nodeId, Devices hwVtepDevice,
905 Integer defaultVlanId) {
906 if (hwVtepDevice == null || hwVtepDevice.getInterfaces() == null || hwVtepDevice.getInterfaces().isEmpty()) {
907 String errMsg = "HwVtepDevice is null or interfaces are empty.";
909 return Futures.immediateFailedFuture(new RuntimeException(errMsg));
911 NodeId physicalSwitchNodeId = HwvtepSouthboundUtils.createManagedNodeId(nodeId, hwVtepDevice.getDeviceName());
913 WriteTransaction transaction = broker.newWriteOnlyTransaction();
914 for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712.l2gateway.attributes.devices.Interfaces deviceInterface : hwVtepDevice
916 String phyPortName = deviceInterface.getInterfaceName();
917 if (deviceInterface.getSegmentationIds() != null && !deviceInterface.getSegmentationIds().isEmpty()) {
918 for (Integer vlanId : deviceInterface.getSegmentationIds()) {
919 HwvtepUtils.deleteVlanBinding(transaction, physicalSwitchNodeId, phyPortName, vlanId);
922 // Use defaultVlanId (specified in L2GatewayConnection) if Vlan
923 // ID not specified at interface level.
924 HwvtepUtils.deleteVlanBinding(transaction, physicalSwitchNodeId, phyPortName, defaultVlanId);
927 ListenableFuture<Void> future = transaction.submit();
929 LOG.info("Deleted Hwvtep VlanBindings from config DS. NodeID: {}, hwVtepDevice: {}, defaultVlanId: {} ",
930 nodeId.getValue(), hwVtepDevice, defaultVlanId);
935 * Gets the elan name from logical switch name.
937 * @param logicalSwitchName
938 * the logical switch name
939 * @return the elan name from logical switch name
941 public static String getElanFromLogicalSwitch(String logicalSwitchName) {
942 // Assuming elan name is same as logical switch name
943 String elanName = logicalSwitchName;
948 * Gets the logical switch name from elan name.
952 * @return the logical switch from elan name
954 public static String getLogicalSwitchFromElan(String elanName) {
955 // Assuming logical switch name is same as elan name
956 String logicalSwitchName = elanName;
957 return logicalSwitchName;
961 * Gets the l2 gateway connection job key.
965 * @param logicalSwitchName
966 * the logical switch name
967 * @return the l2 gateway connection job key
969 public static String getL2GatewayConnectionJobKey(String nodeId, String logicalSwitchName) {
970 return logicalSwitchName;
973 public static InstanceIdentifier<Interface> getInterfaceIdentifier(InterfaceKey interfaceKey) {
974 InstanceIdentifier.InstanceIdentifierBuilder<Interface> interfaceInstanceIdentifierBuilder =
975 InstanceIdentifier.builder(Interfaces.class).child(Interface.class, interfaceKey);
976 return interfaceInstanceIdentifierBuilder.build();
979 public static Interface getInterfaceFromConfigDS(InterfaceKey interfaceKey, DataBroker dataBroker) {
980 InstanceIdentifier<Interface> interfaceId = getInterfaceIdentifier(interfaceKey);
981 Optional<Interface> interfaceOptional = IfmUtil.read(LogicalDatastoreType.CONFIGURATION, interfaceId, dataBroker);
982 if (!interfaceOptional.isPresent()) {
986 return interfaceOptional.get();
990 * Delete l2 gateway device ucast local macs from elan.<br>
991 * Deletes macs from internal ELAN nodes and also on rest of external l2
992 * gateway devices which are part of the ELAN.
994 * @param l2GatewayDevice
995 * the l2 gateway device whose ucast local macs to be deleted
999 * @return the listenable future
1001 public static List<ListenableFuture<Void>> deleteL2GwDeviceUcastLocalMacsFromElan(L2GatewayDevice l2GatewayDevice,
1003 LOG.info("Deleting L2GatewayDevice [{}] UcastLocalMacs from elan [{}]", l2GatewayDevice.getHwvtepNodeId(), elanName);
1005 List<ListenableFuture<Void>> futures = new ArrayList<>();
1006 ElanInstance elan = ElanUtils.getElanInstanceByName(elanName);
1008 LOG.error("Could not find Elan by name: {}", elanName);
1012 List<MacAddress> localMacs = getL2GwDeviceLocalMacs(l2GatewayDevice);
1013 unInstallL2GwUcastMacFromElan(elan, l2GatewayDevice, localMacs);
1017 public static void createItmTunnels(ItmRpcService itmRpcService, String hwvtepId, String psName,
1018 IpAddress tunnelIp) {
1019 AddL2GwDeviceInputBuilder builder = new AddL2GwDeviceInputBuilder();
1020 builder.setTopologyId(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID.getValue());
1021 builder.setNodeId(HwvtepSouthboundUtils.createManagedNodeId(new NodeId(hwvtepId), psName).getValue());
1022 builder.setIpAddress(tunnelIp);
1024 Future<RpcResult<Void>> result = itmRpcService.addL2GwDevice(builder.build());
1025 RpcResult<Void> rpcResult = result.get();
1026 if (rpcResult.isSuccessful()) {
1027 LOG.info("Created ITM tunnels for {}", hwvtepId);
1029 LOG.error("Failed to create ITM Tunnels: ", rpcResult.getErrors());
1031 } catch (InterruptedException | ExecutionException e) {
1032 LOG.error("RPC to create ITM tunnels failed", e);
1036 public static String getNodeIdFromDpnId(BigInteger dpnId) {
1037 return MDSALUtil.NODE_PREFIX + MDSALUtil.SEPARATOR + dpnId.toString();
1040 public static void scheduleAddDpnMacInExtDevices(String elanName, BigInteger dpId,
1041 List<PhysAddress> staticMacAddresses) {
1042 ConcurrentMap<String, L2GatewayDevice> elanDevices = ElanL2GwCacheUtils
1043 .getInvolvedL2GwDevices(elanName);
1044 for (final L2GatewayDevice externalDevice : elanDevices.values()) {
1045 scheduleAddDpnMacsInExtDevice(elanName, dpId, staticMacAddresses, externalDevice);
1049 public static void scheduleAddDpnMacsInExtDevice(final String elanName, BigInteger dpId,
1050 final List<PhysAddress> staticMacAddresses,
1051 final L2GatewayDevice externalDevice) {
1052 NodeId nodeId = new NodeId(externalDevice.getHwvtepNodeId());
1053 final IpAddress dpnTepIp = ElanL2GatewayUtils.getSourceDpnTepIp(dpId, nodeId);
1054 LOG.trace("Dpn Tep IP: {} for dpnId: {} and nodeId: {}", dpnTepIp, dpId, nodeId);
1055 if (dpnTepIp == null) {
1056 LOG.error("could not install dpn mac in l2gw TEP IP not found for dpnId {} and nodeId {}", dpId, nodeId);
1059 TerminationPointKey tpKey = HwvtepSouthboundUtils.getTerminationPointKey(
1060 dpnTepIp.getIpv4Address().getValue());
1061 InstanceIdentifier<TerminationPoint> tpPath = HwvtepSouthboundUtils.createTerminationPointId
1064 HwvtepPhysicalLocatorListener.runJobAfterPhysicalLocatorIsAvialable(tpPath, new Runnable() {
1067 HwvtepUtils.installUcastMacs(broker,
1068 externalDevice.getHwvtepNodeId(), staticMacAddresses,
1069 elanName, dpnTepIp);
1074 public static void scheduleDeleteLogicalSwitch(final NodeId hwvtepNodeId, final String lsName) {
1075 TimerTask logicalSwitchDeleteTask = new TimerTask() {
1078 LogicalSwitchDeletedJob logicalSwitchDeletedJob = new LogicalSwitchDeletedJob(broker, hwvtepNodeId,
1080 ElanL2GatewayUtils.dataStoreJobCoordinator.enqueueJob(logicalSwitchDeletedJob.getJobKey(),
1081 logicalSwitchDeletedJob, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries());
1084 Pair<NodeId, String> nodeIdLogicalSwitchNamePair = new ImmutablePair<NodeId, String>(hwvtepNodeId, lsName);
1085 LogicalSwitchDeletedTasks.putIfAbsent(nodeIdLogicalSwitchNamePair, logicalSwitchDeleteTask);
1086 LogicalSwitchDeleteJobTimer.schedule(logicalSwitchDeleteTask, LOGICAL_SWITCH_DELETE_DELAY);
1089 public static void cancelDeleteLogicalSwitch(final NodeId hwvtepNodeId, final String lsName) {
1090 Pair<NodeId, String> nodeIdLogicalSwitchNamePair = new ImmutablePair<NodeId, String>(hwvtepNodeId, lsName);
1091 TimerTask logicalSwitchDeleteTask = LogicalSwitchDeletedTasks.get(nodeIdLogicalSwitchNamePair);
1092 if (logicalSwitchDeleteTask != null) {
1093 LOG.debug("Delete logical switch {} action on node {} cancelled", lsName, hwvtepNodeId);
1094 logicalSwitchDeleteTask.cancel();
1095 LogicalSwitchDeletedTasks.remove(nodeIdLogicalSwitchNamePair);