bug 12556: Add more CIDR checking when create network with specify CIDR

Pod and vlan creation have already got them.

status 12556: fixed resolved
This commit is contained in:
Sheng Yang 2012-01-09 15:08:53 -08:00
parent 3355c6cffe
commit 861fdbee17
3 changed files with 86 additions and 30 deletions

View File

@ -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);
}

View File

@ -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<VlanVO> 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<Long, List<Object>> currentPodCidrSubnets = _podDao.getCurrentPodCidrSubnets(zoneId, podId);
List<Object> newCidrPair = new ArrayList<Object>();
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<VlanVO> 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<Long, List<Object>> 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<Long, List<Object>> currentPodCidrSubnets = _podDao.getCurrentPodCidrSubnets(dcId, skipPod);
List<Object> newCidrPair = new ArrayList<Object>();
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)) {

View File

@ -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<NetworkVO> networks = _networksDao.listByZone((long)zoneId);
Map<Long, String> networkToCidr = new HashMap<Long, String>();
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();