X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=vpnservice%2Felanmanager%2Felanmanager-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fnetvirt%2Felan%2Finternal%2FElanServiceProvider.java;h=cb1a9978328d6e22929b9cc9065e5066768b993a;hb=35f27a7e0cf6da670d7559d0755ede25ec8638b9;hp=4b23d07321c14945ae40e6d002a4992e4b03ffb4;hpb=d0e8a64bbe86935a6f4dcd78b3e4274914bce65a;p=netvirt.git diff --git a/vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanServiceProvider.java b/vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanServiceProvider.java index 4b23d07321..cb1a997832 100644 --- a/vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanServiceProvider.java +++ b/vpnservice/elanmanager/elanmanager-impl/src/main/java/org/opendaylight/netvirt/elan/internal/ElanServiceProvider.java @@ -8,36 +8,45 @@ 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 java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Map; +import java.util.Set; 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.controller.md.sal.common.api.clustering.EntityOwnershipService; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext; -import org.opendaylight.controller.sal.binding.api.BindingAwareProvider; -import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; -import org.opendaylight.netvirt.elan.utils.ElanForwardingEntriesHandler; -import org.opendaylight.netvirt.elanmanager.api.IElanService; -import org.opendaylight.netvirt.elanmanager.exceptions.MacNotFoundException; -import org.opendaylight.genius.datastoreutils.DataStoreJobCoordinator; -import org.opendaylight.netvirt.elan.l2gw.internal.ElanL2GatewayProvider; -import org.opendaylight.netvirt.elan.statisitcs.ElanStatisticsImpl; +import org.opendaylight.genius.interfacemanager.exceptions.InterfaceAlreadyExistsException; +import org.opendaylight.genius.interfacemanager.globals.IfmConstants; +import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager; +import org.opendaylight.genius.mdsalutil.MDSALUtil; import org.opendaylight.netvirt.elan.statusanddiag.ElanStatusMonitor; -import org.opendaylight.netvirt.elan.utils.ElanClusterUtils; import org.opendaylight.netvirt.elan.utils.ElanConstants; import org.opendaylight.netvirt.elan.utils.ElanUtils; -import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager; -import org.opendaylight.genius.itm.api.IITMProvider; -import org.opendaylight.genius.mdsalutil.MDSALUtil; -import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager; +import org.opendaylight.netvirt.elanmanager.api.IElanService; +import org.opendaylight.netvirt.elanmanager.exceptions.MacNotFoundException; +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.genius.idmanager.rev160406.CreateIdPoolInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rev160406.IfL2vlan; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInstance; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInstanceBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterface.EtreeInterfaceType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.etree.rev160614.EtreeInterfaceBuilder; 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; @@ -46,245 +55,64 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.interfaces.ElanInterfaceKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.state.Elan; import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntry; -import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.statistics.rev150824.ElanStatisticsService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInput; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.CreateIdPoolInputBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService; -import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.common.RpcResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Optional; - -public class ElanServiceProvider implements BindingAwareProvider, IElanService, AutoCloseable { - - private IdManagerService idManager; - private IMdsalApiManager mdsalManager; - private IInterfaceManager interfaceManager; - private OdlInterfaceRpcService interfaceManagerRpcService; - private ElanInstanceManager elanInstanceManager; - private ElanForwardingEntriesHandler elanForwardingEntriesHandler; - public IdManagerService getIdManager() { - return idManager; - } +public class ElanServiceProvider implements IElanService { - public ElanForwardingEntriesHandler getElanForwardingEntriesHandler() { - return elanForwardingEntriesHandler; - } - - public ElanPacketInHandler getElanPacketInHandler() { - return elanPacketInHandler; - } + private static final Logger LOG = LoggerFactory.getLogger(ElanServiceProvider.class); - public ElanSmacFlowEventListener getElanSmacFlowEventListener() { - return elanSmacFlowEventListener; - } - - public ElanInterfaceStateChangeListener getElanInterfaceStateChangeListener() { - return elanInterfaceStateChangeListener; - } - - public ElanInterfaceStateClusteredListener getInfStateChangeClusteredListener() { - return infStateChangeClusteredListener; - } - - public ElanDpnInterfaceClusteredListener getElanDpnInterfaceClusteredListener() { - return elanDpnInterfaceClusteredListener; - } - - public ElanNodeListener getElanNodeListener() { - return elanNodeListener; - } - - public NotificationService getNotificationService() { - return notificationService; - } - - public RpcProviderRegistry getRpcProviderRegistry() { - return rpcProviderRegistry; - } - - public ElanL2GatewayProvider getElanL2GatewayProvider() { - return elanL2GatewayProvider; - } - - public static ElanStatusMonitor getElanstatusmonitor() { - return elanStatusMonitor; - } - - public ElanItmEventListener getElanItmEventListener() { - return elanItmEventListener; - } - - public static Logger getLogger() { - return logger; - } - - private ElanInterfaceManager elanInterfaceManager; - private ElanPacketInHandler elanPacketInHandler; - private ElanSmacFlowEventListener elanSmacFlowEventListener; - private ElanInterfaceStateChangeListener elanInterfaceStateChangeListener; - private ElanInterfaceStateClusteredListener infStateChangeClusteredListener; - private ElanDpnInterfaceClusteredListener elanDpnInterfaceClusteredListener; - private ElanNodeListener elanNodeListener; - private NotificationService notificationService; - private RpcProviderRegistry rpcProviderRegistry; - private IITMProvider itmManager; - private ItmRpcService itmRpcService; - private DataBroker broker; - private ElanL2GatewayProvider elanL2GatewayProvider; - private ElanStatisticsService interfaceStatsService; - private EntityOwnershipService entityOwnershipService; - private static final ElanStatusMonitor elanStatusMonitor = ElanStatusMonitor.getInstance(); - static DataStoreJobCoordinator dataStoreJobCoordinator; - private ElanOvsdbNodeListener elanOvsdbNodeListener; + private final IdManagerService idManager; + private final IInterfaceManager interfaceManager; + private final ElanInstanceManager elanInstanceManager; + private final ElanBridgeManager bridgeMgr; + private final DataBroker broker; + private final ElanStatusMonitor elanStatusMonitor; + private static ElanUtils elanUtils; private boolean generateIntBridgeMac = true; - public static void setDataStoreJobCoordinator(DataStoreJobCoordinator ds) { - dataStoreJobCoordinator = ds; - } - - public void setBroker(DataBroker broker) { - this.broker = broker; - } - - public static DataStoreJobCoordinator getDataStoreJobCoordinator() { - if (dataStoreJobCoordinator == null) { - dataStoreJobCoordinator = DataStoreJobCoordinator.getInstance(); - } - return dataStoreJobCoordinator; - } - - - public ElanServiceProvider(RpcProviderRegistry rpcRegistry) { - rpcProviderRegistry = rpcRegistry; - elanStatusMonitor.registerMbean(); + public ElanServiceProvider(IdManagerService idManager, IInterfaceManager interfaceManager, + ElanInstanceManager elanInstanceManager, ElanBridgeManager bridgeMgr, + DataBroker dataBroker, + ElanInterfaceManager elanInterfaceManager, + ElanStatusMonitor elanStatusMonitor, ElanUtils elanUtils) { + this.idManager = idManager; + this.interfaceManager = interfaceManager; + this.elanInstanceManager = elanInstanceManager; + this.bridgeMgr = bridgeMgr; + this.broker = dataBroker; + this.elanStatusMonitor = elanStatusMonitor; + this.elanUtils = elanUtils; + elanInterfaceManager.setElanUtils(elanUtils); } - // private ElanInterfaceStateChangeListener elanInterfaceEventListener; - private ElanItmEventListener elanItmEventListener; - - private static final Logger logger = LoggerFactory.getLogger(ElanServiceProvider.class); - - @Override - public void onSessionInitiated(ProviderContext session) { + public void init() { + LOG.info("Starting ElnaServiceProvider"); elanStatusMonitor.reportStatus("STARTING"); try { createIdPool(); - getDataStoreJobCoordinator(); - broker = session.getSALService(DataBroker.class); - - elanOvsdbNodeListener = new ElanOvsdbNodeListener(broker, generateIntBridgeMac); - ElanUtils.setElanServiceProvider(this); - elanForwardingEntriesHandler = ElanForwardingEntriesHandler.getElanForwardingEntriesHandler(this); - elanInterfaceManager = ElanInterfaceManager.getElanInterfaceManager(this); - elanInstanceManager = ElanInstanceManager.getElanInstanceManager(this); - elanNodeListener = ElanNodeListener.getElanNodeListener(this); - elanPacketInHandler = ElanPacketInHandler.getElanPacketInHandler(this); - elanSmacFlowEventListener = ElanSmacFlowEventListener.getElanSmacFlowEventListener(this); - // Initialize statistics rpc provider for elan - interfaceStatsService = ElanStatisticsImpl.getElanStatisticsService(this); - rpcProviderRegistry.addRpcImplementation(ElanStatisticsService.class, interfaceStatsService); - elanInterfaceStateChangeListener = ElanInterfaceStateChangeListener.getElanInterfaceStateChangeListener(this); - infStateChangeClusteredListener = ElanInterfaceStateClusteredListener.getElanInterfaceStateClusteredListener(this); - elanDpnInterfaceClusteredListener = ElanDpnInterfaceClusteredListener.getElanDpnInterfaceClusteredListener(this); - ElanClusterUtils.setElanServiceProvider(this); - this.elanL2GatewayProvider = new ElanL2GatewayProvider(this); - elanInterfaceManager.registerListener(LogicalDatastoreType.CONFIGURATION,broker); - elanInstanceManager.registerListener(LogicalDatastoreType.CONFIGURATION,broker); - notificationService.registerNotificationListener(elanSmacFlowEventListener); - notificationService.registerNotificationListener(elanPacketInHandler); + elanStatusMonitor.reportStatus("OPERATIONAL"); } catch (Exception e) { - logger.error("Error initializing services", e); + LOG.error("Error initializing services", e); elanStatusMonitor.reportStatus("ERROR"); } } - - - public void setIdManager(IdManagerService idManager) { - this.idManager = idManager; - } - - public void setMdsalManager(IMdsalApiManager mdsalManager) { - this.mdsalManager = mdsalManager; - } - - public void setInterfaceManager(IInterfaceManager interfaceManager) { - this.interfaceManager = interfaceManager; - } - - public void setEntityOwnershipService(EntityOwnershipService entityOwnershipService) { - this.entityOwnershipService = entityOwnershipService; - } - - public IInterfaceManager getInterfaceManager() { - return this.interfaceManager; - } - - public IMdsalApiManager getMdsalManager() { - return mdsalManager; - } - - public IITMProvider getItmManager() { - return itmManager; - } - - public DataBroker getBroker() { - return broker; - } - - public void setNotificationService(NotificationService notificationService) { - this.notificationService = notificationService; - } - - public void setInterfaceManagerRpcService(OdlInterfaceRpcService interfaceManager) { - this.interfaceManagerRpcService = interfaceManager; - } - - public OdlInterfaceRpcService getInterfaceManagerRpcService() { - return interfaceManagerRpcService; - } - - public void setItmManager(IITMProvider itmManager) { - this.itmManager = itmManager; - } - - public void setItmRpcService(ItmRpcService itmRpcService) { - this.itmRpcService = itmRpcService; - } - - public ItmRpcService getItmRpcService() { - return itmRpcService; - } - - public ElanInstanceManager getElanInstanceManager() { - return elanInstanceManager; - } - - public ElanInterfaceManager getElanInterfaceManager() { - return elanInterfaceManager; - } - - public EntityOwnershipService getEntityOwnershipService() { - return entityOwnershipService; - } - private void createIdPool() { CreateIdPoolInput createPool = new CreateIdPoolInputBuilder().setPoolName(ElanConstants.ELAN_ID_POOL_NAME) - .setLow(ElanConstants.ELAN_ID_LOW_VALUE).setHigh(ElanConstants.ELAN_ID_HIGH_VALUE).build(); + .setLow(ElanConstants.ELAN_ID_LOW_VALUE).setHigh(ElanConstants.ELAN_ID_HIGH_VALUE).build(); try { Future> result = idManager.createIdPool(createPool); - if ((result != null) && (result.get().isSuccessful())) { - logger.debug("ELAN Id Pool is created successfully"); + if (result != null && result.get().isSuccessful()) { + LOG.debug("ELAN Id Pool is created successfully"); } } catch (Exception e) { - logger.error("Failed to create ELAN Id pool {}", e); + LOG.error("Failed to create ELAN Id pool {}", e); } } @@ -294,33 +122,69 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService, boolean isSuccess = true; if (existingElanInstance != null) { if (compareWithExistingElanInstance(existingElanInstance, macTimeout, description)) { - logger.debug("Elan Instance is already present in the Operational DS {}", existingElanInstance); + LOG.debug("Elan Instance is already present in the Operational DS {}", existingElanInstance); return true; } else { ElanInstance updateElanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName) - .setDescription(description).setMacTimeout(macTimeout) - .setKey(new ElanInstanceKey(elanInstanceName)).build(); + .setDescription(description).setMacTimeout(macTimeout) + .setKey(new ElanInstanceKey(elanInstanceName)).build(); MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, - ElanUtils.getElanInstanceConfigurationDataPath(elanInstanceName), updateElanInstance); - logger.debug("Updating the Elan Instance {} with MAC TIME-OUT %l and Description %s ", - updateElanInstance, macTimeout, description); + ElanUtils.getElanInstanceConfigurationDataPath(elanInstanceName), updateElanInstance); + LOG.debug("Updating the Elan Instance {} with MAC TIME-OUT %l and Description %s ", + updateElanInstance, macTimeout, description); } } else { ElanInstance elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName) - .setMacTimeout(macTimeout).setDescription(description).setKey(new ElanInstanceKey(elanInstanceName)) - .build(); + .setMacTimeout(macTimeout).setDescription(description).setKey(new ElanInstanceKey(elanInstanceName)) + .build(); + MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, + ElanUtils.getElanInstanceConfigurationDataPath(elanInstanceName), elanInstance); + LOG.debug("Creating the new Elan Instance {}", elanInstance); + } + return isSuccess; + } + + @Override + public boolean createEtreeInstance(String elanInstanceName, long macTimeout, String description) { + ElanInstance existingElanInstance = elanInstanceManager.getElanInstanceByName(elanInstanceName); + boolean isSuccess = true; + if (existingElanInstance != null) { + if (compareWithExistingElanInstance(existingElanInstance, macTimeout, description)) { + LOG.warn("Etree Instance is already present in the Operational DS {}", existingElanInstance); + return true; + } else { + EtreeInstance etreeInstance = new EtreeInstanceBuilder().build(); + ElanInstance updateElanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName) + .setDescription(description).setMacTimeout(macTimeout) + .setKey(new ElanInstanceKey(elanInstanceName)) + .addAugmentation(EtreeInstance.class, etreeInstance).build(); + MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, + ElanUtils.getElanInstanceConfigurationDataPath(elanInstanceName), updateElanInstance); + LOG.debug("Updating the Etree Instance {} with MAC TIME-OUT %l and Description %s ", + updateElanInstance, macTimeout, description); + } + } else { + EtreeInstance etreeInstance = new EtreeInstanceBuilder().build(); + ElanInstance elanInstance = new ElanInstanceBuilder().setElanInstanceName(elanInstanceName) + .setMacTimeout(macTimeout).setDescription(description).setKey(new ElanInstanceKey(elanInstanceName)) + .addAugmentation(EtreeInstance.class, etreeInstance).build(); MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, - ElanUtils.getElanInstanceConfigurationDataPath(elanInstanceName), elanInstance); - logger.debug("Creating the new Elan Instance {}", elanInstance); + ElanUtils.getElanInstanceConfigurationDataPath(elanInstanceName), elanInstance); + LOG.debug("Creating the new Etree Instance {}", elanInstance); } return isSuccess; } + @Override + public EtreeInterface getEtreeInterfaceByElanInterfaceName(String elanInterface) { + return ElanUtils.getEtreeInterfaceByElanInterfaceName(broker, elanInterface); + } + public static boolean compareWithExistingElanInstance(ElanInstance existingElanInstance, long macTimeOut, - String description) { + String description) { boolean isEqual = false; if (existingElanInstance.getMacTimeout() == macTimeOut - && existingElanInstance.getDescription().equals(description)) { + && existingElanInstance.getDescription().equals(description)) { isEqual = true; } return isEqual; @@ -331,48 +195,76 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService, createElanInstance(elanInstanceName, newMacTimout, newDescription); } + @Override + public boolean deleteEtreeInstance(String etreeInstanceName) { + return deleteElanInstance(etreeInstanceName); + } + @Override public boolean deleteElanInstance(String elanInstanceName) { boolean isSuccess = false; ElanInstance existingElanInstance = elanInstanceManager.getElanInstanceByName(elanInstanceName); if (existingElanInstance == null) { - logger.debug("Elan Instance is not present {}", existingElanInstance); + LOG.debug("Elan Instance is not present {}", existingElanInstance); return isSuccess; } - logger.debug("Deletion of the existing Elan Instance {}", existingElanInstance); + LOG.debug("Deletion of the existing Elan Instance {}", existingElanInstance); ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, - ElanUtils.getElanInstanceConfigurationDataPath(elanInstanceName)); + ElanUtils.getElanInstanceConfigurationDataPath(elanInstanceName)); isSuccess = true; return isSuccess; } + @Override + public void addEtreeInterface(String etreeInstanceName, String interfaceName, EtreeInterfaceType interfaceType, + List staticMacAddresses, String description) { + ElanInstance existingElanInstance = elanInstanceManager.getElanInstanceByName(etreeInstanceName); + if (existingElanInstance != null && existingElanInstance.getAugmentation(EtreeInstance.class) != null) { + EtreeInterface etreeInterface = new EtreeInterfaceBuilder().setEtreeInterfaceType(interfaceType).build(); + ElanInterface elanInterface; + if (staticMacAddresses == null) { + elanInterface = new ElanInterfaceBuilder().setElanInstanceName(etreeInstanceName) + .setDescription(description).setName(interfaceName).setKey(new ElanInterfaceKey(interfaceName)) + .addAugmentation(EtreeInterface.class, etreeInterface).build(); + } else { + elanInterface = new ElanInterfaceBuilder().setElanInstanceName(etreeInstanceName) + .setDescription(description).setName(interfaceName) + .setStaticMacEntries(getPhysAddress(staticMacAddresses)) + .setKey(new ElanInterfaceKey(interfaceName)) + .addAugmentation(EtreeInterface.class, etreeInterface).build(); + } + MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, + ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface); + LOG.debug("Creating the new Etree Interface {}", elanInterface); + } + } + @Override public void addElanInterface(String elanInstanceName, String interfaceName, List staticMacAddresses, - String description) { + String description) { ElanInstance existingElanInstance = elanInstanceManager.getElanInstanceByName(elanInstanceName); if (existingElanInstance != null) { ElanInterface elanInterface; if (staticMacAddresses == null) { elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName) - .setDescription(description).setName(interfaceName).setKey(new ElanInterfaceKey(interfaceName)) - .build(); + .setDescription(description).setName(interfaceName).setKey(new ElanInterfaceKey(interfaceName)) + .build(); } else { elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName) - .setDescription(description).setName(interfaceName) - .setStaticMacEntries(getPhysAddress(staticMacAddresses)) - .setKey(new ElanInterfaceKey(interfaceName)).build(); + .setDescription(description).setName(interfaceName) + .setStaticMacEntries(getPhysAddress(staticMacAddresses)) + .setKey(new ElanInterfaceKey(interfaceName)).build(); } MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, - ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface); - logger.debug("Creating the new ELan Interface {}", elanInterface); + ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface); + LOG.debug("Creating the new ELan Interface {}", elanInterface); } - } @Override public void updateElanInterface(String elanInstanceName, String interfaceName, - List updatedStaticMacAddresses, String newDescription) { - ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName); + List updatedStaticMacAddresses, String newDescription) { + ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName); if (existingElanInterface == null) { return; } @@ -380,28 +272,34 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService, List updatedMacAddresses = getPhysAddress(updatedStaticMacAddresses); List updatedPhysAddress = getUpdatedPhyAddress(existingMacAddress, updatedMacAddresses); if (updatedPhysAddress.size() > 0) { - logger.debug("updating the ElanInterface with new Mac Entries {}", updatedStaticMacAddresses); + LOG.debug("updating the ElanInterface with new Mac Entries {}", updatedStaticMacAddresses); ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName) - .setName(interfaceName).setDescription(newDescription).setStaticMacEntries(updatedPhysAddress) - .setKey(new ElanInterfaceKey(interfaceName)).build(); + .setName(interfaceName).setDescription(newDescription).setStaticMacEntries(updatedPhysAddress) + .setKey(new ElanInterfaceKey(interfaceName)).build(); MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, - ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface); + ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface); } } + @Override + public void deleteEtreeInterface(String elanInstanceName, String interfaceName) { + deleteElanInterface(elanInstanceName, interfaceName); + LOG.debug("deleting the Etree Interface {}", interfaceName); + } + @Override public void deleteElanInterface(String elanInstanceName, String interfaceName) { - ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName); + ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName); if (existingElanInterface != null) { ElanUtils.delete(broker, LogicalDatastoreType.CONFIGURATION, - ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName)); - logger.debug("deleting the Elan Interface {}", existingElanInterface); + ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName)); + LOG.debug("deleting the Elan Interface {}", existingElanInterface); } } @Override public void addStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress) { - ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName); + ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName); PhysAddress updateStaticMacAddress = new PhysAddress(macAddress); if (existingElanInterface != null) { List existingMacAddress = existingElanInterface.getStaticMacEntries(); @@ -410,18 +308,18 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService, } existingMacAddress.add(updateStaticMacAddress); ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName) - .setName(interfaceName).setStaticMacEntries(existingMacAddress) - .setDescription(existingElanInterface.getDescription()).setKey(new ElanInterfaceKey(interfaceName)) - .build(); + .setName(interfaceName).setStaticMacEntries(existingMacAddress) + .setDescription(existingElanInterface.getDescription()).setKey(new ElanInterfaceKey(interfaceName)) + .build(); MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, - ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface); + ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface); } } @Override public void deleteStaticMacAddress(String elanInstanceName, String interfaceName, String macAddress) - throws MacNotFoundException { - ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(interfaceName); + throws MacNotFoundException { + ElanInterface existingElanInterface = ElanUtils.getElanInterfaceByElanInterfaceName(broker, interfaceName); PhysAddress physAddress = new PhysAddress(macAddress); if (existingElanInterface == null) { return; @@ -430,19 +328,19 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService, if (existingMacAddress.contains(physAddress)) { existingMacAddress.remove(physAddress); ElanInterface elanInterface = new ElanInterfaceBuilder().setElanInstanceName(elanInstanceName) - .setName(interfaceName).setStaticMacEntries(existingMacAddress) - .setDescription(existingElanInterface.getDescription()).setKey(new ElanInterfaceKey(interfaceName)) - .build(); + .setName(interfaceName).setStaticMacEntries(existingMacAddress) + .setDescription(existingElanInterface.getDescription()).setKey(new ElanInterfaceKey(interfaceName)) + .build(); MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, - ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface); + ElanUtils.getElanInterfaceConfigurationDataPathId(interfaceName), elanInterface); } else { - throw new MacNotFoundException("Mac Not Found Exception"); + throw new MacNotFoundException("deleteStaticMacAddress did not find MAC: " + macAddress); } } @Override public Collection getElanMacTable(String elanInstanceName) { - Elan elanInfo = ElanUtils.getElanByName(elanInstanceName); + Elan elanInfo = ElanUtils.getElanByName(broker, elanInstanceName); List macAddress = new ArrayList<>(); if (elanInfo == null) { return macAddress; @@ -450,9 +348,9 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService, List elanInterfaces = elanInfo.getElanInterfaces(); if (elanInterfaces != null && elanInterfaces.size() > 0) { for (String elanInterface : elanInterfaces) { - ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(elanInterface); + ElanInterfaceMac elanInterfaceMac = elanUtils.getElanInterfaceMacByInterfaceName(elanInterface); if (elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null - && elanInterfaceMac.getMacEntry().size() > 0) { + && elanInterfaceMac.getMacEntry().size() > 0) { macAddress.addAll(elanInterfaceMac.getMacEntry()); } } @@ -462,7 +360,7 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService, @Override public void flushMACTable(String elanInstanceName) { - Elan elanInfo = ElanUtils.getElanByName(elanInstanceName); + Elan elanInfo = ElanUtils.getElanByName(broker, elanInstanceName); if (elanInfo == null) { return; } @@ -471,14 +369,14 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService, return; } for (String elanInterface : elanInterfaces) { - ElanInterfaceMac elanInterfaceMac = ElanUtils.getElanInterfaceMacByInterfaceName(elanInterface); + ElanInterfaceMac elanInterfaceMac = elanUtils.getElanInterfaceMacByInterfaceName(elanInterface); if (elanInterfaceMac.getMacEntry() != null && elanInterfaceMac.getMacEntry().size() > 0) { List macEntries = elanInterfaceMac.getMacEntry(); for (MacEntry macEntry : macEntries) { try { deleteStaticMacAddress(elanInstanceName, elanInterface, macEntry.getMacAddress().getValue()); } catch (MacNotFoundException e) { - logger.error("Mac Not Found Exception {}", e); + LOG.error("Mac Not Found Exception {}", e); e.printStackTrace(); } } @@ -487,12 +385,6 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService, } - @Override - public void close() throws Exception { - this.elanInstanceManager.close(); - this.elanL2GatewayProvider.close(); - } - public static List getPhysAddress(List macAddress) { List physAddresses = new ArrayList<>(); for (String mac : macAddress) { @@ -502,7 +394,7 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService, } public List getUpdatedPhyAddress(List originalAddresses, - List updatePhyAddresses) { + List updatePhyAddresses) { if (updatePhyAddresses != null && !updatePhyAddresses.isEmpty()) { List existingClonedPhyAddress = new ArrayList<>(); if (originalAddresses != null && !originalAddresses.isEmpty()) { @@ -516,16 +408,16 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService, @Override public ElanInstance getElanInstance(String elanName) { - return ElanUtils.getElanInstanceByName(elanName); + return ElanUtils.getElanInstanceByName(broker, elanName); } @Override public List getElanInstances() { List elanList = new ArrayList<>(); InstanceIdentifier elanInstancesIdentifier = InstanceIdentifier.builder(ElanInstances.class) - .build(); - Optional elansOptional = ElanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, - elanInstancesIdentifier); + .build(); + Optional elansOptional = elanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, + elanInstancesIdentifier); if (elansOptional.isPresent()) { elanList.addAll(elansOptional.get().getElanInstance()); } @@ -536,9 +428,9 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService, public List getElanInterfaces(String elanInstanceName) { List elanInterfaces = new ArrayList<>(); InstanceIdentifier elanInterfacesIdentifier = InstanceIdentifier.builder(ElanInterfaces.class) - .build(); - Optional elanInterfacesOptional = ElanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, - elanInterfacesIdentifier); + .build(); + Optional elanInterfacesOptional = elanUtils.read(broker, LogicalDatastoreType.CONFIGURATION, + elanInterfacesIdentifier); if (!elanInterfacesOptional.isPresent()) { return elanInterfaces; } @@ -558,4 +450,248 @@ public class ElanServiceProvider implements BindingAwareProvider, IElanService, public void setGenerateIntBridgeMac(boolean generateIntBridgeMac) { this.generateIntBridgeMac = generateIntBridgeMac; } + + @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; + }); + } + + @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; + }); + } + + @Override + public void updateExternalElanNetworks(Node origNode, Node updatedNode) { + if (!bridgeMgr.isIntegrationBridge(updatedNode)) { + return; + } + + List elanInstances = getElanInstances(); + if (elanInstances == null || elanInstances.isEmpty()) { + LOG.trace("No ELAN instances found"); + return; + } + + Optional> origProviderMapOpt = bridgeMgr.getOpenvswitchOtherConfigMap(origNode, + ElanBridgeManager.PROVIDER_MAPPINGS_KEY); + Optional> updatedProviderMapOpt = bridgeMgr.getOpenvswitchOtherConfigMap(updatedNode, + ElanBridgeManager.PROVIDER_MAPPINGS_KEY); + Map origProviderMappping = origProviderMapOpt.or(Collections.emptyMap()); + Map 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)); + } + } + } + } + + 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); + } + + 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 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 getExternalElanInterfaces(String elanInstanceName) { + List elanInterfaces = getElanInterfaces(elanInstanceName); + if (elanInterfaces == null || elanInterfaces.isEmpty()) { + LOG.trace("No ELAN interfaces defined for {}", elanInstanceName); + return Collections.emptySet(); + } + + Set 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.
+ * For segment type flat - create transparent interface pointing to the + * patch-port attached to the physnet port.
+ * 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"; + 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 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 function) { + if (!bridgeMgr.isIntegrationBridge(node)) { + return; + } + + List 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 function) { + String elanInstanceName = elanInstance.getElanInstanceName(); + if (elanInstance.getPhysicalNetworkName() == null) { + LOG.trace("No physical network attached to {}", elanInstanceName); + return; + } + + List 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); + } + } + } + }