You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2015/05/26 17:25:22 UTC
[2/2] git commit: updated refs/heads/4.4 to fdf47a2
CLOUDSTACK-8506 slash 31 bit backport
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/fdf47a22
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/fdf47a22
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/fdf47a22
Branch: refs/heads/4.4
Commit: fdf47a221e124ad7ebf87b81eed6c54b95d8a459
Parents: 8b5b5de
Author: Daan Hoogland <da...@gmail.com>
Authored: Tue May 26 15:46:39 2015 +0200
Committer: Daan Hoogland <da...@gmail.com>
Committed: Tue May 26 17:24:43 2015 +0200
----------------------------------------------------------------------
.../configuration/ConfigurationManagerImpl.java | 28 ++---
utils/src/com/cloud/utils/net/NetUtils.java | 97 ++++++++++-----
.../test/com/cloud/utils/net/NetUtilsTest.java | 117 ++++++++++++++++++-
3 files changed, 197 insertions(+), 45 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fdf47a22/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 48b3cab..989c5b3 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -3016,22 +3016,24 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
}
} else {
- String[] otherVlanIpRange = vlan.getIpRange().split("\\-");
- String otherVlanStartIP = otherVlanIpRange[0];
- String otherVlanEndIP = null;
- if (otherVlanIpRange.length > 1) {
- otherVlanEndIP = otherVlanIpRange[1];
- }
+ String[] otherVlanIpRange = vlan.getIpRange().split("\\-");
+ String otherVlanStartIP = otherVlanIpRange[0];
+ String otherVlanEndIP = null;
+ if (otherVlanIpRange.length > 1) {
+ otherVlanEndIP = otherVlanIpRange[1];
+ }
// extend IP range
- if (!vlanGateway.equals(otherVlanGateway) || !vlanNetmask.equals(vlan.getVlanNetmask())) {
+ if (!vlanGateway.equals(otherVlanGateway) || !vlanNetmask.equals(vlan.getVlanNetmask())) {
throw new InvalidParameterValueException("The IP range has already been added with gateway "
- + otherVlanGateway + " ,and netmask " + otherVlanNetmask
- + ", Please specify the gateway/netmask if you want to extend ip range" );
- }
- if (NetUtils.ipRangesOverlap(startIP, endIP, otherVlanStartIP, otherVlanEndIP)) {
- throw new InvalidParameterValueException("The IP range already has IPs that overlap with the new range." +
- " Please specify a different start IP/end IP.");
+ + otherVlanGateway + " ,and netmask " + otherVlanNetmask
+ + ", Please specify the gateway/netmask if you want to extend ip range" );
+ }
+ if (!NetUtils.is31PrefixCidr(newCidr)) {
+ if (NetUtils.ipRangesOverlap(startIP, endIP, otherVlanStartIP, otherVlanEndIP)) {
+ throw new InvalidParameterValueException("The IP range already has IPs that overlap with the new range." +
+ " Please specify a different start IP/end IP.");
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fdf47a22/utils/src/com/cloud/utils/net/NetUtils.java
----------------------------------------------------------------------
diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java
index aab1437..4f7ee51 100755
--- a/utils/src/com/cloud/utils/net/NetUtils.java
+++ b/utils/src/com/cloud/utils/net/NetUtils.java
@@ -52,6 +52,10 @@ import java.util.regex.Pattern;
public class NetUtils {
protected final static Logger s_logger = Logger.getLogger(NetUtils.class);
+
+ private static final int MAX_CIDR = 32;
+ private static final int RFC_3021_31_BIT_CIDR = 31;
+
public final static String HTTP_PORT = "80";
public final static String HTTPS_PORT = "443";
public final static int VPN_PORT = 500;
@@ -141,7 +145,7 @@ public class NetUtils {
for (InterfaceAddress address : ifc.getInterfaceAddresses()) {
InetAddress addr = address.getAddress();
int prefixLength = address.getNetworkPrefixLength();
- if (prefixLength < 32 && prefixLength > 0) {
+ if (prefixLength < MAX_CIDR && prefixLength > 0) {
String ip = ipFromInetAddress(addr);
if (ip.equalsIgnoreCase(defaultHostIp))
cidrList.add(ipAndNetMaskToCidr(ip, getCidrNetmask(prefixLength)));
@@ -334,8 +338,14 @@ public class NetUtils {
return macAddressAsLong;
}
- public static boolean ipRangesOverlap(String startIp1, String endIp1, String startIp2, String endIp2) {
- long startIp1Long = ip2Long(startIp1);
+ /**
+ * This method will fail in case we have a 31 Bit prefix network
+ * See RFC 3021.
+ *
+ * In order to avoid calling this method, please check the <code>NetUtils.is31PrefixCidr(cidr)</code> first.
+ */
+ public static boolean ipRangesOverlap(final String startIp1, final String endIp1, final String startIp2, final String endIp2) {
+ final long startIp1Long = ip2Long(startIp1);
long endIp1Long = startIp1Long;
if (endIp1 != null) {
endIp1Long = ip2Long(endIp1);
@@ -534,6 +544,20 @@ public class NetUtils {
return true;
}
+ public static boolean is31PrefixCidr(final String cidr) {
+ final boolean isValidCird = isValidCIDR(cidr);
+ if (isValidCird){
+ final String[] cidrPair = cidr.split("\\/");
+ final String cidrSize = cidrPair[1];
+
+ final int cidrSizeNum = Integer.parseInt(cidrSize);
+ if (cidrSizeNum == RFC_3021_31_BIT_CIDR) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public static boolean isValidCIDR(final String cidr) {
if (cidr == null || cidr.isEmpty()) {
return false;
@@ -616,17 +640,17 @@ public class NetUtils {
}
public static String[] getIpRangeFromCidr(String cidr, long size) {
- assert (size < 32) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size;
+ assert (size < MAX_CIDR) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size;
String[] result = new String[2];
long ip = ip2Long(cidr);
long startNetMask = ip2Long(getCidrNetmask(size));
long start = (ip & startNetMask) + 1;
long end = start;
- end = end >> (32 - size);
+ end = end >> (MAX_CIDR - size);
end++;
- end = (end << (32 - size)) - 2;
+ end = (end << (MAX_CIDR - size)) - 2;
result[0] = long2Ip(start);
result[1] = long2Ip(end);
@@ -635,17 +659,17 @@ public class NetUtils {
}
public static Set<Long> getAllIpsFromCidr(String cidr, long size, Set<Long> usedIps) {
- assert (size < 32) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size;
+ assert (size < MAX_CIDR) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size;
Set<Long> result = new TreeSet<Long>();
long ip = ip2Long(cidr);
long startNetMask = ip2Long(getCidrNetmask(size));
long start = (ip & startNetMask) + 1;
long end = start;
- end = end >> (32 - size);
+ end = end >> (MAX_CIDR - size);
end++;
- end = (end << (32 - size)) - 2;
+ end = (end << (MAX_CIDR - size)) - 2;
int maxIps = 255; // get 255 ips as maximum
while (start <= end && maxIps > 0) {
if (!usedIps.contains(start)) {
@@ -687,7 +711,7 @@ public class NetUtils {
long startNetMask = ip2Long(getCidrNetmask(size));
long startIp = (cidr & startNetMask) + 1; //exclude the first ip since it isnt valid, e.g., 192.168.10.0
- int range = 1 << (32 - size); //e.g., /24 = 2^8 = 256
+ int range = 1 << (MAX_CIDR - size); //e.g., /24 = 2^8 = 256
range = range - 1; //exclude end of the range since that is the broadcast address, e.g., 192.168.10.255
if (avoid.size() >= range) {
@@ -723,10 +747,10 @@ public class NetUtils {
long startNetMask = ip2Long(getCidrNetmask(size));
long start = (ip & startNetMask) + 1;
long end = start;
- end = end >> (32 - size);
+ end = end >> (MAX_CIDR - size);
end++;
- end = (end << (32 - size)) - 2;
+ end = (end << (MAX_CIDR - size)) - 2;
return long2Ip(end);
}
@@ -758,7 +782,7 @@ public class NetUtils {
}
public static String getCidrSubNet(String ip, long cidrSize) {
- long numericNetmask = (0xffffffff >> (32 - cidrSize)) << (32 - cidrSize);
+ long numericNetmask = (0xffffffff >> (MAX_CIDR - cidrSize)) << (MAX_CIDR - cidrSize);
String netmask = NetUtils.long2Ip(numericNetmask);
return getSubNet(ip, netmask);
}
@@ -793,10 +817,10 @@ public class NetUtils {
while ((subnet = (subnet >> 1) & subnet) != 0) {
bits++;
}
- end = end >> (32 - bits);
+ end = end >> (MAX_CIDR - bits);
end++;
- end = (end << (32 - bits)) - 2;
+ end = (end << (MAX_CIDR - bits)) - 2;
return new String[] {long2Ip(start), long2Ip(end)};
@@ -820,9 +844,9 @@ public class NetUtils {
return supersetOrSubset.errorInCidrFormat;
}
if (cidrALong[1] >= cidrBLong[1]) {
- shift = 32 - cidrBLong[1];
+ shift = MAX_CIDR - cidrBLong[1];
} else {
- shift = 32 - cidrALong[1];
+ shift = MAX_CIDR - cidrALong[1];
}
long result = (cidrALong[0] >> shift) - (cidrBLong[0] >> shift);
if (result == 0) {
@@ -846,7 +870,7 @@ public class NetUtils {
if (cidrALong == null || cidrBLong == null) {
return false;
}
- long shift = 32 - cidrBLong[1];
+ long shift = MAX_CIDR - cidrBLong[1];
return ((cidrALong[0] >> shift) == (cidrBLong[0] >> shift));
}
@@ -870,7 +894,7 @@ public class NetUtils {
} catch (Exception e) {
return null;
}
- long numericNetmask = (0xffffffff >> (32 - cidrSizeNum)) << (32 - cidrSizeNum);
+ long numericNetmask = (0xffffffff >> (MAX_CIDR - cidrSizeNum)) << (MAX_CIDR - cidrSizeNum);
long ipAddr = ip2Long(cidrAddress);
Long[] cidrlong = {ipAddr & numericNetmask, (long)cidrSizeNum};
return cidrlong;
@@ -897,13 +921,13 @@ public class NetUtils {
} catch (Exception e) {
return null;
}
- long numericNetmask = (0xffffffff >> (32 - cidrSizeNum)) << (32 - cidrSizeNum);
+ long numericNetmask = (0xffffffff >> (MAX_CIDR - cidrSizeNum)) << (MAX_CIDR - cidrSizeNum);
String netmask = NetUtils.long2Ip(numericNetmask);
return getSubNet(cidrAddress, netmask);
}
public static String getCidrNetmask(long cidrSize) {
- long numericNetmask = (0xffffffff >> (32 - cidrSize)) << (32 - cidrSize);
+ long numericNetmask = (0xffffffff >> (MAX_CIDR - cidrSize)) << (MAX_CIDR - cidrSize);
return long2Ip(numericNetmask);
}
@@ -921,7 +945,7 @@ public class NetUtils {
public static long getCidrSize(String netmask) {
long ip = ip2Long(netmask);
int count = 0;
- for (int i = 0; i < 32; i++) {
+ for (int i = 0; i < MAX_CIDR; i++) {
if (((ip >> i) & 0x1) == 0) {
count++;
} else {
@@ -929,7 +953,7 @@ public class NetUtils {
}
}
- return 32 - count;
+ return MAX_CIDR - count;
}
public static boolean isValidPort(String p) {
@@ -991,7 +1015,7 @@ public class NetUtils {
return null;
}
/* reserve gateway */
- String[] range = getIpRangeFromCidr(getLinkLocalGateway(), 32 - size);
+ String[] range = getIpRangeFromCidr(getLinkLocalGateway(), MAX_CIDR - size);
if (range[0].equalsIgnoreCase(getLinkLocalGateway())) {
/* remove the gateway */
@@ -1006,7 +1030,7 @@ public class NetUtils {
String[] cidrPair = getLinkLocalCIDR().split("\\/");
String cidr = cidrPair[0];
- return getIpRangeEndIpFromCidr(cidr, 32 - Long.parseLong(cidrPair[1]));
+ return getIpRangeEndIpFromCidr(cidr, MAX_CIDR - Long.parseLong(cidrPair[1]));
}
public static String portRangeToString(int portRange[]) {
@@ -1136,7 +1160,7 @@ public class NetUtils {
if (cidrALong == null || cidrBLong == null) {
return false;
}
- long shift = 32 - (cidrALong[1] > cidrBLong[1] ? cidrBLong[1] : cidrALong[1]);
+ long shift = MAX_CIDR - (cidrALong[1] > cidrBLong[1] ? cidrBLong[1] : cidrALong[1]);
return ((cidrALong[0] >> shift) == (cidrBLong[0] >> shift));
}
@@ -1490,12 +1514,23 @@ public class NetUtils {
if (!isValidCIDR(cidr)) {
return false;
}
- SubnetUtils subnetUtils = new SubnetUtils(cidr);
- return subnetUtils.getInfo().isInRange(ipAddress);
+
+ // check if the gatewayip is the part of the ip range being added.
+ // RFC 3021 - 31-Bit Prefixes on IPv4 Point-to-Point Links
+ // GW Netmask Stat IP End IP
+ // 192.168.24.0 - 255.255.255.254 - 192.168.24.0 - 192.168.24.1
+ // https://tools.ietf.org/html/rfc3021
+ // Added by Wilder Rodrigues
+ final SubnetUtils subnetUtils = new SubnetUtils(cidr);
+ subnetUtils.setInclusiveHostCount(true);
+
+ final boolean isInRange = subnetUtils.getInfo().isInRange(ipAddress);
+
+ return isInRange;
}
public static Boolean IsIpEqualToNetworkOrBroadCastIp(String requestedIp, String cidr, long size) {
- assert (size < 32) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size;
+ assert (size < MAX_CIDR) : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size;
long ip = ip2Long(cidr);
long startNetMask = ip2Long(getCidrNetmask(size));
@@ -1503,10 +1538,10 @@ public class NetUtils {
long start = (ip & startNetMask);
long end = start;
- end = end >> (32 - size);
+ end = end >> (MAX_CIDR - size);
end++;
- end = (end << (32 - size)) - 1;
+ end = (end << (MAX_CIDR - size)) - 1;
long reqIp = ip2Long(requestedIp);
if (reqIp == start || reqIp == end) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fdf47a22/utils/test/com/cloud/utils/net/NetUtilsTest.java
----------------------------------------------------------------------
diff --git a/utils/test/com/cloud/utils/net/NetUtilsTest.java b/utils/test/com/cloud/utils/net/NetUtilsTest.java
index 96c3baf..3ee7c9a 100644
--- a/utils/test/com/cloud/utils/net/NetUtilsTest.java
+++ b/utils/test/com/cloud/utils/net/NetUtilsTest.java
@@ -288,4 +288,119 @@ public class NetUtilsTest {
assertTrue(NetUtils.validateGuestCidr(guestCidr));
}
-}
+
+ @Test
+ public void testMac2Long() {
+ assertEquals(0l, NetUtils.mac2Long("00:00:00:00:00:00"));
+ assertEquals(1l, NetUtils.mac2Long("00:00:00:00:00:01"));
+ assertEquals(0xFFl, NetUtils.mac2Long("00:00:00:00:00:FF"));
+ assertEquals(0xFFAAl, NetUtils.mac2Long("00:00:00:00:FF:AA"));
+ assertEquals(0x11FFAAl, NetUtils.mac2Long("00:00:00:11:FF:AA"));
+ assertEquals(0x12345678l, NetUtils.mac2Long("00:00:12:34:56:78"));
+ assertEquals(0x123456789Al, NetUtils.mac2Long("00:12:34:56:78:9A"));
+ assertEquals(0x123456789ABCl, NetUtils.mac2Long("12:34:56:78:9A:BC"));
+ }
+
+ @Test
+ public void testLong2Mac() {
+ assertEquals("00:00:00:00:00:00", NetUtils.long2Mac(0l));
+ assertEquals("00:00:00:00:00:01", NetUtils.long2Mac(1l));
+ assertEquals("00:00:00:00:00:ff", NetUtils.long2Mac(0xFFl));
+ assertEquals("00:00:00:00:ff:aa", NetUtils.long2Mac(0xFFAAl));
+ assertEquals("00:00:00:11:ff:aa", NetUtils.long2Mac(0x11FFAAl));
+ assertEquals("00:00:12:34:56:78", NetUtils.long2Mac(0x12345678l));
+ assertEquals("00:12:34:56:78:9a", NetUtils.long2Mac(0x123456789Al));
+ assertEquals("12:34:56:78:9a:bc", NetUtils.long2Mac(0x123456789ABCl));
+ }
+
+ @Test
+ public void testIp2Long() {
+ assertEquals(0x7f000001l, NetUtils.ip2Long("127.0.0.1"));
+ assertEquals(0xc0a80001l, NetUtils.ip2Long("192.168.0.1"));
+ assertEquals(0x08080808l, NetUtils.ip2Long("8.8.8.8"));
+ }
+
+ @Test
+ public void testLong2Ip() {
+ assertEquals("127.0.0.1", NetUtils.long2Ip(0x7f000001l));
+ assertEquals("192.168.0.1", NetUtils.long2Ip(0xc0a80001l));
+ assertEquals("8.8.8.8", NetUtils.long2Ip(0x08080808l));
+ }
+
+ @Test
+ public void test31BitPrefixStart() {
+ final String ipAddress = "192.168.0.0";
+ final String cidr = "192.168.0.0/31";
+
+ final boolean isInRange = NetUtils.isIpWithtInCidrRange(ipAddress, cidr);
+
+ assertTrue("Check if the subnetUtils.setInclusiveHostCount(true) has been called.", isInRange);
+ }
+
+ @Test
+ public void test31BitPrefixEnd() {
+ final String ipAddress = "192.168.0.1";
+ final String cidr = "192.168.0.0/31";
+
+ final boolean isInRange = NetUtils.isIpWithtInCidrRange(ipAddress, cidr);
+
+ assertTrue("Check if the subnetUtils.setInclusiveHostCount(true) has been called.", isInRange);
+ }
+
+ @Test
+ public void test31BitPrefixFail() {
+ final String ipAddress = "192.168.0.2";
+ final String cidr = "192.168.0.0/31";
+
+ final boolean isInRange = NetUtils.isIpWithtInCidrRange(ipAddress, cidr);
+
+ assertFalse("Out of the range. Why did it return true?", isInRange);
+ }
+
+ @Test
+ public void test31BitPrefixIpRangesOverlapd() {
+ final String gw = "192.168.0.0";
+ String ip1;
+ String ip2;
+
+ for (int i = 1, j = 2; i <= 254; i++, j++) {
+ ip1 = "192.168.0." + i;
+ ip2 = "192.168.0." + j;
+
+ final boolean doesOverlap = NetUtils.ipRangesOverlap(ip1, ip2, gw, gw);
+ assertFalse("It should overlap, but it's a 31-bit ip", doesOverlap);
+ }
+ }
+
+ @Test
+ public void test31BitPrefixIpRangesOverlapdFail() {
+ String gw;
+ String ip1;
+ String ip2;
+
+ for (int i = 10, j = 12; i <= 254; i++, j++) {
+ gw = "192.168.0." + i;
+ ip1 = "192.168.0." + i;
+ ip2 = "192.168.0." + j;
+
+ final boolean doesOverlap = NetUtils.ipRangesOverlap(ip1, ip2, gw, gw);
+ assertTrue("It overlaps!", doesOverlap);
+ }
+ }
+
+ @Test
+ public void testIs31PrefixCidrFail() {
+ final String cidr = "10.10.0.0/32";
+ final boolean is31PrefixCidr = NetUtils.is31PrefixCidr(cidr);
+
+ assertFalse("It should fail! 32 bit prefix.", is31PrefixCidr);
+ }
+
+ @Test
+ public void testIs31PrefixCidr() {
+ final String cidr = "10.10.0.0/31";
+ final boolean is31PrefixCidr = NetUtils.is31PrefixCidr(cidr);
+
+ assertTrue("It should pass! 31 bit prefix.", is31PrefixCidr);
+ }
+}
\ No newline at end of file