Skip to content

Commit f9a68e7

Browse files
author
Sheng Yang
committed
IPv6: Add vlan overlap checking
1 parent b1972f6 commit f9a68e7

4 files changed

Lines changed: 60 additions & 15 deletions

File tree

server/src/com/cloud/configuration/ConfigurationManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ NetworkOfferingVO createNetworkOffering(String name, String displayText, Traffic
198198
boolean isDefault, Network.GuestType type, boolean systemOnly, Long serviceOfferingId, boolean conserveMode, Map<Service, Map<Capability, String>> serviceCapabilityMap,
199199
boolean specifyIpRanges);
200200

201-
Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, String vlanId, Account vlanOwner, String startIPv6, String endIPv6, String vlanGatewayv6, String vlanCidrv6) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException;
201+
Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId, String startIP, String endIP, String vlanGateway, String vlanNetmask, String vlanId, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr) throws InsufficientCapacityException, ConcurrentOperationException, InvalidParameterValueException;
202202

203203
void createDefaultSystemNetworks(long zoneId) throws ConcurrentOperationException;
204204

server/src/com/cloud/configuration/ConfigurationManagerImpl.java

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2278,7 +2278,7 @@ public Vlan createVlanAndPublicIpRange(CreateVlanIpRangeCmd cmd) throws Insuffic
22782278
@DB
22792279
public Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physicalNetworkId, boolean forVirtualNetwork, Long podId,
22802280
String startIP, String endIP, String vlanGateway, String vlanNetmask,
2281-
String vlanId, Account vlanOwner, String startIPv6, String endIPv6, String vlanGatewayv6, String vlanCidrv6) {
2281+
String vlanId, Account vlanOwner, String startIPv6, String endIPv6, String vlanIp6Gateway, String vlanIp6Cidr) {
22822282
Network network = _networkModel.getNetwork(networkId);
22832283

22842284
boolean ipv4 = false, ipv6 = false;
@@ -2372,15 +2372,14 @@ public Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physica
23722372
}
23732373

