From 1b28ea1ebb81f4a61bc7d705ffaa1563794030be Mon Sep 17 00:00:00 2001 From: Wei Zhou <57355700+weizhouapache@users.noreply.github.com> Date: Thu, 13 May 2021 11:01:47 +0200 Subject: [PATCH] network: fix dhcp/password/metadata issues on shared networks with multiple subnets (#5013) * #4943: apply iptables for password and metadata * #4943: fix wrong ip alias * #4943: revert previous change and add ip_aliases Co-authored-by: Wei Zhou --- .../com/cloud/network/IpAddressManager.java | 3 +- .../cloud/network/IpAddressManagerImpl.java | 28 +++++++++++-------- .../cloud/network/rules/DhcpSubNetRules.java | 6 ++-- .../cloud/server/ManagementServerImpl.java | 2 +- systemvm/debian/opt/cloud/bin/configure.py | 1 + 5 files changed, 24 insertions(+), 16 deletions(-) diff --git a/engine/components-api/src/main/java/com/cloud/network/IpAddressManager.java b/engine/components-api/src/main/java/com/cloud/network/IpAddressManager.java index 0a50e4b29df..61489e5f7c8 100644 --- a/engine/components-api/src/main/java/com/cloud/network/IpAddressManager.java +++ b/engine/components-api/src/main/java/com/cloud/network/IpAddressManager.java @@ -185,7 +185,7 @@ public interface IpAddressManager { IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerId, DataCenter zone, Boolean displayIp, String ipaddress) throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException; - PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List vlanDbIds, Long networkId, String requestedIp, boolean isSystem) + PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List vlanDbIds, Long networkId, String requestedIp, String requestedGateway, boolean isSystem) throws InsufficientAddressCapacityException; PublicIp getAvailablePublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List vlanDbIds, Long networkId, String requestedIp, boolean isSystem) @@ -219,6 +219,7 @@ public interface IpAddressManager { final boolean assign, final boolean allocate, final String requestedIp, + final String requestedGateway, final boolean isSystem, final Long vpcId, final Boolean displayIp, diff --git a/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java b/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java index 2f630cfa682..99c9ae4c779 100644 --- a/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java +++ b/server/src/main/java/com/cloud/network/IpAddressManagerImpl.java @@ -476,6 +476,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage SearchBuilder vlanSearch = _vlanDao.createSearchBuilder(); vlanSearch.and("type", vlanSearch.entity().getVlanType(), Op.EQ); vlanSearch.and("networkId", vlanSearch.entity().getNetworkId(), Op.EQ); + vlanSearch.and("vlanGateway", vlanSearch.entity().getVlanGateway(), Op.EQ); AssignIpAddressSearch.join("vlan", vlanSearch, vlanSearch.entity().getId(), AssignIpAddressSearch.entity().getVlanId(), JoinType.INNER); AssignIpAddressSearch.done(); @@ -487,6 +488,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage SearchBuilder podVlanSearch = _vlanDao.createSearchBuilder(); podVlanSearch.and("type", podVlanSearch.entity().getVlanType(), Op.EQ); podVlanSearch.and("networkId", podVlanSearch.entity().getNetworkId(), Op.EQ); + podVlanSearch.and("vlanGateway", podVlanSearch.entity().getVlanGateway(), Op.EQ); SearchBuilder podVlanMapSB = _podVlanMapDao.createSearchBuilder(); podVlanMapSB.and("podId", podVlanMapSB.entity().getPodId(), Op.EQ); AssignIpAddressFromPodVlanSearch.join("podVlanMapSB", podVlanMapSB, podVlanMapSB.entity().getVlanDbId(), AssignIpAddressFromPodVlanSearch.entity().getVlanId(), @@ -755,34 +757,34 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Override public PublicIp assignPublicIpAddress(long dcId, Long podId, Account owner, VlanType type, Long networkId, String requestedIp, boolean isSystem, boolean forSystemVms) throws InsufficientAddressCapacityException { - return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, isSystem, null, null, forSystemVms); + return fetchNewPublicIp(dcId, podId, null, owner, type, networkId, false, true, requestedIp, null, isSystem, null, null, forSystemVms); } @Override - public PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List vlanDbIds, Long networkId, String requestedIp, boolean isSystem) + public PublicIp assignPublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List vlanDbIds, Long networkId, String requestedIp, String requestedGateway, boolean isSystem) throws InsufficientAddressCapacityException { - return fetchNewPublicIp(dcId, podId, vlanDbIds, owner, type, networkId, false, true, requestedIp, isSystem, null, null, false); + return fetchNewPublicIp(dcId, podId, vlanDbIds, owner, type, networkId, false, true, requestedIp, requestedGateway, isSystem, null, null, false); } @Override public PublicIp getAvailablePublicIpAddressFromVlans(long dcId, Long podId, Account owner, VlanType type, List vlanDbIds, Long networkId, String requestedIp, boolean isSystem) throws InsufficientAddressCapacityException { - return fetchNewPublicIp(dcId, podId, vlanDbIds, owner, type, networkId, false, false, false, requestedIp, isSystem, null, null, false); + return fetchNewPublicIp(dcId, podId, vlanDbIds, owner, type, networkId, false, false, false, requestedIp, null, isSystem, null, null, false); } @DB public PublicIp fetchNewPublicIp(final long dcId, final Long podId, final List vlanDbIds, final Account owner, final VlanType vlanUse, final Long guestNetworkId, - final boolean sourceNat, final boolean allocate, final String requestedIp, final boolean isSystem, final Long vpcId, final Boolean displayIp, final boolean forSystemVms) + final boolean sourceNat, final boolean allocate, final String requestedIp, final String requestedGateway, final boolean isSystem, final Long vpcId, final Boolean displayIp, final boolean forSystemVms) throws InsufficientAddressCapacityException { return fetchNewPublicIp(dcId, podId, vlanDbIds, owner, vlanUse, guestNetworkId, - sourceNat, true, allocate, requestedIp, isSystem, vpcId, displayIp, forSystemVms); + sourceNat, true, allocate, requestedIp, requestedGateway, isSystem, vpcId, displayIp, forSystemVms); } @DB public PublicIp fetchNewPublicIp(final long dcId, final Long podId, final List vlanDbIds, final Account owner, final VlanType vlanUse, final Long guestNetworkId, - final boolean sourceNat, final boolean assign, final boolean allocate, final String requestedIp, final boolean isSystem, final Long vpcId, final Boolean displayIp, final boolean forSystemVms) + final boolean sourceNat, final boolean assign, final boolean allocate, final String requestedIp, final String requestedGateway, final boolean isSystem, final Long vpcId, final Boolean displayIp, final boolean forSystemVms) throws InsufficientAddressCapacityException { - List addrs = listAvailablePublicIps(dcId, podId, vlanDbIds, owner, vlanUse, guestNetworkId, sourceNat, assign, allocate, requestedIp, isSystem, vpcId, displayIp, forSystemVms, true); + List addrs = listAvailablePublicIps(dcId, podId, vlanDbIds, owner, vlanUse, guestNetworkId, sourceNat, assign, allocate, requestedIp, requestedGateway, isSystem, vpcId, displayIp, forSystemVms, true); IPAddressVO addr = addrs.get(0); if (vlanUse == VlanType.VirtualNetwork) { _firewallMgr.addSystemFirewallRules(addr, owner); @@ -793,7 +795,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage @Override public List listAvailablePublicIps(final long dcId, final Long podId, final List vlanDbIds, final Account owner, final VlanType vlanUse, final Long guestNetworkId, - final boolean sourceNat, final boolean assign, final boolean allocate, final String requestedIp, final boolean isSystem, + final boolean sourceNat, final boolean assign, final boolean allocate, final String requestedIp, final String requestedGateway, final boolean isSystem, final Long vpcId, final Boolean displayIp, final boolean forSystemVms, final boolean lockOneRow) throws InsufficientAddressCapacityException { return Transaction.execute(new TransactionCallbackWithException, InsufficientAddressCapacityException>() { @Override @@ -864,6 +866,10 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage sc.setJoinParameters("vlan", "networkId", guestNetworkId); errorMessage.append(", network id=" + guestNetworkId); } + if (requestedGateway != null) { + sc.setJoinParameters("vlan", "vlanGateway", requestedGateway); + errorMessage.append(", requested gateway=" + requestedGateway); + } sc.setJoinParameters("vlan", "type", vlanUse); if (requestedIp != null) { @@ -1023,7 +1029,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage VpcVO vpc = _vpcDao.findById(vpcId); displayIp = vpc.isDisplay(); } - return fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, true, null, false, vpcId, displayIp, false); + return fetchNewPublicIp(dcId, null, null, owner, VlanType.VirtualNetwork, guestNtwkId, isSourceNat, true, null, null, false, vpcId, displayIp, false); } }); if (ip.getState() != State.Allocated) { @@ -1219,7 +1225,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage ip = Transaction.execute(new TransactionCallbackWithException() { @Override public PublicIp doInTransaction(TransactionStatus status) throws InsufficientAddressCapacityException { - PublicIp ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, ipaddress, isSystem, null, displayIp, false); + PublicIp ip = fetchNewPublicIp(zone.getId(), null, null, ipOwner, vlanType, null, false, assign, ipaddress, null, isSystem, null, displayIp, false); if (ip == null) { InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Unable to find available public IP addresses", DataCenter.class, zone diff --git a/server/src/main/java/com/cloud/network/rules/DhcpSubNetRules.java b/server/src/main/java/com/cloud/network/rules/DhcpSubNetRules.java index ed5513795a3..dd12acd8972 100644 --- a/server/src/main/java/com/cloud/network/rules/DhcpSubNetRules.java +++ b/server/src/main/java/com/cloud/network/rules/DhcpSubNetRules.java @@ -123,10 +123,10 @@ public class DhcpSubNetRules extends RuleApplier { IpAddressManager ipAddrMgr = visitor.getVirtualNetworkApplianceFactory().getIpAddrMgr(); if (dc.getNetworkType() == NetworkType.Basic) { routerPublicIP = ipAddrMgr.assignPublicIpAddressFromVlans(_router.getDataCenterId(), vm.getPodIdToDeployIn(), caller, Vlan.VlanType.DirectAttached, - vlanDbIdList, _nic.getNetworkId(), null, false); + vlanDbIdList, _nic.getNetworkId(), null, _nic.getIPv4Gateway(), false); } else { routerPublicIP = ipAddrMgr.assignPublicIpAddressFromVlans(_router.getDataCenterId(), null, caller, Vlan.VlanType.DirectAttached, vlanDbIdList, - _nic.getNetworkId(), null, false); + _nic.getNetworkId(), null, _nic.getIPv4Gateway(), false); } _routerAliasIp = routerPublicIP.getAddress().addr(); @@ -171,4 +171,4 @@ public class DhcpSubNetRules extends RuleApplier { public String getRouterAliasIp() { return _routerAliasIp; } -} \ No newline at end of file +} diff --git a/server/src/main/java/com/cloud/server/ManagementServerImpl.java b/server/src/main/java/com/cloud/server/ManagementServerImpl.java index 44024e75650..65204e82335 100644 --- a/server/src/main/java/com/cloud/server/ManagementServerImpl.java +++ b/server/src/main/java/com/cloud/server/ManagementServerImpl.java @@ -2178,7 +2178,7 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe long dcId = dc.getId(); try { freeAddrs.addAll(_ipAddressMgr.listAvailablePublicIps(dcId, null, vlanDbIds, owner, VlanType.VirtualNetwork, associatedNetworkId, - false, false, false, null, false, cmd.getVpcId(), cmd.isDisplay(), false, false)); // Free + false, false, false, null, null, false, cmd.getVpcId(), cmd.isDisplay(), false, false)); // Free } catch (InsufficientAddressCapacityException e) { s_logger.warn("no free address is found in zone " + dcId); } diff --git a/systemvm/debian/opt/cloud/bin/configure.py b/systemvm/debian/opt/cloud/bin/configure.py index d0a83abd855..8fdf134b506 100755 --- a/systemvm/debian/opt/cloud/bin/configure.py +++ b/systemvm/debian/opt/cloud/bin/configure.py @@ -1070,6 +1070,7 @@ def main(argv): config.address().process() databag_map = OrderedDict([("guest_network", {"process_iptables": True, "executor": []}), + ("ip_aliases", {"process_iptables": True, "executor": []}), ("vm_password", {"process_iptables": False, "executor": [CsPassword("vmpassword", config)]}), ("vm_metadata", {"process_iptables": False, "executor": [CsVmMetadata('vmdata', config)]}), ("network_acl", {"process_iptables": True, "executor": []}),