void createExternalElanNetworks(Node node);
+ void updateExternalElanNetworks(Node origNode, Node updatedNode);
+
+ void deleteExternalElanNetwork(ElanInstance elanInstance);
+
+ void deleteExternalElanNetworks(Node node);
+
}
import java.math.BigInteger;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
} catch (InterruptedException e1) {
logger.warn("Error while waiting for local BC group for ELAN {} to install", elanInfo);
}
- setupElanBroadcastGroups(elanInfo, dpId);
+ setupElanBroadcastGroups(elanInfo, dpnInterfaces, dpId);
try {
Thread.sleep(waitTimeForSyncInstall);
} catch (InterruptedException e1) {
private List<Bucket> getRemoteBCGroupBucketInfos(ElanInstance elanInfo,
int bucketKeyStart, InterfaceInfo interfaceInfo) {
- BigInteger dpnId = interfaceInfo.getDpId();
- int elanTag = elanInfo.getElanTag().intValue();
- int bucketId = bucketKeyStart;
- List<Bucket> listBuckets = new ArrayList<Bucket>();
- ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
- if (elanDpns != null) {
- List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
- for(DpnInterfaces dpnInterface : dpnInterfaceses) {
- if (ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
- try {
- List<Action> listAction = ElanUtils.getInternalItmEgressAction(dpnId, dpnInterface.getDpId(), elanTag);
- listBuckets.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
- bucketId++;
- } catch (Exception ex) {
- logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
- }
- }
- }
- List<Bucket> elanL2GwDevicesBuckets = getRemoteBCGroupBucketsOfElanL2GwDevices(elanInfo, dpnId, bucketId);
- listBuckets.addAll(elanL2GwDevicesBuckets);
- }
- return listBuckets;
+ return getRemoteBCGroupBuckets(elanInfo, null, interfaceInfo.getDpId(), bucketKeyStart);
}
- private List<Bucket> getRemoteBCGroupBuckets(ElanInstance elanInfo, BigInteger dpnId, int bucketId) {
+ private List<Bucket> getRemoteBCGroupBuckets(ElanInstance elanInfo, DpnInterfaces dpnInterfaces, BigInteger dpnId, int bucketId) {
int elanTag = elanInfo.getElanTag().intValue();
List<Bucket> listBucketInfo = new ArrayList<Bucket>();
ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
+ listBucketInfo.addAll(getRemoteBCGroupTunnelBuckets(elanDpns, dpnId, bucketId, elanTag));
+ listBucketInfo.addAll(getRemoteBCGroupExternalPortBuckets(elanDpns, dpnInterfaces, dpnId, bucketId));
+ listBucketInfo.addAll(getRemoteBCGroupBucketsOfElanL2GwDevices(elanInfo, dpnId, bucketId));
+ return listBucketInfo;
+ }
+
+ private List<Bucket> getRemoteBCGroupTunnelBuckets(ElanDpnInterfacesList elanDpns, BigInteger dpnId, int bucketId,
+ int elanTag) {
+ List<Bucket> listBucketInfo = new ArrayList<Bucket>();
if (elanDpns != null) {
- List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
- for(DpnInterfaces dpnInterface : dpnInterfaceses) {
- if (ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
+ for (DpnInterfaces dpnInterface : elanDpns.getDpnInterfaces()) {
+ if (ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId
+ && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
try {
- List<Action> listActionInfo = ElanUtils.getInternalItmEgressAction(dpnId, dpnInterface.getDpId(), elanTag);
+ List<Action> listActionInfo = ElanUtils.getInternalTunnelItmEgressAction(dpnId,
+ dpnInterface.getDpId(), elanTag);
if (listActionInfo.isEmpty()) {
continue;
}
- listBucketInfo.add(MDSALUtil.buildBucket(listActionInfo, 0, bucketId, 0xffffffffL, 0xffffffffL));
+ listBucketInfo.add(MDSALUtil.buildBucket(listActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId,
+ MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
bucketId++;
} catch (Exception ex) {
- logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
+ logger.error("Logical Group Interface not found between source Dpn - {}, destination Dpn - {} ",
+ dpnId, dpnInterface.getDpId());
}
}
}
+ }
+ return listBucketInfo;
+ }
+
+ private List<Bucket> getRemoteBCGroupExternalPortBuckets(ElanDpnInterfacesList elanDpns, DpnInterfaces dpnInterfaces, BigInteger dpnId,
+ int bucketId) {
+ DpnInterfaces currDpnInterfaces = dpnInterfaces != null ? dpnInterfaces : getDpnInterfaces(elanDpns, dpnId);
+ if (currDpnInterfaces == null || !ElanUtils.isDpnPresent(currDpnInterfaces.getDpId())
+ || currDpnInterfaces.getInterfaces() == null || currDpnInterfaces.getInterfaces().isEmpty()) {
+ return Collections.emptyList();
+ }
- List<Bucket> elanL2GwDevicesBuckets = getRemoteBCGroupBucketsOfElanL2GwDevices(elanInfo, dpnId, bucketId);
- listBucketInfo.addAll(elanL2GwDevicesBuckets);
+ List<Bucket> listBucketInfo = new ArrayList<Bucket>();
+ for (String interfaceName : currDpnInterfaces.getInterfaces()) {
+ if (ElanUtils.isExternal(interfaceName)) {
+ List<Action> listActionInfo = ElanUtils.getExternalPortItmEgressAction(interfaceName);
+ if (!listActionInfo.isEmpty()) {
+ listBucketInfo.add(MDSALUtil.buildBucket(listActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId,
+ MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
+ bucketId++;
+ }
+ }
}
return listBucketInfo;
}
+ private DpnInterfaces getDpnInterfaces(ElanDpnInterfacesList elanDpns, BigInteger dpnId) {
+ if (elanDpns != null) {
+ for (DpnInterfaces dpnInterface : elanDpns.getDpnInterfaces()) {
+ if (dpnInterface.getDpId() == dpnId) {
+ return dpnInterface;
+ }
+ }
+ }
+ return null;
+ }
+
private void setElanBCGrouponOtherDpns(ElanInstance elanInfo,
BigInteger dpId, WriteTransaction tx) {
int elanTag = elanInfo.getElanTag().intValue();
if (ElanUtils.isDpnPresent(otherFes.getDpId()) && otherFes.getDpId() != dpnInterface.getDpId()
&& otherFes.getInterfaces() != null && ! otherFes.getInterfaces().isEmpty()) {
try {
- List<Action> remoteListActionInfo = ElanUtils.getInternalItmEgressAction(dpnInterface.getDpId(), otherFes.getDpId(), elanTag);
- remoteListBucketInfo.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,MDSALUtil.WATCH_GROUP));
- bucketId++;
+ List<Action> remoteListActionInfo = ElanUtils.getInternalTunnelItmEgressAction(dpnInterface.getDpId(), otherFes.getDpId(), elanTag);
+ if (!remoteListActionInfo.isEmpty()) {
+ remoteListBucketInfo.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,MDSALUtil.WATCH_GROUP));
+ bucketId++;
+ }
} catch (Exception ex) {
logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), otherFes.getDpId() );
return;
}
public void setupElanBroadcastGroups(ElanInstance elanInfo, BigInteger dpnId) {
+ setupElanBroadcastGroups(elanInfo, null, dpnId);
+ }
+
+ public void setupElanBroadcastGroups(ElanInstance elanInfo, DpnInterfaces dpnInterfaces, BigInteger dpnId) {
List<Bucket> listBucket = new ArrayList<Bucket>();
int bucketId = 0;
int actionKey = 0;
listAction.add((new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}, ++actionKey)).buildAction());
listBucket.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
bucketId++;
- List<Bucket> listBucketInfoRemote = getRemoteBCGroupBuckets(elanInfo, dpnId, bucketId);
+ List<Bucket> listBucketInfoRemote = getRemoteBCGroupBuckets(elanInfo, dpnInterfaces, dpnId, bucketId);
listBucket.addAll(listBucketInfoRemote);
Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
logger.trace("Installing the remote BroadCast Group:{}", group);
continue;
}
- listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
- bucketId++;
+ if (!ElanUtils.isExternal(ifName)) {
+ listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId,
+ MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
+ bucketId++;
+ }
}
Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
elanServiceProvider.getMdsalManager().addFlowToTx(dpId, flowEntity, writeFlowGroupTx);
- // only if ELAN can connect to external netowrk, perform the following
+ // only if ELAN can connect to external network, perform the following
if (ElanUtils.isVxlan(elanInfo) || ElanUtils.isVlan(elanInfo) || ElanUtils.isFlat(elanInfo)) {
Flow flowEntity2 = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getUnknownDmacFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag, /*SH flag*/true),
5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)), getMatchesForElanTag(elanTag, /*SH flag*/true),
if (interfaceName == null) {
continue;
}
- List<Action> listActionInfo = ElanUtils.buildItmEgressActions(interfaceName, elanInfo.getSegmentationId());
+ List<Action> listActionInfo = ElanUtils.buildTunnelItmEgressActions(interfaceName, elanInfo.getSegmentationId());
listBucketInfo.add(MDSALUtil.buildBucket(listActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId,
MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
bucketId++;
}
@Override
- protected void remove(InstanceIdentifier<Node> identifier, Node del) {
+ protected void remove(InstanceIdentifier<Node> identifier, Node node) {
+ elanProvider.deleteExternalElanNetworks(node);
}
@Override
protected void update(InstanceIdentifier<Node> identifier, Node original, Node update) {
logger.debug("ElanOvsdbNodeListener.update, updated node detected. original: {} new: {}", original, update);
doNodeUpdate(update);
+ elanProvider.updateExternalElanNetworks(original, update);
}
@Override
private void doNodeUpdate(Node node) {
bridgeMgr.processNodePrep(node, generateIntBridgeMac);
}
-
}
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.concurrent.Future;
+import java.util.function.BiFunction;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.NotificationService;
import org.opendaylight.genius.itm.api.IITMProvider;
import org.opendaylight.genius.mdsalutil.MDSALUtil;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInstances;
import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.ElanInterfaces;
@Override
public void createExternalElanNetworks(Node node) {
- if (!bridgeMgr.isIntegrationBridge(node)) {
+ handleExternalElanNetworks(node, new BiFunction<ElanInstance, String, Void>() {
+
+ @Override
+ public Void apply(ElanInstance elanInstance, String interfaceName) {
+ createExternalElanNetwork(elanInstance, interfaceName);
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public void createExternalElanNetwork(ElanInstance elanInstance) {
+ handleExternalElanNetwork(elanInstance, new BiFunction<ElanInstance, String, Void>() {
+
+ @Override
+ public Void apply(ElanInstance elanInstance, String interfaceName) {
+ createExternalElanNetwork(elanInstance, interfaceName);
+ return null;
+ }
+
+ });
+ }
+
+ @Override
+ public void deleteExternalElanNetworks(Node node) {
+ handleExternalElanNetworks(node, new BiFunction<ElanInstance, String, Void>() {
+
+ @Override
+ public Void apply(ElanInstance elanInstance, String interfaceName) {
+ deleteExternalElanNetwork(elanInstance, interfaceName);
+ return null;
+ }
+ });
+ }
+
+ @Override
+ public void deleteExternalElanNetwork(ElanInstance elanInstance) {
+ handleExternalElanNetwork(elanInstance, new BiFunction<ElanInstance, String, Void>() {
+
+ @Override
+ public Void apply(ElanInstance elanInstance, String interfaceName) {
+ deleteExternalElanNetwork(elanInstance, interfaceName);
+ return null;
+ }
+
+ });
+ }
+
+ @Override
+ public void updateExternalElanNetworks(Node origNode, Node updatedNode) {
+ if (!bridgeMgr.isIntegrationBridge(updatedNode)) {
return;
}
return;
}
+ Optional<Map<String, String>> origProviderMapOpt = bridgeMgr.getOpenvswitchOtherConfigMap(origNode,
+ ElanBridgeManager.PROVIDER_MAPPINGS_KEY);
+ Optional<Map<String, String>> updatedProviderMapOpt = bridgeMgr.getOpenvswitchOtherConfigMap(updatedNode,
+ ElanBridgeManager.PROVIDER_MAPPINGS_KEY);
+ Map<String, String> origProviderMappping = origProviderMapOpt.or(Collections.emptyMap());
+ Map<String, String> updatedProviderMappping = updatedProviderMapOpt.or(Collections.emptyMap());
+
for (ElanInstance elanInstance : elanInstances) {
- String interfaceName = getExtInterfaceName(node, elanInstance.getPhysicalNetworkName());
- createExternalElanNetwork(elanInstance, node, interfaceName);
+ 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 (updatedPortName != null && !updatedPortName.equals(origPortName)) {
+ createExternalElanNetwork(elanInstance, getExtInterfaceName(updatedNode, updatedPortName));
+ }
+ }
}
}
- @Override
- public void createExternalElanNetwork(ElanInstance elanInstance) {
- if (elanInstance.getPhysicalNetworkName() == null) {
- logger.trace("No physical network attached to {}", elanInstance.getElanInstanceName());
+ private void createExternalElanNetwork(ElanInstance elanInstance, String interfaceName) {
+ if (interfaceName == null) {
+ logger.trace("No physial interface is attached to {}", elanInstance.getPhysicalNetworkName());
return;
}
- List<Node> nodes = bridgeMgr.southboundUtils.getOvsdbNodes();
- if (nodes == null || nodes.isEmpty()) {
- logger.trace("No OVS nodes found while creating external network for ELAN {}",
- elanInstance.getElanInstanceName());
+ String elanInterfaceName = createIetfInterfaces(elanInstance, interfaceName);
+ addElanInterface(elanInstance.getElanInstanceName(), elanInterfaceName, null, null);
+ }
+
+ private void deleteExternalElanNetwork(ElanInstance elanInstance, String interfaceName) {
+ if (interfaceName == null) {
+ logger.trace("No physial interface is attached to {}", elanInstance.getPhysicalNetworkName());
return;
}
- for (Node node : nodes) {
- if (bridgeMgr.isIntegrationBridge(node)) {
- String interfaceName = getExtInterfaceName(node, elanInstance.getPhysicalNetworkName());
- createExternalElanNetwork(elanInstance, node, interfaceName);
- }
+ String elanInstanceName = elanInstance.getElanInstanceName();
+ List<String> elanInterfaces = getElanInterfaces(elanInstanceName);
+ if (elanInterfaces == null || elanInterfaces.isEmpty()) {
+ logger.trace("No ELAN interfaces defined for {}", elanInstanceName);
+ return;
}
- }
- private void createExternalElanNetwork(ElanInstance elanInstance, Node node, String interfaceName) {
- if (interfaceName == null) {
- logger.trace("No physial interface is attached to {} node {}", elanInstance.getPhysicalNetworkName(),
- node.getNodeId().getValue());
+ for (String elanInterface : elanInterfaces) {
+ if (ElanUtils.isExternal(elanInterface) && elanInterface.startsWith(interfaceName)) {
+ deleteIetfInterface(elanInterface);
+ deleteElanInterface(elanInstanceName, elanInterface);
+ return;
+ }
}
-
- String elanInterfaceName = createIetfInterfaces(elanInstance, interfaceName);
- addElanInterface(elanInstance.getElanInstanceName(), elanInterfaceName, null, null);
}
/**
if (ElanUtils.isFlat(elanInstance)) {
interfaceName = parentRef + IfmConstants.OF_URI_PREFIX + "flat";
interfaceManager.createVLANInterface(interfaceName, parentRef, null, null, null,
- IfL2vlan.L2vlanMode.Transparent);
+ IfL2vlan.L2vlanMode.Transparent, true);
} else if (ElanUtils.isVlan(elanInstance)) {
String trunkName = parentRef + IfmConstants.OF_URI_PREFIX + "trunk";
interfaceManager.createVLANInterface(interfaceName, parentRef, null, null, null,
- IfL2vlan.L2vlanMode.Trunk);
+ IfL2vlan.L2vlanMode.Trunk, true);
Long segmentationId = elanInstance.getSegmentationId();
interfaceName = parentRef + IfmConstants.OF_URI_PREFIX + segmentationId;
interfaceManager.createVLANInterface(interfaceName, trunkName, null, segmentationId.intValue(), null,
- IfL2vlan.L2vlanMode.TrunkMember);
+ IfL2vlan.L2vlanMode.TrunkMember, true);
}
} catch (InterfaceAlreadyExistsException e) {
logger.trace("Interface {} was already created", interfaceName);
return interfaceName;
}
+ private void deleteIetfInterface(String interfaceName) {
+ InterfaceKey interfaceKey = new InterfaceKey(interfaceName);
+ InstanceIdentifier<Interface> interfaceInstanceIdentifier = InstanceIdentifier
+ .builder(Interfaces.class).child(Interface.class, interfaceKey).build();
+ MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, interfaceInstanceIdentifier);
+ logger.debug("Deleting IETF interface {}", interfaceName);
+ }
+
private String getExtInterfaceName(Node node, String physicalNetworkName) {
if (physicalNetworkName == null) {
return null;
+ bridgeMgr.getIntBridgePortNameFor(node, providerMappingValue);
}
+ private void handleExternalElanNetworks(Node node, BiFunction<ElanInstance, String, Void> function) {
+ if (!bridgeMgr.isIntegrationBridge(node)) {
+ return;
+ }
+
+ List<ElanInstance> elanInstances = getElanInstances();
+ if (elanInstances == null || elanInstances.isEmpty()) {
+ logger.trace("No ELAN instances found");
+ return;
+ }
+
+ for (ElanInstance elanInstance : elanInstances) {
+ String interfaceName = getExtInterfaceName(node, elanInstance.getPhysicalNetworkName());
+ if (interfaceName != null) {
+ function.apply(elanInstance, interfaceName);
+ }
+ }
+ }
+
+ private void handleExternalElanNetwork(ElanInstance elanInstance, BiFunction<ElanInstance, String, Void> function) {
+ String elanInstanceName = elanInstance.getElanInstanceName();
+ if (elanInstance.getPhysicalNetworkName() == null) {
+ logger.trace("No physical network attached to {}", elanInstanceName);
+ return;
+ }
+
+ List<Node> nodes = bridgeMgr.southboundUtils.getOvsdbNodes();
+ if (nodes == null || nodes.isEmpty()) {
+ logger.trace("No OVS nodes found while creating external network for ELAN {}",
+ elanInstance.getElanInstanceName());
+ return;
+ }
+
+ for (Node node : nodes) {
+ if (bridgeMgr.isIntegrationBridge(node)) {
+ String interfaceName = getExtInterfaceName(node, elanInstance.getPhysicalNetworkName());
+ function.apply(elanInstance, interfaceName);
+ }
+ }
+ }
+
}
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
import org.opendaylight.netvirt.elan.internal.ElanServiceProvider;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.InterfacesState;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.AdminStatus;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406.IfIndexesInterfaceMap;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterface;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.meta.rev160406._if.indexes._interface.map.IfIndexInterfaceKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfExternal;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.TunnelTypeVxlan;
import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetDpidFromInterfaceInputBuilder;
//List of Action for the provided Source and Destination DPIDs
try {
- List<Action> actions = getInternalItmEgressAction(srcDpId, destDpId, lportTag);
+ List<Action> actions = getInternalTunnelItmEgressAction(srcDpId, destDpId, lportTag);
mkInstructions.add(MDSALUtil.buildApplyActionsInstruction(actions));
} catch (Exception e) {
logger.error("Interface Not Found exception");
* the tunnel key
* @return the list
*/
- public static List<Action> buildItmEgressActions(String tunnelIfaceName, Long tunnelKey) {
- List<Action> result = Collections.emptyList();
+ public static List<Action> buildTunnelItmEgressActions(String tunnelIfaceName, Long tunnelKey) {
if (tunnelIfaceName != null && !tunnelIfaceName.isEmpty()) {
- GetEgressActionsForInterfaceInput getEgressActInput = new GetEgressActionsForInterfaceInputBuilder()
- .setIntfName(tunnelIfaceName).setTunnelKey(tunnelKey).build();
-
- Future<RpcResult<GetEgressActionsForInterfaceOutput>> egressActionsOutputFuture =
- elanServiceProvider.getInterfaceManagerRpcService().getEgressActionsForInterface(getEgressActInput);
- try {
- if (egressActionsOutputFuture.get().isSuccessful()) {
- GetEgressActionsForInterfaceOutput egressActionsOutput = egressActionsOutputFuture.get().getResult();
- result = egressActionsOutput.getAction();
- }
- } catch (InterruptedException | ExecutionException e) {
- logger.error("Error in RPC call getEgressActionsForInterface {}", e);
+ return buildItmEgressActions(tunnelIfaceName, tunnelKey);
+ }
+
+ return Collections.emptyList();
+ }
+
+ /**
+ * Builds the list of actions to be taken when sending the packet over external
+ * port such as tunnel, physical port etc.
+ *
+ * @param interfaceName
+ * the interface name
+ * @param tunnelKey
+ * can be VNI for VxLAN tunnel interfaces, Gre Key for GRE tunnels, etc.
+ * @return the list
+ */
+ public static List<Action> buildItmEgressActions(String interfaceName, Long tunnelKey) {
+ List<Action> result = Collections.emptyList();
+ GetEgressActionsForInterfaceInput getEgressActInput = new GetEgressActionsForInterfaceInputBuilder()
+ .setIntfName(interfaceName).setTunnelKey(tunnelKey).build();
+
+ Future<RpcResult<GetEgressActionsForInterfaceOutput>> egressActionsOutputFuture = elanServiceProvider
+ .getInterfaceManagerRpcService().getEgressActionsForInterface(getEgressActInput);
+ try {
+ if (egressActionsOutputFuture.get().isSuccessful()) {
+ GetEgressActionsForInterfaceOutput egressActionsOutput = egressActionsOutputFuture.get().getResult();
+ result = egressActionsOutput.getAction();
}
+ } catch (InterruptedException | ExecutionException e) {
+ logger.error("Error in RPC call getEgressActionsForInterface {}", e);
}
if ( result == null || result.size() == 0 ) {
- logger.warn("Could not build Egress actions for interface {} and tunnelId {}", tunnelIfaceName, tunnelKey);
+ logger.warn("Could not build Egress actions for interface {} and tunnelId {}", interfaceName, tunnelKey);
}
return result;
}
* Vni to be stamped on the VxLAN Header.
* @return the external itm egress action
*/
- public static List<Action> getExternalItmEgressAction(BigInteger srcDpnId, NodeId torNode, long vni ) {
+ public static List<Action> getExternalTunnelItmEgressAction(BigInteger srcDpnId, NodeId torNode, long vni ) {
List<Action> result = Collections.emptyList();
GetExternalTunnelInterfaceNameInput input = new GetExternalTunnelInterfaceNameInputBuilder()
if ( logger.isDebugEnabled() )
logger.debug("Received tunnelInterfaceName from getTunnelInterfaceName RPC {}", tunnelIfaceName);
- result = buildItmEgressActions(tunnelIfaceName, vni);
+ result = buildTunnelItmEgressActions(tunnelIfaceName, vni);
}
} catch (InterruptedException | ExecutionException e) {
* serviceId to be sent on the VxLAN header.
* @return the internal itm egress action
*/
- public static List<Action> getInternalItmEgressAction(BigInteger sourceDpnId, BigInteger destinationDpnId,
+ public static List<Action> getInternalTunnelItmEgressAction(BigInteger sourceDpnId, BigInteger destinationDpnId,
long serviceTag) {
List<Action> result = Collections.emptyList();
String tunnelIfaceName = tunnelInterfaceNameOutput.getInterfaceName();
logger.debug("Received tunnelInterfaceName from getTunnelInterfaceName RPC {}", tunnelIfaceName);
- result = buildItmEgressActions(tunnelIfaceName, serviceTag);
+ result = buildTunnelItmEgressActions(tunnelIfaceName, serviceTag);
}
} catch (InterruptedException | ExecutionException e) {
logger.error("Error in RPC call getTunnelInterfaceName {}", e);
return result;
}
+ /**
+ * Build the list of actions to be taken when sending the packet to
+ * external (physical) port
+ *
+ * @param interfaceName
+ * Interface name
+ * @return the external port itm egress actions
+ */
+ public static List<Action> getExternalPortItmEgressAction(String interfaceName) {
+ return buildItmEgressActions(interfaceName, null);
+ }
+
public static List<MatchInfo> getTunnelMatchesForServiceId(int elanTag) {
List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
// Matching metadata
List<MatchInfo> mkMatches = buildMatchesForElanTagShFlagAndDstMac(elanTag, /*shFlag*/ false, dstMacAddress);
List<Instruction> mkInstructions = new ArrayList<Instruction>();
try {
- List<Action> actions = getExternalItmEgressAction(dpId, new NodeId(extDeviceNodeId), vni);
+ List<Action> actions = getExternalTunnelItmEgressAction(dpId, new NodeId(extDeviceNodeId), vni);
mkInstructions.add( MDSALUtil.buildApplyActionsInstruction(actions) );
} catch (Exception e) {
logger.error("Could not get Egress Actions for DpId={} externalNode={}", dpId, extDeviceNodeId );
try {
//List of Action for the provided Source and Destination DPIDs
- List<Action> actions = getInternalItmEgressAction(localDpId, remoteDpId, lportTag);
+ List<Action> actions = getInternalTunnelItmEgressAction(localDpId, remoteDpId, lportTag);
mkInstructions.add( MDSALUtil.buildApplyActionsInstruction(actions) );
} catch (Exception e) {
logger.error("Could not get Egress Actions for localDpId={} remoteDpId={} lportTag={}",
return null;
}
+ /**
+ * Gets the interface from config ds.
+ *
+ * @param interfaceName
+ * the interface name
+ * @param dataBroker
+ * the data broker
+ * @return the interface from config ds
+ */
+ public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface getInterfaceFromConfigDS(
+ String interfaceName, DataBroker dataBroker) {
+ InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> ifaceId = createInterfaceInstanceIdentifier(
+ interfaceName);
+ Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> iface = MDSALUtil
+ .read(dataBroker, LogicalDatastoreType.CONFIGURATION, ifaceId);
+ if (iface.isPresent()) {
+ return iface.get();
+ }
+ return null;
+ }
+
/**
* Creates the interface state instance identifier.
*
return idBuilder.build();
}
+ /**
+ * Creates the interface instance identifier.
+ *
+ * @param interfaceName
+ * the interface name
+ * @return the instance identifier
+ */
+ public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> createInterfaceInstanceIdentifier(
+ String interfaceName) {
+ InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> idBuilder = InstanceIdentifier
+ .builder(Interfaces.class)
+ .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface.class,
+ new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey(
+ interfaceName));
+ return idBuilder.build();
+ }
+
public static void waitForTransactionToComplete(WriteTransaction tx) {
CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
try {
return elanInstance != null && elanInstance.getSegmentType() != null
&& elanInstance.getSegmentType().isAssignableFrom(SegmentTypeFlat.class);
}
+
+ public static boolean isExternal(String interfaceName) {
+ return isExternal(getInterfaceFromConfigDS(interfaceName, elanServiceProvider.getBroker()));
+ }
+
+ public static boolean isExternal(
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface) {
+ if (iface == null) {
+ return false;
+ }
+
+ IfExternal ifExternal = iface.getAugmentation(IfExternal.class);
+ return ifExternal != null && Boolean.TRUE.equals(ifExternal.isExternal());
+ }
}
package org.opendaylight.netvirt.neutronvpn;
+import java.util.Objects;
+
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
}
//Delete ELAN instance for this network
String elanInstanceName = input.getUuid().getValue();
- deleteElanInstance(elanInstanceName);
+ ElanInstance elanInstance = NeutronvpnServiceAccessor.getElanProvider().getElanInstance(elanInstanceName);
+ if (elanInstance != null) {
+ NeutronvpnServiceAccessor.getElanProvider().deleteExternalElanNetwork(elanInstance);
+ deleteElanInstance(elanInstanceName);
+ }
if (input.getAugmentation(NetworkL3Extension.class).isExternal()) {
nvpnNatManager.removeExternalNetwork(input);
NeutronvpnUtils.removeFromNetworkCache(input);
}
-
- // TODO: delete elan-interfaces for physnet port
}
@Override
LOG.trace("Updating Network : key: " + identifier + ", original value=" + original + ", update value=" +
update);
}
+
+ String elanInstanceName = original.getUuid().getValue();
+ Class<? extends SegmentTypeBase> origSegmentType = NeutronvpnUtils.getSegmentTypeFromNeutronNetwork(original);
+ String origSegmentationId = NeutronUtils.getSegmentationIdFromNeutronNetwork(original);
+ String origPhysicalNetwork = NeutronvpnUtils.getPhysicalNetworkName(original);
+ Class<? extends SegmentTypeBase> updateSegmentType = NeutronvpnUtils.getSegmentTypeFromNeutronNetwork(update);
+ String updateSegmentationId = NeutronUtils.getSegmentationIdFromNeutronNetwork(update);
+ String updatePhysicalNetwork = NeutronvpnUtils.getPhysicalNetworkName(update);
+
+ if (!Objects.equals(origSegmentType, updateSegmentType)
+ || !Objects.equals(origSegmentationId, updateSegmentationId)
+ || !Objects.equals(origPhysicalNetwork, updatePhysicalNetwork)) {
+ ElanInstance elanInstance = NeutronvpnServiceAccessor.getElanProvider().getElanInstance(elanInstanceName);
+ if (elanInstance != null) {
+ NeutronvpnServiceAccessor.getElanProvider().deleteExternalElanNetwork(elanInstance);
+ elanInstance = updateElanInstance(elanInstanceName, updateSegmentType, updateSegmentationId,
+ updatePhysicalNetwork);
+ NeutronvpnServiceAccessor.getElanProvider().createExternalElanNetwork(elanInstance);
+ }
+ }
}
private ElanInstance createElanInstance(Network input) {
Class<? extends SegmentTypeBase> segmentType = NeutronvpnUtils.getSegmentTypeFromNeutronNetwork(input);
String segmentationId = NeutronUtils.getSegmentationIdFromNeutronNetwork(input);
String physicalNetworkName = NeutronvpnUtils.getPhysicalNetworkName(input);
+ ElanInstance elanInstance = createElanInstance(elanInstanceName, segmentType, segmentationId, physicalNetworkName);
+ InstanceIdentifier<ElanInstance> id = createElanInstanceIdentifier(elanInstanceName);
+ MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, id, elanInstance);
+ return elanInstance;
+ }
+
+ private void deleteElanInstance(String elanInstanceName) {
+ InstanceIdentifier<ElanInstance> id = createElanInstanceIdentifier(elanInstanceName);
+ MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, id);
+ }
+
+ private ElanInstance updateElanInstance(String elanInstanceName, Class<? extends SegmentTypeBase> segmentType,
+ String segmentationId, String physicalNetworkName) {
+ ElanInstance elanInstance = createElanInstance(elanInstanceName, segmentType, segmentationId, physicalNetworkName);
+ InstanceIdentifier<ElanInstance> id = createElanInstanceIdentifier(elanInstanceName);
+ MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION, id, elanInstance);
+ return elanInstance;
+ }
+
+ private InstanceIdentifier<ElanInstance> createElanInstanceIdentifier(String elanInstanceName) {
+ InstanceIdentifier<ElanInstance> id = InstanceIdentifier.builder(ElanInstances.class)
+ .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
+ return id;
+ }
+
+ private ElanInstance createElanInstance(String elanInstanceName, Class<? extends SegmentTypeBase> segmentType,
+ String segmentationId, String physicalNetworkName) {
ElanInstanceBuilder elanInstanceBuilder = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName);
if (segmentType != null) {
elanInstanceBuilder.setSegmentType(segmentType);
}
}
elanInstanceBuilder.setKey(new ElanInstanceKey(elanInstanceName));
- ElanInstance elanInstance = elanInstanceBuilder.build();
- InstanceIdentifier<ElanInstance> id = InstanceIdentifier.builder(ElanInstances.class)
- .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
- MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, id, elanInstance);
- return elanInstance;
- }
-
- private void deleteElanInstance(String elanInstanceName) {
- InstanceIdentifier<ElanInstance> id = InstanceIdentifier.builder(ElanInstances.class)
- .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
- MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, id);
+ return elanInstanceBuilder.build();
}
}