Implement static nat handling

Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/61f205d5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/61f205d5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/61f205d5

Branch: refs/heads/junit-tests
Commit: 61f205d5b076916547e2053c81b103d67ce58674
Parents: 2f1621b
Author: Hugo Trippaers <[email protected]>
Authored: Thu Oct 11 18:13:47 2012 +0200
Committer: Chip Childers <[email protected]>
Committed: Mon Oct 15 16:19:15 2012 -0400

----------------------------------------------------------------------
 .../src/com/cloud/network/nicira/NatRule.java      |    4 +-
 .../src/com/cloud/network/nicira/NiciraNvpApi.java |   12 +-
 .../cloud/network/resource/NiciraNvpResource.java  |  133 ++++++++++++++-
 3 files changed, 141 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/61f205d5/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NatRule.java
----------------------------------------------------------------------
diff --git 
a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NatRule.java 
b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NatRule.java
index 82a3378..7255ab6 100644
--- 
a/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NatRule.java
+++ 
b/plugins/network-elements/nicira-nvp/src/com/cloud/network/nicira/NatRule.java
@@ -19,7 +19,7 @@ package com.cloud.network.nicira;
 /**
  * 
  */
-public abstract class NatRule {
+public class NatRule {
        protected Match match;
        protected String to_source_ip_address_min;
        protected String to_source_ip_address_max;
@@ -31,6 +31,8 @@ public abstract class NatRule {
        protected String to_destination_ip_address_max;
        protected Integer to_destination_port;
        
+       public NatRule() {}
+       
        public Match getMatch() {
                return match;
        }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/61f205d5/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 fe4deec..77feb0f 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
@@ -256,6 +256,12 @@ public class NiciraNvpApi {
        throw new NiciraNvpApiException("Unknown NatRule type");
     }
     
+    public void modifyLogicalRouterNatRule(String logicalRouterUuid, NatRule 
natRule) throws NiciraNvpApiException {
+       String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/nat/" + 
natRule.getUuid();
+       
+       executeUpdateObject(natRule, uri, 
Collections.<String,String>emptyMap());
+    }
+    
     public void deleteLogicalRouterNatRule(String logicalRouterUuid, String 
natRuleUuid) throws NiciraNvpApiException {
        String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/nat/" + 
natRuleUuid;
        
@@ -286,8 +292,10 @@ public class NiciraNvpApi {
     
     public NiciraNvpList<NatRule> findNatRulesByLogicalRouterUuid(String 
logicalRouterUuid) throws NiciraNvpApiException {
        String uri = "/ws.v1/lrouter/" + logicalRouterUuid + "/nat";
-       
-       return executeRetrieveObject(new 
TypeToken<NiciraNvpList<NatRule>>(){}.getType(), uri, 
Collections.<String,String>emptyMap());
+        Map<String,String> params = new HashMap<String,String>();
+        params.put("fields","*");
+        
+       return executeRetrieveObject(new 
TypeToken<NiciraNvpList<NatRule>>(){}.getType(), uri, params);
     }
     
     private <T> void executeUpdateObject(T newObject, String uri, 
Map<String,String> parameters) throws NiciraNvpApiException {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/61f205d5/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 4d01bc6..83a889f 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
@@ -59,6 +59,7 @@ import com.cloud.host.Host;
 import com.cloud.host.Host.Type;
 import com.cloud.network.nicira.Attachment;
 import com.cloud.network.nicira.ControlClusterStatus;
+import com.cloud.network.nicira.DestinationNatRule;
 import com.cloud.network.nicira.L3GatewayAttachment;
 import com.cloud.network.nicira.LogicalRouterConfig;
 import com.cloud.network.nicira.LogicalRouterPort;
@@ -492,16 +493,138 @@ public class NiciraNvpResource implements ServerResource 
{
                
                for (StaticNatRuleTO rule : cmd.getRules()) {
                        // Find if a DestinationNat rule exists for this rule
-                       for (NatRule storedRule : existingRules.getResults()) {
+                       boolean found = false;
+                               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 (s_logger.isDebugEnabled()) {
+                                               StringBuilder natRuleStr = new 
StringBuilder();
+                                               natRuleStr.append("Rule ");
+                                               
natRuleStr.append(storedRule.getUuid());
+                                               natRuleStr.append(" (");
+                                               
natRuleStr.append(storedRule.getType());
+                                               natRuleStr.append(") :");
+                                               Match m = storedRule.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(storedRule.getType())) {
+                                                       
natRuleStr.append(storedRule.getToSourceIpAddressMin());
+                                                       natRuleStr.append("-");
+                                                       
natRuleStr.append(storedRule.getToSourceIpAddressMax());
+                                                       natRuleStr.append(" [");
+                                                       
natRuleStr.append(storedRule.getToSourcePortMin());
+                                                       natRuleStr.append("-");
+                                                       
natRuleStr.append(storedRule.getToSourcePortMax());
+                                                       natRuleStr.append(" 
])");
+                                               }
+                                               else {
+                                                       
natRuleStr.append(storedRule.getToDestinationIpAddressMin());
+                                                       natRuleStr.append("-");
+                                                       
natRuleStr.append(storedRule.getToDestinationIpAddressMax());
+                                                       natRuleStr.append(" [");
+                                                       
natRuleStr.append(storedRule.getToDestinationPort());
+                                                       natRuleStr.append(" 
])");
+                                               }
+                                               
s_logger.debug(natRuleStr.toString());
+                                       }
+                                       
                                if 
("SourceNatRule".equals(storedRule.getType())) {
+                                       if 
(outsideIp.equals(storedRule.getToSourceIpAddressMin()) && 
+                                                       
outsideIp.equals(storedRule.getToSourceIpAddressMax()) &&
+                                                       
storedRule.getToSourcePortMin() == null) {
+                                               // The outgoing rule exists
+                                               outgoing = storedRule;
+                                       }                                       
+                               }
+                               if 
("DestinationNatRule".equals(storedRule.getType()) &&
+                                               
storedRule.getToDestinationPort() != null) {
+                                       // Skip PortForwarding rules
                                        continue;
                                }
-                               String insideCidr = rule.getDstIp() + "/32";
-                               String outsideCidr = rule.getSrcIp() + "/32";
-                               //if 
(insideCidr.equals(storedRule.getMatch().getDestinationIpAddresses()))
+                               // Compare against Ip as it should be a /32 
cidr and the /32 is omitted
+                               if 
(outsideIp.equals(storedRule.getMatch().getDestinationIpAddresses())) {
+                                       // 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);
+                                               
_niciraNvpApi.modifyLogicalRouterNatRule(cmd.getLogicalRouterUuid(), outgoing);
+
+                                               s_logger.debug("Updating 
incoming rule " + outgoing.getUuid());
+                                               
incoming.setToSourceIpAddressMin(insideIp);
+                                               
incoming.setToSourceIpAddressMax(insideIp);
+                                               
_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);
+                                       DestinationNatRule newDnatRule = new 
DestinationNatRule();
+                                       newDnatRule.setMatch(m);
+                                       
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());
+
+                                       // create matching snat rule
+                                       m = new Match();
+                                       m.setSourceIpAddresses(insideIp + 
"/32");
+                                       SourceNatRule newSnatRule = new 
SourceNatRule();
+                                       newSnatRule.setMatch(m);
+                                       
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());
+                                       
+                               }
                }
-               //FIXME implement!
                return new ConfigureStaticNatRulesOnLogicalRouterAnswer(cmd, 
true, cmd.getRules().size() +" StaticNat rules applied");
         } catch (NiciraNvpApiException e) {
                if (numRetries > 0) {

Reply via email to