diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java index 57eeb290c05..0432e4fb363 100644 --- a/api/src/com/cloud/network/NetworkModel.java +++ b/api/src/com/cloud/network/NetworkModel.java @@ -249,7 +249,7 @@ public interface NetworkModel { boolean isNetworkInlineMode(Network network); - Vlan getVlanForNetwork(long networkId); + boolean isIP6AddressAvailableInNetwork(long networkId); - boolean isIP6AddressAvailable(long networkId); + boolean isIP6AddressAvailableInVlan(long vlanId); } \ No newline at end of file diff --git a/server/src/com/cloud/network/Ipv6AddressManagerImpl.java b/server/src/com/cloud/network/Ipv6AddressManagerImpl.java index f5ad7da1d14..ecef5a225e9 100644 --- a/server/src/com/cloud/network/Ipv6AddressManagerImpl.java +++ b/server/src/com/cloud/network/Ipv6AddressManagerImpl.java @@ -17,6 +17,7 @@ package com.cloud.network; +import java.util.List; import java.util.Map; import javax.ejb.Local; @@ -30,6 +31,7 @@ import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenterVO; import com.cloud.dc.Vlan; +import com.cloud.dc.VlanVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.VlanDao; import com.cloud.exception.InsufficientAddressCapacityException; @@ -76,25 +78,34 @@ public class Ipv6AddressManagerImpl extends ManagerBase implements Ipv6AddressMa if (network == null) { return null; } - Vlan vlan = _networkModel.getVlanForNetwork(networkId); - if (vlan == null) { + List vlans = _vlanDao.listVlansByNetworkId(networkId); + if (vlans == null) { s_logger.debug("Cannot find related vlan or too many vlan attached to network " + networkId); return null; } String ip = null; + Vlan ipVlan = null; if (requestedIp6 == null) { - if (!_networkModel.isIP6AddressAvailable(networkId)) { + if (!_networkModel.isIP6AddressAvailableInNetwork(networkId)) { throw new InsufficientAddressCapacityException("There is no more address available in the network " + network.getName(), DataCenter.class, network.getDataCenterId()); } - ip = NetUtils.getIp6FromRange(vlan.getIp6Range()); - int count = 0; - while (_ipv6Dao.findByNetworkIdAndIp(networkId, ip) != null) { - ip = NetUtils.getNextIp6InRange(ip, vlan.getIp6Range()); - count ++; - // It's an arbitrate number to prevent the infinite loop - if (count > _ipv6RetryMax) { - ip = null; - break; + for (Vlan vlan : vlans) { + if (!_networkModel.isIP6AddressAvailableInVlan(vlan.getId())) { + continue; + } + ip = NetUtils.getIp6FromRange(vlan.getIp6Range()); + int count = 0; + while (_ipv6Dao.findByNetworkIdAndIp(networkId, ip) != null) { + ip = NetUtils.getNextIp6InRange(ip, vlan.getIp6Range()); + count ++; + // It's an arbitrate number to prevent the infinite loop + if (count > _ipv6RetryMax) { + ip = null; + break; + } + } + if (ip != null) { + ipVlan = vlan; } } if (ip == null) { @@ -102,7 +113,13 @@ public class Ipv6AddressManagerImpl extends ManagerBase implements Ipv6AddressMa DataCenter.class, network.getDataCenterId()); } } else { - if (!NetUtils.isIp6InRange(requestedIp6, vlan.getIp6Range())) { + for (Vlan vlan : vlans) { + if (NetUtils.isIp6InRange(requestedIp6, vlan.getIp6Range())) { + ipVlan = vlan; + break; + } + } + if (ipVlan == null) { throw new CloudRuntimeException("Requested IPv6 is not in the predefined range!"); } ip = requestedIp6; @@ -117,9 +134,9 @@ public class Ipv6AddressManagerImpl extends ManagerBase implements Ipv6AddressMa _dcDao.update(dc.getId(), dc); String macAddress = NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(mac)); - UserIpv6AddressVO ipVO = new UserIpv6AddressVO(ip, dcId, macAddress, vlan.getId()); - ipVO.setPhysicalNetworkId(vlan.getPhysicalNetworkId()); - ipVO.setSourceNetworkId(vlan.getNetworkId()); + UserIpv6AddressVO ipVO = new UserIpv6AddressVO(ip, dcId, macAddress, ipVlan.getId()); + ipVO.setPhysicalNetworkId(network.getPhysicalNetworkId()); + ipVO.setSourceNetworkId(networkId); ipVO.setState(UserIpv6Address.State.Allocated); ipVO.setDomainId(owner.getDomainId()); ipVO.setAccountId(owner.getAccountId()); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 65b4b1aeafa..f24623ef577 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -3405,11 +3405,7 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L if (nic.getIp6Address() == null) { ipv6 = true; UserIpv6Address ip = _ipv6Mgr.assignDirectIp6Address(dc.getId(), vm.getOwner(), network.getId(), requestedIpv6); - Vlan vlan = _networkModel.getVlanForNetwork(network.getId()); - if (vlan == null) { - s_logger.debug("Cannot find related vlan or too many vlan attached to network " + network.getId()); - return; - } + Vlan vlan = _vlanDao.findById(ip.getVlanId()); nic.setIp6Address(ip.getAddress().toString()); nic.setIp6Gateway(vlan.getIp6Gateway()); nic.setIp6Cidr(vlan.getIp6Cidr()); diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java index f8d0addd1da..ce8fac7fb2d 100644 --- a/server/src/com/cloud/network/NetworkModelImpl.java +++ b/server/src/com/cloud/network/NetworkModelImpl.java @@ -527,7 +527,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { return false; } if (network.getIp6Gateway() != null) { - hasFreeIps = isIP6AddressAvailable(network.getId()); + hasFreeIps = isIP6AddressAvailableInNetwork(network.getId()); } } else { hasFreeIps = (getAvailableIps(network, null)).size() > 0; @@ -537,17 +537,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { } @Override - public Vlan getVlanForNetwork(long networkId) { - List vlans = _vlanDao.listVlansByNetworkId(networkId); - if (vlans == null || vlans.size() > 1) { - s_logger.debug("Cannot find related vlan or too many vlan attached to network " + networkId); - return null; - } - return vlans.get(0); - } - - @Override - public boolean isIP6AddressAvailable(long networkId) { + public boolean isIP6AddressAvailableInNetwork(long networkId) { Network network = _networksDao.findById(networkId); if (network == null) { return false; @@ -555,8 +545,19 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel { if (network.getIp6Gateway() == null) { return false; } - Vlan vlan = getVlanForNetwork(network.getId()); - long existedCount = _ipv6Dao.countExistedIpsInNetwork(network.getId()); + List vlans = _vlanDao.listVlansByNetworkId(networkId); + for (Vlan vlan : vlans) { + if (isIP6AddressAvailableInVlan(vlan.getId())) { + return true; + } + } + return false; + } + + @Override + public boolean isIP6AddressAvailableInVlan(long vlanId) { + VlanVO vlan = _vlanDao.findById(vlanId); + long existedCount = _ipv6Dao.countExistedIpsInVlan(vlanId); BigInteger existedInt = BigInteger.valueOf(existedCount); BigInteger rangeInt = NetUtils.countIp6InRange(vlan.getIp6Range()); return (existedInt.compareTo(rangeInt) < 0); diff --git a/server/src/com/cloud/network/dao/UserIpv6AddressDao.java b/server/src/com/cloud/network/dao/UserIpv6AddressDao.java index 81e0da83764..555b7f60253 100644 --- a/server/src/com/cloud/network/dao/UserIpv6AddressDao.java +++ b/server/src/com/cloud/network/dao/UserIpv6AddressDao.java @@ -36,4 +36,6 @@ public interface UserIpv6AddressDao extends GenericDao List listByPhysicalNetworkId(long physicalNetworkId); long countExistedIpsInNetwork(long networkId); + + long countExistedIpsInVlan(long vlanId); } diff --git a/server/src/com/cloud/network/dao/UserIpv6AddressDaoImpl.java b/server/src/com/cloud/network/dao/UserIpv6AddressDaoImpl.java index 8a1115dd3b6..587193c73f8 100644 --- a/server/src/com/cloud/network/dao/UserIpv6AddressDaoImpl.java +++ b/server/src/com/cloud/network/dao/UserIpv6AddressDaoImpl.java @@ -59,6 +59,7 @@ public class UserIpv6AddressDaoImpl extends GenericDaoBase sc = CountFreePublicIps.create(); + sc.setParameters("vlanId", vlanId); + return customSearch(sc, null).get(0); + } } diff --git a/server/test/com/cloud/network/MockNetworkModelImpl.java b/server/test/com/cloud/network/MockNetworkModelImpl.java index 502354ea108..1088321e46f 100644 --- a/server/test/com/cloud/network/MockNetworkModelImpl.java +++ b/server/test/com/cloud/network/MockNetworkModelImpl.java @@ -810,13 +810,13 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { } @Override - public Vlan getVlanForNetwork(long networkId) { + public boolean isIP6AddressAvailableInNetwork(long networkId) { // TODO Auto-generated method stub - return null; + return false; } @Override - public boolean isIP6AddressAvailable(long networkId) { + public boolean isIP6AddressAvailableInVlan(long vlanId) { // TODO Auto-generated method stub return false; } diff --git a/server/test/com/cloud/vpc/MockNetworkModelImpl.java b/server/test/com/cloud/vpc/MockNetworkModelImpl.java index 1080d48f1be..aed54c7f254 100644 --- a/server/test/com/cloud/vpc/MockNetworkModelImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkModelImpl.java @@ -824,13 +824,13 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel { } @Override - public Vlan getVlanForNetwork(long networkId) { + public boolean isIP6AddressAvailableInNetwork(long networkId) { // TODO Auto-generated method stub - return null; + return false; } @Override - public boolean isIP6AddressAvailable(long networkId) { + public boolean isIP6AddressAvailableInVlan(long vlanId) { // TODO Auto-generated method stub return false; }