Skip to content

Commit d5f0100

Browse files
authored
utils: fix NetUtils method to retrieve all IPs for a CIDR (#7026)
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
1 parent 63bc5a8 commit d5f0100

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

server/src/main/java/com/cloud/network/NetworkModelImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2001,7 +2001,7 @@ public Set<Long> getAvailableIps(Network network, String requestedIp) {
20012001
usedIps.add(NetUtils.ip2Long(ip));
20022002
}
20032003

2004-
Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]), usedIps);
2004+
Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]), usedIps, -1);
20052005

20062006
String gateway = network.getGateway();
20072007
if ((gateway != null) && (allPossibleIps.contains(NetUtils.ip2Long(gateway))))

utils/src/main/java/com/cloud/utils/net/NetUtils.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ public static String[] getIpRangeFromCidr(final String cidr, final long size) {
617617
return result;
618618
}
619619

620-
public static Set<Long> getAllIpsFromCidr(final String cidr, final long size, final Set<Long> usedIps) {
620+
public static Set<Long> getAllIpsFromCidr(final String cidr, final long size, final Set<Long> usedIps, int maxIps) {
621621
assert size < MAX_CIDR : "You do know this is not for ipv6 right? Keep it smaller than 32 but you have " + size;
622622
final Set<Long> result = new TreeSet<Long>();
623623
final long ip = ip2Long(cidr);
@@ -629,11 +629,9 @@ public static Set<Long> getAllIpsFromCidr(final String cidr, final long size, fi
629629

630630
end++;
631631
end = (end << MAX_CIDR - size) - 2;
632-
int maxIps = 255; // get 255 ips as maximum
633-
while (start <= end && maxIps > 0) {
632+
while (start <= end && (maxIps == -1 || result.size() < maxIps)) {
634633
if (!usedIps.contains(start)) {
635634
result.add(start);
636-
maxIps--;
637635
}
638636
start++;
639637
}

utils/src/test/java/com/cloud/utils/net/NetUtilsTest.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,12 @@
3434
import java.math.BigInteger;
3535
import java.net.InetAddress;
3636
import java.net.UnknownHostException;
37+
import java.util.ArrayList;
38+
import java.util.List;
39+
import java.util.Set;
3740
import java.util.SortedSet;
3841
import java.util.TreeSet;
42+
import java.util.stream.Collectors;
3943

4044
import org.apache.log4j.Logger;
4145
import org.junit.Test;
@@ -48,6 +52,8 @@
4852
public class NetUtilsTest {
4953

5054
private static final Logger s_logger = Logger.getLogger(NetUtilsTest.class);
55+
private static final String WIDE_SHARED_NET_CIDR_IP = "10.20.0.0";
56+
private static final List<String> WIDE_SHARED_NET_USED_IPS = List.of("10.20.0.22", "10.20.1.22", "10.20.2.22");
5157

5258
@Test
5359
public void testGetRandomIpFromCidrWithSize24() throws Exception {
@@ -741,4 +747,50 @@ public void testCidrNetmask() {
741747
assertEquals("255.255.0.0", NetUtils.cidr2Netmask("169.254.0.0/16"));
742748
assertEquals("255.255.240.0", NetUtils.cidr2Netmask("169.254.240.0/20"));
743749
}
750+
751+
private void runTestGetAllIpsFromCidr(int cidrSize, int maxIps, boolean usedIpPresent, int resultSize) {
752+
Set<Long> usedIps = new TreeSet<>();
753+
if (usedIpPresent) {
754+
for (String ip : WIDE_SHARED_NET_USED_IPS) {
755+
usedIps.add(NetUtils.ip2Long(ip));
756+
}
757+
}
758+
Set<Long> result = NetUtils.getAllIpsFromCidr(WIDE_SHARED_NET_CIDR_IP, cidrSize, usedIps, maxIps);
759+
assertNotNull(result);
760+
assertEquals(resultSize, result.size());
761+
if (usedIpPresent) {
762+
for (String ip : WIDE_SHARED_NET_USED_IPS) {
763+
assertFalse(result.contains(NetUtils.ip2Long(ip)));
764+
}
765+
}
766+
}
767+
768+
@Test
769+
public void testGetAllIpsFromCidrNoneUsedNoLimit() {
770+
runTestGetAllIpsFromCidr(22, -1, false, 1022);
771+
}
772+
773+
@Test
774+
public void testGetAllIpsFromCidrNoneUsedLimit() {
775+
runTestGetAllIpsFromCidr(22, 255, false, 255);
776+
}
777+
778+
@Test
779+
public void testGetAllIpsFromCidrNoneUsedLessLimit() {
780+
runTestGetAllIpsFromCidr(22, 10, false, 10);
781+
}
782+
783+
784+
@Test
785+
public void testGetAllIpsFromCidrUsedNoLimit() {
786+
runTestGetAllIpsFromCidr(22, -1, true, 1022 - WIDE_SHARED_NET_USED_IPS.size());
787+
}
788+
789+
@Test
790+
public void testGetAllIpsFromCidrUsedLimit() {
791+
runTestGetAllIpsFromCidr(22, 50, true, 50);
792+
List<String> usedIpsInRange = new ArrayList<>(WIDE_SHARED_NET_USED_IPS);
793+
usedIpsInRange = usedIpsInRange.stream().filter(x -> x.startsWith("10.20.0.")).collect(Collectors.toList());
794+
runTestGetAllIpsFromCidr(24, 255, true, 254 - usedIpsInRange.size());
795+
}
744796
}

0 commit comments

Comments
 (0)