23742374
if (ipv6) {
2375-
if (!NetUtils.isValidIpv6(vlanGatewayv6)) {
2375+
if (!NetUtils.isValidIpv6(vlanIp6Gateway)) {
23762376
throw new InvalidParameterValueException("Please specify a valid IPv6 gateway");
23772377
}
2378-
if (!NetUtils.isValidIp6Cidr(vlanCidrv6)) {
2378+
if (!NetUtils.isValidIp6Cidr(vlanIp6Cidr)) {
23792379
throw new InvalidParameterValueException("Please specify a valid IPv6 CIDR");
23802380
}
23812381
}
23822382

2383-
// TODO skip all vlan check for ipv6 now
23842383
if (ipv4) {
23852384
String newVlanSubnet = NetUtils.getSubNet(vlanGateway, vlanNetmask);
23862385

@@ -2426,7 +2425,7 @@ public Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physica
24262425
List<VlanVO> vlans = _vlanDao.listByZone(zone.getId());
24272426
for (VlanVO vlan : vlans) {
24282427
String otherVlanGateway = vlan.getVlanGateway();
2429-
// Continue if it's IPv6
2428+
// Continue if it's not IPv4
24302429
if (otherVlanGateway == null) {
24312430
continue;
24322431
}
@@ -2462,6 +2461,32 @@ public Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physica
24622461
}
24632462
}
24642463
}
2464+
2465+
String ipv6Range = null;
2466+
if (ipv6) {
2467+
ipv6Range = startIPv6;
2468+
if (endIPv6 != null) {
2469+
ipv6Range += "-" + endIPv6;
2470+
}
2471+
2472+
List<VlanVO> vlans = _vlanDao.listByZone(zone.getId());
2473+
for (VlanVO vlan : vlans) {
2474+
if (vlan.getIp6Gateway() == null) {
2475+
continue;
2476+
}
2477+
if (vlanId.equals(vlan.getVlanTag())) {
2478+
if (NetUtils.isIp6RangeOverlap(ipv6Range, vlan.getIp6Range())) {
2479+
throw new InvalidParameterValueException("The IPv6 range with tag: " + vlan.getVlanTag()
2480+
+ " already has IPs that overlap with the new range. Please specify a different start IP/end IP.");
2481+
}
2482+
2483+
if (!vlanIp6Gateway.equals(vlan.getIp6Gateway())) {
2484+
throw new InvalidParameterValueException("The IP range with tag: " + vlan.getVlanTag() + " has already been added with gateway " + vlan.getIp6Gateway()
2485+
+ ". Please specify a different tag.");
2486+
}
2487+
}
2488+
}
2489+
}
24652490

24662491
// Check if a guest VLAN is using the same tag
24672492
if (_zoneDao.findVnet(zoneId, physicalNetworkId, vlanId).size() > 0) {
@@ -2491,19 +2516,11 @@ public Vlan createVlanAndPublicIpRange(long zoneId, long networkId, long physica
24912516
}
24922517
}
24932518

2494-
String ipv6Range = null;
2495-
if (ipv6) {
2496-
ipv6Range = startIPv6;
2497-
if (endIPv6 != null) {
2498-
ipv6Range += "-" + endIPv6;
2499-
}
2500-
}
2501-
25022519
// Everything was fine, so persist the VLAN
25032520
Transaction txn = Transaction.currentTxn();
25042521
txn.start();
25052522

2506-
VlanVO vlan = new VlanVO(vlanType, vlanId, vlanGateway, vlanNetmask, zone.getId(), ipRange, networkId, physicalNetworkId, vlanGatewayv6, vlanCidrv6, ipv6Range);
2523+
VlanVO vlan = new VlanVO(vlanType, vlanId, vlanGateway, vlanNetmask, zone.getId(), ipRange, networkId, physicalNetworkId, vlanIp6Gateway, vlanIp6Cidr, ipv6Range);
25072524
s_logger.debug("Saving vlan range " + vlan);
25082525
vlan = _vlanDao.persist(vlan);
25092526

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.apache.log4j.xml.DOMConfigurator;
4343

4444
import com.googlecode.ipv6.IPv6Address;
45+
import com.googlecode.ipv6.IPv6AddressRange;
4546
import com.googlecode.ipv6.IPv6Network;
4647

4748
import com.cloud.utils.IteratorUtil;
@@ -1233,4 +1234,26 @@ public static boolean isIp6InRange(String ip6, String ip6Range) {
12331234
}
12341235
return false;
12351236
}
1237+
1238+
public static boolean isIp6RangeOverlap(String ipRange1, String ipRange2) {
1239+
String[] ips = ipRange1.split("-");
1240+
String startIp1 = ips[0];
1241+
String endIp1 = null;
1242+
if (ips.length > 1) {
1243+
endIp1 = ips[1];
1244+
}
1245+
IPv6Address start1 = IPv6Address.fromString(startIp1);
1246+
IPv6Address end1 = IPv6Address.fromString(endIp1);
1247+
IPv6AddressRange range1 = IPv6AddressRange.fromFirstAndLast(start1, end1);
1248+
ips = ipRange2.split("-");
1249+
String startIp2 = ips[0];
1250+
String endIp2 = null;
1251+
if (ips.length > 1) {
1252+
endIp2 = ips[1];
1253+
}
1254+
IPv6Address start2 = IPv6Address.fromString(startIp2);
1255+
IPv6Address end2 = IPv6Address.fromString(endIp2);
1256+
IPv6AddressRange range2 = IPv6AddressRange.fromFirstAndLast(start2, end2);
1257+
return range1.overlaps(range2);
1258+
}
12361259
}

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,5 +96,10 @@ public void testIpv6() {
9696
assertTrue(ip.compareTo(ipStart) >= 0);
9797
assertTrue(ip.compareTo(ipEnd) <= 0);
9898
}
99+
assertFalse(NetUtils.isIp6RangeOverlap("1234:5678::1-1234:5678::ffff", "1234:5678:1::1-1234:5678:1::ffff"));
100+
assertTrue(NetUtils.isIp6RangeOverlap("1234:5678::1-1234:5678::ffff", "1234:5678::2-1234:5678::f"));
101+
assertTrue(NetUtils.isIp6RangeOverlap("1234:5678::f-1234:5678::ffff", "1234:5678::2-1234:5678::f"));
102+
assertFalse(NetUtils.isIp6RangeOverlap("1234:5678::f-1234:5678::ffff", "1234:5678::2-1234:5678::e"));
103+
assertFalse(NetUtils.isIp6RangeOverlap("1234:5678::f-1234:5678::f", "1234:5678::2-1234:5678::e"));
99104
}
100105
}

0 commit comments

Comments
 (0)