From 7664baf9520c32cf75703d5004589be2795e7a44 Mon Sep 17 00:00:00 2001 From: Somashekar Byrappa Date: Thu, 2 Jun 2016 17:35:30 +0530 Subject: [PATCH] L2 gateway functionality related fixes. + Earlier during l2gw connection delete, remote ucast macs to be deleted were the combination from ELAN MAC table plus other Elan L2Gateway devices local macs. This logic is changed. Now remote ucast macs for that particular elan is read/filtered from node config DS. + If batch deletion operation fails, macs are deleted sequentially. + During deletion of logical switch, updated to delete entry from LogicalSwitchDeletedTasks. + Renamed LogicalSwitchDeletedJob to DeleteLogicalSwitchJob which reflects its functionality. + Corrected job key in DeleteL2GwDeviceMacsFromElanJob. Change-Id: Ice6892c7a0bd8d703ba5527fa34afe613180230d Signed-off-by: Somashekar Byrappa --- .../jobs/DeleteL2GwDeviceMacsFromElanJob.java | 11 +- ...edJob.java => DeleteLogicalSwitchJob.java} | 8 +- .../elan/l2gw/utils/ElanL2GatewayUtils.java | 120 +++++++++--------- 3 files changed, 74 insertions(+), 65 deletions(-) rename vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/jobs/{LogicalSwitchDeletedJob.java => DeleteLogicalSwitchJob.java} (85%) diff --git a/vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/jobs/DeleteL2GwDeviceMacsFromElanJob.java b/vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/jobs/DeleteL2GwDeviceMacsFromElanJob.java index 3fb23d1c0e..6fc6bc2728 100644 --- a/vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/jobs/DeleteL2GwDeviceMacsFromElanJob.java +++ b/vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/l2gw/jobs/DeleteL2GwDeviceMacsFromElanJob.java @@ -71,8 +71,17 @@ public class DeleteL2GwDeviceMacsFromElanJob implements Callable>> { +public class DeleteLogicalSwitchJob implements Callable>> { private DataBroker broker; /** The logical switch name. */ @@ -31,9 +31,9 @@ public class LogicalSwitchDeletedJob implements Callable deleteElanMacsFromL2GatewayDevice(L2GatewayDevice l2GatewayDevice, String elanName) { - List elanMacTableEntries = getElanMacTableEntries(elanName); - List elanL2GatewayDevicesLocalMacs = getElanL2GatewayDevicesLocalMacs(l2GatewayDevice, elanName); - - List lstElanLocalMacs = new ArrayList<>(elanMacTableEntries); - lstElanLocalMacs.addAll(elanL2GatewayDevicesLocalMacs); + String hwvtepNodeId = l2GatewayDevice.getHwvtepNodeId(); + String logicalSwitch = getLogicalSwitchFromElan(elanName); - return HwvtepUtils.deleteRemoteUcastMacs(broker, new NodeId(l2GatewayDevice.getHwvtepNodeId()), - elanName, lstElanLocalMacs); - } + List lstElanMacs = + getRemoteUcastMacs(new NodeId(hwvtepNodeId), logicalSwitch, LogicalDatastoreType.CONFIGURATION); + ListenableFuture future = + HwvtepUtils.deleteRemoteUcastMacs(broker, new NodeId(hwvtepNodeId), logicalSwitch, lstElanMacs); - /** - * Gets the elan mac table entries. - * - * @param elanName - * the elan name - * @return the elan mac table entries as list - */ - public static List getElanMacTableEntries(String elanName) { - MacTable macTable = ElanUtils.getElanMacTable(elanName); - if (macTable == null || macTable.getMacEntry() == null || macTable.getMacEntry().isEmpty()) { - LOG.trace("MacTable is empty for elan: {}", elanName); - return Collections.emptyList(); - } - List lstMacs = Lists.transform(macTable.getMacEntry(), new Function() { + Futures.addCallback(future, new FutureCallback() { @Override - public MacAddress apply(MacEntry macEntry) { - return (macEntry != null) ? new MacAddress(macEntry.getMacAddress().getValue()) : null; + public void onSuccess(Void noarg) { + LOG.trace("Successful in batch deletion of elan [{}] macs from l2gw device [{}]", elanName, + hwvtepNodeId); } + + @Override + public void onFailure(Throwable error) { + LOG.warn(String.format( + "Failed during batch delete of elan [%s] macs from l2gw device [%s]. Retrying with sequential deletes.", + elanName, hwvtepNodeId), error); + if (lstElanMacs != null && !lstElanMacs.isEmpty()) { + for (MacAddress mac : lstElanMacs) { + HwvtepUtils.deleteRemoteUcastMac(broker, new NodeId(hwvtepNodeId), logicalSwitch, mac); + } + } + }; }); - return lstMacs; + + if (LOG.isDebugEnabled()) { + List elanMacs = lstElanMacs.stream().map(mac -> mac.getValue()).collect(Collectors.toList()); + LOG.debug("Deleting elan [{}] macs from node [{}]. Deleted macs = {}", elanName, hwvtepNodeId, elanMacs); + } + return future; } /** - * Gets the elan l2 gateway devices local macs. + * Gets the remote ucast macs from hwvtep node filtering based on logical + * switch. * - * @param l2GwDeviceToBeExcluded - * the l2 gw device to be excluded - * @param elanName - * the elan name - * @return the elan l2 gateway devices local macs + * @param hwvtepNodeId the hwvtep node id + * @param logicalSwitch the logical switch + * @param datastoreType the datastore type + * @return the remote ucast macs */ - public static List getElanL2GatewayDevicesLocalMacs(L2GatewayDevice l2GwDeviceToBeExcluded, - String elanName) { - List lstL2GatewayDeviceMacs = new ArrayList<>(); - - ConcurrentMap elanL2GwDevicesFromCache = ElanL2GwCacheUtils - .getInvolvedL2GwDevices(elanName); - if (elanL2GwDevicesFromCache != null) { - for (L2GatewayDevice otherDevice : elanL2GwDevicesFromCache.values()) { - if (!otherDevice.getHwvtepNodeId().equals(l2GwDeviceToBeExcluded.getHwvtepNodeId())) { - List lstUcastLocalMacs = otherDevice.getUcastLocalMacs(); - if (lstUcastLocalMacs != null) { - List l2GwDeviceMacs = Lists.transform(lstUcastLocalMacs, - new Function() { - @Override - public MacAddress apply(LocalUcastMacs localUcastMac) { - return (localUcastMac != null) ? localUcastMac.getMacEntryKey() : null; - } - }); - lstL2GatewayDeviceMacs.addAll(l2GwDeviceMacs); - } - } + public static List getRemoteUcastMacs(NodeId hwvtepNodeId, String logicalSwitch, + LogicalDatastoreType datastoreType) { + List lstMacs = Collections.emptyList(); + Node hwvtepNode = HwvtepUtils.getHwVtepNode(broker, datastoreType, hwvtepNodeId); + if (hwvtepNode != null) { + List remoteUcastMacs = + hwvtepNode.getAugmentation(HwvtepGlobalAugmentation.class).getRemoteUcastMacs(); + if (remoteUcastMacs != null && !remoteUcastMacs.isEmpty()) { + // Filtering remoteUcastMacs based on the logical switch and + // forming a list of MacAddress + lstMacs = remoteUcastMacs.stream() + .filter(mac -> logicalSwitch.equals(mac.getLogicalSwitchRef().getValue() + .firstKeyOf(LogicalSwitches.class).getHwvtepNodeName().getValue())) + .map(mac -> mac.getMacEntryKey()).collect(Collectors.toList()); } } - return lstL2GatewayDeviceMacs; + return lstMacs; } /** @@ -1100,14 +1097,17 @@ public class ElanL2GatewayUtils { TimerTask logicalSwitchDeleteTask = new TimerTask() { @Override public void run() { - LogicalSwitchDeletedJob logicalSwitchDeletedJob = new LogicalSwitchDeletedJob(broker, hwvtepNodeId, - lsName); - ElanL2GatewayUtils.dataStoreJobCoordinator.enqueueJob(logicalSwitchDeletedJob.getJobKey(), - logicalSwitchDeletedJob, SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries()); + Pair nodeIdLogicalSwitchNamePair = + new ImmutablePair(hwvtepNodeId, lsName); + LogicalSwitchDeletedTasks.remove(nodeIdLogicalSwitchNamePair); + + DeleteLogicalSwitchJob deleteLsJob = new DeleteLogicalSwitchJob(broker, hwvtepNodeId, lsName); + ElanL2GatewayUtils.dataStoreJobCoordinator.enqueueJob(deleteLsJob.getJobKey(), deleteLsJob, + SystemPropertyReader.getDataStoreJobCoordinatorMaxRetries()); } }; Pair nodeIdLogicalSwitchNamePair = new ImmutablePair(hwvtepNodeId, lsName); - LogicalSwitchDeletedTasks.putIfAbsent(nodeIdLogicalSwitchNamePair, logicalSwitchDeleteTask); + LogicalSwitchDeletedTasks.put(nodeIdLogicalSwitchNamePair, logicalSwitchDeleteTask); LogicalSwitchDeleteJobTimer.schedule(logicalSwitchDeleteTask, LOGICAL_SWITCH_DELETE_DELAY); } -- 2.36.6