From 477e5d6389caa4848b3889da8efa710389010a88 Mon Sep 17 00:00:00 2001 From: alena Date: Thu, 11 Aug 2011 11:18:38 -0700 Subject: [PATCH] bug 10561: reapply static nat on the backend as a part of domR restart and network restart --- .../src/com/cloud/network/NetworkManager.java | 2 + .../com/cloud/network/NetworkManagerImpl.java | 13 +++++ .../VirtualNetworkApplianceManagerImpl.java | 15 ++++++ .../com/cloud/network/rules/RulesManager.java | 7 +-- .../cloud/network/rules/RulesManagerImpl.java | 51 ++++++++++++++----- 5 files changed, 73 insertions(+), 15 deletions(-) diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 163c428cc10..09fa13e6c56 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -213,4 +213,6 @@ public interface NetworkManager extends NetworkService { String getStartIpAddress(long networkId); boolean applyStaticNats(List staticNats, boolean continueOnError) throws ResourceUnavailableException; + + String getIpInNetwork(long vmId, long networkId); } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index 3cb30dea9af..f4a50f22cb2 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -2432,6 +2432,12 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag success = false; } + // apply static nat + if (!_rulesMgr.applyStaticNatsForNetwork(networkId, false, caller)) { + s_logger.warn("Failed to apply static nats a part of network id" + networkId + " restart"); + success = false; + } + // apply firewall rules List firewallRulesToApply = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.Firewall); if (!_firewallMgr.applyFirewallRules(firewallRulesToApply, false, caller)) { @@ -2631,6 +2637,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag public Nic getNicInNetwork(long vmId, long networkId) { return _nicDao.findByInstanceIdAndNetworkId(networkId, vmId); } + + @Override + public String getIpInNetwork(long vmId, long networkId) { + Nic guestNic = getNicInNetwork(vmId, networkId); + assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with ipAddress or ip4 address is null...how is it possible?"; + return guestNic.getIp4Address(); + } @Override public Nic getNicInNetworkIncludingRemoved(long vmId, long networkId) { diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 90a40472733..2c47ce5f017 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -136,6 +136,7 @@ import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.RulesManager; import com.cloud.network.rules.StaticNat; +import com.cloud.network.rules.StaticNatImpl; import com.cloud.network.rules.StaticNatRule; import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.offering.NetworkOffering; @@ -1392,7 +1393,9 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian List vpns = new ArrayList(); List pfRules = new ArrayList(); List staticNatFirewallRules = new ArrayList(); + List staticNats = new ArrayList(); + //Get information about all the rules (StaticNats and StaticNatRules; PFVPN to reapply on domR start) for (PublicIpAddress ip : publicIps) { pfRules.addAll(_pfRulesDao.listForApplication(ip.getId())); staticNatFirewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat)); @@ -1401,6 +1404,18 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (vpn != null) { vpns.add(vpn); } + + if (ip.isOneToOneNat()) { + String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), networkId); + StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), networkId, ip.getId(), dstIp, false); + staticNats.add(staticNat); + } + } + + //Re-apply static nats + s_logger.debug("Found " + staticNats.size() + " static nat(s) to apply as a part of domR " + router + " start."); + if (!staticNats.isEmpty()) { + createApplyStaticNatCommands(staticNats, router, cmds); } // Re-apply port forwarding rules diff --git a/server/src/com/cloud/network/rules/RulesManager.java b/server/src/com/cloud/network/rules/RulesManager.java index 1f83b1ca320..04ea5829a75 100644 --- a/server/src/com/cloud/network/rules/RulesManager.java +++ b/server/src/com/cloud/network/rules/RulesManager.java @@ -67,7 +67,8 @@ public interface RulesManager extends RulesService { List listByNetworkId(long networkId); - boolean applyStaticNat(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke); - - + boolean applyStaticNatForIp(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke); + + boolean applyStaticNatsForNetwork(long networkId, boolean continueOnError, Account caller); + } diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index d1130dad42b..767ae557200 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -251,10 +251,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { Long accountId = ipAddress.getAccountId(); Long domainId = ipAddress.getDomainId(); - // Get nic IP4 address - Nic guestNic = _networkMgr.getNicInNetwork(ipAddress.getAssociatedWithVmId(), networkId); - assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with ipAddress or ip4 address is null...how is it possible?"; - String dstIp = guestNic.getIp4Address(); + String dstIp = _networkMgr.getIpInNetwork(ipAddress.getAssociatedWithVmId(), networkId); Transaction txn = Transaction.currentTxn(); txn.start(); @@ -354,7 +351,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { if (_ipAddressDao.update(ipAddress.getId(), ipAddress)) { //enable static nat on the backend s_logger.trace("Enabling static nat for ip address " + ipAddress + " and vm id=" + vmId + " on the backend"); - if (applyStaticNat(ipId, false, caller, false)) { + if (applyStaticNatForIp(ipId, false, caller, false)) { return true; } else { ipAddress.setOneToOneNat(false); @@ -706,6 +703,38 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { return true; } + + @Override + public boolean applyStaticNatsForNetwork(long networkId, boolean continueOnError, Account caller) { + List ips = _ipAddressDao.listStaticNatPublicIps(networkId); + if (ips.isEmpty()) { + s_logger.debug("There are no static nat to apply for network id=" + networkId); + return true; + } + + if (caller != null) { + _accountMgr.checkAccess(caller, ips.toArray(new IPAddressVO[ips.size()])); + } + + List staticNats = new ArrayList(); + for (IPAddressVO ip : ips) { + // Get nic IP4 address + String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), networkId); + StaticNatImpl staticNat = new StaticNatImpl(ip.getAccountId(), ip.getDomainId(), networkId, ip.getId(), dstIp, false); + staticNats.add(staticNat); + } + + try { + if (!_networkMgr.applyStaticNats(staticNats, continueOnError)) { + return false; + } + } catch (ResourceUnavailableException ex) { + s_logger.warn("Failed to create static nat rule due to ", ex); + return false; + } + + return true; + } @Override public List searchStaticNatRules(Long ipId, Long id, Long vmId, Long start, Long size, String accountName, Long domainId) { @@ -819,7 +848,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { } //revoke static nat for the ip address - boolean staticNatRevoked = applyStaticNat(ipId, false, caller, true); + boolean staticNatRevoked = applyStaticNatForIp(ipId, false, caller, true); // revoke all port forwarding rules applyPortForwardingRules(ipId, true, caller); @@ -1021,13 +1050,13 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { throw new InvalidParameterValueException("Source ip address of the rule id=" + rule.getId() + " is not static nat enabled"); } - Nic guestNic = _networkMgr.getNicInNetwork(ip.getAssociatedWithVmId(), rule.getNetworkId()); + String dstIp = _networkMgr.getIpInNetwork(ip.getAssociatedWithVmId(), rule.getNetworkId()); - return new StaticNatRuleImpl(ruleVO, guestNic.getIp4Address()); + return new StaticNatRuleImpl(ruleVO, dstIp); } @Override - public boolean applyStaticNat(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke) { + public boolean applyStaticNatForIp(long sourceIpId, boolean continueOnError, Account caller, boolean forRevoke) { List staticNats = new ArrayList(); IpAddress sourceIp = _ipAddressDao.findById(sourceIpId); @@ -1054,9 +1083,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { //create new static nat rule // Get nic IP4 address - Nic guestNic = _networkMgr.getNicInNetwork(sourceIp.getAssociatedWithVmId(), networkId); - assert (guestNic != null && guestNic.getIp4Address() != null) : "Vm doesn't belong to network associated with ipAddress or ip4 address is null...how is it possible?"; - String dstIp = guestNic.getIp4Address(); + String dstIp = _networkMgr.getIpInNetwork(sourceIp.getAssociatedWithVmId(), networkId); StaticNatImpl staticNat = new StaticNatImpl(sourceIp.getAccountId(), sourceIp.getDomainId(), networkId, sourceIpId, dstIp, forRevoke); staticNats.add(staticNat);