Changes for supporting "opendaylight-vni-ranges" pool 71/52171/12
authorcgowdru <chetan.arakere@altencalsoftlabs.com>
Wed, 22 Feb 2017 12:17:34 +0000 (17:47 +0530)
committerVivekanandan Narasimhan <n.vivekanandan@ericsson.com>
Wed, 8 Mar 2017 10:06:48 +0000 (10:06 +0000)
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 <chetan.arakere@altencalsoftlabs.com>
vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatConstants.java
vpnservice/natservice/natservice-impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatOverVxlanUtil.java [new file with mode: 0644]
vpnservice/neutronvpn/neutronvpn-api/src/main/java/org/opendaylight/netvirt/neutronvpn/interfaces/INeutronVpnManager.java
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManager.java
vpnservice/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/netvirt/neutronvpn/NeutronvpnManagerImpl.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnConstants.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnManagerImpl.java

index 8042d8340ba4a3175645011e7498c0d64fc2de75..c1bda376e07f204790c71f3b5b7c68444e9f8b9b 100644 (file)
@@ -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 (file)
index 0000000..7d4cb5a
--- /dev/null
@@ -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<RpcResult<AllocateIdOutput>> result = idManager.allocateId(getIdInput);
+            RpcResult<AllocateIdOutput> 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<RpcResult<Void>> result = idManager.releaseId(releaseIdInput);
+            RpcResult<Void> 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<IdPool> 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<RpcResult<Void>> 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<RpcResult<Void>> 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<IdPool> getIdPoolInstance(String poolName) {
+        InstanceIdentifier.InstanceIdentifierBuilder<IdPool> idPoolBuilder = InstanceIdentifier.builder(IdPools.class)
+                .child(IdPool.class, new IdPoolKey(poolName));
+        InstanceIdentifier<IdPool> id = idPoolBuilder.build();
+        return id;
+    }
+}
\ No newline at end of file
index 015a415144fe99c3e41c31e2e4525d46bfda6c19..794049314f9987a253f6cc03ca0d5243638fc082 100644 (file)
@@ -42,5 +42,9 @@ public interface INeutronVpnManager {
 
     List<Uuid> getNetworksForVpn(Uuid vpnId);
 
+    String getOpenDaylightVniRangesConfig();
+
+    Boolean getEnforceOpenstackSemanticsConfig();
+
 }
 
index 7d8df05a4e214d8d2808fe210981d2619124e7b4..e3e9719c0e710af11eeac7fb27d5c3160608488e 100644 (file)
@@ -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<Uuid> 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
index 9217449fc733cdbb2c30443d5da26b5851003084..0f4a5c7aa8ba1563311272c5e6933339b0f1411e 100644 (file)
@@ -87,4 +87,14 @@ public class NeutronvpnManagerImpl implements INeutronVpnManager {
     public Collection<Uuid> getSubnetIdsForGatewayIp(IpAddress ipAddress) {
         return  NeutronvpnUtils.getSubnetIdsForGatewayIp(ipAddress);
     }
+
+    @Override
+    public String getOpenDaylightVniRangesConfig() {
+        return nvManager.getOpenDaylightVniRangesConfig();
+    }
+
+    @Override
+    public Boolean getEnforceOpenstackSemanticsConfig() {
+        return nvManager.getEnforceOpenstackSemanticsConfig();
+    }
 }
index 20063736b6c53a7a37284b274445da7aaa11bbe7..125fe04f44b4aecc088695a1d58ffc4b3cf07e75 100644 (file)
@@ -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;
index 6cf345dc4bae8cfbe33ac3d9efda60c30c584845..7451b98a71f1aa092d9e70930d7b3c1e32119e43 100644 (file)
@@ -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<RpcResult<Void>> result = idManager.createIdPool(createPool);