import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
+import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
-import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.cache.InstanceIdDataObjectCache;
import org.opendaylight.genius.utils.SystemPropertyReader;
import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
import org.opendaylight.genius.utils.hwvtep.HwvtepUtils;
+import org.opendaylight.infrautils.caches.CacheProvider;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
import org.opendaylight.mdsal.common.api.CommitInfo;
import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.ReadFailedException;
import org.opendaylight.netvirt.elan.cache.ElanInstanceCache;
import org.opendaylight.netvirt.elan.cache.ElanInstanceDpnsCache;
import org.opendaylight.netvirt.elan.l2gw.ha.HwvtepHAUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.config.rev150710.ElanConfig;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan._interface.forwarding.entries.ElanInterfaceMac;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.dpn.interfaces.elan.dpn.interfaces.list.DpnInterfaces;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.forwarding.tables.MacTable;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepNodeName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorAugmentation;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalLocatorRef;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepPhysicalPortAugmentationBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LocalUcastMacs;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.LogicalSwitches;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacs;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteMcastMacsKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacs;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.global.attributes.RemoteUcastMacsKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.locator.set.attributes.LocatorSet;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.hwvtep.physical.port.attributes.VlanBindings;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
import org.opendaylight.yangtools.util.concurrent.FluentFutures;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcResult;
private final ConcurrentMap<Pair<NodeId, String>, DeleteLogicalSwitchJob> deleteJobs = new ConcurrentHashMap<>();
private final Scheduler scheduler;
private final ElanConfig elanConfig;
+ private final ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils;
+ private final InstanceIdDataObjectCache<TerminationPoint> portsCache;
@Inject
public ElanL2GatewayUtils(DataBroker broker, ElanDmacUtils elanDmacUtils, ElanItmUtils elanItmUtils,
- ElanClusterUtils elanClusterUtils, OdlInterfaceRpcService interfaceManagerRpcService,
- JobCoordinator jobCoordinator, ElanUtils elanUtils,
- Scheduler scheduler, ElanConfig elanConfig, ElanInstanceCache elanInstanceCache,
- ElanInstanceDpnsCache elanInstanceDpnsCache) {
+ ElanClusterUtils elanClusterUtils, OdlInterfaceRpcService interfaceManagerRpcService,
+ JobCoordinator jobCoordinator, ElanUtils elanUtils,
+ Scheduler scheduler, ElanConfig elanConfig, ElanInstanceCache elanInstanceCache,
+ ElanInstanceDpnsCache elanInstanceDpnsCache,
+ ElanL2GatewayMulticastUtils elanL2GatewayMulticastUtils,
+ CacheProvider cacheProvider) {
this.broker = broker;
this.txRunner = new ManagedNewTransactionRunnerImpl(broker);
this.elanDmacUtils = elanDmacUtils;
this.elanConfig = elanConfig;
this.elanInstanceCache = elanInstanceCache;
this.elanInstanceDpnsCache = elanInstanceDpnsCache;
+ this.elanL2GatewayMulticastUtils = elanL2GatewayMulticastUtils;
+ InstanceIdentifier<TerminationPoint> iid = InstanceIdentifier.create(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID))
+ .child(Node.class).child(TerminationPoint.class);
+ LOG.info("termination point iid: {}", iid);
+ portsCache = new InstanceIdDataObjectCache<>(TerminationPoint.class, broker,
+ LogicalDatastoreType.CONFIGURATION, iid, cacheProvider);
}
@PreDestroy
* the lst elan interface names
* @return the list
*/
+ /*
public List<PhysAddress> getElanDpnMacsFromInterfaces(Set<String> lstElanInterfaceNames) {
List<PhysAddress> result = new ArrayList<>();
for (String interfaceName : lstElanInterfaceNames) {
ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(broker, interfaceName);
- if (elanInterfaceMac != null && elanInterfaceMac.nonnullMacEntry() != null) {
- for (MacEntry macEntry : new ArrayList<>(elanInterfaceMac.nonnullMacEntry().values())) {
+ if (elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
+ for (MacEntry macEntry : elanInterfaceMac.getMacEntry()) {
result.add(macEntry.getMacAddress());
}
}
}
return result;
- }
+ }*/
/**
* Check if phy locator already exists in remote mcast entry.
* the elan instance
* @param macAddresses
* the mac addresses
- * @return Future which completes once the removal is done.
*/
- public FluentFuture<?> removeMacsFromElanExternalDevices(ElanInstance elanInstance,
- List<PhysAddress> macAddresses) {
- final String elanName = elanInstance.getElanInstanceName();
- final Collection<L2GatewayDevice> devices = ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName);
- if (devices.isEmpty()) {
- return FluentFutures.immediateNullFluentFuture();
+ public void removeMacsFromElanExternalDevices(ElanInstance elanInstance, List<PhysAddress> macAddresses) {
+ ConcurrentMap<String, L2GatewayDevice> elanL2GwDevices = ElanL2GwCacheUtils
+ .getInvolvedL2GwDevices(elanInstance.getElanInstanceName());
+ for (L2GatewayDevice l2GatewayDevice : elanL2GwDevices.values()) {
+ removeRemoteUcastMacsFromExternalDevice(l2GatewayDevice.getHwvtepNodeId(),
+ elanInstance.getElanInstanceName(), macAddresses);
}
+ }
- final List<MacAddress> lstMac = macAddresses.stream()
- .filter(Objects::nonNull)
- .map(physAddress -> new MacAddress(physAddress.getValue()))
- .collect(Collectors.toList());
- if (lstMac.isEmpty()) {
- return FluentFutures.immediateNullFluentFuture();
- }
+ /**
+ * Removes the given MAC Addresses from the specified External Device.
+ *
+ * @param deviceNodeId
+ * the device node id
+ * @param macAddresses
+ * the mac addresses
+ * @return the listenable future
+ */
+ private FluentFuture<? extends @NonNull CommitInfo> removeRemoteUcastMacsFromExternalDevice(String deviceNodeId,
+ String logicalSwitchName, List<PhysAddress> macAddresses) {
+ NodeId nodeId = new NodeId(deviceNodeId);
+
+ // TODO (eperefr)
+ List<MacAddress> lstMac = macAddresses.stream().filter(Objects::nonNull).map(
+ physAddress -> new MacAddress(physAddress.getValue().toLowerCase(Locale.getDefault())))
+ .collect(Collectors.toList());
+ return HwvtepUtils.deleteRemoteUcastMacs(broker, nodeId, logicalSwitchName, lstMac);
+ }
- return txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, transaction -> {
- for (L2GatewayDevice l2GatewayDevice : devices) {
- final NodeId nodeId = new NodeId(l2GatewayDevice.getHwvtepNodeId());
- for (MacAddress mac : lstMac) {
- HwvtepUtils.deleteRemoteUcastMac(transaction, nodeId, elanName, mac);
- }
- }
- });
+ @Nullable
+ public ElanInstance getElanInstanceForUcastLocalMac(LocalUcastMacs localUcastMac) {
+ Optional<LogicalSwitches> lsOpc = ElanUtils.read(broker, LogicalDatastoreType.OPERATIONAL,
+ (InstanceIdentifier<LogicalSwitches>) localUcastMac.getLogicalSwitchRef().getValue());
+ if (lsOpc.isPresent()) {
+ LogicalSwitches ls = lsOpc.get();
+ // Logical switch name is Elan name
+ String elanName = getElanFromLogicalSwitch(ls.getHwvtepNodeName().getValue());
+ return elanInstanceCache.get(elanName).orElse(null);
+ }
+ return null;
}
/**
String elanName = elan.getElanInstanceName();
List<ListenableFuture<Void>> fts = new ArrayList<>();
Collection<LocalUcastMacs> l2gwDeviceLocalMacs = l2gwDevice.getUcastLocalMacs();
- if (!l2gwDeviceLocalMacs.isEmpty()) {
+ if (l2gwDeviceLocalMacs != null && !l2gwDeviceLocalMacs.isEmpty()) {
for (LocalUcastMacs localUcastMac : l2gwDeviceLocalMacs) {
fts.addAll(elanDmacUtils.installDmacFlowsToExternalRemoteMacInBatch(dpnId, l2gwDevice.getHwvtepNodeId(),
elan.getElanTag().toJava(), ElanUtils.getVxlanSegmentationId(elan).longValue(),
* the interface name
*/
public void installElanL2gwDevicesLocalMacsInDpn(Uint64 dpnId, ElanInstance elan, String interfaceName) {
- for (L2GatewayDevice l2gwDevice : ElanL2GwCacheUtils.getInvolvedL2GwDevices(elan.getElanInstanceName())) {
- installDmacFlowsOnDpn(dpnId, l2gwDevice, elan, interfaceName);
+ ConcurrentMap<String, L2GatewayDevice> elanL2GwDevicesFromCache = ElanL2GwCacheUtils
+ .getInvolvedL2GwDevices(elan.getElanInstanceName());
+ if (elanL2GwDevicesFromCache != null) {
+ for (L2GatewayDevice l2gwDevice : elanL2GwDevicesFromCache.values()) {
+ installDmacFlowsOnDpn(dpnId, l2gwDevice, elan, interfaceName);
+ }
+ } else {
+ LOG.debug("No Elan l2 gateway devices in cache for [{}] ", elan.getElanInstanceName());
}
}
final String extDeviceNodeId = extL2GwDevice.getHwvtepNodeId();
final String elanInstanceName = elan.getElanInstanceName();
final Collection<DpnInterfaces> elanDpns = getElanDpns(elanInstanceName);
- Collection<L2GatewayDevice> elanL2GwDevices = ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanInstanceName);
+ ConcurrentMap<String, L2GatewayDevice> elanL2GwDevices = ElanL2GwCacheUtils
+ .getInvolvedL2GwDevices(elanInstanceName);
// Retrieve all participating DPNs in this Elan. Populate this MAC in
// DMAC table.
// Looping through all DPNs in order to add/remove mac flows in their
// DMAC table
- if (elanDpns.size() > 0 || elanL2GwDevices.size() > 0) {
+ if (elanDpns.size() > 0 || elanL2GwDevices.values().size() > 0) {
String jobKey = elanInstanceName + ":" + macToBeAdded;
IpAddress extL2GwDeviceTepIp = extL2GwDevice.getTunnelIp();
List<PhysAddress> macList = Lists.newArrayList(new PhysAddress(macToBeAdded));
elanClusterUtils.runOnlyInOwnerNode(jobKey, "install l2gw macs in dmac table", () -> {
if (doesLocalUcastMacExistsInCache(extL2GwDevice, localUcastMacs)) {
- List<ListenableFuture<Void>> futures = new ArrayList<>();
+ List<ListenableFuture<?>> futures = new ArrayList<>();
for (DpnInterfaces elanDpn : elanDpns) {
- futures.addAll(elanDmacUtils.installDmacFlowsToExternalRemoteMacInBatch(
- elanDpn.getDpId(),
+ futures.addAll(elanDmacUtils.installDmacFlowsToExternalRemoteMacInBatch(elanDpn.getDpId(),
extDeviceNodeId, elan.getElanTag().toJava(),
ElanUtils.getVxlanSegmentationId(elan).longValue(),
macToBeAdded, elanInstanceName, interfaceName));
}
- for (L2GatewayDevice otherDevice : elanL2GwDevices) {
+ for (L2GatewayDevice otherDevice : elanL2GwDevices.values()) {
if (!otherDevice.getHwvtepNodeId().equals(extDeviceNodeId)
&& !areMLAGDevices(extL2GwDevice, otherDevice)) {
final String hwvtepId = otherDevice.getHwvtepNodeId();
final String logicalSwitchName = elanInstanceName;
- HwvtepUtils.installUcastMacs(broker, hwvtepId, macList, logicalSwitchName,
- extL2GwDeviceTepIp);
+ HwvtepUtils.installUcastMacs(
+ broker, hwvtepId, macList, logicalSwitchName, extL2GwDeviceTepIp);
}
}
return futures;
for (DpnInterfaces elanDpn : elanDpns) {
Uint64 dpnId = elanDpn.getDpId();
result.addAll(elanDmacUtils.deleteDmacFlowsToExternalMac(elan.getElanTag().toJava(), dpnId,
- l2GwDevice.getHwvtepNodeId(),
- IetfYangUtil.INSTANCE.canonizeMacAddress(mac).getValue()));
+ l2GwDevice.getHwvtepNodeId(),
+ IetfYangUtil.INSTANCE.canonizeMacAddress(mac).getValue()));
}
return result;
});
* the dpn id
*/
public void deleteElanL2GwDevicesUcastLocalMacsFromDpn(final String elanName, final Uint64 dpnId) {
- Collection<L2GatewayDevice> elanL2GwDevices = ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName);
- if (elanL2GwDevices.isEmpty()) {
+ ConcurrentMap<String, L2GatewayDevice> elanL2GwDevices = ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName);
+ if (elanL2GwDevices == null || elanL2GwDevices.isEmpty()) {
LOG.trace("No L2 gateway devices in Elan [{}] cache.", elanName);
return;
}
LOG.info("Deleting Elan [{}] L2GatewayDevices UcastLocalMacs from Dpn [{}]", elanName, dpnId);
final Long elanTag = elan.getElanTag().toJava();
- for (final L2GatewayDevice l2GwDevice : elanL2GwDevices) {
+ for (final L2GatewayDevice l2GwDevice : elanL2GwDevices.values()) {
getL2GwDeviceLocalMacsAndRunCallback(elan.getElanInstanceName(), l2GwDevice, (localMacs) -> {
for (MacAddress mac : localMacs) {
String jobKey = elanName + ":" + mac.getValue();
Collection<LocalUcastMacs> lstUcastLocalMacs = l2gwDevice.getUcastLocalMacs();
if (!lstUcastLocalMacs.isEmpty()) {
macs.addAll(lstUcastLocalMacs.stream().filter(Objects::nonNull)
- .map(mac -> new MacAddress(mac.getMacEntryKey().getValue().toLowerCase(Locale.ENGLISH)))
+ .map(mac -> new MacAddress(mac.getMacEntryKey().getValue().toLowerCase(Locale.getDefault())))
.collect(Collectors.toList()));
}
HwvtepGlobalAugmentation augmentation = configNode.get().augmentation(
HwvtepGlobalAugmentation.class);
if (augmentation != null && augmentation.nonnullLocalUcastMacs() != null) {
- macs.addAll(new ArrayList<>(augmentation
- .nonnullLocalUcastMacs().values()).stream()
+ macs.addAll(augmentation.nonnullLocalUcastMacs().values().stream()
.filter(mac -> getLogicalSwitchName(mac).equals(elanName))
- .map(HwvtepMacTableGenericAttributes::getMacEntryKey)
+ .map(mac -> mac.getMacEntryKey())
.collect(Collectors.toSet()));
}
function.apply(macs);
}, MoreExecutors.directExecutor());
}
- private static String getLogicalSwitchName(LocalUcastMacs mac) {
+ private String getLogicalSwitchName(LocalUcastMacs mac) {
return ((InstanceIdentifier<LogicalSwitches>)mac.getLogicalSwitchRef().getValue())
.firstKeyOf(LogicalSwitches.class).getHwvtepNodeName().getValue();
}
* the elan name
* @return the listenable future
*/
- public FluentFuture<? extends CommitInfo> deleteElanMacsFromL2GatewayDevice(String hwvtepNodeId, String elanName) {
- String logicalSwitch = getLogicalSwitchFromElan(elanName);
+ public FluentFuture<? extends @NonNull CommitInfo> deleteElanMacsFromL2GatewayDevice(String hwvtepNodeId,
+ String elanName) {
+ String logicalSwitch = getLogicalSwitchFromElan(elanName);
List<MacAddress> lstElanMacs = getRemoteUcastMacs(new NodeId(hwvtepNodeId), logicalSwitch,
LogicalDatastoreType.CONFIGURATION);
- FluentFuture<? extends CommitInfo> future = HwvtepUtils.deleteRemoteUcastMacs(broker, new NodeId(hwvtepNodeId),
- logicalSwitch, lstElanMacs);
-
- Futures.addCallback(future, new FutureCallback<CommitInfo>() {
- @Override
- public void onSuccess(CommitInfo noarg) {
- LOG.trace("Successful in batch deletion of elan [{}] macs from l2gw device [{}]", elanName,
- hwvtepNodeId);
- }
-
- @Override
- public void onFailure(Throwable error) {
- LOG.warn("Failed during batch delete of elan {} macs from l2gw device {}. "
- + "Retrying with sequential deletes.", elanName, hwvtepNodeId, error);
- if (lstElanMacs != null && !lstElanMacs.isEmpty()) {
- for (MacAddress mac : lstElanMacs) {
- HwvtepUtils.deleteRemoteUcastMac(broker, new NodeId(hwvtepNodeId), logicalSwitch, mac);
- }
- }
- }
- }, MoreExecutors.directExecutor());
-
if (LOG.isDebugEnabled()) {
List<String> elanMacs = lstElanMacs.stream().map(MacAddress::getValue).collect(Collectors.toList());
LOG.debug("Deleting elan [{}] macs from node [{}]. Deleted macs = {}", elanName, hwvtepNodeId, elanMacs);
}
- return future;
+ return HwvtepUtils.deleteRemoteUcastMacs(broker, new NodeId(hwvtepNodeId),
+ logicalSwitch, lstElanMacs);
}
/**
public List<MacAddress> getRemoteUcastMacs(NodeId hwvtepNodeId, String logicalSwitch,
LogicalDatastoreType datastoreType) {
List<MacAddress> lstMacs = Collections.emptyList();
- Node hwvtepNode;
+ Node hwvtepNode = null;
try {
hwvtepNode = HwvtepUtils.getHwVtepNode(broker, datastoreType, hwvtepNodeId);
- } catch (ExecutionException | InterruptedException e) {
- LOG.error("getRemoteUcastMacs: Exception while reading hwvtepNodeId DS for the hwvtepNodeId {}",
- hwvtepNodeId.getValue(), e);
- return Collections.emptyList();
+ } catch (InterruptedException | ExecutionException e) {
+ LOG.error("Exception While Reading Node {}", hwvtepNodeId, e);
}
if (hwvtepNode != null) {
- Map<RemoteUcastMacsKey, RemoteUcastMacs> keyRemoteUcastMacsMap
- = hwvtepNode.augmentation(HwvtepGlobalAugmentation.class)
- .nonnullRemoteUcastMacs();
- if (keyRemoteUcastMacsMap != null && !keyRemoteUcastMacsMap.isEmpty()) {
- // Filtering keyRemoteUcastMacsMap based on the logical switch and
+ Collection<RemoteUcastMacs> remoteUcastMacs = hwvtepNode.augmentation(HwvtepGlobalAugmentation.class)
+ .nonnullRemoteUcastMacs().values();
+ if (remoteUcastMacs != null && !remoteUcastMacs.isEmpty()) {
+ // Filtering remoteUcastMacs based on the logical switch and
// forming a list of MacAddress
- lstMacs = keyRemoteUcastMacsMap.values().stream()
+ lstMacs = remoteUcastMacs.stream()
.filter(mac -> logicalSwitch.equals(mac.getLogicalSwitchRef().getValue()
.firstKeyOf(LogicalSwitches.class).getHwvtepNodeName().getValue()))
.map(HwvtepMacTableGenericAttributes::getMacEntryKey).collect(Collectors.toList());
* @return the listenable future
*/
public FluentFuture<? extends CommitInfo> installElanMacsInL2GatewayDevice(String elanName,
- L2GatewayDevice l2GatewayDevice) {
+ L2GatewayDevice l2GatewayDevice) {
String logicalSwitchName = getLogicalSwitchFromElan(elanName);
NodeId hwVtepNodeId = new NodeId(l2GatewayDevice.getHwvtepNodeId());
lstRemoteUcastMacs.addAll(lstElanMacTableEntries);
FluentFuture<? extends CommitInfo> future = HwvtepUtils.addRemoteUcastMacs(broker, hwVtepNodeId,
- lstRemoteUcastMacs);
+ lstRemoteUcastMacs);
LOG.info("Added RemoteUcastMacs entries [{}] in config DS. NodeID: {}, LogicalSwitch: {}",
lstRemoteUcastMacs.size(), hwVtepNodeId.getValue(), logicalSwitchName);
public static List<RemoteUcastMacs> getOtherDevicesMacs(String elanName,
L2GatewayDevice l2GatewayDeviceToBeConfigured, NodeId hwVtepNodeId, String logicalSwitchName) {
List<RemoteUcastMacs> lstRemoteUcastMacs = new ArrayList<>();
+ ConcurrentMap<String, L2GatewayDevice> elanL2GwDevicesFromCache = ElanL2GwCacheUtils
+ .getInvolvedL2GwDevices(elanName);
- for (L2GatewayDevice otherDevice : ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName)) {
- if (l2GatewayDeviceToBeConfigured.getHwvtepNodeId().equals(otherDevice.getHwvtepNodeId())) {
- continue;
- }
- if (!areMLAGDevices(l2GatewayDeviceToBeConfigured, otherDevice)) {
- for (LocalUcastMacs localUcastMac : otherDevice.getUcastLocalMacs()) {
- HwvtepPhysicalLocatorAugmentation physLocatorAug = HwvtepSouthboundUtils
- .createHwvtepPhysicalLocatorAugmentation(otherDevice.getTunnelIp());
- RemoteUcastMacs remoteUcastMac = HwvtepSouthboundUtils.createRemoteUcastMac(hwVtepNodeId,
- IetfYangUtil.INSTANCE.canonizeMacAddress(localUcastMac.getMacEntryKey()).getValue(),
- localUcastMac.getIpaddr(), logicalSwitchName, physLocatorAug);
- lstRemoteUcastMacs.add(remoteUcastMac);
+ if (elanL2GwDevicesFromCache != null) {
+ for (L2GatewayDevice otherDevice : elanL2GwDevicesFromCache.values()) {
+ if (l2GatewayDeviceToBeConfigured.getHwvtepNodeId().equals(otherDevice.getHwvtepNodeId())) {
+ continue;
+ }
+ if (!areMLAGDevices(l2GatewayDeviceToBeConfigured, otherDevice)) {
+ for (LocalUcastMacs localUcastMac : otherDevice.getUcastLocalMacs()) {
+ HwvtepPhysicalLocatorAugmentation physLocatorAug = HwvtepSouthboundUtils
+ .createHwvtepPhysicalLocatorAugmentation(otherDevice.getTunnelIp().stringValue());
+ RemoteUcastMacs remoteUcastMac = HwvtepSouthboundUtils.createRemoteUcastMac(hwVtepNodeId,
+ localUcastMac.getMacEntryKey().getValue().toLowerCase(Locale.getDefault()),
+ localUcastMac.getIpaddr(), logicalSwitchName, physLocatorAug);
+ lstRemoteUcastMacs.add(remoteUcastMac);
+ }
}
}
}
return lstRemoteUcastMacs;
}
- for (MacEntry macEntry : new ArrayList<>(macTable.nonnullMacEntry().values())) {
+ for (MacEntry macEntry : macTable.nonnullMacEntry().values()) {
Uint64 dpnId = getDpidFromInterface(macEntry.getInterface());
if (dpnId == null) {
LOG.error("DPN ID not found for interface {}", macEntry.getInterface());
// TODO: Query ARP cache to get IP address corresponding to the
// MAC
RemoteUcastMacs remoteUcastMac = HwvtepSouthboundUtils.createRemoteUcastMac(hwVtepNodeId,
- IetfYangUtil.INSTANCE.canonizePhysAddress(macEntry.getMacAddress()).getValue(), null /*IpAddress*/,
+ IetfYangUtil.INSTANCE.canonizePhysAddress(macEntry.getMacAddress()).getValue(), null /*IpAddress*/,
logicalSwitchName, physLocatorAug);
lstRemoteUcastMacs.add(remoteUcastMac);
}
* the interface name
* @return the dpid from interface
*/
- @Nullable
public Uint64 getDpidFromInterface(String interfaceName) {
Uint64 dpId = null;
Future<RpcResult<GetDpidFromInterfaceOutput>> output = interfaceManagerRpcService
dpId = rpcResult.getResult().getDpid();
}
} catch (InterruptedException | ExecutionException e) {
- LOG.error("Failed to get the DPN ID for interface {}", interfaceName, e);
+ LOG.error("Failed to get the DPN ID for interface: {} ", interfaceName, e);
}
return dpId;
}
+ /**
+ * Update vlan bindings in l2 gateway device.
+ *
+ * @param nodeId
+ * the node id
+ * @param psName
+ * the physical switch name
+ * @param interfaceName
+ * the interface in physical switch
+ * @param vlanBindings
+ * the vlan bindings to be configured
+ * @return the listenable future
+ */
+ public FluentFuture<?> updateVlanBindingsInL2GatewayDevice(NodeId nodeId, String psName,
+ String interfaceName,
+ List<VlanBindings> vlanBindings) {
+ return txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
+ mergeVlanBindings(tx, nodeId, psName, interfaceName, vlanBindings, false);
+ LOG.info("Updated Hwvtep VlanBindings in config DS. NodeID: {}", nodeId.getValue());
+ });
+ }
+
/**
* Update vlan bindings in l2 gateway device.
*
* the default vlan id
* @return the listenable future
*/
- public ListenableFuture<?> updateVlanBindingsInL2GatewayDevice(NodeId nodeId, String logicalSwitchName,
+ public FluentFuture<?> updateVlanBindingsInL2GatewayDevice(NodeId nodeId, String logicalSwitchName,
Devices hwVtepDevice, Integer defaultVlanId) {
if (hwVtepDevice == null || hwVtepDevice.getInterfaces() == null || hwVtepDevice.getInterfaces().isEmpty()) {
String errMsg = "HwVtepDevice is null or interfaces are empty.";
LOG.error(errMsg);
- return Futures.immediateFailedFuture(new RuntimeException(errMsg));
+ return FluentFutures.immediateFailedFluentFuture(new RuntimeException(errMsg));
}
-
return txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712
- .l2gateway.attributes.devices.Interfaces deviceInterface : new ArrayList<>(hwVtepDevice
- .nonnullInterfaces().values())) {
+ .l2gateway.attributes.devices.Interfaces deviceInterface : hwVtepDevice
+ .nonnullInterfaces().values()) {
//Removed the check for checking terminationPoint present in OP or not
//for coniguring vlan bindings
//As we are not any more dependent on it , plugin takes care of this
// with port reconcilation.
List<VlanBindings> vlanBindings = new ArrayList<>();
- if (deviceInterface.getSegmentationIds() != null && !deviceInterface.getSegmentationIds().isEmpty()) {
+ if (deviceInterface.getSegmentationIds() != null && !deviceInterface
+ .getSegmentationIds().isEmpty()) {
for (Integer vlanId : deviceInterface.getSegmentationIds()) {
- vlanBindings.add(HwvtepSouthboundUtils.createVlanBinding(nodeId, vlanId, logicalSwitchName));
+ vlanBindings.add(HwvtepSouthboundUtils
+ .createVlanBinding(nodeId, vlanId, logicalSwitchName));
}
} else {
// Use defaultVlanId (specified in L2GatewayConnection) if Vlan
// ID not specified at interface level.
- vlanBindings.add(HwvtepSouthboundUtils.createVlanBinding(nodeId, defaultVlanId, logicalSwitchName));
+ vlanBindings.add(HwvtepSouthboundUtils
+ .createVlanBinding(nodeId, defaultVlanId, logicalSwitchName));
+ }
+
+ TerminationPointKey tpKey = new TerminationPointKey(
+ new TpId(deviceInterface.getInterfaceName()));
+ InstanceIdentifier<TerminationPoint> portIid = HwvtepSouthboundUtils
+ .createTerminationPointId(HwvtepSouthboundUtils.createManagedNodeId(nodeId,
+ hwVtepDevice.getDeviceName()), tpKey);
+
+ try {
+ boolean createParent = false;
+ if (!portsCache.get(portIid).isPresent()) {
+ //create port
+ //pass additional flag
+ createParent = true;
+ }
+ mergeVlanBindings(tx, nodeId, hwVtepDevice.getDeviceName(),
+ deviceInterface.getInterfaceName(), vlanBindings, createParent);
+ } catch (ReadFailedException e) {
+ LOG.error("Read Failed for PortIid {} {}", portIid, e.getMessage());
}
- HwvtepUtils.mergeVlanBindings(tx, nodeId, hwVtepDevice.getDeviceName(),
- deviceInterface.getInterfaceName(), vlanBindings);
}
- LOG.info("Updated Hwvtep VlanBindings in config DS. NodeID: {}, LogicalSwitch: {}", nodeId.getValue(),
- logicalSwitchName);
+ LOG.info("Updated Hwvtep VlanBindings in config DS. NodeID: {}, LogicalSwitch: {}",
+ nodeId.getValue(),logicalSwitchName);
});
}
- /**
- * Update vlan bindings in l2 gateway device.
- *
- * @param nodeId
- * the node id
- * @param psName
- * the physical switch name
- * @param interfaceName
- * the interface in physical switch
- * @param vlanBindings
- * the vlan bindings to be configured
- * @return the listenable future
- */
- public ListenableFuture<?> updateVlanBindingsInL2GatewayDevice(NodeId nodeId, String psName,
- String interfaceName, List<VlanBindings> vlanBindings) {
- return txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
- HwvtepUtils.mergeVlanBindings(tx, nodeId, psName, interfaceName, vlanBindings);
- LOG.info("Updated Hwvtep VlanBindings in config DS. NodeID: {}", nodeId.getValue());
- });
+ private static void mergeVlanBindings(TypedWriteTransaction tx, NodeId nodeId, String phySwitchName,
+ String phyPortName, List<VlanBindings> vlanBindings,
+ boolean createParent) {
+ NodeId physicalSwitchNodeId = HwvtepSouthboundUtils.createManagedNodeId(nodeId, phySwitchName);
+ mergeVlanBindings(tx, physicalSwitchNodeId, phyPortName, vlanBindings, createParent);
+ }
+
+ private static void mergeVlanBindings(TypedWriteTransaction tx, NodeId physicalSwitchNodeId,
+ String phyPortName, List<VlanBindings> vlanBindings,
+ boolean createParent) {
+ HwvtepPhysicalPortAugmentation phyPortAug = (new HwvtepPhysicalPortAugmentationBuilder())
+ .setHwvtepNodeName(new HwvtepNodeName(phyPortName)).setVlanBindings(vlanBindings).build();
+ InstanceIdentifier<HwvtepPhysicalPortAugmentation> iid = HwvtepSouthboundUtils
+ .createPhysicalPortInstanceIdentifier(physicalSwitchNodeId, phyPortName);
+ if (createParent) {
+ InstanceIdentifier<TerminationPoint> iid2 =
+ createPhysicalPortInstanceIdentifier(physicalSwitchNodeId, phyPortName);
+ TerminationPointBuilder tpBuilder = new TerminationPointBuilder().setTpId(new TpId(phyPortName))
+ .addAugmentation(phyPortAug);
+ tx.merge(iid2, tpBuilder.build());
+ } else {
+ tx.merge(iid, phyPortAug);
+ }
+ }
+
+ public static InstanceIdentifier<TerminationPoint> createPhysicalPortInstanceIdentifier(
+ NodeId physicalSwitchNodeId, String phyPortName) {
+ return createInstanceIdentifier(physicalSwitchNodeId).child(TerminationPoint.class,
+ new TerminationPointKey(new TpId(phyPortName)));
+ }
+
+ public static InstanceIdentifier<Node> createInstanceIdentifier(NodeId nodeId) {
+ return InstanceIdentifier.create(NetworkTopology.class).child(Topology.class,
+ new TopologyKey(HwvtepSouthboundConstants.HWVTEP_TOPOLOGY_ID)).child(Node.class, new NodeKey(nodeId));
}
/**
return txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l2gateways.rev150712
- .l2gateway.attributes.devices.Interfaces deviceInterface : new ArrayList<>(hwVtepDevice
- .nonnullInterfaces().values())) {
+ .l2gateway.attributes.devices.Interfaces deviceInterface : hwVtepDevice.nonnullInterfaces().values()) {
String phyPortName = deviceInterface.getInterfaceName();
if (deviceInterface.getSegmentationIds() != null && !deviceInterface.getSegmentationIds().isEmpty()) {
for (Integer vlanId : deviceInterface.getSegmentationIds()) {
});
}
+ /**
+ * Gets the elan name from logical switch name.
+ *
+ * @param logicalSwitchName
+ * the logical switch name
+ * @return the elan name from logical switch name
+ */
+ public static String getElanFromLogicalSwitch(String logicalSwitchName) {
+ // Assuming elan name is same as logical switch name
+ String elanName = logicalSwitchName;
+ return elanName;
+ }
+
/**
* Gets the logical switch name from elan name.
*
private static Optional<TransportZones> readTransportZone(DataBroker dataBroker) throws ExecutionException,
InterruptedException {
return new SingleTransactionDataBroker(dataBroker).syncReadOptional(LogicalDatastoreType.CONFIGURATION,
- InstanceIdentifier.builder(TransportZones.class).build());
- }
-
- private static Optional<ElanInstances> readElanInstances(DataBroker dataBroker) throws ExecutionException,
- InterruptedException {
- return new SingleTransactionDataBroker(dataBroker).syncReadOptional(LogicalDatastoreType.CONFIGURATION,
- InstanceIdentifier.builder(ElanInstances.class).build());
+ InstanceIdentifier.builder(TransportZones.class).build());
}
private static String getPsName(DeviceVteps deviceVteps) {
}
private static void deleteStaleL2gwTep(DataBroker dataBroker,
- ItmRpcService itmRpcService,
- DeviceVteps deviceVteps) {
+ ItmRpcService itmRpcService,
+ DeviceVteps deviceVteps) {
String psName = HwvtepHAUtil.getPsName(HwvtepHAUtil.convertToInstanceIdentifier(deviceVteps.getNodeId()));
String globalNodeId = HwvtepHAUtil.convertToGlobalNodeId(deviceVteps.getNodeId());
try {
}
}
+ private static Optional<ElanInstances> readElanInstances(DataBroker dataBroker) throws ExecutionException,
+ InterruptedException {
+ return new SingleTransactionDataBroker(dataBroker).syncReadOptional(LogicalDatastoreType.CONFIGURATION,
+ InstanceIdentifier.builder(ElanInstances.class).build());
+ }
+ /*public static void createItmTunnels(IpAddress tunnelIp, DataBroker dataBroker) {
+ ManagedNewTransactionRunner txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+ txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> {
+ InstanceIdentifier<L2GatewayIp> iid = InstanceIdentifier
+ .builder(L2GatewayIpList.class)
+ .child(L2GatewayIp.class, new L2GatewayIpKey(tunnelIp))
+ .build();
+ tx.put(iid, new L2GatewayIpBuilder().setIpAddress(tunnelIp).build());
+ });
+ }
+
+ public static FluentFuture<? extends CommitInfo> deleteItmTunnels(
+ IpAddress tunnelIp, DataBroker dataBroker) {
+ ManagedNewTransactionRunner txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
+ return txRunner.callWithNewWriteOnlyTransactionAndSubmit(LogicalDatastoreType.CONFIGURATION, tx -> {
+ InstanceIdentifier<L2GatewayIp> iid = InstanceIdentifier
+ .builder(L2GatewayIpList.class)
+ .child(L2GatewayIp.class, new L2GatewayIpKey(tunnelIp))
+ .build();
+ tx.delete(iid);
+ });
+ }*/
+
+ public static String getNodeIdFromDpnId(BigInteger dpnId) {
+ return MDSALUtil.NODE_PREFIX + MDSALUtil.SEPARATOR + dpnId.toString();
+ }
+
public void scheduleAddDpnMacInExtDevices(String elanName, Uint64 dpId,
List<PhysAddress> staticMacAddresses) {
- for (final L2GatewayDevice externalDevice : ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName)) {
+ ConcurrentMap<String, L2GatewayDevice> elanDevices = ElanL2GwCacheUtils.getInvolvedL2GwDevices(elanName);
+ for (final L2GatewayDevice externalDevice : elanDevices.values()) {
scheduleAddDpnMacsInExtDevice(elanName, dpId, staticMacAddresses, externalDevice);
}
}
- public void scheduleAddDpnMacsInExtDevice(final String elanName, Uint64 dpId,
- final List<PhysAddress> staticMacAddresses, final L2GatewayDevice externalDevice) {
+ public FluentFuture<? extends @NonNull CommitInfo> scheduleAddDpnMacsInExtDevice(final String elanName, Uint64 dpId,
+ final List<PhysAddress> staticMacAddresses,
+ final L2GatewayDevice externalDevice) {
NodeId nodeId = new NodeId(externalDevice.getHwvtepNodeId());
final IpAddress dpnTepIp = elanItmUtils.getSourceDpnTepIp(dpId, nodeId);
LOG.trace("Dpn Tep IP: {} for dpnId: {} and nodeId: {}", dpnTepIp, dpId, nodeId);
if (dpnTepIp == null) {
LOG.error("could not install dpn mac in l2gw TEP IP not found for dpnId {} and nodeId {}", dpId, nodeId);
- return;
+ return null;
}
-
+ //TerminationPointKey tpKey = HwvtepSouthboundUtils.getTerminationPointKey(dpnTepIp
+ // .getIpv4Address().getValue());
+ //InstanceIdentifier<TerminationPoint> tpPath = HwvtepSouthboundUtils.createTerminationPointId(nodeId, tpKey);
//TODO: to be batched in genius
- HwvtepUtils.installUcastMacs(broker, externalDevice.getHwvtepNodeId(), staticMacAddresses, elanName, dpnTepIp);
+ return HwvtepUtils.installUcastMacs(broker, externalDevice.getHwvtepNodeId(), staticMacAddresses,
+ elanName, dpnTepIp);
+
}
public void scheduleDeleteLogicalSwitch(NodeId hwvtepNodeId, String lsName) {
* the l2gw device
* @return the l2 gw device local macs
*/
- public Collection<MacAddress> getL2GwDeviceLocalMacs(String elanName, L2GatewayDevice l2gwDevice) {
+ public List<MacAddress> getL2GwDeviceLocalMacs(String elanName, L2GatewayDevice l2gwDevice) {
+ Set<MacAddress> macs = new HashSet<>();
if (l2gwDevice == null) {
- return Collections.emptyList();
+ return Collections.EMPTY_LIST;
}
Collection<LocalUcastMacs> lstUcastLocalMacs = l2gwDevice.getUcastLocalMacs();
- Set<MacAddress> macs = new HashSet<>();
- if (!lstUcastLocalMacs.isEmpty()) {
+ if (lstUcastLocalMacs != null && !lstUcastLocalMacs.isEmpty()) {
macs.addAll(lstUcastLocalMacs.stream().filter(Objects::nonNull)
- .map(mac -> new MacAddress(mac.getMacEntryKey().getValue().toLowerCase(Locale.ENGLISH)))
+ .map(mac -> new MacAddress(mac.getMacEntryKey().getValue().toLowerCase(Locale.getDefault())))
.collect(Collectors.toList()));
}
- Optional<Node> configNode;
+ Optional<Node> configNode = null;
try {
configNode = SingleTransactionDataBroker.syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION,
- HwvtepSouthboundUtils.createInstanceIdentifier(new NodeId(l2gwDevice.getHwvtepNodeId())));
+ HwvtepSouthboundUtils.createInstanceIdentifier(new NodeId(l2gwDevice.getHwvtepNodeId())));
} catch (ExecutionException | InterruptedException e) {
LOG.error("getL2GwDeviceLocalMacs: Exception while reading l2gwDevice DS for the elan {}, l2gwDevice {}",
- elanName, l2gwDevice, e);
+ elanName, l2gwDevice, e);
return Collections.emptyList();
}
+
if (configNode.isPresent()) {
HwvtepGlobalAugmentation augmentation = configNode.get().augmentation(HwvtepGlobalAugmentation.class);
if (augmentation != null && augmentation.getLocalUcastMacs() != null) {
macs.addAll(augmentation.nonnullLocalUcastMacs().values().stream()
.filter(mac -> getLogicalSwitchName(mac).equals(elanName))
- .map(HwvtepMacTableGenericAttributes::getMacEntryKey)
+ .map(mac -> mac.getMacEntryKey())
.collect(Collectors.toSet()));
}
}
- return macs;
+ return new ArrayList<>(macs);
}
}