Implement the portforwarding code in the resource Fix a small naming typo
Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/cd247399 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/cd247399 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/cd247399 Branch: refs/heads/junit-tests Commit: cd2473991e2afba15a2a35a39b316b339f20385c Parents: 7ef0426 Author: Hugo Trippaers <[email protected]> Authored: Fri Oct 12 11:57:27 2012 +0200 Committer: Chip Childers <[email protected]> Committed: Mon Oct 15 16:19:19 2012 -0400 ---------------------------------------------------------------------- .../ConfigurePublicIpsOnLogicalRouterAnswer.java | 14 + .../ConfigurePublicIpsOnLogicalRouterCommand.java | 50 ++++ .../network/dao/NiciraNvpRouterMappingDao.java | 2 +- .../network/dao/NiciraNvpRouterMappingDaoImpl.java | 2 +- .../cloud/network/element/NiciraNvpElement.java | 49 +++- .../src/com/cloud/network/nicira/NiciraNvpApi.java | 15 + .../cloud/network/resource/NiciraNvpResource.java | 203 ++++++++++++++- 7 files changed, 310 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/cd247399/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterAnswer.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterAnswer.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterAnswer.java new file mode 100644 index 0000000..d0749ed --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterAnswer.java @@ -0,0 +1,14 @@ +package com.cloud.agent.api; + +public class ConfigurePublicIpsOnLogicalRouterAnswer extends Answer { + + public ConfigurePublicIpsOnLogicalRouterAnswer(Command command, + boolean success, String details) { + super(command, success, details); + } + + public ConfigurePublicIpsOnLogicalRouterAnswer(Command command, Exception e) { + super(command, e); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/cd247399/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterCommand.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterCommand.java b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterCommand.java new file mode 100644 index 0000000..8c7c8d7 --- /dev/null +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/agent/api/ConfigurePublicIpsOnLogicalRouterCommand.java @@ -0,0 +1,50 @@ +package com.cloud.agent.api; + +import java.util.List; + +public class ConfigurePublicIpsOnLogicalRouterCommand extends Command { + + private String logicalRouterUuid; + private String l3GatewayServiceUuid; + private List<String> publicCidrs; + + public ConfigurePublicIpsOnLogicalRouterCommand(String logicalRouterUuid, + String l3GatewayServiceUuid, + List<String> publicCidrs) { + super(); + this.logicalRouterUuid = logicalRouterUuid; + this.publicCidrs = publicCidrs; + this.l3GatewayServiceUuid = l3GatewayServiceUuid; + } + + public String getLogicalRouterUuid() { + return logicalRouterUuid; + } + + public void setLogicalRouterUuid(String logicalRouterUuid) { + this.logicalRouterUuid = logicalRouterUuid; + } + + public String getL3GatewayServiceUuid() { + return l3GatewayServiceUuid; + } + + public void setL3GatewayServiceUuid(String l3GatewayServiceUuid) { + this.l3GatewayServiceUuid = l3GatewayServiceUuid; + } + + public List<String> getPublicCidrs() { + return publicCidrs; + } + + public void setPublicCidrs(List<String> publicCidrs) { + this.publicCidrs = publicCidrs; + } + + @Override + public boolean executeInSequence() { + // TODO Auto-generated method stub + return false; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/cd247399/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDao.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDao.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDao.java index 6fae52e..bb3454a 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDao.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDao.java @@ -5,5 +5,5 @@ import com.cloud.utils.db.GenericDao; public interface NiciraNvpRouterMappingDao extends GenericDao<NiciraNvpRouterMappingVO, Long> { - public NiciraNvpRouterMappingVO findByNetworkIdI(long id); + public NiciraNvpRouterMappingVO findByNetworkId(long id); } http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/cd247399/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java index 303b760..1edcc03 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/dao/NiciraNvpRouterMappingDaoImpl.java @@ -20,7 +20,7 @@ public class NiciraNvpRouterMappingDaoImpl extends GenericDaoBase<NiciraNvpRoute } @Override - public NiciraNvpRouterMappingVO findByNetworkIdI(long id) { + public NiciraNvpRouterMappingVO findByNetworkId(long id) { SearchCriteria<NiciraNvpRouterMappingVO> sc = networkSearch.create(); sc.setParameters("network_id", id); return findOneBy(sc); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/cd247399/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java index 487a64d..71f8454 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/element/NiciraNvpElement.java @@ -49,6 +49,8 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterAnswer; import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterCommand; import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterAnswer; import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterCommand; import com.cloud.agent.api.CreateLogicalRouterAnswer; @@ -469,7 +471,7 @@ public class NiciraNvpElement extends AdapterBase implements // Deleting the LogicalRouter will also take care of all provisioned // nat rules. NiciraNvpRouterMappingVO routermapping = _niciraNvpRouterMappingDao - .findByNetworkIdI(network.getId()); + .findByNetworkId(network.getId()); if (routermapping == null) { s_logger.warn("No logical router uuid found for network " + network.getDisplayText()); @@ -834,13 +836,40 @@ public class NiciraNvpElement extends AdapterBase implements public boolean applyIps(Network network, List<? extends PublicIpAddress> ipAddress, Set<Service> services) throws ResourceUnavailableException { - s_logger.debug("Entering applyIps"); // TODO Remove this line - - // The Nicira Nvp L3 Gateway doesn't need the addresses configured on - // the router interface. Only configure the CIDR and individual ip - // addresses become available when DNAT rules are created for them. - // The cidr setup is done during implementation of the logical router - // in the function implement + if (services.contains(Service.SourceNat)) { + // Only if we need to provide SourceNat we need to configure the logical router + // SourceNat is required for StaticNat and PortForwarding + List<NiciraNvpDeviceVO> devices = _niciraNvpDao + .listByPhysicalNetwork(network.getPhysicalNetworkId()); + if (devices.isEmpty()) { + s_logger.error("No NiciraNvp Controller on physical network " + + network.getPhysicalNetworkId()); + return false; + } + NiciraNvpDeviceVO niciraNvpDevice = devices.get(0); + HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); + _hostDao.loadDetails(niciraNvpHost); + + NiciraNvpRouterMappingVO routermapping = _niciraNvpRouterMappingDao + .findByNetworkId(network.getId()); + if (routermapping == null) { + s_logger.error("No logical router uuid found for network " + + network.getDisplayText()); + return false; + } + + List<String> cidrs = new ArrayList<String>(); + for (PublicIpAddress ip : ipAddress) { + cidrs.add(ip.getAddress().addr() + "/" + NetUtils.getCidrSize(ip.getNetmask())); + } + ConfigurePublicIpsOnLogicalRouterCommand cmd = new ConfigurePublicIpsOnLogicalRouterCommand(routermapping.getLogicalRouterUuid(), + niciraNvpHost.getDetail("l3gatewayserviceuuid"), cidrs); + ConfigurePublicIpsOnLogicalRouterAnswer answer = (ConfigurePublicIpsOnLogicalRouterAnswer) _agentMgr.easySend(niciraNvpHost.getId(), cmd); + return answer.getResult(); + } + else { + s_logger.debug("No need to provision ip addresses as we are not providing L3 services."); + } return true; } @@ -867,7 +896,7 @@ public class NiciraNvpElement extends AdapterBase implements HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); NiciraNvpRouterMappingVO routermapping = _niciraNvpRouterMappingDao - .findByNetworkIdI(network.getId()); + .findByNetworkId(network.getId()); if (routermapping == null) { s_logger.error("No logical router uuid found for network " + network.getDisplayText()); @@ -915,7 +944,7 @@ public class NiciraNvpElement extends AdapterBase implements HostVO niciraNvpHost = _hostDao.findById(niciraNvpDevice.getHostId()); NiciraNvpRouterMappingVO routermapping = _niciraNvpRouterMappingDao - .findByNetworkIdI(network.getId()); + .findByNetworkId(network.getId()); if (routermapping == null) { s_logger.error("No logical router uuid found for network " + network.getDisplayText()); http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/cd247399/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java index 77feb0f..a714e57 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NiciraNvpApi.java @@ -237,6 +237,12 @@ public class NiciraNvpApi { executeDeleteObject(uri); } + + public void modifyLogicalRouterPort(String logicalRouterUuid, LogicalRouterPort logicalRouterPort) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport/" + logicalRouterPort.getUuid(); + + executeUpdateObject(logicalRouterPort, uri, Collections.<String,String>emptyMap()); + } public void modifyLogicalRouterPortAttachment(String logicalRouterUuid, String logicalRouterPortUuid, Attachment attachment) throws NiciraNvpApiException { String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport/" + logicalRouterPortUuid + "/attachment"; @@ -298,6 +304,15 @@ public class NiciraNvpApi { return executeRetrieveObject(new TypeToken<NiciraNvpList<NatRule>>(){}.getType(), uri, params); } + public NiciraNvpList<LogicalRouterPort> findLogicalRouterPortByGatewayServiceUuid(String logicalRouterUuid, String l3GatewayServiceUuid) throws NiciraNvpApiException { + String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/lport"; + Map<String,String> params = new HashMap<String,String>(); + params.put("fields", "*"); + params.put("attachment_gwsvc_uuid", l3GatewayServiceUuid); + + return executeRetrieveObject(new TypeToken<NiciraNvpList<LogicalRouterPort>>(){}.getType(), uri, params); + } + private <T> void executeUpdateObject(T newObject, String uri, Map<String,String> parameters) throws NiciraNvpApiException { String url; try { http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/cd247399/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java index 83a889f..5f445fa 100644 --- a/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java +++ b/plugins/network-elements/nicira-nvp/src/com/cloud/network/resource/NiciraNvpResource.java @@ -29,6 +29,8 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterAnswer; import com.cloud.agent.api.ConfigurePortForwardingRulesOnLogicalRouterCommand; +import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterAnswer; +import com.cloud.agent.api.ConfigurePublicIpsOnLogicalRouterCommand; import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterAnswer; import com.cloud.agent.api.ConfigureStaticNatRulesOnLogicalRouterCommand; import com.cloud.agent.api.CreateLogicalRouterAnswer; @@ -54,6 +56,7 @@ import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupNiciraNvpCommand; import com.cloud.agent.api.UpdateLogicalSwitchPortAnswer; import com.cloud.agent.api.UpdateLogicalSwitchPortCommand; +import com.cloud.agent.api.to.PortForwardingRuleTO; import com.cloud.agent.api.to.StaticNatRuleTO; import com.cloud.host.Host; import com.cloud.host.Host.Type; @@ -230,7 +233,10 @@ public class NiciraNvpResource implements ServerResource { } else if (cmd instanceof ConfigurePortForwardingRulesOnLogicalRouterCommand) { return executeRequest((ConfigurePortForwardingRulesOnLogicalRouterCommand) cmd, numRetries); - } + } + else if (cmd instanceof ConfigurePublicIpsOnLogicalRouterCommand) { + return executeRequest((ConfigurePublicIpsOnLogicalRouterCommand) cmd, numRetries); + } s_logger.debug("Received unsupported command " + cmd.toString()); return Answer.createUnsupportedCommandAnswer(cmd); } @@ -483,9 +489,30 @@ public class NiciraNvpResource implements ServerResource { } } + private Answer executeRequest(ConfigurePublicIpsOnLogicalRouterCommand cmd, int numRetries) { + try { + NiciraNvpList<LogicalRouterPort> ports = _niciraNvpApi.findLogicalRouterPortByGatewayServiceUuid(cmd.getLogicalRouterUuid(), cmd.getL3GatewayServiceUuid()); + if (ports.getResultCount() != 1) { + return new ConfigurePublicIpsOnLogicalRouterAnswer(cmd, false, "No logical router ports found, unable to set ip addresses"); + } + LogicalRouterPort lrp = ports.getResults().get(0); + lrp.setIpAddresses(cmd.getPublicCidrs()); + _niciraNvpApi.modifyLogicalRouterPort(cmd.getLogicalRouterUuid(), lrp); + + return new ConfigurePublicIpsOnLogicalRouterAnswer(cmd, true, "Logical Router deleted (uuid " + cmd.getLogicalRouterUuid() + ")"); + } catch (NiciraNvpApiException e) { + if (numRetries > 0) { + return retry(cmd, --numRetries); + } + else { + return new ConfigurePublicIpsOnLogicalRouterAnswer(cmd, e); + } + } + + } + private Answer executeRequest(ConfigureStaticNatRulesOnLogicalRouterCommand cmd, int numRetries) { try { - LogicalRouterConfig lrc = _niciraNvpApi.findOneLogicalRouterByUuid(cmd.getLogicalRouterUuid()); NiciraNvpList<NatRule> existingRules = _niciraNvpApi.findNatRulesByLogicalRouterUuid(cmd.getLogicalRouterUuid()); // Rules of the game (also known as assumptions-that-will-make-stuff-break-later-on) // A SourceNat rule with a match other than a /32 cidr is assumed to be the "main" SourceNat rule @@ -493,7 +520,6 @@ public class NiciraNvpResource implements ServerResource { for (StaticNatRuleTO rule : cmd.getRules()) { // Find if a DestinationNat rule exists for this rule - boolean found = false; String insideIp = rule.getDstIp(); String insideCidr = rule.getDstIp() + "/32"; String outsideIp = rule.getSrcIp(); @@ -605,10 +631,7 @@ public class NiciraNvpResource implements ServerResource { newDnatRule.setToDestinationIpAddressMin(insideIp); newDnatRule.setToDestinationIpAddressMax(insideIp); newDnatRule = (DestinationNatRule) _niciraNvpApi.createLogicalRouterNatRule(cmd.getLogicalRouterUuid(), newDnatRule); - s_logger.debug("Created " + newDnatRule.getType() + " rule " - + newDnatRule.getUuid() + ", " - + newDnatRule.getMatch().getDestinationIpAddresses() - + " -> " + newDnatRule.getToDestinationIpAddressMin()); + s_logger.debug("Created " + natRuleToString(newDnatRule)); // create matching snat rule m = new Match(); @@ -618,10 +641,7 @@ public class NiciraNvpResource implements ServerResource { newSnatRule.setToSourceIpAddressMin(outsideIp); newSnatRule.setToSourceIpAddressMax(outsideIp); newSnatRule = (SourceNatRule) _niciraNvpApi.createLogicalRouterNatRule(cmd.getLogicalRouterUuid(), newSnatRule); - s_logger.debug("Created " + newSnatRule.getType() + " rule " - + newSnatRule.getUuid() + ", " - + newSnatRule.getMatch().getSourceIpAddresses() + " -> " - + newSnatRule.getToSourceIpAddressMin()); + s_logger.debug("Created " + natRuleToString(newSnatRule)); } } @@ -639,8 +659,120 @@ public class NiciraNvpResource implements ServerResource { private Answer executeRequest(ConfigurePortForwardingRulesOnLogicalRouterCommand cmd, int numRetries) { try { - LogicalRouterConfig lrc = _niciraNvpApi.findOneLogicalRouterByUuid(cmd.getLogicalRouterUuid()); - //FIXME implement! + NiciraNvpList<NatRule> existingRules = _niciraNvpApi.findNatRulesByLogicalRouterUuid(cmd.getLogicalRouterUuid()); + // Rules of the game (also known as assumptions-that-will-make-stuff-break-later-on) + // A SourceNat rule with a match other than a /32 cidr is assumed to be the "main" SourceNat rule + // Any other SourceNat rule should have a corresponding DestinationNat rule + + for (PortForwardingRuleTO rule : cmd.getRules()) { + if (rule.isAlreadyAdded()) { + // Don't need to do anything + continue; + } + + // Find if a DestinationNat rule exists for this rule + String insideIp = rule.getDstIp(); + String insideCidr = rule.getDstIp() + "/32"; + String outsideIp = rule.getSrcIp(); + String outsideCidr = rule.getSrcIp() + "/32"; + + NatRule incoming = null; + NatRule outgoing = null; + + for (NatRule storedRule : existingRules.getResults()) { + if ("SourceNatRule".equals(storedRule.getType())) { + if (outsideIp.equals(storedRule.getToSourceIpAddressMin()) && + outsideIp.equals(storedRule.getToSourceIpAddressMax()) && + storedRule.getToSourcePortMin() == rule.getSrcPortRange()[0] && + storedRule.getToSourcePortMax() == rule.getSrcPortRange()[1]) { + // The outgoing rule exists + outgoing = storedRule; + } + } + else if ("DestinationNatRule".equals(storedRule.getType())) { + if (insideIp.equals(storedRule.getToDestinationIpAddressMin()) && + insideIp.equals(storedRule.getToDestinationIpAddressMax()) && + storedRule.getToDestinationPort() == rule.getDstPortRange()[0]) { + // The incoming rule exists + incoming = storedRule; + } + } + } + if (incoming != null && outgoing != null) { + if (insideIp.equals(incoming.getToDestinationIpAddressMin())) { + if (rule.revoked()) { + s_logger.debug("Deleting incoming rule " + incoming.getUuid()); + _niciraNvpApi.deleteLogicalRouterNatRule(cmd.getLogicalRouterUuid(), incoming.getUuid()); + + s_logger.debug("Deleting outgoing rule " + outgoing.getUuid()); + _niciraNvpApi.deleteLogicalRouterNatRule(cmd.getLogicalRouterUuid(), outgoing.getUuid()); + } + } + else { + s_logger.debug("Updating outgoing rule " + outgoing.getUuid()); + outgoing.setToDestinationIpAddressMin(insideIp); + outgoing.setToDestinationIpAddressMax(insideIp); + outgoing.setToDestinationPort(rule.getDstPortRange()[0]); + _niciraNvpApi.modifyLogicalRouterNatRule(cmd.getLogicalRouterUuid(), outgoing); + + s_logger.debug("Updating incoming rule " + outgoing.getUuid()); + incoming.setToSourceIpAddressMin(insideIp); + incoming.setToSourceIpAddressMax(insideIp); + incoming.setToSourcePortMin(rule.getSrcPortRange()[0]); + incoming.setToSourcePortMax(rule.getSrcPortRange()[1]); + _niciraNvpApi.modifyLogicalRouterNatRule(cmd.getLogicalRouterUuid(), incoming); + break; + } + } + else { + if (rule.revoked()) { + s_logger.warn("Tried deleting a rule that does not exist, " + + rule.getSrcIp() + " -> " + rule.getDstIp()); + break; + } + + // api createLogicalRouterNatRule + // create the dnat rule + Match m = new Match(); + m.setDestinationIpAddresses(outsideCidr); + if ("tcp".equals(rule.getProtocol())) { + m.setProtocol(6); + } + else if ("udp".equals(rule.getProtocol())) { + m.setProtocol(17); + } + m.setDestinationPortMin(rule.getSrcPortRange()[0]); + m.setDestinationPortMax(rule.getSrcPortRange()[1]); + DestinationNatRule newDnatRule = new DestinationNatRule(); + newDnatRule.setMatch(m); + newDnatRule.setToDestinationIpAddressMin(insideIp); + newDnatRule.setToDestinationIpAddressMax(insideIp); + newDnatRule.setToDestinationPort(rule.getDstPortRange()[0]); + newDnatRule = (DestinationNatRule) _niciraNvpApi.createLogicalRouterNatRule(cmd.getLogicalRouterUuid(), newDnatRule); + s_logger.debug("Created " + natRuleToString(newDnatRule)); + + // create matching snat rule + m = new Match(); + m.setSourceIpAddresses(insideIp + "/32"); + if ("tcp".equals(rule.getProtocol())) { + m.setProtocol(6); + } + else if ("udp".equals(rule.getProtocol())) { + m.setProtocol(17); + } + m.setSourcePortMin(rule.getDstPortRange()[0]); + m.setSourcePortMax(rule.getDstPortRange()[1]); + SourceNatRule newSnatRule = new SourceNatRule(); + newSnatRule.setMatch(m); + newSnatRule.setToSourceIpAddressMin(outsideIp); + newSnatRule.setToSourceIpAddressMax(outsideIp); + newSnatRule.setToSourcePortMin(rule.getSrcPortRange()[0]); + newSnatRule.setToSourcePortMax(rule.getSrcPortRange()[1]); + newSnatRule = (SourceNatRule) _niciraNvpApi.createLogicalRouterNatRule(cmd.getLogicalRouterUuid(), newSnatRule); + s_logger.debug("Created " + natRuleToString(newSnatRule)); + + } + } return new ConfigurePortForwardingRulesOnLogicalRouterAnswer(cmd, true, cmd.getRules().size() +" PortForwarding rules applied"); } catch (NiciraNvpApiException e) { if (numRetries > 0) { @@ -667,4 +799,49 @@ public class NiciraNvpResource implements ServerResource { return executeRequest(cmd, numRetriesRemaining); } + private String natRuleToString(NatRule rule) { + + StringBuilder natRuleStr = new StringBuilder(); + natRuleStr.append("Rule "); + natRuleStr.append(rule.getUuid()); + natRuleStr.append(" ("); + natRuleStr.append(rule.getType()); + natRuleStr.append(") :"); + Match m = rule.getMatch(); + natRuleStr.append("match ("); + natRuleStr.append(m.getProtocol()); + natRuleStr.append(" "); + natRuleStr.append(m.getSourceIpAddresses()); + natRuleStr.append(" ["); + natRuleStr.append(m.getSource_port_min()); + natRuleStr.append("-"); + natRuleStr.append(m.getSourcePortMax()); + natRuleStr.append(" ] -> "); + natRuleStr.append(m.getDestinationIpAddresses()); + natRuleStr.append(" ["); + natRuleStr.append(m.getDestinationPortMin()); + natRuleStr.append("-"); + natRuleStr.append(m.getDestinationPortMax()); + natRuleStr.append(" ]) -->"); + if ("SourceNatRule".equals(rule.getType())) { + natRuleStr.append(rule.getToSourceIpAddressMin()); + natRuleStr.append("-"); + natRuleStr.append(rule.getToSourceIpAddressMax()); + natRuleStr.append(" ["); + natRuleStr.append(rule.getToSourcePortMin()); + natRuleStr.append("-"); + natRuleStr.append(rule.getToSourcePortMax()); + natRuleStr.append(" ])"); + } + else { + natRuleStr.append(rule.getToDestinationIpAddressMin()); + natRuleStr.append("-"); + natRuleStr.append(rule.getToDestinationIpAddressMax()); + natRuleStr.append(" ["); + natRuleStr.append(rule.getToDestinationPort()); + natRuleStr.append(" ])"); + } + return natRuleStr.toString(); + } + }
