From a83f74d83e4d0699ad631d2efa4cd674bc53076b Mon Sep 17 00:00:00 2001 From: wilderrodrigues Date: Fri, 22 May 2015 20:08:09 +0200 Subject: [PATCH] CLOUDSTACK-8506 - Changing the implementation of the NetUtils.ipRangesOverlap() a little bit in order to be compliant with RFC 3021 - 2 unit tests added - ranges from 0 to 255 covered by the tests, which also test the negative cases. --- .../ConfigurationManagerImpl.java | 5 +++ utils/src/com/cloud/utils/net/NetUtils.java | 18 +++++++++ .../com/cloud/utils/net/NetUtilsTest.java | 40 +++++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index d08cac6566d..182c67c1900 100644 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -3556,6 +3556,11 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati throw new InvalidParameterValueException("Please ensure that your end IP is in the same subnet as your IP range's gateway, as per the IP range's netmask."); } // 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 if (NetUtils.ipRangesOverlap(startIP, endIP, vlanGateway, vlanGateway)) { throw new InvalidParameterValueException( "The gateway ip should not be the part of the ip range being added."); diff --git a/utils/src/com/cloud/utils/net/NetUtils.java b/utils/src/com/cloud/utils/net/NetUtils.java index a93f65d79e0..19dec36367b 100644 --- a/utils/src/com/cloud/utils/net/NetUtils.java +++ b/utils/src/com/cloud/utils/net/NetUtils.java @@ -358,6 +358,17 @@ public class NetUtils { endIp2Long = ip2Long(endIp2); } + // 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 int ip31bitPrefixOffSet = 1; + if (startIp2Long - startIp1Long == startIp2Long - (endIp1Long - ip31bitPrefixOffSet)) { + return false; + } + if (startIp1Long == startIp2Long || startIp1Long == endIp2Long || endIp1Long == startIp2Long || endIp1Long == endIp2Long) { return true; } else if (startIp1Long > startIp2Long && startIp1Long < endIp2Long) { @@ -1487,6 +1498,13 @@ public class NetUtils { if (!isValidCIDR(cidr)) { return false; } + + // 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); diff --git a/utils/test/com/cloud/utils/net/NetUtilsTest.java b/utils/test/com/cloud/utils/net/NetUtilsTest.java index fa4042d318a..0130b9a1b7f 100644 --- a/utils/test/com/cloud/utils/net/NetUtilsTest.java +++ b/utils/test/com/cloud/utils/net/NetUtilsTest.java @@ -371,4 +371,44 @@ public class NetUtilsTest { 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; + + // 192.168.0.0 - 192.168.0.0 - 192.168.0.1 + // GW and IP1 overlaps, but in that case it's a 31bit IP. + // 192.168.0.0 - 192.168.0.1 - 192.168.0.2 + // GW and IP1 overlaps, but in that case it's a 31bit IP. + // and so on. + + for (int i = 0, j = 1; 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; + + // 192.168.0.10 - 192.168.0.10 - 192.168.0.12 + // GW and IP1 overlaps and in that case it's not a 31bit IP. + + 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); + } + } } \ No newline at end of file