bug 10561: reapply static nat on the backend as a part of domR restart and network restart

This commit is contained in:
alena 2011-08-11 11:18:38 -07:00
parent 0504832425
commit 477e5d6389
5 changed files with 73 additions and 15 deletions

View File

@ -213,4 +213,6 @@ public interface NetworkManager extends NetworkService {
String getStartIpAddress(long networkId);
boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError) throws ResourceUnavailableException;
String getIpInNetwork(long vmId, long networkId);
}

View File

@ -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<FirewallRuleVO> 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) {

View File

@ -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<RemoteAccessVpn> vpns = new ArrayList<RemoteAccessVpn>();
List<PortForwardingRule> pfRules = new ArrayList<PortForwardingRule>();
List<FirewallRule> staticNatFirewallRules = new ArrayList<FirewallRule>();
List<StaticNat> staticNats = new ArrayList<StaticNat>();
//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

View File

@ -67,7 +67,8 @@ public interface RulesManager extends RulesService {
List<PortForwardingRuleVO> 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);
}

View File

@ -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<IPAddressVO> 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<StaticNat> staticNats = new ArrayList<StaticNat>();
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<? extends FirewallRule> 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<StaticNat> staticNats = new ArrayList<StaticNat>();
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);