diff --git a/server/src/com/cloud/configuration/ConfigurationManager.java b/server/src/com/cloud/configuration/ConfigurationManager.java index c5222dadf78..2e9bffd597d 100644 --- a/server/src/com/cloud/configuration/ConfigurationManager.java +++ b/server/src/com/cloud/configuration/ConfigurationManager.java @@ -214,5 +214,9 @@ public interface ConfigurationManager extends ConfigurationService, Manager { * @throws */ Pod editPod(long id, String name, String startIp, String endIp, String gateway, String netmask, String allocationStateStr); + + void checkPodCidrSubnets(long zoneId, Long podIdToBeSkipped, String cidr); + + void checkCidrVlanOverlap(long zoneId, String cidr); } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 0c19b9b89f1..933053162d2 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -636,7 +636,25 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura } } } + + @Override + public void checkCidrVlanOverlap(long zoneId, String cidr) { + // Prevent using the same CIDR for POD and virtual networking + List vlans = _vlanDao.listByZoneAndType(zoneId, VlanType.VirtualNetwork); + for (VlanVO vlan : vlans) { + String vlanCidr = NetUtils.ipAndNetMaskToCidr(vlan.getVlanGateway(), vlan.getVlanNetmask()); + String[] cidrPairVlan = vlanCidr.split("\\/"); + String[] vlanIpRange = NetUtils.getIpRangeFromCidr(cidrPairVlan[0], Long.valueOf(cidrPairVlan[1])); + String[] cidrPairPod = cidr.split("\\/"); + String[] podIpRange = NetUtils.getIpRangeFromCidr(cidrPairPod[0], Long.valueOf(cidrPairPod[1])); + + if (NetUtils.ipRangesOverlap(vlanIpRange[0], vlanIpRange[1], podIpRange[0], podIpRange[1])) { + throw new InvalidParameterValueException("Pod's cidr conflicts with cidr of virtual network in zone id=" + zoneId); + } + } + } + private void checkPodAttributes(long podId, String podName, long zoneId, String gateway, String cidr, String startIp, String endIp, String allocationStateStr, boolean checkForDuplicates, boolean skipGatewayOverlapCheck) { if (checkForDuplicates) { @@ -684,28 +702,8 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura String checkPodCIDRs = _configDao.getValue("check.pod.cidrs"); if (checkPodCIDRs == null || checkPodCIDRs.trim().isEmpty() || Boolean.parseBoolean(checkPodCIDRs)) { - // Check if the CIDR conflicts with the Guest Network or other pods - HashMap> currentPodCidrSubnets = _podDao.getCurrentPodCidrSubnets(zoneId, podId); - List newCidrPair = new ArrayList(); - newCidrPair.add(0, cidrAddress); - newCidrPair.add(1, new Long(cidrSize)); - currentPodCidrSubnets.put(new Long(-1), newCidrPair); - checkPodCidrSubnets(zoneId, currentPodCidrSubnets); - - // Prevent using the same CIDR for POD and virtual networking - List vlans = _vlanDao.listByZoneAndType(zoneId, VlanType.VirtualNetwork); - for (VlanVO vlan : vlans) { - String vlanCidr = NetUtils.ipAndNetMaskToCidr(vlan.getVlanGateway(), vlan.getVlanNetmask()); - String[] cidrPairVlan = vlanCidr.split("\\/"); - String[] vlanIpRange = NetUtils.getIpRangeFromCidr(cidrPairVlan[0], Long.valueOf(cidrPairVlan[1])); - - String[] cidrPairPod = cidr.split("\\/"); - String[] podIpRange = NetUtils.getIpRangeFromCidr(cidrPairPod[0], Long.valueOf(cidrPairPod[1])); - - if (NetUtils.ipRangesOverlap(vlanIpRange[0], vlanIpRange[1], podIpRange[0], podIpRange[1])) { - throw new InvalidParameterValueException("Pod's cidr conflicts with cidr of virtual network in zone id=" + zoneId); - } - } + checkPodCidrSubnets(zoneId, podId, cidr); + checkCidrVlanOverlap(zoneId, cidr); } Grouping.AllocationState allocationState = null; @@ -2692,16 +2690,25 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura return pod.getCidrSize(); } - private void checkPodCidrSubnets(long dcId, HashMap> currentPodCidrSubnets) { + @Override + public void checkPodCidrSubnets(long dcId, Long podIdToBeSkipped, String cidr) { // For each pod, return an error if any of the following is true: - // 1. The pod's CIDR subnet conflicts with the guest network subnet - // 2. The pod's CIDR subnet conflicts with the CIDR subnet of any other - // pod + // The pod's CIDR subnet conflicts with the CIDR subnet of any other pod - // Iterate through all pods in this zone + // Check if the CIDR conflicts with the Guest Network or other pods + long skipPod = 0; + if (podIdToBeSkipped != null) { + skipPod = podIdToBeSkipped; + } + HashMap> currentPodCidrSubnets = _podDao.getCurrentPodCidrSubnets(dcId, skipPod); + List newCidrPair = new ArrayList(); + newCidrPair.add(0, getCidrAddress(cidr)); + newCidrPair.add(1, getCidrSize(cidr)); + currentPodCidrSubnets.put(new Long(-1), newCidrPair); String zoneName = getZoneName(dcId); + // Iterate through all pods in this zone for (Long podId : currentPodCidrSubnets.keySet()) { String podName; if (podId.longValue() == -1) { @@ -2719,8 +2726,6 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSizeToUse); - //TODO add checking for CIDR of guest network in this data center - // Iterate through the rest of the pods for (Long otherPodId : currentPodCidrSubnets.keySet()) { if (podId.equals(otherPodId)) { diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 6701e6aaede..511ad1eaf0f 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -2006,7 +2006,52 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag _nicDao.expunge(nic.getId()); } } + + private String getCidrAddress(String cidr) { + String[] cidrPair = cidr.split("\\/"); + return cidrPair[0]; + } + private int getCidrSize(String cidr) { + String[] cidrPair = cidr.split("\\/"); + return Integer.parseInt(cidrPair[1]); + } + + public void checkVirtualNetworkCidrOverlap(Long zoneId, String cidr) { + if (zoneId == null) { + return; + } + List networks = _networksDao.listByZone((long)zoneId); + Map networkToCidr = new HashMap(); + for (NetworkVO network : networks) { + if (network.getGuestType() != GuestType.Isolated) { + continue; + } + networkToCidr.put(network.getId(), network.getCidr()); + } + if (networkToCidr == null || networkToCidr.isEmpty()) { + return; + } + + String currCidrAddress = getCidrAddress(cidr); + int currCidrSize = getCidrSize(cidr); + + for (long networkId : networkToCidr.keySet()) { + String ntwkCidr = networkToCidr.get(networkId); + String ntwkCidrAddress = getCidrAddress(ntwkCidr); + int ntwkCidrSize = getCidrSize(ntwkCidr); + + long cidrSizeToUse = currCidrSize < ntwkCidrSize ? currCidrSize : ntwkCidrSize; + + String ntwkCidrSubnet = NetUtils.getCidrSubNet(getCidrAddress(ntwkCidr), cidrSizeToUse); + String cidrSubnet = NetUtils.getCidrSubNet(currCidrAddress, cidrSizeToUse); + + if (cidrSubnet.equals(ntwkCidrSubnet)) { + throw new InvalidParameterValueException("Warning: The existing network " + networkId + " have conflict CIDR subnets with new network!"); + } + } + } + @Override @DB @ActionEvent(eventType = EventTypes.EVENT_NETWORK_CREATE, eventDescription = "creating network") @@ -2174,7 +2219,9 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag if (cidr != null && networkOfferingIsConfiguredForExternalNetworking(networkOfferingId)) { throw new InvalidParameterValueException("Cannot specify CIDR when using network offering with external firewall!"); } - + + checkVirtualNetworkCidrOverlap(zoneId, cidr); + Transaction txn = Transaction.currentTxn(); txn.start();