package org.opendaylight.netvirt.elan.internal;
import com.google.common.base.Optional;
+
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import org.opendaylight.genius.interfacemanager.globals.IfmConstants;
import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.utils.ServiceIndex;
import org.opendaylight.genius.utils.clustering.EntityOwnerUtils;
import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
import org.opendaylight.netvirt.elan.statusanddiag.ElanStatusMonitor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
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.instances.ElanInstance;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+
public class ElanServiceProvider implements IElanService {
private static final Logger LOG = LoggerFactory.getLogger(ElanServiceProvider.class);
private final ElanBridgeManager bridgeMgr;
private final DataBroker broker;
private final ElanStatusMonitor elanStatusMonitor;
- private static ElanUtils elanUtils;
+ private final ElanUtils elanUtils;
private boolean generateIntBridgeMac = true;
+ private boolean isL2BeforeL3;
public ElanServiceProvider(IdManagerService idManager, IInterfaceManager interfaceManager,
ElanInstanceManager elanInstanceManager, ElanBridgeManager bridgeMgr,
public void init() throws Exception {
LOG.info("Starting ElnaServiceProvider");
elanStatusMonitor.reportStatus("STARTING");
+ setIsL2BeforeL3();
try {
createIdPool();
elanStatusMonitor.reportStatus("OPERATIONAL");
@Override
public List<ElanInstance> getElanInstances() {
- List<ElanInstance> elanList = new ArrayList<>();
InstanceIdentifier<ElanInstances> elanInstancesIdentifier = InstanceIdentifier.builder(ElanInstances.class)
.build();
- Optional<ElanInstances> elansOptional = elanUtils.read(broker, LogicalDatastoreType.CONFIGURATION,
- elanInstancesIdentifier);
- if (elansOptional.isPresent()) {
- elanList.addAll(elansOptional.get().getElanInstance());
- }
- return elanList;
+ return elanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, elanInstancesIdentifier).transform(
+ ElanInstances::getElanInstance).or(Collections.emptyList());
}
@Override
private void createExternalElanNetwork(ElanInstance elanInstance, String interfaceName) {
if (interfaceName == null) {
- LOG.trace("No physial interface is attached to {}", elanInstance.getPhysicalNetworkName());
+ LOG.trace("No physical interface is attached to {}", elanInstance.getPhysicalNetworkName());
return;
}
return;
}
- Optional<Map<String, String>> origProviderMapOpt = bridgeMgr.getOpenvswitchOtherConfigMap(origNode,
+ LOG.debug("updateExternalElanNetworks, orig bridge {} . updated bridge {}", origNode, updatedNode);
+
+ Map<String, String> origProviderMappping = getMapFromOtherConfig(origNode,
ElanBridgeManager.PROVIDER_MAPPINGS_KEY);
- Optional<Map<String, String>> updatedProviderMapOpt = bridgeMgr.getOpenvswitchOtherConfigMap(updatedNode,
+ Map<String, String> updatedProviderMappping = getMapFromOtherConfig(updatedNode,
ElanBridgeManager.PROVIDER_MAPPINGS_KEY);
- Map<String, String> origProviderMappping = origProviderMapOpt.or(Collections.emptyMap());
- Map<String, String> updatedProviderMappping = updatedProviderMapOpt.or(Collections.emptyMap());
+
+ boolean hasDatapathIdOnOrigNode = bridgeMgr.hasDatapathID(origNode);
+ boolean hasDatapathIdOnUpdatedNode = bridgeMgr.hasDatapathID(updatedNode);
for (ElanInstance elanInstance : elanInstances) {
String physicalNetworkName = elanInstance.getPhysicalNetworkName();
if (physicalNetworkName != null) {
String origPortName = origProviderMappping.get(physicalNetworkName);
String updatedPortName = updatedProviderMappping.get(physicalNetworkName);
- if (origPortName != null && !origPortName.equals(updatedPortName)) {
- deleteExternalElanNetwork(elanInstance, getExtInterfaceName(origNode, physicalNetworkName));
+ if (hasPortNameRemoved(origPortName, updatedPortName)) {
+ deleteExternalElanNetwork(elanInstance,
+ bridgeMgr.getProviderInterfaceName(origNode, physicalNetworkName));
}
- if (updatedPortName != null && !updatedPortName.equals(origPortName)) {
- createExternalElanNetwork(elanInstance, getExtInterfaceName(updatedNode, updatedPortName));
+ if (hasPortNameUpdated(origPortName, updatedPortName)
+ || hasDatapathIdAdded(hasDatapathIdOnOrigNode, hasDatapathIdOnUpdatedNode)) {
+ createExternalElanNetwork(elanInstance,
+ bridgeMgr.getProviderInterfaceName(updatedNode, physicalNetworkName));
}
}
}
}
- @Override
- public String getExternalElanInterface(String elanInstanceName, BigInteger dpnId) {
- DpnInterfaces dpnInterfaces = elanUtils.getElanInterfaceInfoByElanDpn(elanInstanceName, dpnId);
- if (dpnInterfaces == null || dpnInterfaces.getInterfaces() == null) {
- LOG.trace("Elan {} does not have interfaces in DPN {}", elanInstanceName, dpnId);
- return null;
- }
+ private boolean hasDatapathIdAdded(boolean hasDatapathIdOnOrigNode, boolean hasDatapathIdOnUpdatedNode) {
+ return !hasDatapathIdOnOrigNode && hasDatapathIdOnUpdatedNode;
+ }
- for (String dpnInterface : dpnInterfaces.getInterfaces()) {
- if (elanUtils.isExternal(dpnInterface)) {
- return dpnInterface;
- }
- }
+ private boolean hasPortNameUpdated(String origPortName, String updatedPortName) {
+ return updatedPortName != null && !updatedPortName.equals(origPortName);
+ }
+
+ private boolean hasPortNameRemoved(String origPortName, String updatedPortName) {
+ return origPortName != null && !origPortName.equals(updatedPortName);
+ }
- LOG.trace("Elan {} does not have any external interace attached to DPN {}", elanInstanceName, dpnId);
- return null;
+ private Map<String, String> getMapFromOtherConfig(Node node, String otherConfigColumn) {
+ return bridgeMgr.getOpenvswitchOtherConfigMap(node, otherConfigColumn);
}
@Override
Set<String> externalElanInterfaces = new HashSet<>();
for (String elanInterface : elanInterfaces) {
- if (elanUtils.isExternal(elanInterface)) {
+ if (interfaceManager.isExternalInterface(elanInterface)) {
externalElanInterfaces.add(elanInterface);
}
}
return externalElanInterfaces;
}
+ @Override
+ public String getExternalElanInterface(String elanInstanceName, BigInteger dpnId) {
+ return elanUtils.getExternalElanInterface(elanInstanceName, dpnId);
+ }
+
@Override
public boolean isExternalInterface(String interfaceName) {
- return elanUtils.isExternal(interfaceName);
+ return interfaceManager.isExternalInterface(interfaceName);
}
@Override
return ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
}
+ @Override
+ public void handleKnownL3DmacAddress(String macAddress, String elanInstanceName, int addOrRemove) {
+ if (!isL2BeforeL3) {
+ LOG.trace("ELAN service is after L3VPN in the Netvirt pipeline skip known L3DMAC flows installation");
+ return;
+ }
+ ElanInstance elanInstance = ElanUtils.getElanInstanceByName(broker, elanInstanceName);
+ if (elanInstance == null) {
+ LOG.warn("Null elan instance {}", elanInstanceName);
+ return;
+ }
+
+ List<BigInteger> dpnsIdsForElanInstance = elanUtils.getParticipatingDpnsInElanInstance(elanInstanceName);
+ if (dpnsIdsForElanInstance == null || dpnsIdsForElanInstance.isEmpty()) {
+ LOG.warn("No DPNs for elan instance {}", elanInstance);
+ return;
+ }
+
+ elanUtils.handleDmacRedirectToDispatcherFlows(elanInstance.getElanTag(), elanInstanceName, macAddress,
+ addOrRemove, dpnsIdsForElanInstance);
+ }
+
/**
* Create ietf-interfaces based on the ELAN segment type.<br>
* For segment type flat - create transparent interface pointing to the
interfaceName = parentRef + IfmConstants.OF_URI_SEPARATOR + segmentationId;
String trunkName = parentRef + IfmConstants.OF_URI_SEPARATOR + "trunk";
// trunk interface may have been created by other vlan network
- Interface trunkInterface = ElanUtils.getInterfaceFromConfigDS(trunkName, broker);
+ Interface trunkInterface = interfaceManager.getInterfaceInfoFromConfigDataStore(trunkName);
if (trunkInterface == null) {
interfaceManager.createVLANInterface(trunkName, parentRef, null, null, null,
IfL2vlan.L2vlanMode.Trunk, true);
LOG.debug("Deleting IETF interface {}", interfaceName);
}
- private String getExtInterfaceName(Node node, String physicalNetworkName) {
- if (physicalNetworkName == null) {
- return null;
- }
-
- String providerMappingValue = bridgeMgr.getProviderMappingValue(node, physicalNetworkName);
- if (providerMappingValue == null) {
- LOG.trace("No provider mapping found for physicalNetworkName {} node {}", physicalNetworkName,
- node.getNodeId().getValue());
- return null;
- }
-
- return bridgeMgr.southboundUtils.getDataPathId(node) + IfmConstants.OF_URI_SEPARATOR
- + bridgeMgr.getIntBridgePortNameFor(node, providerMappingValue);
- }
-
private void handleExternalElanNetworks(Node node, BiFunction<ElanInstance, String, Void> function) {
if (!bridgeMgr.isIntegrationBridge(node)) {
return;
}
for (ElanInstance elanInstance : elanInstances) {
- String interfaceName = getExtInterfaceName(node, elanInstance.getPhysicalNetworkName());
+ String interfaceName = bridgeMgr.getProviderInterfaceName(node, elanInstance.getPhysicalNetworkName());
if (interfaceName != null) {
function.apply(elanInstance, interfaceName);
}
for (Node node : nodes) {
if (bridgeMgr.isIntegrationBridge(node)) {
- String interfaceName = getExtInterfaceName(node, elanInstance.getPhysicalNetworkName());
+ String interfaceName = bridgeMgr.getProviderInterfaceName(node, elanInstance.getPhysicalNetworkName());
function.apply(elanInstance, interfaceName);
}
}
}
+ private void setIsL2BeforeL3() {
+ short elanServiceRealIndex = ServiceIndex.getIndex(NwConstants.ELAN_SERVICE_NAME,
+ NwConstants.ELAN_SERVICE_INDEX);
+ short l3vpnServiceRealIndex = ServiceIndex.getIndex(NwConstants.L3VPN_SERVICE_NAME,
+ NwConstants.L3VPN_SERVICE_INDEX);
+ if (elanServiceRealIndex < l3vpnServiceRealIndex) {
+ LOG.info("ELAN service is set before L3VPN service in the Netvirt pipeline");
+ isL2BeforeL3 = true;
+ } else {
+ LOG.info("ELAN service is set after L3VPN service in the Netvirt pipeline");
+ isL2BeforeL3 = false;
+ }
+ }
}