package org.opendaylight.neutron.spi;
import java.io.Serializable;
+import java.math.BigInteger;
import java.net.InetAddress;
import java.net.Inet6Address;
import java.util.ArrayList;
Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();
while (i.hasNext()) {
NeutronSubnet_IPAllocationPool pool = i.next();
- if (pool.contains(gatewayIP)) {
- return true;
+ if (ipVersion == 4) {
+ if (pool.contains(gatewayIP)) {
+ return true;
+ }
+ }
+ if (ipVersion == 6) {
+ if (pool.contains_V6(gatewayIP)) {
+ return true;
+ }
}
}
return false;
}
if (allocationPools == null) {
allocationPools = new ArrayList<NeutronSubnet_IPAllocationPool>();
- try {
- SubnetUtils util = new SubnetUtils(cidr);
- SubnetInfo info = util.getInfo();
- if (gatewayIP == null || ("").equals(gatewayIP)) {
- gatewayIP = info.getLowAddress();
+ if (ipVersion == 4) {
+ try {
+ SubnetUtils util = new SubnetUtils(cidr);
+ SubnetInfo info = util.getInfo();
+ if (gatewayIP == null || ("").equals(gatewayIP)) {
+ gatewayIP = info.getLowAddress();
+ }
+ if (allocationPools.size() < 1) {
+ NeutronSubnet_IPAllocationPool source =
+ new NeutronSubnet_IPAllocationPool(info.getLowAddress(),
+ info.getHighAddress());
+ allocationPools = source.splitPool(gatewayIP);
+ }
+ } catch (Exception e) {
+ return false;
}
- if (allocationPools.size() < 1) {
- NeutronSubnet_IPAllocationPool source =
- new NeutronSubnet_IPAllocationPool(info.getLowAddress(),
- info.getHighAddress());
- allocationPools = source.splitPool(gatewayIP);
+ }
+ if (ipVersion == 6) {
+ String[] parts = cidr.split("/");
+ if (parts.length != 2) {
+ return false;
+ }
+ try {
+ int length = Integer.parseInt(parts[1]);
+ BigInteger lowAddress_bi = NeutronSubnet_IPAllocationPool.convert_V6(parts[0]);
+ String lowAddress = NeutronSubnet_IPAllocationPool.bigIntegerToIP(lowAddress_bi.add(BigInteger.ONE));
+ BigInteger mask = BigInteger.ONE.shiftLeft(length).subtract(BigInteger.ONE);
+ String highAddress = NeutronSubnet_IPAllocationPool.bigIntegerToIP(lowAddress_bi.add(mask).subtract(BigInteger.ONE));
+ if (gatewayIP == null || ("").equals(gatewayIP)) {
+ gatewayIP = lowAddress;
+ }
+ if (allocationPools.size() < 1) {
+ NeutronSubnet_IPAllocationPool source =
+ new NeutronSubnet_IPAllocationPool(lowAddress,
+ highAddress);
+ allocationPools = source.splitPool_V6(gatewayIP);
+ }
+ } catch (Exception e) {
+ return false;
}
- } catch (Exception e) {
- return false;
}
}
return true;
Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();
while (i.hasNext()) {
NeutronSubnet_IPAllocationPool pool = i.next();
- if (pool.contains(ipAddress)) {
+ if (ipVersion == 4 && pool.contains(ipAddress)) {
+ return false;
+ }
+ if (ipVersion == 6 && pool.contains_V6(ipAddress)) {
return false;
}
}
if (ans == null) {
ans = pool.getPoolStart();
}
- else
- if (NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart()) <
- NeutronSubnet_IPAllocationPool.convert(ans)) {
- ans = pool.getPoolStart();
+ else {
+ if (ipVersion == 4) {
+ if (NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart()) <
+ NeutronSubnet_IPAllocationPool.convert(ans)) {
+ ans = pool.getPoolStart();
+ }
+ }
+ if (ipVersion == 6) {
+ if (NeutronSubnet_IPAllocationPool.convert_V6(pool.getPoolStart()).compareTo(NeutronSubnet_IPAllocationPool.convert_V6(ans)) < 0) {
+ ans = pool.getPoolStart();
+ }
}
+ }
}
return ans;
}
*/
if (!(pool.getPoolEnd().equalsIgnoreCase(ipAddress) &&
pool.getPoolStart().equalsIgnoreCase(ipAddress))) {
- if (pool.contains(ipAddress)) {
- List<NeutronSubnet_IPAllocationPool> pools = pool.splitPool(ipAddress);
- newList.addAll(pools);
- } else {
- newList.add(pool);
+ if (ipVersion == 4) {
+ if (pool.contains(ipAddress)) {
+ List<NeutronSubnet_IPAllocationPool> pools = pool.splitPool(ipAddress);
+ newList.addAll(pools);
+ } else {
+ newList.add(pool);
+ }
+ }
+ if (ipVersion == 6) {
+ if (pool.contains_V6(ipAddress)) {
+ List<NeutronSubnet_IPAllocationPool> pools = pool.splitPool_V6(ipAddress);
+ newList.addAll(pools);
+ } else {
+ newList.add(pool);
+ }
}
}
}
NeutronSubnet_IPAllocationPool lPool = null;
NeutronSubnet_IPAllocationPool hPool = null;
Iterator<NeutronSubnet_IPAllocationPool> i = allocationPools.iterator();
- long sIP = NeutronSubnet_IPAllocationPool.convert(ipAddress);
- //look for lPool where ipAddr - 1 is high address
- //look for hPool where ipAddr + 1 is low address
- while (i.hasNext()) {
- NeutronSubnet_IPAllocationPool pool = i.next();
- long lIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart());
- long hIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolEnd());
- if (sIP+1 == lIP) {
- hPool = pool;
+ if (ipVersion == 4) {
+ long sIP = NeutronSubnet_IPAllocationPool.convert(ipAddress);
+ //look for lPool where ipAddr - 1 is high address
+ //look for hPool where ipAddr + 1 is low address
+ while (i.hasNext()) {
+ NeutronSubnet_IPAllocationPool pool = i.next();
+ long lIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolStart());
+ long hIP = NeutronSubnet_IPAllocationPool.convert(pool.getPoolEnd());
+ if (sIP+1 == lIP) {
+ hPool = pool;
+ }
+ if (sIP-1 == hIP) {
+ lPool = pool;
+ }
}
- if (sIP-1 == hIP) {
- lPool = pool;
+ }
+ if (ipVersion == 6) {
+ BigInteger sIP = NeutronSubnet_IPAllocationPool.convert_V6(ipAddress);
+ //look for lPool where ipAddr - 1 is high address
+ //look for hPool where ipAddr + 1 is low address
+ while (i.hasNext()) {
+ NeutronSubnet_IPAllocationPool pool = i.next();
+ BigInteger lIP = NeutronSubnet_IPAllocationPool.convert_V6(pool.getPoolStart());
+ BigInteger hIP = NeutronSubnet_IPAllocationPool.convert_V6(pool.getPoolEnd());
+ if (lIP.compareTo(sIP.add(BigInteger.ONE)) == 0) {
+ hPool = pool;
+ }
+ if (hIP.compareTo(sIP.subtract(BigInteger.ONE)) == 0) {
+ lPool = pool;
+ }
}
}
//if (lPool == NULL and hPool == NULL) create new pool where low = ip = high
package org.opendaylight.neutron.spi;
import java.io.Serializable;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.Inet6Address;
import java.util.ArrayList;
import java.util.List;
return ans;
}
+ /**
+ * This method determines if this allocation pool contains the
+ * input IPv4 address
+ *
+ * @param inputString
+ * IPv4 address in dotted decimal format
+ * @returns a boolean on whether the pool contains the address or not
+ */
+
+ public boolean contains_V6(String inputString) {
+ BigInteger inputIP = convert_V6(inputString);
+ BigInteger startIP = convert_V6(poolStart);
+ BigInteger endIP = convert_V6(poolEnd);
+ return (inputIP.compareTo(startIP) >= 0 && inputIP.compareTo(endIP) <= 0);
+ }
+
+ /**
+ * This static method converts the supplied IPv4 address to a long
+ * integer for comparison
+ *
+ * @param inputString
+ * IPv6 address in dotted decimal format
+ * @returns high-endian representation of the IPv4 address as a BigInteger.
+ * This method will return 0 if the input is null.
+ */
+
+ static BigInteger convert_V6(String inputString) {
+ if (inputString == null) {
+ return BigInteger.ZERO;
+ }
+ try {
+ return new BigInteger(((Inet6Address) InetAddress.getByName(inputString)).getAddress());
+ } catch (Exception e) {
+ return BigInteger.ZERO;
+ }
+ }
+
/**
* This static method converts the supplied high-ending long back
* into a dotted decimal representation of an IPv4 address
* high-endian representation of the IPv4 address as a long
* @returns IPv4 address in dotted decimal format
*/
- static String longtoIP(long l) {
+ static String longToIP(long l) {
int i;
String[] parts = new String[4];
for (i=0; i<4; i++) {
return join(parts,".");
}
+ /**
+ * This static method converts the supplied high-ending long back
+ * into a dotted decimal representation of an IPv4 address
+ *
+ * @param l
+ * high-endian representation of the IPv4 address as a long
+ * @returns IPv4 address in dotted decimal format
+ */
+ static String bigIntegerToIP(BigInteger b) {
+ try {
+ return Inet6Address.getByAddress(b.toByteArray()).getHostAddress();
+ } catch (Exception e) {
+ return "ERROR";
+ }
+ }
+
/*
- * helper routine used by longtoIP
+ * helper routine used by longToIP
*/
public static String join(String r[],String d)
{
poolStarted = true;
} else {
//FIX for bug 533
- p.setPoolStart(NeutronSubnet_IPAllocationPool.longtoIP(i+1));
+ p.setPoolStart(NeutronSubnet_IPAllocationPool.longToIP(i+1));
}
}
if (i == eIP) {
if (i != gIP) {
p.setPoolEnd(poolEnd);
} else {
- p.setPoolEnd(NeutronSubnet_IPAllocationPool.longtoIP(i-1));
+ p.setPoolEnd(NeutronSubnet_IPAllocationPool.longToIP(i-1));
}
ans.add(p);
}
if (i != sIP && i != eIP) {
if (i != gIP) {
if (!poolStarted) {
- p.setPoolStart(NeutronSubnet_IPAllocationPool.longtoIP(i));
+ p.setPoolStart(NeutronSubnet_IPAllocationPool.longToIP(i));
poolStarted = true;
}
} else {
- p.setPoolEnd(NeutronSubnet_IPAllocationPool.longtoIP(i-1));
+ p.setPoolEnd(NeutronSubnet_IPAllocationPool.longToIP(i-1));
poolStarted = false;
ans.add(p);
p = new NeutronSubnet_IPAllocationPool();
// Fix for 2120
- p.setPoolStart(NeutronSubnet_IPAllocationPool.longtoIP(i+1));
+ p.setPoolStart(NeutronSubnet_IPAllocationPool.longToIP(i+1));
poolStarted = true;
}
}
"start=" + poolStart +
", end=" + poolEnd + "]";
}
+
+ /*
+ * This method splits the current instance by removing the supplied
+ * parameter.
+ *
+ * If the parameter is either the low or high address,
+ * then that member is adjusted and a list containing just this instance
+ * is returned.
+ new *
+ * If the parameter is in the middle of the pool, then
+ * create two new instances, one ranging from low to parameter-1
+ * the other ranging from parameter+1 to high
+ * If the pool is a single address, return null
+ */
+ public List<NeutronSubnet_IPAllocationPool> splitPool_V6(String ipAddress) {
+ List<NeutronSubnet_IPAllocationPool> ans = new ArrayList<NeutronSubnet_IPAllocationPool>();
+ BigInteger gIP = NeutronSubnet_IPAllocationPool.convert_V6(ipAddress);
+ BigInteger sIP = NeutronSubnet_IPAllocationPool.convert_V6(poolStart);
+ BigInteger eIP = NeutronSubnet_IPAllocationPool.convert_V6(poolEnd);
+ if (gIP.compareTo(sIP) == 0 && gIP.compareTo(eIP) < 0) {
+ NeutronSubnet_IPAllocationPool p = new NeutronSubnet_IPAllocationPool();
+ p.setPoolStart(NeutronSubnet_IPAllocationPool.bigIntegerToIP(sIP.add(BigInteger.ONE)));
+ p.setPoolEnd(poolEnd);
+ ans.add(p);
+ return(ans);
+ }
+ if (gIP.compareTo(eIP) == 0 && gIP.compareTo(sIP) > 0) {
+ NeutronSubnet_IPAllocationPool p = new NeutronSubnet_IPAllocationPool();
+ p.setPoolStart(poolStart);
+ p.setPoolEnd(NeutronSubnet_IPAllocationPool.bigIntegerToIP(eIP.subtract(BigInteger.ONE)));
+ ans.add(p);
+ return(ans);
+ }
+ if (gIP.compareTo(eIP) < 0 && gIP.compareTo(sIP) > 0) {
+ NeutronSubnet_IPAllocationPool p = new NeutronSubnet_IPAllocationPool();
+ p.setPoolStart(poolStart);
+ p.setPoolEnd(NeutronSubnet_IPAllocationPool.bigIntegerToIP(gIP.subtract(BigInteger.ONE)));
+ ans.add(p);
+ NeutronSubnet_IPAllocationPool p2 = new NeutronSubnet_IPAllocationPool();
+ p2.setPoolStart(NeutronSubnet_IPAllocationPool.bigIntegerToIP(gIP.add(BigInteger.ONE)));
+ p2.setPoolEnd(poolEnd);
+ ans.add(p2);
+ return ans;
+ }
+ return null;
+ }
}