From 391371db72d63974a4b59fd2991995cad348ec09 Mon Sep 17 00:00:00 2001 From: cgowdru Date: Wed, 22 Feb 2017 17:47:34 +0530 Subject: [PATCH] Changes for supporting "opendaylight-vni-ranges" pool Description: 1) Re-defined VPN_POOL range to 100000-130000 2) Adding Util API's for creating and deleting VNI Pool. 3) NeutronVpn APIs exposed to retreive 'opendaylight-vni-ranges' and 'enforce-openstack-semantics' Change-Id: I61d518aa694416aca7b47b266c0f2c56edf350cf Signed-off-by: cgowdru --- .../natservice/internal/NatConstants.java | 3 + .../natservice/internal/NatOverVxlanUtil.java | 155 ++++++++++++++++++ .../interfaces/INeutronVpnManager.java | 4 + .../netvirt/neutronvpn/NeutronvpnManager.java | 10 +- .../neutronvpn/NeutronvpnManagerImpl.java | 10 ++ .../netvirt/vpnmanager/VpnConstants.java | 4 +- .../netvirt/vpnmanager/VpnManagerImpl.java | 4 +- 7 files changed, 185 insertions(+), 5 deletions(-) create mode 100644 vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatOverVxlanUtil.java diff --git a/vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatConstants.java b/vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatConstants.java index 8042d8340b..c1bda376e0 100644 --- a/vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatConstants.java +++ b/vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatConstants.java @@ -30,6 +30,9 @@ public class NatConstants { public static final String SNAT_IDPOOL_NAME = "snatGroupIdPool"; public static final long SNAT_ID_LOW_VALUE = 200000L; public static final long SNAT_ID_HIGH_VALUE = 225000L; + public static final String ODL_VNI_POOL_NAME = "opendaylight-vni-ranges"; + public static final long VNI_DEFAULT_LOW_VALUE = 70000L; + public static final long VNI_DEFAULT_HIGH_VALUE = 99999L; public static final int DEFAULT_TS_FLOW_PRIORITY = 10; public static final short DEFAULT_PREFIX = 32; public static final long DEFAULT_L3VNI_VALUE = 0; diff --git a/vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatOverVxlanUtil.java b/vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatOverVxlanUtil.java new file mode 100644 index 0000000000..7d4cb5a027 --- /dev/null +++ b/vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatOverVxlanUtil.java @@ -0,0 +1,155 @@ +/* + * Copyright © 2017 Ericsson India Global Services Pvt Ltd. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.netvirt.natservice.internal; + +import com.google.common.base.Optional; + +import java.math.BigInteger; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdOutput; +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.DeleteIdPoolInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.DeleteIdPoolInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdPools; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.ReleaseIdInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPool; +import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.id.pools.IdPoolKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class NatOverVxlanUtil { + + private static final Logger LOG = LoggerFactory.getLogger(NatOverVxlanUtil.class); + + public static BigInteger getVNI(String vniKey, IdManagerService idManager) { + AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(NatConstants.ODL_VNI_POOL_NAME) + .setIdKey(vniKey).build(); + try { + Future> result = idManager.allocateId(getIdInput); + RpcResult rpcResult = result.get(); + if (rpcResult.isSuccessful()) { + return BigInteger.valueOf(rpcResult.getResult().getIdValue()); + } + } catch (NullPointerException | InterruptedException | ExecutionException e) { + LOG.error("NAT Service : getVNI Exception {}", e); + } + return BigInteger.valueOf(-1); + } + + public static void releaseVNI(String vniKey, IdManagerService idManager) { + ReleaseIdInput releaseIdInput = new ReleaseIdInputBuilder().setPoolName(NatConstants.ODL_VNI_POOL_NAME) + .setIdKey(vniKey).build(); + try { + Future> result = idManager.releaseId(releaseIdInput); + RpcResult rpcResult = result.get(); + if (!rpcResult.isSuccessful()) { + LOG.warn("NAT Service : Unable to release ID {} from OpenDaylight VXLAN VNI range pool. Error {}", + vniKey, rpcResult.getErrors()); + } + } catch (NullPointerException | InterruptedException | ExecutionException e) { + LOG.error("NAT Service : getVNI Exception {}", e); + } + } + + public static void validateAndCreateVxlanVniPool(DataBroker broker, INeutronVpnManager neutronvpnManager, + IdManagerService idManager, String poolName) { + /* + * 1. If a NatPool doesn't exist create it. 2. If a NatPool exists, but + * the range value is changed incorrectly (say some allocations exist in + * the old range), we should NOT honor the new range . Throw the WARN + * but continue running NAT Service with Old range. 3. If a NatPool + * exists, but the given range is wider than the earlier one, we should + * attempt to allocate with the new range again(TODO) + */ + long lowLimit = NatConstants.VNI_DEFAULT_LOW_VALUE; + long highLimit = NatConstants.VNI_DEFAULT_HIGH_VALUE; + String configureVniRange = neutronvpnManager.getOpenDaylightVniRangesConfig(); + if (configureVniRange != null) { + String[] configureVniRangeSplit = configureVniRange.split(":"); + lowLimit = Long.parseLong(configureVniRangeSplit[0]); + highLimit = Long.parseLong(configureVniRangeSplit[1]); + } + Optional existingIdPool = NatUtil.read(broker, LogicalDatastoreType.CONFIGURATION, + getIdPoolInstance(poolName)); + if (existingIdPool.isPresent()) { + IdPool odlVniIdPool = existingIdPool.get(); + long currentStartLimit = odlVniIdPool.getAvailableIdsHolder().getStart(); + long currentEndLimit = odlVniIdPool.getAvailableIdsHolder().getEnd(); + + if (lowLimit == currentStartLimit && highLimit == currentEndLimit) { + LOG.debug("NAT Service : OpenDaylight VXLAN VNI range pool already exists with configured Range"); + } else { + if (odlVniIdPool.getIdEntries() != null && odlVniIdPool.getIdEntries().size() != 0) { + LOG.warn("NAT Service : Some Allocation already exists with old Range. " + + "Cannot modify existing limit of OpenDaylight VXLAN VNI range pool"); + } else { + LOG.debug("NAT Service : No VNI's allocated from OpenDaylight VXLAN VNI range pool." + + "Delete and re-create pool with new configured Range {}-{}",lowLimit, highLimit); + deleteOpenDaylightVniRangesPool(idManager, poolName); + createOpenDaylightVniRangesPool(idManager, poolName, lowLimit, highLimit); + } + } + } else { + createOpenDaylightVniRangesPool(idManager, poolName, lowLimit, highLimit); + } + } + + public static void createOpenDaylightVniRangesPool(IdManagerService idManager, String poolName, long lowLimit, + long highLimit) { + + CreateIdPoolInput createPool = null; + createPool = new CreateIdPoolInputBuilder().setPoolName(poolName).setLow(lowLimit).setHigh(highLimit).build(); + try { + Future> result = idManager.createIdPool(createPool); + if (result != null && result.get().isSuccessful()) { + LOG.debug("NAT Service : Created OpenDaylight VXLAN VNI range pool {} with range {}-{}", poolName, + lowLimit, highLimit); + } else { + LOG.error("NAT Service : Failed to create OpenDaylight VXLAN VNI range pool {} with range {}-{}", + poolName, lowLimit, highLimit); + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("NAT Service : Failed to create OpenDaylight VXLAN VNI range pool {} with range {}-{}", poolName, + lowLimit, highLimit); + } + } + + public static void deleteOpenDaylightVniRangesPool(IdManagerService idManager, String poolName) { + + DeleteIdPoolInput deletePool = new DeleteIdPoolInputBuilder().setPoolName(poolName).build(); + Future> result = idManager.deleteIdPool(deletePool); + try { + if (result != null && result.get().isSuccessful()) { + LOG.debug("NAT Service : Deleted OpenDaylight VXLAN VNI range pool {} successfully", poolName); + } else { + LOG.error("NAT Service : Failed to delete OpenDaylight VXLAN VNI range pool {} ", poolName); + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("NAT Service : Failed to delete OpenDaylight VXLAN VNI range pool {} ", poolName); + } + } + + private static InstanceIdentifier getIdPoolInstance(String poolName) { + InstanceIdentifier.InstanceIdentifierBuilder idPoolBuilder = InstanceIdentifier.builder(IdPools.class) + .child(IdPool.class, new IdPoolKey(poolName)); + InstanceIdentifier id = idPoolBuilder.build(); + return id; + } +} \ No newline at end of file diff --git a/vpnservice/neutronvpn/neutronvpn-api/src/main/java/org/opendaylight/netvirt/neutronvpn/interfaces/INeutronVpnManager.java b/vpnservice/neutronvpn/neutronvpn-api/src/main/java/org/opendaylight/netvirt/neutronvpn/interfaces/INeutronVpnManager.java index 015a415144..794049314f 100644 --- a/vpnservice/neutronvpn/neutronvpn-api/src/main/java/org/opendaylight/netvirt/neutronvpn/interfaces/INeutronVpnManager.java +++ b/vpnservice/neutronvpn/neutronvpn-api/src/main/java/org/opendaylight/netvirt/neutronvpn/interfaces/INeutronVpnManager.java @@ -42,5 +42,9 @@ public interface INeutronVpnManager { List getNetworksForVpn(Uuid vpnId); + String getOpenDaylightVniRangesConfig(); + + Boolean getEnforceOpenstackSemanticsConfig(); + } diff --git a/vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManager.java b/vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManager.java index 7d8df05a4e..e3e9719c0e 100644 --- a/vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManager.java +++ b/vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManager.java @@ -1940,6 +1940,14 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even return result; } + public String getOpenDaylightVniRangesConfig() { + return neutronvpnConfig.getOpendaylightVniRanges(); + } + + public Boolean getEnforceOpenstackSemanticsConfig() { + return neutronvpnConfig.isEnforceOpenstackSemantics(); + } + protected void handleNeutronRouterDeleted(Uuid routerId, List routerSubnetIds) { // check if the router is associated to some VPN Uuid vpnId = NeutronvpnUtils.getVpnForRouter(dataBroker, routerId, true); @@ -2230,4 +2238,4 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable, Even protected void dissociatefixedIPFromFloatingIP(String fixedNeutronPortName) { floatingIpMapListener.dissociatefixedIPFromFloatingIP(fixedNeutronPortName); } -} +} \ No newline at end of file diff --git a/vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManagerImpl.java b/vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManagerImpl.java index 9217449fc7..0f4a5c7aa8 100644 --- a/vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManagerImpl.java +++ b/vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManagerImpl.java @@ -87,4 +87,14 @@ public class NeutronvpnManagerImpl implements INeutronVpnManager { public Collection getSubnetIdsForGatewayIp(IpAddress ipAddress) { return NeutronvpnUtils.getSubnetIdsForGatewayIp(ipAddress); } + + @Override + public String getOpenDaylightVniRangesConfig() { + return nvManager.getOpenDaylightVniRangesConfig(); + } + + @Override + public Boolean getEnforceOpenstackSemanticsConfig() { + return nvManager.getEnforceOpenstackSemanticsConfig(); + } } diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnConstants.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnConstants.java index 20063736b6..125fe04f44 100644 --- a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnConstants.java +++ b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnConstants.java @@ -12,8 +12,8 @@ import java.math.BigInteger; public class VpnConstants { public static final String VPN_IDPOOL_NAME = "vpnservices"; - public static final long VPN_IDPOOL_START = 70000L; - public static final String VPN_IDPOOL_SIZE = "100000"; + public static final long VPN_IDPOOL_LOW = 100000L; + public static final long VPN_IDPOOL_HIGH = 130000L; public static final short DEFAULT_FLOW_PRIORITY = 10; public static final int DEFAULT_LPORT_DISPATCHER_FLOW_PRIORITY = 1; public static final long INVALID_ID = -1; diff --git a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnManagerImpl.java b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnManagerImpl.java index 6cf345dc4b..7451b98a71 100644 --- a/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnManagerImpl.java +++ b/vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnManagerImpl.java @@ -73,8 +73,8 @@ public class VpnManagerImpl implements IVpnManager { private void createIdPool() { CreateIdPoolInput createPool = new CreateIdPoolInputBuilder() .setPoolName(VpnConstants.VPN_IDPOOL_NAME) - .setLow(VpnConstants.VPN_IDPOOL_START) - .setHigh(new BigInteger(VpnConstants.VPN_IDPOOL_SIZE).longValue()) + .setLow(VpnConstants.VPN_IDPOOL_LOW) + .setHigh(VpnConstants.VPN_IDPOOL_HIGH) .build(); try { Future> result = idManager.createIdPool(createPool); -- 2.36.6