IPv6: Add vlan overlap checking

Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/59419156
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/59419156
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/59419156

Branch: refs/heads/network-refactor
Commit: 5941915648a5ba29f9fd6365ab4443b80e177bc9
Parents: f5ee570
Author: Sheng Yang <[email protected]>
Authored: Tue Jan 29 21:43:58 2013 -0800
Committer: Sheng Yang <[email protected]>
Committed: Mon Feb 4 15:17:00 2013 -0800

----------------------------------------------------------------------
 .../cloud/configuration/ConfigurationManager.java  |    2 +-
 .../configuration/ConfigurationManagerImpl.java    |   45 ++++++++++-----
 utils/src/com/cloud/utils/net/NetUtils.java        |   23 ++++++++
 utils/test/com/cloud/utils/net/NetUtilsTest.java   |    5 ++
 4 files changed, 60 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/59419156/server/src/com/cloud/configuration/ConfigurationManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/ConfigurationManager.java 
b/server/src/com/cloud/configuration/ConfigurationManager.java
index 58fdeed..09e8ac9 100644
--- a/server/src/com/cloud/configuration/ConfigurationManager.java
+++ b/server/src/com/cloud/configuration/ConfigurationManager.java
@@ -198,7 +198,7 @@ public interface ConfigurationManager extends 
ConfigurationService, Manager {
             boolean isDefault, Network.GuestType type, boolean systemOnly, 
Long serviceOfferingId, boolean conserveMode, Map<Service, Map<Capability, 
String>> serviceCapabilityMap,
             boolean specifyIpRanges);
 
-    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;
+    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;
 
     void createDefaultSystemNetworks(long zoneId) throws 
