+
+ @Override
+ public void createExternalElanNetworks(Node node) {
+ handleExternalElanNetworks(node, (elanInstance, interfaceName) -> {
+ createExternalElanNetwork(elanInstance, interfaceName);
+ return null;
+ });
+ }
+
+ @Override
+ public void createExternalElanNetwork(ElanInstance elanInstance) {
+ handleExternalElanNetwork(elanInstance, (elanInstance1, interfaceName) -> {
+ createExternalElanNetwork(elanInstance1, interfaceName);
+ return null;
+ });
+ }
+
+ private void createExternalElanNetwork(ElanInstance elanInstance, String interfaceName) {
+ if (interfaceName == null) {
+ LOG.trace("No physial interface is attached to {}", elanInstance.getPhysicalNetworkName());
+ return;
+ }
+
+ String elanInterfaceName = createIetfInterfaces(elanInstance, interfaceName);
+ addElanInterface(elanInstance.getElanInstanceName(), elanInterfaceName, null, null);
+ }
+
+ @Override
+ public void deleteExternalElanNetworks(Node node) {
+ handleExternalElanNetworks(node, (elanInstance, interfaceName) -> {
+ deleteExternalElanNetwork(elanInstance, interfaceName);
+ return null;
+ });
+ }
+
+ @Override
+ public void deleteExternalElanNetwork(ElanInstance elanInstance) {
+ handleExternalElanNetwork(elanInstance, (elanInstance1, interfaceName) -> {
+ deleteExternalElanNetwork(elanInstance1, interfaceName);
+ return null;
+ });
+ }
+
+ private void deleteExternalElanNetwork(ElanInstance elanInstance, String interfaceName) {
+ if (interfaceName == null) {
+ LOG.trace("No physial interface is attached to {}", elanInstance.getPhysicalNetworkName());
+ return;
+ }
+
+ String elanInstanceName = elanInstance.getElanInstanceName();
+ for (String elanInterface : getExternalElanInterfaces(elanInstanceName)) {
+ if (elanInterface.startsWith(interfaceName)) {
+ deleteIetfInterface(elanInterface);
+ deleteElanInterface(elanInstanceName, elanInterface);
+ }
+ }
+ }
+
+ @Override
+ public void updateExternalElanNetworks(Node origNode, Node updatedNode) {
+ if (!bridgeMgr.isIntegrationBridge(updatedNode)) {
+ return;
+ }
+
+ List<ElanInstance> elanInstances = getElanInstances();
+ if (elanInstances == null || elanInstances.isEmpty()) {
+ LOG.trace("No ELAN instances found");
+ 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 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 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;
+ }
+
+ for (String dpnInterface : dpnInterfaces.getInterfaces()) {
+ if (elanUtils.isExternal(dpnInterface)) {
+ return dpnInterface;
+ }
+ }
+
+ LOG.trace("Elan {} does not have any external interace attached to DPN {}", elanInstanceName, dpnId);
+ return null;
+ }
+
+ @Override
+ public Collection<String> getExternalElanInterfaces(String elanInstanceName) {
+ List<String> elanInterfaces = getElanInterfaces(elanInstanceName);
+ if (elanInterfaces == null || elanInterfaces.isEmpty()) {
+ LOG.trace("No ELAN interfaces defined for {}", elanInstanceName);
+ return Collections.emptySet();
+ }
+
+ Set<String> externalElanInterfaces = new HashSet<>();
+ for (String elanInterface : elanInterfaces) {
+ if (elanUtils.isExternal(elanInterface)) {
+ externalElanInterfaces.add(elanInterface);
+ }
+ }
+
+ return externalElanInterfaces;
+ }
+
+ @Override
+ public boolean isExternalInterface(String interfaceName) {
+ return elanUtils.isExternal(interfaceName);
+ }
+
+ @Override
+ public ElanInterface getElanInterfaceByElanInterfaceName(String interfaceName) {
+ return ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName);
+ }
+
+ /**
+ * Create ietf-interfaces based on the ELAN segment type.<br>
+ * For segment type flat - create transparent interface pointing to the
+ * patch-port attached to the physnet port.<br>
+ * For segment type vlan - create trunk interface pointing to the patch-port
+ * attached to the physnet port + trunk-member interface pointing to the
+ * trunk interface.
+ *
+ * @param elanInstance
+ * ELAN instance
+ * @param parentRef
+ * parent interface name
+ * @return the name of the interface to be added to the ELAN instance i.e.
+ * trunk-member name for vlan network and transparent for flat
+ * network or null otherwise
+ */
+ private String createIetfInterfaces(ElanInstance elanInstance, String parentRef) {
+ String interfaceName = null;
+
+ try {
+ if (ElanUtils.isFlat(elanInstance)) {
+ interfaceName = parentRef + IfmConstants.OF_URI_SEPARATOR + "flat";
+ interfaceManager.createVLANInterface(interfaceName, parentRef, null, null, null,
+ IfL2vlan.L2vlanMode.Transparent, true);
+ } else if (ElanUtils.isVlan(elanInstance)) {
+ Long segmentationId = elanInstance.getSegmentationId();
+ 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);
+ if (trunkInterface == null) {
+ interfaceManager.createVLANInterface(trunkName, parentRef, null, null, null,
+ IfL2vlan.L2vlanMode.Trunk, true);
+ }
+ interfaceManager.createVLANInterface(interfaceName, trunkName, null, segmentationId.intValue(), null,
+ IfL2vlan.L2vlanMode.TrunkMember, true);
+ }
+ } catch (InterfaceAlreadyExistsException e) {
+ LOG.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);
+ 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;
+ }
+
+ List<ElanInstance> elanInstances = getElanInstances();
+ if (elanInstances == null || elanInstances.isEmpty()) {
+ LOG.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) {
+ LOG.trace("No physical network attached to {}", elanInstanceName);
+ return;
+ }
+
+ List<Node> nodes = bridgeMgr.southboundUtils.getOvsdbNodes();
+ if (nodes == null || nodes.isEmpty()) {
+ LOG.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);
+ }
+ }
+ }
+