diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index e2e800b2257..e8fcabec555 100755 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -91,6 +91,7 @@ import com.cloud.keystore.KeystoreManagerImpl; import com.cloud.maint.UpgradeManagerImpl; import com.cloud.maint.dao.AgentUpgradeDaoImpl; import com.cloud.network.ExternalLoadBalancerUsageManagerImpl; +import com.cloud.network.Ipv6AddressManagerImpl; import com.cloud.network.NetworkManagerImpl; import com.cloud.network.NetworkModelImpl; import com.cloud.network.NetworkServiceImpl; @@ -464,6 +465,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com addManager("TaggedResourcesManager", TaggedResourceManagerImpl.class); addManager("Site2SiteVpnManager", Site2SiteVpnManagerImpl.class); addManager("QueryManager", QueryManagerImpl.class); + addManager("Ipv6AddressManager", Ipv6AddressManagerImpl.class); } @Override diff --git a/server/src/com/cloud/network/Ipv6AddressManager.java b/server/src/com/cloud/network/Ipv6AddressManager.java new file mode 100644 index 00000000000..21c65a926df --- /dev/null +++ b/server/src/com/cloud/network/Ipv6AddressManager.java @@ -0,0 +1,28 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package com.cloud.network; + +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.user.Account; +import com.cloud.utils.component.Manager; + +public interface Ipv6AddressManager extends Manager { + public PublicIpv6Address assignDirectIp6Address(long dcId, Account owner, Long networkId, String requestedIp6) throws InsufficientAddressCapacityException; + + public void revokeDirectIpv6Address(long networkId, String ip6Address); +} diff --git a/server/src/com/cloud/network/Ipv6AddressManagerImpl.java b/server/src/com/cloud/network/Ipv6AddressManagerImpl.java new file mode 100644 index 00000000000..d794ff7e57f --- /dev/null +++ b/server/src/com/cloud/network/Ipv6AddressManagerImpl.java @@ -0,0 +1,132 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package com.cloud.network; + +import java.util.Map; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; + +import org.apache.log4j.Logger; + +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.Vlan; +import com.cloud.dc.dao.DataCenterDao; +import com.cloud.dc.dao.VlanDao; +import com.cloud.exception.InsufficientAddressCapacityException; +import com.cloud.network.dao.PublicIpv6AddressDao; +import com.cloud.user.Account; +import com.cloud.utils.component.Inject; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.net.NetUtils; + +@Local(value = { Ipv6AddressManager.class } ) +public class Ipv6AddressManagerImpl implements Ipv6AddressManager { + public static final Logger s_logger = Logger.getLogger(Ipv6AddressManagerImpl.class.getName()); + + String _name = null; + + @Inject + DataCenterDao _dcDao; + @Inject + VlanDao _vlanDao; + @Inject + NetworkModel _networkModel; + @Inject + PublicIpv6AddressDao _ipv6Dao; + + @Override + public boolean configure(String name, Map params) + throws ConfigurationException { + _name = name; + return true; + } + + @Override + public boolean start() { + return true; + } + + @Override + public boolean stop() { + return true; + } + + @Override + public String getName() { + return _name; + } + + @Override + public PublicIpv6Address assignDirectIp6Address(long dcId, Account owner, Long networkId, String requestedIp6) + throws InsufficientAddressCapacityException { + Vlan vlan = _networkModel.getVlanForNetwork(networkId); + if (vlan == null) { + s_logger.debug("Cannot find related vlan or too many vlan attached to network " + networkId); + return null; + } + String ip = null; + if (requestedIp6 == null) { + int count = 0; + while (ip == null || count >= 10) { + ip = NetUtils.getIp6FromRange(vlan.getIp6Range()); + //Check for duplicate IP + if (_ipv6Dao.findByNetworkIdAndIp(networkId, ip) == null) { + break; + } else { + ip = null; + } + count ++; + } + if (ip == null) { + throw new CloudRuntimeException("Fail to get unique ipv6 address after 10 times trying!"); + } + } else { + if (!NetUtils.isIp6InRange(requestedIp6, vlan.getIp6Range())) { + throw new CloudRuntimeException("Requested IPv6 is not in the predefined range!"); + } + ip = requestedIp6; + if (_ipv6Dao.findByNetworkIdAndIp(networkId, ip) != null) { + throw new CloudRuntimeException("The requested IP is already taken!"); + } + } + DataCenterVO dc = _dcDao.findById(dcId); + Long mac = dc.getMacAddress(); + Long nextMac = mac + 1; + dc.setMacAddress(nextMac); + _dcDao.update(dc.getId(), dc); + + String macAddress = NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(mac)); + PublicIpv6AddressVO ipVO = new PublicIpv6AddressVO(ip, dcId, macAddress, vlan.getId()); + ipVO.setPhysicalNetworkId(vlan.getPhysicalNetworkId()); + ipVO.setSourceNetworkId(vlan.getNetworkId()); + ipVO.setState(PublicIpv6Address.State.Allocated); + ipVO.setDomainId(owner.getDomainId()); + ipVO.setAccountId(owner.getAccountId()); + _ipv6Dao.persist(ipVO); + return ipVO; + } + + @Override + public void revokeDirectIpv6Address(long networkId, String ip6Address) { + PublicIpv6AddressVO ip = _ipv6Dao.findByNetworkIdAndIp(networkId, ip6Address); + if (ip != null) { + _ipv6Dao.remove(ip.getId()); + } + } +} diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 71ad72abd6a..149d13437cf 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -327,8 +327,4 @@ public interface NetworkManager { int getRuleCountForIp(Long addressId, FirewallRule.Purpose purpose, FirewallRule.State state); LoadBalancingServiceProvider getLoadBalancingProviderForNetwork(Network network); - - PublicIpv6Address assignPublicIp6Address(long dcId, Long podId, Account owner, - VlanType type, Long networkId, String requestedIp6, boolean isSystem) - throws InsufficientAddressCapacityException; } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index cea935e8633..e06a59b95a4 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -276,6 +276,8 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { NetworkModel _networkModel; @Inject PublicIpv6AddressDao _ipv6Dao; + @Inject + Ipv6AddressManager _ipv6Mgr; ScheduledExecutorService _executor; @@ -297,57 +299,6 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isSystem, null); } - @Override - public PublicIpv6Address assignPublicIp6Address(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp6, boolean isSystem) throws InsufficientAddressCapacityException { - Vlan vlan = _networkModel.getVlanForNetwork(networkId); - if (vlan == null) { - s_logger.debug("Cannot find related vlan or too many vlan attached to network " + networkId); - return null; - } - //TODO should check before this point - if (!NetUtils.isIp6InRange(requestedIp6, vlan.getIp6Range())) { - throw new CloudRuntimeException("Requested IPv6 is not in the predefined range!"); - } - String ip = null; - if (requestedIp6 == null) { - int count = 0; - while (ip == null || count >= 10) { - ip = NetUtils.getIp6FromRange(vlan.getIp6Range()); - //Check for duplicate IP - if (_ipv6Dao.findByDcIdAndIp(dcId, ip) == null) { - break; - } else { - ip = null; - } - count ++; - } - if (ip == null) { - throw new CloudRuntimeException("Fail to get unique ipv6 address after 10 times trying!"); - } - } else { - ip = requestedIp6; - //TODO should check before this point - if (_ipv6Dao.findByDcIdAndIp(dcId, ip) != null) { - throw new CloudRuntimeException("The requested IP is already taken!"); - } - } - DataCenterVO dc = _dcDao.findById(dcId); - Long mac = dc.getMacAddress(); - Long nextMac = mac + 1; - dc.setMacAddress(nextMac); - _dcDao.update(dc.getId(), dc); - - String macAddress = NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(mac)); - PublicIpv6AddressVO ipVO = new PublicIpv6AddressVO(ip, dcId, macAddress, vlan.getId()); - ipVO.setPhysicalNetworkId(vlan.getPhysicalNetworkId()); - ipVO.setSourceNetworkId(vlan.getNetworkId()); - ipVO.setState(PublicIpv6Address.State.Allocated); - ipVO.setDomainId(owner.getDomainId()); - ipVO.setAccountId(owner.getAccountId()); - _ipv6Dao.persist(ipVO); - return ipVO; - } - @DB public PublicIp fetchNewPublicIp(long dcId, Long podId, Long vlanDbId, Account owner, VlanType vlanUse, Long guestNetworkId, boolean sourceNat, boolean assign, String requestedIp, boolean isSystem, Long vpcId) @@ -3411,7 +3362,7 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener { if (network.getIp6Gateway() != null) { if (nic.getIp6Address() == null) { ipv6 = true; - PublicIpv6Address ip = assignPublicIp6Address(dc.getId(), null, vm.getOwner(), VlanType.DirectAttached, network.getId(), requestedIpv6, false); + PublicIpv6Address 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()); diff --git a/server/src/com/cloud/network/dao/PublicIpv6AddressDao.java b/server/src/com/cloud/network/dao/PublicIpv6AddressDao.java index b8de08a9926..c347052bc82 100644 --- a/server/src/com/cloud/network/dao/PublicIpv6AddressDao.java +++ b/server/src/com/cloud/network/dao/PublicIpv6AddressDao.java @@ -15,7 +15,7 @@ public interface PublicIpv6AddressDao extends GenericDao listByNetwork(long networkId); - public PublicIpv6AddressVO findByDcIdAndIp(long dcId, String ipAddress); + public PublicIpv6AddressVO findByNetworkIdAndIp(long networkId, String ipAddress); List listByPhysicalNetworkId(long physicalNetworkId); diff --git a/server/src/com/cloud/network/dao/PublicIpv6AddressDaoImpl.java b/server/src/com/cloud/network/dao/PublicIpv6AddressDaoImpl.java index 6883d4ec662..8a6bfcc5546 100644 --- a/server/src/com/cloud/network/dao/PublicIpv6AddressDaoImpl.java +++ b/server/src/com/cloud/network/dao/PublicIpv6AddressDaoImpl.java @@ -73,9 +73,9 @@ public class PublicIpv6AddressDaoImpl extends GenericDaoBase sc = AllFieldsSearch.create(); - sc.setParameters("dataCenterId", dcId); + sc.setParameters("networkId", networkId); sc.setParameters("ipAddress", ipAddress); return findOneBy(sc); } diff --git a/server/src/com/cloud/network/guru/DirectNetworkGuru.java b/server/src/com/cloud/network/guru/DirectNetworkGuru.java index d6a8812da08..ef286bdadb8 100755 --- a/server/src/com/cloud/network/guru/DirectNetworkGuru.java +++ b/server/src/com/cloud/network/guru/DirectNetworkGuru.java @@ -31,6 +31,7 @@ import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; import com.cloud.exception.InvalidParameterValueException; import com.cloud.network.IPAddressVO; +import com.cloud.network.Ipv6AddressManager; import com.cloud.network.Network; import com.cloud.network.Network.GuestType; import com.cloud.network.Network.Service; @@ -76,6 +77,8 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { NetworkOfferingDao _networkOfferingDao; @Inject PublicIpv6AddressDao _ipv6Dao; + @Inject + Ipv6AddressManager _ipv6Mgr; private static final TrafficType[] _trafficTypes = {TrafficType.Guest}; @@ -230,10 +233,7 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { } if (nic.getIp6Address() != null) { - PublicIpv6AddressVO ip = _ipv6Dao.findByDcIdAndIp(network.getDataCenterId(), nic.getIp6Address()); - if (ip != null) { - _ipv6Dao.remove(ip.getId()); - } + _ipv6Mgr.revokeDirectIpv6Address(nic.getNetworkId(), nic.getIp6Address()); } nic.deallocate(); } diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index df409a83ebc..122d75a63de 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -818,12 +818,4 @@ public class MockNetworkManagerImpl implements NetworkManager, Manager, NetworkS // TODO Auto-generated method stub return null; } - - @Override - public PublicIpv6Address assignPublicIp6Address(long dcId, Long podId, - Account owner, VlanType type, Long networkId, String requestedIpv6, - boolean isSystem) throws InsufficientAddressCapacityException { - // TODO Auto-generated method stub - return null; - } } diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index 13426e601a9..970f5ade04c 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -1321,12 +1321,4 @@ public class MockNetworkManagerImpl implements NetworkManager, NetworkService, M // TODO Auto-generated method stub return null; } - - @Override - public PublicIpv6Address assignPublicIp6Address(long dcId, Long podId, - Account owner, VlanType type, Long networkId, String requestedIpv6, - boolean isSystem) throws InsufficientAddressCapacityException { - // TODO Auto-generated method stub - return null; - } }