ConcurrentOperationException;
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/59419156/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 5e02e27..a8eec4c 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -2275,7 +2275,7 @@ public class ConfigurationManagerImpl implements 
ConfigurationManager, Configura
     @DB
     public 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) {
+            String vlanId, Account vlanOwner, String startIPv6, String 
endIPv6, String vlanIp6Gateway, String vlanIp6Cidr) {
         Network network = _networkModel.getNetwork(networkId);
         
         boolean ipv4 = false, ipv6 = false;
@@ -2369,15 +2369,14 @@ public class ConfigurationManagerImpl implements 
ConfigurationManager, Configura
         }
         
         if (ipv6) {
-               if (!NetUtils.isValidIpv6(vlanGatewayv6)) {
+               if (!NetUtils.isValidIpv6(vlanIp6Gateway)) {
                        throw new InvalidParameterValueException("Please 
specify a valid IPv6 gateway");
                }
-               if (!NetUtils.isValidIp6Cidr(vlanCidrv6)) {
+               if (!NetUtils.isValidIp6Cidr(vlanIp6Cidr)) {
                        throw new InvalidParameterValueException("Please 
specify a valid IPv6 CIDR");
                }
         }
 
-        // TODO skip all vlan check for ipv6 now
         if (ipv4) {
                String newVlanSubnet = NetUtils.getSubNet(vlanGateway, 
vlanNetmask);
 
@@ -2423,7 +2422,7 @@ public class ConfigurationManagerImpl implements 
ConfigurationManager, Configura
                List<VlanVO> vlans = _vlanDao.listByZone(zone.getId());
                for (VlanVO vlan : vlans) {
                        String otherVlanGateway = vlan.getVlanGateway();
-                       // Continue if it's IPv6
+                       // Continue if it's not IPv4 
                        if (otherVlanGateway == null) {
                                continue;
                        }
@@ -2459,6 +2458,32 @@ public class ConfigurationManagerImpl implements 
ConfigurationManager, Configura
                        }
                }
         }
+        
+        String ipv6Range = null;
+        if (ipv6) {
+               ipv6Range = startIPv6;
+               if (endIPv6 != null) {
+                       ipv6Range += "-" + endIPv6;
+               }
+               
+               List<VlanVO> vlans = _vlanDao.listByZone(zone.getId());
+               for (VlanVO vlan : vlans) {
+                       if (vlan.getIp6Gateway() == null) {
+                               continue;
+                       }
+                       if (vlanId.equals(vlan.getVlanTag())) {
+                               if (NetUtils.isIp6RangeOverlap(ipv6Range, 
vlan.getIp6Range())) {
+                                       throw new 
InvalidParameterValueException("The IPv6 range with tag: " + vlan.getVlanTag()
+                                                       + " already has IPs 
that overlap with the new range. Please specify a different start IP/end IP.");
+                               }
+
+                               if 
(!vlanIp6Gateway.equals(vlan.getIp6Gateway())) {
+                                       throw new 
InvalidParameterValueException("The IP range with tag: " + vlan.getVlanTag() + 
" has already been added with gateway " + vlan.getIp6Gateway()
+                                                       + ". Please specify a 
different tag.");
+                               }
+                       }
+               }
+        }
 
         // Check if a guest VLAN is using the same tag
         if (_zoneDao.findVnet(zoneId, physicalNetworkId, vlanId).size() > 0) {
@@ -2488,19 +2513,11 @@ public class ConfigurationManagerImpl implements 
ConfigurationManager, Configura
                }
         }
         
-        String ipv6Range = null;
-        if (ipv6) {
-               ipv6Range = startIPv6;
-               if (endIPv6 != null) {
-                       ipv6Range += "-" + endIPv6;
-               }
-        }
-
         // Everything was fine, so persist the VLAN
         Transaction txn = Transaction.currentTxn();
         txn.start();
 
-        VlanVO vlan = new VlanVO(vlanType, vlanId, vlanGateway, vlanNetmask, 
zone.getId(), ipRange, networkId, physicalNetworkId, vlanGatewayv6, vlanCidrv6, 
ipv6Range);
+        VlanVO vlan = new VlanVO(vlanType, vlanId, vlanGateway, vlanNetmask, 
zone.getId(), ipRange, networkId, physicalNetworkId, vlanIp6Gateway, 
vlanIp6Cidr, ipv6Range);
         s_logger.debug("Saving vlan range " + vlan);
         vlan = _vlanDao.persist(vlan);
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/59419156/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 51d9fa0..fdda5b8 100755
--- a/utils/src/com/cloud/utils/net/NetUtils.java
+++ b/utils/src/com/cloud/utils/net/NetUtils.java
@@ -42,6 +42,7 @@ import org.apache.log4j.Logger;
 import org.apache.log4j.xml.DOMConfigurator;
 
 import com.googlecode.ipv6.IPv6Address;
+import com.googlecode.ipv6.IPv6AddressRange;
 import com.googlecode.ipv6.IPv6Network;
 
 import com.cloud.utils.IteratorUtil;
@@ -1233,4 +1234,26 @@ public class NetUtils {
        }
                return false;
        }
+       
+       public static boolean isIp6RangeOverlap(String ipRange1, String 
ipRange2) {
+               String[] ips = ipRange1.split("-");
+       String startIp1 = ips[0];
+       String endIp1 = null;
+       if (ips.length > 1) {
+               endIp1 = ips[1];
+       }
+       IPv6Address start1 = IPv6Address.fromString(startIp1);
+       IPv6Address end1 = IPv6Address.fromString(endIp1);
+       IPv6AddressRange range1 = IPv6AddressRange.fromFirstAndLast(start1, 
end1);
+               ips = ipRange2.split("-");
+       String startIp2 = ips[0];
+       String endIp2 = null;
+       if (ips.length > 1) {
+               endIp2 = ips[1];
+       }
+       IPv6Address start2 = IPv6Address.fromString(startIp2);
+       IPv6Address end2 = IPv6Address.fromString(endIp2);
+       IPv6AddressRange range2 = IPv6AddressRange.fromFirstAndLast(start2, 
end2);
+       return range1.overlaps(range2);
+       }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/59419156/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 c256d6d..5336d93 100644
--- a/utils/test/com/cloud/utils/net/NetUtilsTest.java
+++ b/utils/test/com/cloud/utils/net/NetUtilsTest.java
@@ -96,5 +96,10 @@ public class NetUtilsTest extends TestCase {
                assertTrue(ip.compareTo(ipStart) >= 0);
                assertTrue(ip.compareTo(ipEnd) <= 0);
        }
+       assertFalse(NetUtils.isIp6RangeOverlap("1234:5678::1-1234:5678::ffff", 
"1234:5678:1::1-1234:5678:1::ffff"));
+       assertTrue(NetUtils.isIp6RangeOverlap("1234:5678::1-1234:5678::ffff", 
"1234:5678::2-1234:5678::f"));
+       assertTrue(NetUtils.isIp6RangeOverlap("1234:5678::f-1234:5678::ffff", 
"1234:5678::2-1234:5678::f"));
+       assertFalse(NetUtils.isIp6RangeOverlap("1234:5678::f-1234:5678::ffff", 
"1234:5678::2-1234:5678::e"));
+       assertFalse(NetUtils.isIp6RangeOverlap("1234:5678::f-1234:5678::f", 
"1234:5678::2-1234:5678::e"));
     }
 }

Reply via email to