You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by al...@apache.org on 2012/06/21 02:21:41 UTC

[2/4] git commit: VPC: initial checkin for network ACLs

VPC: initial checkin for network ACLs

Conflicts:

	client/tomcatconf/commands.properties.in


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

Branch: refs/heads/vpc
Commit: 374a600746585a2b0fc30d7dc1245a0b6333aa9f
Parents: 7fda630
Author: Alena Prokharchyk <al...@citrix.com>
Authored: Wed Jun 20 12:48:00 2012 -0700
Committer: Alena Prokharchyk <al...@citrix.com>
Committed: Wed Jun 20 17:19:49 2012 -0700

----------------------------------------------------------------------
 .../agent/api/routing/SetNetworkACLAnswer.java     |   21 +
 .../agent/api/routing/SetNetworkACLCommand.java    |   35 ++
 .../routing/SetPortForwardingRulesVpcCommand.java  |   29 ++
 api/src/com/cloud/agent/api/to/NetworkACLTO.java   |  109 +++++
 api/src/com/cloud/api/BaseCmd.java                 |    4 +-
 api/src/com/cloud/api/ResponseGenerator.java       |    8 +
 .../cloud/api/commands/CreateFirewallRuleCmd.java  |    2 +-
 .../api/commands/CreateIpForwardingRuleCmd.java    |    2 +-
 .../cloud/api/commands/CreateNetworkACLCmd.java    |  314 +++++++++++++++
 .../api/commands/CreatePortForwardingRuleCmd.java  |    2 +-
 .../com/cloud/api/response/FirewallResponse.java   |   10 +-
 .../com/cloud/api/response/NetworkACLResponse.java |   84 ++++
 .../network/element/NetworkACLServiceProvider.java |   34 ++
 .../cloud/network/firewall/NetworkACLService.java  |   38 ++
 .../com/cloud/network/lb/LoadBalancingRule.java    |    2 +-
 api/src/com/cloud/network/rules/FirewallRule.java  |    8 +-
 api/src/com/cloud/network/rules/NetworkACL.java    |   26 ++
 api/src/com/cloud/network/rules/StaticNatRule.java |    2 +-
 client/tomcatconf/commands.properties.in           |    6 +-
 .../xen/resource/CitrixResourceBase.java           |   16 +
 server/src/com/cloud/api/ApiResponseHelper.java    |   35 ++
 .../configuration/DefaultComponentLibrary.java     |    2 +
 .../ExternalLoadBalancerDeviceManagerImpl.java     |    2 +-
 .../src/com/cloud/network/NetworkManagerImpl.java  |    9 +-
 .../com/cloud/network/dao/FirewallRulesDao.java    |    3 +
 .../cloud/network/dao/FirewallRulesDaoImpl.java    |   17 +
 .../network/element/VpcVirtualRouterElement.java   |   25 ++-
 .../network/firewall/FirewallManagerImpl.java      |   62 ++--
 .../network/firewall/NetworkACLManagerImpl.java    |  301 ++++++++++++++
 .../network/lb/LoadBalancingRulesManagerImpl.java  |    2 +-
 .../router/VirtualNetworkApplianceManagerImpl.java |   10 +-
 .../router/VpcVirtualNetworkApplianceManager.java  |   12 +
 .../VpcVirtualNetworkApplianceManagerImpl.java     |   54 +++
 .../com/cloud/network/rules/FirewallManager.java   |    8 +-
 .../com/cloud/network/rules/FirewallRuleVO.java    |   34 ++-
 .../cloud/network/rules/PortForwardingRuleVO.java  |    2 +-
 .../com/cloud/network/rules/RulesManagerImpl.java  |    8 +-
 .../com/cloud/network/rules/StaticNatRuleImpl.java |    2 +-
 setup/db/create-schema.sql                         |    5 +-
 39 files changed, 1274 insertions(+), 71 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java b/api/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java
new file mode 100644
index 0000000..b715a72
--- /dev/null
+++ b/api/src/com/cloud/agent/api/routing/SetNetworkACLAnswer.java
@@ -0,0 +1,21 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+package com.cloud.agent.api.routing;
+
+import com.cloud.agent.api.Answer;
+
+public class SetNetworkACLAnswer extends Answer {
+    String[] results;
+    
+    protected SetNetworkACLAnswer() {
+    }
+    
+    public SetNetworkACLAnswer(SetNetworkACLCommand cmd, boolean success, String[] results) {
+        super(cmd, success, null);
+        assert (cmd.getRules().length == results.length) : "ACLs and their results should be the same length";
+        this.results = results;
+    }
+    
+    public String[] getResults() {
+        return results;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java b/api/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java
new file mode 100644
index 0000000..f26e337
--- /dev/null
+++ b/api/src/com/cloud/agent/api/routing/SetNetworkACLCommand.java
@@ -0,0 +1,35 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License.  Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// 
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.agent.api.routing;
+
+import java.util.List;
+
+import com.cloud.agent.api.to.NetworkACLTO;
+
+/**
+ * @author Alena Prokharchyk
+ */
+public class SetNetworkACLCommand extends NetworkElementCommand{
+    NetworkACLTO[] rules;
+
+    protected SetNetworkACLCommand() {
+    }
+    
+    public SetNetworkACLCommand(List<NetworkACLTO> rules) {
+        this.rules = rules.toArray(new NetworkACLTO[rules.size()]); 
+    }
+    
+    public NetworkACLTO[] getRules() {
+        return rules;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java b/api/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java
new file mode 100644
index 0000000..e6e91f5
--- /dev/null
+++ b/api/src/com/cloud/agent/api/routing/SetPortForwardingRulesVpcCommand.java
@@ -0,0 +1,29 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License.  Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// 
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.agent.api.routing;
+
+import java.util.List;
+
+import com.cloud.agent.api.to.PortForwardingRuleTO;
+
+/**
+ * @author Alena Prokharchyk
+ */
+public class SetPortForwardingRulesVpcCommand extends SetPortForwardingRulesCommand{
+    protected SetPortForwardingRulesVpcCommand() {
+    }
+    
+    public SetPortForwardingRulesVpcCommand(List<? extends PortForwardingRuleTO> pfRules) {
+        super(pfRules);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/agent/api/to/NetworkACLTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/NetworkACLTO.java b/api/src/com/cloud/agent/api/to/NetworkACLTO.java
new file mode 100644
index 0000000..2f72563
--- /dev/null
+++ b/api/src/com/cloud/agent/api/to/NetworkACLTO.java
@@ -0,0 +1,109 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+package com.cloud.agent.api.to;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.TrafficType;
+import com.cloud.utils.net.NetUtils;
+
+
+public class NetworkACLTO {
+    long id;
+    String vlanTag;
+    String protocol;
+    int[] portRange;
+    boolean revoked;
+    boolean alreadyAdded;
+    private List<String> cidrList;
+    private Integer icmpType;
+    private Integer icmpCode;
+    private FirewallRule.TrafficType trafficType;
+    
+
+    protected NetworkACLTO() {
+    }
+    
+
+    public NetworkACLTO(long id,String vlanTag, String protocol, Integer portStart, Integer portEnd, boolean revoked,
+            boolean alreadyAdded, List<String> cidrList, Integer icmpType,Integer icmpCode,TrafficType trafficType) {
+        this.vlanTag = vlanTag;
+        this.protocol = protocol;
+        
+        if (portStart != null) {
+            List<Integer> range = new ArrayList<Integer>();
+            range.add(portStart);
+            if (portEnd != null) {
+                range.add(portEnd);
+            }
+            
+            portRange = new int[range.size()];
+            int i = 0;
+            for (Integer port : range) {
+                portRange[i] = port.intValue();
+                i ++;
+            }   
+        } 
+        
+        this.revoked = revoked;
+        this.alreadyAdded = alreadyAdded;
+        this.cidrList = cidrList;
+        this.icmpType = icmpType;
+        this.icmpCode = icmpCode;
+        this.trafficType = trafficType;
+    }
+
+    public NetworkACLTO(FirewallRule rule, String vlanTag, FirewallRule.TrafficType  trafficType ) {
+        this(rule.getId(), vlanTag, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), 
+                rule.getState() == FirewallRule.State.Revoke, rule.getState() == FirewallRule.State.Active,
+                rule.getSourceCidrList() ,rule.getIcmpType(), rule.getIcmpCode(),trafficType);
+    }
+    
+    public long getId() {
+        return id;
+    }
+
+    public String getSrcVlanTag() {
+    	return vlanTag;
+    }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public int[] getSrcPortRange() {
+        return portRange;
+    }
+    
+    public Integer getIcmpType(){
+    	return icmpType;
+    }
+    
+    public Integer getIcmpCode(){
+    	return icmpCode;  
+    }
+    
+    public String getStringPortRange() {
+    	if (portRange == null || portRange.length < 2)
+    		return "0:0";
+    	else
+    		return NetUtils.portRangeToString(portRange);
+    }
+
+    public boolean revoked() {
+        return revoked;
+    }
+    
+    public List<String> getSourceCidrList() {
+        return cidrList;
+    }
+    
+    public boolean isAlreadyAdded() {
+        return alreadyAdded;
+    }
+
+    public FirewallRule.TrafficType getTrafficType() {
+        return trafficType;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/api/BaseCmd.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/BaseCmd.java b/api/src/com/cloud/api/BaseCmd.java
index 623cdec..294e264 100755
--- a/api/src/com/cloud/api/BaseCmd.java
+++ b/api/src/com/cloud/api/BaseCmd.java
@@ -41,6 +41,7 @@ import com.cloud.network.NetworkService;
 import com.cloud.network.StorageNetworkService;
 import com.cloud.network.VirtualNetworkApplianceService;
 import com.cloud.network.firewall.FirewallService;
+import com.cloud.network.firewall.NetworkACLService;
 import com.cloud.network.lb.LoadBalancingRulesService;
 import com.cloud.network.rules.RulesService;
 import com.cloud.network.security.SecurityGroupService;
@@ -59,7 +60,6 @@ import com.cloud.user.DomainService;
 import com.cloud.user.ResourceLimitService;
 import com.cloud.utils.Pair;
 import com.cloud.utils.component.ComponentLocator;
-import com.cloud.utils.AnnotationHelper;
 import com.cloud.vm.BareMetalVmService;
 import com.cloud.vm.UserVmService;
 
@@ -130,6 +130,7 @@ public abstract class BaseCmd {
     public static IdentityService _identityService;
     public static StorageNetworkService _storageNetworkService;
     public static VpcService _vpcService;
+    public static NetworkACLService _networkACLService;
 
     static void setComponents(ResponseGenerator generator) {
         ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name);
@@ -158,6 +159,7 @@ public abstract class BaseCmd {
         _identityService = locator.getManager(IdentityService.class);
         _storageNetworkService = locator.getManager(StorageNetworkService.class);
         _vpcService = locator.getManager(VpcService.class);
+        _networkACLService = locator.getManager(NetworkACLService.class);
     }
 
     public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException, NetworkRuleConflictException;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/api/ResponseGenerator.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/ResponseGenerator.java b/api/src/com/cloud/api/ResponseGenerator.java
index 5886021..201883d 100755
--- a/api/src/com/cloud/api/ResponseGenerator.java
+++ b/api/src/com/cloud/api/ResponseGenerator.java
@@ -23,6 +23,7 @@ import java.util.List;
 import com.cloud.api.ApiConstants.HostDetails;
 import com.cloud.api.ApiConstants.VMDetails;
 import com.cloud.api.commands.QueryAsyncJobResultCmd;
+import com.cloud.api.response.NetworkACLResponse;
 import com.cloud.api.response.AccountResponse;
 import com.cloud.api.response.AsyncJobResponse;
 import com.cloud.api.response.CapacityResponse;
@@ -103,6 +104,7 @@ import com.cloud.network.VpnUser;
 import com.cloud.network.router.VirtualRouter;
 import com.cloud.network.rules.FirewallRule;
 import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.rules.NetworkACL;
 import com.cloud.network.rules.PortForwardingRule;
 import com.cloud.network.rules.StaticNatRule;
 import com.cloud.network.rules.StickinessPolicy;
@@ -296,4 +298,10 @@ public interface ResponseGenerator {
      * @return
      */
     VpcResponse createVpcResponse(Vpc vpc);
+
+    /**
+     * @param networkACL
+     * @return
+     */
+    NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL);
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java b/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java
index 800dac8..77caf19 100644
--- a/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java
+++ b/api/src/com/cloud/api/commands/CreateFirewallRuleCmd.java
@@ -159,7 +159,7 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal
     }
 
     @Override
-    public long getSourceIpAddressId() {
+    public Long getSourceIpAddressId() {
         return ipAddressId;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java b/api/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java
index 53bd87d..ba2992b 100644
--- a/api/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java
+++ b/api/src/com/cloud/api/commands/CreateIpForwardingRuleCmd.java
@@ -199,7 +199,7 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
     }
 
     @Override
-    public long getSourceIpAddressId() {
+    public Long getSourceIpAddressId() {
         return ipAddressId;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/api/commands/CreateNetworkACLCmd.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/commands/CreateNetworkACLCmd.java b/api/src/com/cloud/api/commands/CreateNetworkACLCmd.java
new file mode 100644
index 0000000..ccc092b
--- /dev/null
+++ b/api/src/com/cloud/api/commands/CreateNetworkACLCmd.java
@@ -0,0 +1,314 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+package com.cloud.api.commands;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.api.ApiConstants;
+import com.cloud.api.BaseAsyncCmd;
+import com.cloud.api.BaseAsyncCreateCmd;
+import com.cloud.api.BaseCmd;
+import com.cloud.api.IdentityMapper;
+import com.cloud.api.Implementation;
+import com.cloud.api.Parameter;
+import com.cloud.api.ServerApiException;
+import com.cloud.api.response.NetworkACLResponse;
+import com.cloud.async.AsyncJob;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.NetworkACL;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.user.Account;
+import com.cloud.user.UserContext;
+import com.cloud.utils.net.NetUtils;
+
+@Implementation(description = "Creates a ACL rule the given network (the network has to belong to VPC)", 
+responseObject = NetworkACLResponse.class)
+public class CreateNetworkACLCmd extends BaseAsyncCreateCmd implements NetworkACL {
+    public static final Logger s_logger = Logger.getLogger(CreateFirewallRuleCmd.class.getName());
+
+    private static final String s_name = "createnetworkaclresponse";
+
+    // ///////////////////////////////////////////////////
+    // ////////////// API parameters /////////////////////
+    // ///////////////////////////////////////////////////
+
+    @Parameter(name = ApiConstants.PROTOCOL, type = CommandType.STRING, required = true, description = 
+            "the protocol for the ACL rule. Valid values are TCP/UDP/ICMP.")
+    private String protocol;
+
+    @Parameter(name = ApiConstants.START_PORT, type = CommandType.INTEGER, required=true, description = "the starting port of ACL")
+    private Integer publicStartPort;
+
+    @Parameter(name = ApiConstants.END_PORT, type = CommandType.INTEGER, description = "the ending port of ACL")
+    private Integer publicEndPort;
+    
+    @Parameter(name = ApiConstants.CIDR_LIST, type = CommandType.LIST, collectionType = CommandType.STRING, 
+            description = "the cidr list to allow traffic from/to")
+    private List<String> cidrlist;
+    
+    @Parameter(name = ApiConstants.ICMP_TYPE, type = CommandType.INTEGER, description = "type of the icmp message being sent")
+    private Integer icmpType;
+
+    @Parameter(name = ApiConstants.ICMP_CODE, type = CommandType.INTEGER, description = "error code for this icmp message")
+    private Integer icmpCode;
+    
+    @IdentityMapper(entityTableName="networks")
+    @Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, required=true,
+        description="The network of the vm the ACL will be created for")
+    private Long networkId;
+    
+    @Parameter(name=ApiConstants.TRAFFIC_TYPE, type=CommandType.LONG, description="the traffic type for the ACL," +
+    		"can be Ingress or Egress, defaulted to Ingress if not specified")
+    private String trafficType;
+    
+    // ///////////////////////////////////////////////////
+    // ///////////////// Accessors ///////////////////////
+    // ///////////////////////////////////////////////////
+    
+    public String getEntityTable() {
+        return "firewall_rules";
+    }
+
+    public Long getIpAddressId() {
+        return null;
+    }
+
+    @Override
+    public String getProtocol() {
+        return protocol.trim();
+    }
+
+    public List<String> getSourceCidrList() {
+        if (cidrlist != null) {
+            return cidrlist;
+        } else {
+            List<String> oneCidrList = new ArrayList<String>();
+            oneCidrList.add(NetUtils.ALL_CIDRS);
+            return oneCidrList;
+        }
+    }
+    
+    public long getVpcId() {
+        Network network = _networkService.getNetwork(getNetworkId());
+        if (network == null) {
+            throw new InvalidParameterValueException("Invalid networkId is given");
+        }
+        
+        Long vpcId = network.getVpcId();
+        if (vpcId == null) {
+            throw new InvalidParameterValueException("Can create network ACL only for the network belonging to the VPC");
+        }
+        
+        return vpcId;
+    }
+    
+    @Override
+    public FirewallRule.TrafficType getTrafficType() {
+        if (trafficType == null) {
+            return FirewallRule.TrafficType.Ingress;
+        }
+        for (FirewallRule.TrafficType type : FirewallRule.TrafficType.values()) {
+            if (type.toString().equalsIgnoreCase(trafficType)) {
+                return type;
+            }
+        }
+        throw new InvalidParameterValueException("Invalid traffic type " + trafficType);
+    }
+
+    // ///////////////////////////////////////////////////
+    // ///////////// API Implementation///////////////////
+    // ///////////////////////////////////////////////////
+
+    @Override
+    public String getCommandName() {
+        return s_name;
+    }
+    
+    public void setSourceCidrList(List<String> cidrs){
+        cidrlist = cidrs;
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException {
+        UserContext callerContext = UserContext.current();
+        boolean success = false;
+        NetworkACL rule = _networkACLService.getNetworkACL(getEntityId());
+        try {
+            UserContext.current().setEventDetails("Rule Id: " + getEntityId());
+            success = _networkACLService.applyNetworkACLs(rule.getNetworkId(), callerContext.getCaller());
+
+            // State is different after the rule is applied, so get new object here
+            NetworkACLResponse aclResponse = new NetworkACLResponse(); 
+            if (rule != null) {
+                aclResponse = _responseGenerator.createNetworkACLResponse(rule);
+                setResponseObject(aclResponse);
+            }
+            aclResponse.setResponseName(getCommandName());
+        } finally {
+            if (!success || rule == null) {
+                _networkACLService.revokeNetworkACL(getEntityId(), true);
+                throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to create network ACL");
+            }
+        }
+    }
+
+    @Override
+    public long getId() {
+        throw new UnsupportedOperationException("database id can only provided by VO objects");
+    }
+
+    @Override
+    public String getXid() {
+        // FIXME: We should allow for end user to specify Xid.
+        return null;
+    }
+
+    @Override
+    public Long getSourceIpAddressId() {
+        return null;
+    }
+
+    @Override
+    public Integer getSourcePortStart() {
+        if (publicStartPort != null) {
+            return publicStartPort.intValue();
+        }
+        return null;
+    }
+
+    @Override
+    public Integer getSourcePortEnd() {
+        if (publicEndPort == null) {
+            if (publicStartPort != null) {
+                return publicStartPort.intValue();
+            }
+        } else {
+            return publicEndPort.intValue();
+        }
+        
+        return null;
+    }
+
+    @Override
+    public Purpose getPurpose() {
+        return Purpose.Firewall;
+    }
+
+    @Override
+    public State getState() {
+        throw new UnsupportedOperationException("Should never call me to find the state");
+    }
+
+    @Override
+    public long getNetworkId() {
+        return networkId;
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        Vpc vpc = _vpcService.getVpc(getVpcId());
+        if (vpc == null) {
+            throw new InvalidParameterValueException("Invalid vpcId is given");
+        }
+
+        Account account = _accountService.getAccount(vpc.getAccountId());
+        return account.getId();
+    }
+
+    @Override
+    public long getDomainId() {
+        Vpc vpc = _vpcService.getVpc(getVpcId());
+        return vpc.getDomainId();
+    }
+
+    @Override
+    public void create() {
+        if (getSourceCidrList() != null) {
+            for (String cidr: getSourceCidrList()){
+                if (!NetUtils.isValidCIDR(cidr)){
+                    throw new ServerApiException(BaseCmd.PARAM_ERROR, "Source cidrs formatting error " + cidr); 
+                }
+            }
+        }
+
+        try {
+            NetworkACL result = _networkACLService.createNetworkACL(this);
+            setEntityId(result.getId());
+        } catch (NetworkRuleConflictException ex) {
+            s_logger.info("Network rule conflict: " + ex.getMessage());
+            s_logger.trace("Network Rule Conflict: ", ex);
+            throw new ServerApiException(BaseCmd.NETWORK_RULE_CONFLICT_ERROR, ex.getMessage());
+        }
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_FIREWALL_OPEN;
+    }
+
+    @Override
+    public String getEventDescription() {
+        Network network = _networkService.getNetwork(networkId);
+        return ("Createing Network ACL for Netowrk: " + network + " for protocol:" + this.getProtocol());
+    }
+
+    @Override
+    public long getAccountId() {
+        Vpc vpc = _vpcService.getVpc(getVpcId());
+        return vpc.getAccountId();
+    }
+
+    @Override
+    public String getSyncObjType() {
+        return BaseAsyncCmd.networkSyncObject;
+    }
+
+    @Override
+    public Long getSyncObjId() {
+        return getNetworkId();
+    }
+    
+    @Override
+    public Integer getIcmpCode() {
+        if (icmpCode != null) {
+            return icmpCode;
+        } else if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
+            return -1;
+        }
+        return null;
+    }
+    
+    @Override
+    public Integer getIcmpType() {
+        if (icmpType != null) {
+            return icmpType;
+        } else if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
+                return -1;
+            
+        }
+        return null;
+    }
+
+    @Override
+    public Long getRelated() {
+        return null;
+    }
+
+    @Override
+    public FirewallRuleType getType() {
+        return FirewallRuleType.User;
+    }
+    
+    @Override
+    public AsyncJob.Type getInstanceType() {
+        return AsyncJob.Type.FirewallRule;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java
index b17b6e1..20132a6 100644
--- a/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java
+++ b/api/src/com/cloud/api/commands/CreatePortForwardingRuleCmd.java
@@ -181,7 +181,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
     }
 
     @Override
-    public long getSourceIpAddressId() {
+    public Long getSourceIpAddressId() {
         return ipAddressId;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/api/response/FirewallResponse.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/response/FirewallResponse.java b/api/src/com/cloud/api/response/FirewallResponse.java
index 0aa5989..a6fd597 100644
--- a/api/src/com/cloud/api/response/FirewallResponse.java
+++ b/api/src/com/cloud/api/response/FirewallResponse.java
@@ -17,10 +17,11 @@
 package com.cloud.api.response;
 
 import com.cloud.api.ApiConstants;
-import com.cloud.utils.IdentityProxy;
 import com.cloud.serializer.Param;
+import com.cloud.utils.IdentityProxy;
 import com.google.gson.annotations.SerializedName;
 
+@SuppressWarnings("unused")
 public class FirewallResponse extends BaseResponse {
     @SerializedName(ApiConstants.ID) @Param(description="the ID of the firewall rule")
     private IdentityProxy id = new IdentityProxy("firewall_rules");
@@ -34,10 +35,10 @@ public class FirewallResponse extends BaseResponse {
     @SerializedName(ApiConstants.END_PORT)  @Param(description = "the ending port of firewall rule's port range")
     private String endPort;
     
-    @SerializedName(ApiConstants.IP_ADDRESS_ID) @Param(description="the public ip address id for the port forwarding rule")
+    @SerializedName(ApiConstants.IP_ADDRESS_ID) @Param(description="the public ip address id for the firewall rule")
     private Long publicIpAddressId;
 
-    @SerializedName(ApiConstants.IP_ADDRESS) @Param(description="the public ip address for the port forwarding rule")
+    @SerializedName(ApiConstants.IP_ADDRESS) @Param(description="the public ip address for the firewall rule")
     private String publicIpAddress;
     
     @SerializedName(ApiConstants.STATE) @Param(description="the state of the rule")
@@ -91,7 +92,4 @@ public class FirewallResponse extends BaseResponse {
     public void setIcmpCode(Integer icmpCode) {
         this.icmpCode = icmpCode;
     }
-
- 
-    
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/api/response/NetworkACLResponse.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/api/response/NetworkACLResponse.java b/api/src/com/cloud/api/response/NetworkACLResponse.java
new file mode 100644
index 0000000..1338d89
--- /dev/null
+++ b/api/src/com/cloud/api/response/NetworkACLResponse.java
@@ -0,0 +1,84 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License.  Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// 
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.api.response;
+
+import com.cloud.api.ApiConstants;
+import com.cloud.serializer.Param;
+import com.cloud.utils.IdentityProxy;
+import com.google.gson.annotations.SerializedName;
+
+@SuppressWarnings("unused")
+public class NetworkACLResponse extends BaseResponse {
+    @SerializedName(ApiConstants.ID) @Param(description="the ID of the ACL")
+    private IdentityProxy id = new IdentityProxy("firewall_rules");
+
+    @SerializedName(ApiConstants.PROTOCOL) @Param(description="the protocol of the ACL")
+    private String protocol;
+
+    @SerializedName(ApiConstants.START_PORT) @Param(description="the starting port of ACL's port range")
+    private String startPort;
+
+    @SerializedName(ApiConstants.END_PORT)  @Param(description = "the ending port of ACL's port range")
+    private String endPort;
+
+    @SerializedName(ApiConstants.TRAFFIC_TYPE) @Param(description="the traffic type for the ACL")
+    private String trafficType;
+    
+    @SerializedName(ApiConstants.STATE) @Param(description="the state of the rule")
+    private String state;
+
+    @SerializedName(ApiConstants.CIDR_LIST) @Param(description="the cidr list to forward traffic from")
+    private String cidrList;
+    
+    @SerializedName(ApiConstants.ICMP_TYPE) @Param(description= "type of the icmp message being sent")
+    private Integer icmpType;
+
+    @SerializedName(ApiConstants.ICMP_CODE) @Param(description = "error code for this icmp message")
+    private Integer icmpCode;
+
+    public void setId(Long id) {
+        this.id.setValue(id);
+    }
+
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    public void setStartPort(String startPort) {
+        this.startPort = startPort;
+    }
+
+    public void setEndPort(String endPort) {
+        this.endPort = endPort;
+    }
+
+    public void setState(String state) {
+        this.state = state;
+    }
+
+    public void setCidrList(String cidrList) {
+        this.cidrList = cidrList;
+    }
+
+    public void setIcmpType(Integer icmpType) {
+        this.icmpType = icmpType;
+    }
+
+    public void setIcmpCode(Integer icmpCode) {
+        this.icmpCode = icmpCode;
+    }
+
+    public void setTrafficType(String trafficType) {
+        this.trafficType = trafficType;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/network/element/NetworkACLServiceProvider.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/element/NetworkACLServiceProvider.java b/api/src/com/cloud/network/element/NetworkACLServiceProvider.java
new file mode 100644
index 0000000..92c4bb4
--- /dev/null
+++ b/api/src/com/cloud/network/element/NetworkACLServiceProvider.java
@@ -0,0 +1,34 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License.  Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// 
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.network.element;
+
+import java.util.List;
+
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.rules.FirewallRule;
+
+/**
+ * @author Alena Prokharchyk
+ */
+public interface NetworkACLServiceProvider extends NetworkElement{
+
+    /**
+     * @param config
+     * @param rules
+     * @return
+     * @throws ResourceUnavailableException
+     */
+    boolean applyNetworkACLs(Network config, List<? extends FirewallRule> rules) throws ResourceUnavailableException;
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/network/firewall/NetworkACLService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/firewall/NetworkACLService.java b/api/src/com/cloud/network/firewall/NetworkACLService.java
new file mode 100644
index 0000000..19b3331
--- /dev/null
+++ b/api/src/com/cloud/network/firewall/NetworkACLService.java
@@ -0,0 +1,38 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License.  Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// 
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.network.firewall;
+
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.rules.NetworkACL;
+import com.cloud.user.Account;
+
+/**
+ * @author Alena Prokharchyk
+ */
+public interface NetworkACLService {
+    NetworkACL getNetworkACL(long ruleId);
+    boolean applyNetworkACLs(long networkId, Account caller) throws ResourceUnavailableException;
+    
+    /**
+     * @param createNetworkACLCmd
+     * @return
+     */
+    NetworkACL createNetworkACL(NetworkACL acl) throws NetworkRuleConflictException;
+    /**
+     * @param ruleId
+     * @param apply
+     * @return
+     */
+    boolean revokeNetworkACL(long ruleId, boolean apply);
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/network/lb/LoadBalancingRule.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/lb/LoadBalancingRule.java b/api/src/com/cloud/network/lb/LoadBalancingRule.java
index c79ab18..d49d0e9 100644
--- a/api/src/com/cloud/network/lb/LoadBalancingRule.java
+++ b/api/src/com/cloud/network/lb/LoadBalancingRule.java
@@ -78,7 +78,7 @@ public class LoadBalancingRule implements FirewallRule, LoadBalancer{
     }
     
     @Override
-    public long getSourceIpAddressId() {
+    public Long getSourceIpAddressId() {
         return lb.getSourceIpAddressId();
     }
     

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/network/rules/FirewallRule.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/rules/FirewallRule.java b/api/src/com/cloud/network/rules/FirewallRule.java
index 7c8fa66..cb79e5e 100644
--- a/api/src/com/cloud/network/rules/FirewallRule.java
+++ b/api/src/com/cloud/network/rules/FirewallRule.java
@@ -27,6 +27,7 @@ public interface FirewallRule extends ControlledEntity {
         LoadBalancing,
         Vpn,
         StaticNat,
+        NetworkACL,
     }
     
     enum FirewallRuleType {
@@ -41,6 +42,11 @@ public interface FirewallRule extends ControlledEntity {
         Revoke  // Revoke means this rule has been revoked. If this rule has been sent to the network elements, the rule will be deleted from database.
     }
     
+    enum TrafficType {
+        Ingress,
+        Egress
+    }
+    
     /**
      * @return database id.
      */
@@ -72,7 +78,7 @@ public interface FirewallRule extends ControlledEntity {
     
     long getNetworkId();
     
-    long getSourceIpAddressId();
+    Long getSourceIpAddressId();
 
     Integer getIcmpCode();
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/network/rules/NetworkACL.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/rules/NetworkACL.java b/api/src/com/cloud/network/rules/NetworkACL.java
new file mode 100644
index 0000000..d0f7f21
--- /dev/null
+++ b/api/src/com/cloud/network/rules/NetworkACL.java
@@ -0,0 +1,26 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License.  Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// 
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.network.rules;
+
+
+/**
+ * @author Alena Prokharchyk
+ */
+public interface NetworkACL extends FirewallRule{
+
+    /**
+     * @return
+     */
+    TrafficType getTrafficType();
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/api/src/com/cloud/network/rules/StaticNatRule.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/rules/StaticNatRule.java b/api/src/com/cloud/network/rules/StaticNatRule.java
index 0cc67d6..601cd6a 100644
--- a/api/src/com/cloud/network/rules/StaticNatRule.java
+++ b/api/src/com/cloud/network/rules/StaticNatRule.java
@@ -40,7 +40,7 @@ public interface StaticNatRule extends ControlledEntity, FirewallRule {
 
     long getNetworkId();
 
-    long getSourceIpAddressId();
+    Long getSourceIpAddressId();
 
     String getDestIpAddress();
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index b0154f2..d36329d 100755
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -358,4 +358,8 @@ listVPCOfferings=com.cloud.api.commands.ListVPCOfferingsCmd;15
 
 #### Private network command
 createPrivateNetwork=com.cloud.api.commands.CreatePrivateNetworkCmd;1
-
+
+#### 
+createNetworkACL=com.cloud.api.commands.CreateNetworkACLCmd;15
+#deleteNetworkACL=com.cloud.api.commands.DeleteNetworkACLCmd;15
+#listNetworkACLs=com.cloud.api.commands.ListNetworkACLsCmd;15

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index 2c8666d..7153dc4 100644
--- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -148,8 +148,11 @@ import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
 import com.cloud.agent.api.routing.SavePasswordCommand;
 import com.cloud.agent.api.routing.SetFirewallRulesAnswer;
 import com.cloud.agent.api.routing.SetFirewallRulesCommand;
+import com.cloud.agent.api.routing.SetNetworkACLAnswer;
+import com.cloud.agent.api.routing.SetNetworkACLCommand;
 import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer;
 import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand;
 import com.cloud.agent.api.routing.SetSourceNatCommand;
 import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
 import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
@@ -535,11 +538,16 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             return execute((IpAssocVpcCommand) cmd);
         } else if (clazz == SetSourceNatCommand.class) {
             return execute((SetSourceNatCommand) cmd);
+        } else if (clazz == SetNetworkACLCommand.class) {
+            return execute((SetNetworkACLCommand) cmd);
+        } else if (clazz == SetPortForwardingRulesVpcCommand.class) {
+            return execute((SetPortForwardingRulesVpcCommand) cmd);
         } else {
             return Answer.createUnsupportedCommandAnswer(cmd);
         }
     }
 
+
     protected XsLocalNetwork getNativeNetworkForTraffic(Connection conn, TrafficType type, String name) throws XenAPIException, XmlRpcException {
         if (name != null) {
             if (s_logger.isDebugEnabled()) {
@@ -7108,5 +7116,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         return null;
     }
 
+    private SetNetworkACLAnswer execute(SetNetworkACLCommand cmd) {
+        // TODO - add implementation logic here
+        return null;
+    }
 
+    protected SetPortForwardingRulesAnswer execute(SetPortForwardingRulesVpcCommand cmd) {
+       //TODO - add implementation
+        return null;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/server/src/com/cloud/api/ApiResponseHelper.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java
index 634f5d1..f39a8b2 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -32,6 +32,7 @@ import com.cloud.acl.ControlledEntity.ACLType;
 import com.cloud.api.ApiConstants.HostDetails;
 import com.cloud.api.ApiConstants.VMDetails;
 import com.cloud.api.commands.QueryAsyncJobResultCmd;
+import com.cloud.api.response.NetworkACLResponse;
 import com.cloud.api.response.AccountResponse;
 import com.cloud.api.response.ApiResponseSerializer;
 import com.cloud.api.response.AsyncJobResponse;
@@ -137,6 +138,7 @@ import com.cloud.network.VpnUser;
 import com.cloud.network.router.VirtualRouter;
 import com.cloud.network.rules.FirewallRule;
 import com.cloud.network.rules.LoadBalancer;
+import com.cloud.network.rules.NetworkACL;
 import com.cloud.network.rules.PortForwardingRule;
 import com.cloud.network.rules.StaticNatRule;
 import com.cloud.network.rules.StickinessPolicy;
@@ -2959,6 +2961,39 @@ public class ApiResponseHelper implements ResponseGenerator {
         response.setObjectName("firewallrule");
         return response;
     }
+    
+    @Override
+    public NetworkACLResponse createNetworkACLResponse(NetworkACL networkACL) {
+        NetworkACLResponse response = new NetworkACLResponse();
+
+        response.setId(networkACL.getId());
+        response.setProtocol(networkACL.getProtocol());
+        if (networkACL.getSourcePortStart() != null) {
+            response.setStartPort(Integer.toString(networkACL.getSourcePortStart()));
+        }
+
+        if (networkACL.getSourcePortEnd() != null) {
+            response.setEndPort(Integer.toString(networkACL.getSourcePortEnd()));
+        }
+
+        List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(networkACL.getId());
+        response.setCidrList(StringUtils.join(cidrs, ","));
+
+        response.setTrafficType(networkACL.getTrafficType().toString());
+
+        FirewallRule.State state = networkACL.getState();
+        String stateToSet = state.toString();
+        if (state.equals(FirewallRule.State.Revoke)) {
+            stateToSet = "Deleting";
+        }
+
+        response.setIcmpCode(networkACL.getIcmpCode());
+        response.setIcmpType(networkACL.getIcmpType());
+
+        response.setState(stateToSet);
+        response.setObjectName("networkacl");
+        return response;
+    }
 
     public UserVmData newUserVmData(UserVm userVm) {
         UserVmData userVmData = new UserVmData();

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/server/src/com/cloud/configuration/DefaultComponentLibrary.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java
index 4841a25..cf0e61a 100755
--- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java
+++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java
@@ -106,6 +106,7 @@ import com.cloud.network.element.NetscalerLoadBalancerElementService;
 import com.cloud.network.element.VirtualRouterElement;
 import com.cloud.network.element.VirtualRouterElementService;
 import com.cloud.network.firewall.FirewallManagerImpl;
+import com.cloud.network.firewall.NetworkACLManagerImpl;
 import com.cloud.network.lb.ElasticLoadBalancerManagerImpl;
 import com.cloud.network.lb.LoadBalancingRulesManagerImpl;
 import com.cloud.network.lb.dao.ElasticLbVmMapDaoImpl;
@@ -397,6 +398,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
         addManager("HA Manager", HighAvailabilityManagerImpl.class);
         addManager("VPC Manager", VpcManagerImpl.class);
         addManager("VpcVirtualRouterManager", VpcVirtualNetworkApplianceManagerImpl.class);
+        addManager("NetworkACLManager", NetworkACLManagerImpl.class);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
index 1acba8b..c91f4ca 100644
--- a/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
+++ b/server/src/com/cloud/network/ExternalLoadBalancerDeviceManagerImpl.java
@@ -732,7 +732,7 @@ public abstract class ExternalLoadBalancerDeviceManagerImpl extends AdapterBase
         List<StaticNatRuleTO> staticNatRules = new ArrayList<StaticNatRuleTO>();
         IPAddressVO ipVO = _ipAddressDao.listByDcIdIpAddress(zone.getId(), publicIp).get(0);
         VlanVO vlan = _vlanDao.findById(ipVO.getVlanId());
-        FirewallRuleVO fwRule = new FirewallRuleVO(null, ipVO.getId(), -1, -1, "any", network.getId(), network.getAccountId(), network.getDomainId(), Purpose.StaticNat, null, null, null, null);
+        FirewallRuleVO fwRule = new FirewallRuleVO(null, ipVO.getId(), -1, -1, "any", network.getId(), network.getAccountId(), network.getDomainId(), Purpose.StaticNat, null, null, null, null, null);
         FirewallRule.State state = !revoked ? FirewallRule.State.Add : FirewallRule.State.Revoke;
         fwRule.setState(state);
         StaticNatRule rule = new StaticNatRuleImpl(fwRule, privateIp);

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java
index 09bbf22..c891a3e 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -125,6 +125,7 @@ import com.cloud.network.element.DhcpServiceProvider;
 import com.cloud.network.element.FirewallServiceProvider;
 import com.cloud.network.element.IpDeployer;
 import com.cloud.network.element.LoadBalancingServiceProvider;
+import com.cloud.network.element.NetworkACLServiceProvider;
 import com.cloud.network.element.NetworkElement;
 import com.cloud.network.element.PortForwardingServiceProvider;
 import com.cloud.network.element.RemoteAccessVPNServiceProvider;
@@ -172,7 +173,6 @@ import com.cloud.user.User;
 import com.cloud.user.UserContext;
 import com.cloud.user.dao.AccountDao;
 import com.cloud.user.dao.UserStatisticsDao;
-import com.cloud.utils.AnnotationHelper;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.Pair;
 import com.cloud.utils.component.Adapters;
@@ -3679,6 +3679,13 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
                     }
                     handled = ((FirewallServiceProvider) ne).applyFWRules(network, rules);
                     break;
+                case NetworkACL:
+                    boolean isNetworkACLProvider = isProviderSupportServiceInNetwork(network.getId(), Service.Firewall, provider);
+                    if (!(ne instanceof NetworkACLServiceProvider && isNetworkACLProvider)) {
+                        continue;
+                    }
+                    handled = ((NetworkACLServiceProvider) ne).applyNetworkACLs(network, rules);
+                    break;
                 default:
                     s_logger.debug("Unable to handle network rules for purpose: " + purpose.toString());
                     handled = false;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/server/src/com/cloud/network/dao/FirewallRulesDao.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/dao/FirewallRulesDao.java b/server/src/com/cloud/network/dao/FirewallRulesDao.java
index dc9ab00..48aec35 100644
--- a/server/src/com/cloud/network/dao/FirewallRulesDao.java
+++ b/server/src/com/cloud/network/dao/FirewallRulesDao.java
@@ -50,5 +50,8 @@ public interface FirewallRulesDao extends GenericDao<FirewallRuleVO, Long> {
     List<FirewallRuleVO> listByIpAndNotRevoked(long ipAddressId);
 
     long countRulesByIpId(long sourceIpId);
+    
+    List<FirewallRuleVO> listByNetworkPurposeTrafficTypeAndNotRevoked(long networkId, FirewallRule.Purpose purpose, FirewallRule.TrafficType trafficType);
+
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java
index 66cf887..5423ad9 100644
--- a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java
+++ b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java
@@ -21,6 +21,7 @@ import com.cloud.network.rules.FirewallRule;
 import com.cloud.network.rules.FirewallRule.FirewallRuleType;
 import com.cloud.network.rules.FirewallRule.Purpose;
 import com.cloud.network.rules.FirewallRule.State;
+import com.cloud.network.rules.FirewallRule.TrafficType;
 import com.cloud.network.rules.FirewallRuleVO;
 import com.cloud.utils.component.ComponentLocator;
 import com.cloud.utils.db.DB;
@@ -69,6 +70,7 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
         NotRevokedSearch.and("sourcePortStart", NotRevokedSearch.entity().getSourcePortStart(), Op.EQ);
         NotRevokedSearch.and("sourcePortEnd", NotRevokedSearch.entity().getSourcePortEnd(), Op.EQ);
         NotRevokedSearch.and("networkId", NotRevokedSearch.entity().getNetworkId(), Op.EQ);
+        NotRevokedSearch.and("trafficType", NotRevokedSearch.entity().getTrafficType(), Op.EQ);
         NotRevokedSearch.done();
 
         ReleaseSearch = createSearchBuilder();
@@ -265,4 +267,19 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
         return customSearch(sc, null).get(0);
     }
 
+    @Override
+    public List<FirewallRuleVO> listByNetworkPurposeTrafficTypeAndNotRevoked(long networkId, Purpose purpose, TrafficType trafficType) {
+        SearchCriteria<FirewallRuleVO> sc = NotRevokedSearch.create();
+        sc.setParameters("networkId", networkId);
+        sc.setParameters("state", State.Revoke);
+
+        if (purpose != null) {
+            sc.setParameters("purpose", purpose);
+        }
+        
+        sc.setParameters("trafficType", trafficType);
+
+        return listBy(sc);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/server/src/com/cloud/network/element/VpcVirtualRouterElement.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java
index b4462db..321e1c0 100644
--- a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java
+++ b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java
@@ -34,7 +34,10 @@ import com.cloud.network.Network.Service;
 import com.cloud.network.NetworkService;
 import com.cloud.network.PublicIpAddress;
 import com.cloud.network.router.VirtualRouter;
+import com.cloud.network.router.VirtualRouter.Role;
 import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.NetworkACL;
 import com.cloud.network.vpc.Vpc;
 import com.cloud.network.vpc.VpcManager;
 import com.cloud.offering.NetworkOffering;
@@ -51,7 +54,7 @@ import com.cloud.vm.VirtualMachineProfile;
  * @author Alena Prokharchyk
  */
 @Local(value = NetworkElement.class)
-public class VpcVirtualRouterElement extends VirtualRouterElement implements VpcProvider{
+public class VpcVirtualRouterElement extends VirtualRouterElement implements VpcProvider, NetworkACLServiceProvider{
     private static final Logger s_logger = Logger.getLogger(VpcVirtualRouterElement.class);
     @Inject 
     NetworkService _ntwkService;
@@ -341,4 +344,24 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
             return false;
         }
     }
+    
+    @Override
+    public boolean applyNetworkACLs(Network config, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
+        if (canHandle(config, Service.Firewall)) {
+            List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER);
+            if (routers == null || routers.isEmpty()) {
+                s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " +
+                        "router doesn't exist in the network " + config.getId());
+                return true;
+            }
+
+            if (!_vpcRouterMgr.applyNetworkACLs(config, (List<NetworkACL>)rules, routers)) {
+                throw new CloudRuntimeException("Failed to apply firewall rules in network " + config.getId());
+            } else {
+                return true;
+            }
+        } else {
+            return true;
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/server/src/com/cloud/network/firewall/FirewallManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java
index 506b615..ea8aec7 100644
--- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java
+++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java
@@ -33,7 +33,6 @@ import com.cloud.event.EventTypes;
 import com.cloud.event.UsageEventVO;
 import com.cloud.event.dao.EventDao;
 import com.cloud.event.dao.UsageEventDao;
-import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.NetworkRuleConflictException;
 import com.cloud.exception.ResourceUnavailableException;
@@ -73,7 +72,7 @@ import com.cloud.utils.net.NetUtils;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.dao.UserVmDao;
 
-@Local(value = { FirewallService.class, FirewallManager.class })
+@Local(value = { FirewallService.class, FirewallManager.class})
 public class FirewallManagerImpl implements FirewallService, FirewallManager, Manager {
     private static final Logger s_logger = Logger.getLogger(FirewallManagerImpl.class);
     String _name;
@@ -147,22 +146,10 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
         IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
         // Validate ip address
         if (ipAddress == null && type == FirewallRule.FirewallRuleType.User) {
-            throw new InvalidParameterValueException("Unable to create port forwarding rule; ip id=" + ipAddrId + 
+            throw new InvalidParameterValueException("Unable to create firewall rule; ip id=" + ipAddrId + 
                     " doesn't exist in the system");
         }
         
-        //associate ip address to network (if needed)
-        if (ipAddress.getAssociatedWithNetworkId() == null) {
-            s_logger.debug("The ip is not associated with the network id="+ networkId + " so assigning");
-            try {
-                _networkMgr.associateIPToGuestNetwork(ipAddrId, networkId);
-            } catch (Exception ex) {
-                s_logger.warn("Failed to associate ip id=" + ipAddrId + " to network id=" + networkId + " as " +
-                        "a part of firewall rule creation");
-                return null;
-            }
-        }
-        
         _networkMgr.checkIpForService(ipAddress, Service.Firewall);  
 
         validateFirewallRule(caller, ipAddress, portStart, portEnd, protocol, Purpose.Firewall, type);
@@ -184,16 +171,16 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
             domainId = ipAddress.getAllocatedInDomainId();
         }
 
-
         Transaction txn = Transaction.currentTxn();
         txn.start();
 
-        FirewallRuleVO newRule = new FirewallRuleVO(xId, ipAddrId, portStart, portEnd, protocol.toLowerCase(), networkId, accountId, domainId, Purpose.Firewall, sourceCidrList, icmpCode, icmpType, relatedRuleId);
+        FirewallRuleVO newRule = new FirewallRuleVO(xId, ipAddrId, portStart, portEnd, protocol.toLowerCase(), networkId,
+                accountId, domainId, Purpose.Firewall, sourceCidrList, icmpCode, icmpType, relatedRuleId, null);
         newRule.setType(type);
         newRule = _firewallDao.persist(newRule);
 
         if (type == FirewallRuleType.User)
-            detectRulesConflict(newRule, ipAddress);
+            detectRulesConflict(newRule);
 
         if (!_firewallDao.setStateToAdd(newRule)) {
             throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
@@ -252,18 +239,19 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
     }
 
     @Override
-    public void detectRulesConflict(FirewallRule newRule, IpAddress ipAddress) throws NetworkRuleConflictException {
-        assert newRule.getSourceIpAddressId() == ipAddress.getId() : "You passed in an ip address that doesn't match the address in the new rule";
+    public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflictException {
 
         List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurposeAndNotRevoked(newRule.getSourceIpAddressId(), null);
-        assert (rules.size() >= 1) : "For network rules, we now always first persist the rule and then check for network conflicts so we should at least have one rule at this point.";
+        assert (rules.size() >= 1) : "For network rules, we now always first persist the rule and then check for " +
+        		"network conflicts so we should at least have one rule at this point.";
 
         for (FirewallRuleVO rule : rules) {
             if (rule.getId() == newRule.getId()) {
                 continue; // Skips my own rule.
             }
 
-            boolean oneOfRulesIsFirewall = ((rule.getPurpose() == Purpose.Firewall || newRule.getPurpose() == Purpose.Firewall) && ((newRule.getPurpose() != rule.getPurpose()) || (!newRule.getProtocol()
+            boolean oneOfRulesIsFirewall = ((rule.getPurpose() == Purpose.Firewall || newRule.getPurpose() == Purpose.Firewall)
+                    && ((newRule.getPurpose() != rule.getPurpose()) || (!newRule.getProtocol()
                     .equalsIgnoreCase(rule.getProtocol()))));
 
             // if both rules are firewall and their cidrs are different, we can skip port ranges verification
@@ -288,24 +276,29 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
 
             if (!oneOfRulesIsFirewall) {
                 if (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() != Purpose.StaticNat) {
-                    throw new NetworkRuleConflictException("There is 1 to 1 Nat rule specified for the ip address id=" + newRule.getSourceIpAddressId());
+                    throw new NetworkRuleConflictException("There is 1 to 1 Nat rule specified for the ip address id=" 
+                + newRule.getSourceIpAddressId());
                 } else if (rule.getPurpose() != Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat) {
-                    throw new NetworkRuleConflictException("There is already firewall rule specified for the ip address id=" + newRule.getSourceIpAddressId());
+                    throw new NetworkRuleConflictException("There is already firewall rule specified for the ip address id="
+                + newRule.getSourceIpAddressId());
                 }
             }
 
             if (rule.getNetworkId() != newRule.getNetworkId() && rule.getState() != State.Revoke) {
-                throw new NetworkRuleConflictException("New rule is for a different network than what's specified in rule " + rule.getXid());
+                throw new NetworkRuleConflictException("New rule is for a different network than what's specified in rule "
+            + rule.getXid());
             }
 
             if (newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO) && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())) {
-                if (newRule.getIcmpCode().longValue() == rule.getIcmpCode().longValue() && newRule.getIcmpType().longValue() == rule.getIcmpType().longValue()
+                if (newRule.getIcmpCode().longValue() == rule.getIcmpCode().longValue() 
+                        && newRule.getIcmpType().longValue() == rule.getIcmpType().longValue()
                         && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()) && duplicatedCidrs) {
                     throw new InvalidParameterValueException("New rule conflicts with existing rule id=" + rule.getId());
                 }
             }
 
-            boolean notNullPorts = (newRule.getSourcePortStart() != null && newRule.getSourcePortEnd() != null && rule.getSourcePortStart() != null && rule.getSourcePortEnd() != null);
+            boolean notNullPorts = (newRule.getSourcePortStart() != null && newRule.getSourcePortEnd() != null && 
+                    rule.getSourcePortStart() != null && rule.getSourcePortEnd() != null);
             if (!notNullPorts) {
                 continue;
             } else if (!oneOfRulesIsFirewall && !(bothRulesFirewall && !duplicatedCidrs)
@@ -331,7 +324,8 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
     }
 
     @Override
-    public void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto, Purpose purpose, FirewallRuleType type) {
+    public void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, 
+            String proto, Purpose purpose, FirewallRuleType type) {
         if (portStart != null && !NetUtils.isValidPort(portStart)) {
             throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart);
         }
@@ -351,10 +345,13 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
         // Validate ip address
         _accountMgr.checkAccess(caller, null, true, ipAddress);
 
-        Long networkId = ipAddress.getAssociatedWithNetworkId();
-        if (networkId == null) {
-            throw new InvalidParameterValueException("Unable to create port forwarding rule ; ip id=" + ipAddress.getId() + " is not associated with any network");
+        Long networkId = null;
 
+        if (ipAddress.getAssociatedWithNetworkId() == null) {
+            throw new InvalidParameterValueException("Unable to create port forwarding rule ; ip id=" + 
+                    ipAddress.getId() + " is not associated with any network");
+        } else {
+            networkId = ipAddress.getAssociatedWithNetworkId();
         }
 
         Network network = _networkMgr.getNetwork(networkId);
@@ -441,7 +438,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
     public boolean applyFirewallRules(List<FirewallRuleVO> rules, boolean continueOnError, Account caller) {
 
         if (rules.size() == 0) {
-            s_logger.debug("There are no firewall rules to apply for ip id=" + rules);
+            s_logger.debug("There are no firewall rules to apply");
             return true;
         }
 
@@ -493,7 +490,6 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
         }
 
         return success;
-
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/server/src/com/cloud/network/firewall/NetworkACLManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/firewall/NetworkACLManagerImpl.java b/server/src/com/cloud/network/firewall/NetworkACLManagerImpl.java
new file mode 100644
index 0000000..366f6bf
--- /dev/null
+++ b/server/src/com/cloud/network/firewall/NetworkACLManagerImpl.java
@@ -0,0 +1,301 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License.  Citrix Systems, Inc.
+// reserves all rights not expressly granted by the License.
+// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// 
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.network.firewall;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.acl.SecurityChecker.AccessType;
+import com.cloud.event.ActionEvent;
+import com.cloud.event.EventTypes;
+import com.cloud.exception.InvalidParameterValueException;
+import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
+import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkManager;
+import com.cloud.network.Networks;
+import com.cloud.network.dao.FirewallRulesDao;
+import com.cloud.network.rules.FirewallManager;
+import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.rules.FirewallRule.Purpose;
+import com.cloud.network.rules.FirewallRule.TrafficType;
+import com.cloud.network.rules.FirewallRuleVO;
+import com.cloud.network.rules.NetworkACL;
+import com.cloud.network.vpc.Vpc;
+import com.cloud.network.vpc.VpcManager;
+import com.cloud.user.Account;
+import com.cloud.user.AccountManager;
+import com.cloud.user.UserContext;
+import com.cloud.utils.component.Inject;
+import com.cloud.utils.component.Manager;
+import com.cloud.utils.db.DB;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.exception.CloudRuntimeException;
+import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.Nic.State;
+
+/**
+ * @author Alena Prokharchyk
+ */
+
+@Local(value = { NetworkACLService.class})
+public class NetworkACLManagerImpl implements Manager,NetworkACLService{
+    String _name;
+    private static final Logger s_logger = Logger.getLogger(NetworkACLManagerImpl.class);
+
+    
+    @Inject
+    AccountManager _accountMgr;
+    @Inject
+    FirewallManager _firewallMgr;
+    @Inject
+    FirewallRulesDao _firewallDao;
+    @Inject
+    NetworkManager _networkMgr;
+    @Inject
+    VpcManager _vpcMgr;
+
+
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
+        _name = name;
+        return true;
+    }
+
+    @Override
+    public boolean start() {
+        return true;
+    }
+
+
+    @Override
+    public boolean stop() {
+        return true;
+    }
+
+
+    @Override
+    public String getName() {
+        return _name;
+    }
+
+    @Override
+    public NetworkACL getNetworkACL(long ruleId) {
+        return _firewallDao.findById(ruleId);
+    }
+
+    @Override
+    public boolean applyNetworkACLs(long networkId, Account caller) throws ResourceUnavailableException {
+        List<FirewallRuleVO> rules = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.NetworkACL);
+        return _firewallMgr.applyFirewallRules(rules, false, caller);
+    }
+
+    @Override
+    public NetworkACL createNetworkACL(NetworkACL acl) throws NetworkRuleConflictException {
+        return createNetworkACL(UserContext.current().getCaller(), acl.getXid(), acl.getSourcePortStart(), 
+                acl.getSourcePortEnd(), acl.getProtocol(), acl.getSourceCidrList(), acl.getIcmpCode(),
+                acl.getIcmpType(), null, acl.getType(), acl.getNetworkId(), acl.getTrafficType());
+    }
+
+    @DB
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true)
+    protected NetworkACL createNetworkACL(Account caller, String xId, Integer portStart, 
+            Integer portEnd, String protocol, List<String> sourceCidrList, Integer icmpCode, Integer icmpType,
+            Long relatedRuleId, FirewallRule.FirewallRuleType type, long networkId, TrafficType trafficType) throws NetworkRuleConflictException {
+        
+        Network network = _networkMgr.getNetwork(networkId);
+        if (network == null) {
+            throw new InvalidParameterValueException("Can't find network by id");
+        }
+        
+        if (network.getVpcId() == null) {
+            throw new UnsupportedOperationException("Network ACL rules are supported just for VPC networks");
+        }
+        
+        Vpc vpc = _vpcMgr.getVpc(network.getVpcId());
+        Account aclOwner = _accountMgr.getAccount(vpc.getAccountId());
+        
+        _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network);
+
+        
+        if (!_networkMgr.areServicesSupportedInNetwork(networkId, Service.Firewall)) {
+            throw new InvalidParameterValueException("Service " + Service.Firewall + " is not supported in network " + network);
+        }
+        
+        // icmp code and icmp type can't be passed in for any other protocol rather than icmp
+        if (!protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (icmpCode != null || icmpType != null)) {
+            throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only");
+        }
+
+        if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (portStart != null || portEnd != null)) {
+            throw new InvalidParameterValueException("Can't specify start/end port when protocol is ICMP");
+        } 
+
+        validateNetworkACL(caller, network, portStart, portEnd, protocol);
+
+
+        Transaction txn = Transaction.currentTxn();
+        txn.start();
+
+        FirewallRuleVO newRule = new FirewallRuleVO(xId, null, portStart, portEnd, protocol.toLowerCase(), networkId,
+                aclOwner.getAccountId(), aclOwner.getDomainId(), Purpose.NetworkACL, sourceCidrList, icmpCode, icmpType, 
+                relatedRuleId, trafficType);
+        newRule.setType(type);
+        newRule = _firewallDao.persist(newRule);
+
+        if (type == FirewallRule.FirewallRuleType.User) {
+            detectNetworkACLConflict(newRule);
+        }
+
+        if (!_firewallDao.setStateToAdd(newRule)) {
+            throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
+        }
+        UserContext.current().setEventDetails("Rule Id: " + newRule.getId());
+
+        txn.commit();
+
+        return newRule;
+    }
+    
+    
+    protected void validateNetworkACL(Account caller, Network network, Integer portStart, Integer portEnd, 
+            String proto) {
+        
+        if (portStart != null && !NetUtils.isValidPort(portStart)) {
+            throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart);
+        }
+        if (portEnd != null && !NetUtils.isValidPort(portEnd)) {
+            throw new InvalidParameterValueException("Public port range is an invalid value: " + portEnd);
+        }
+
+        // start port can't be bigger than end port
+        if (portStart != null && portEnd != null && portStart > portEnd) {
+            throw new InvalidParameterValueException("Start port can't be bigger than end port");
+        }
+        
+        if (network.getTrafficType() != Networks.TrafficType.Guest) {
+            throw new InvalidParameterValueException("Network ACL can be created just for networks of type " + Networks.TrafficType.Guest);
+        }
+
+        // Verify that the network guru supports the protocol specified
+        Map<Network.Capability, String> protocolCapabilities = _networkMgr.getNetworkServiceCapabilities(network.getId(), Service.Firewall);
+        
+
+        if (protocolCapabilities != null) {
+            String supportedProtocols = protocolCapabilities.get(Capability.SupportedProtocols).toLowerCase();
+            if (!supportedProtocols.contains(proto.toLowerCase())) {
+                throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId());
+            }
+        }
+    }
+    
+    protected void detectNetworkACLConflict(NetworkACL newRule) throws NetworkRuleConflictException {
+
+        List<FirewallRuleVO> rules = _firewallDao.listByNetworkPurposeTrafficTypeAndNotRevoked(newRule.getNetworkId(), Purpose.NetworkACL, newRule.getTrafficType());
+        assert (rules.size() >= 1) : "For network ACLs, we now always first persist the rule and then check for " +
+                "network conflicts so we should at least have one rule at this point.";
+
+        for (FirewallRuleVO rule : rules) {
+            if (rule.getId() == newRule.getId()) {
+                continue; // Skips my own rule.
+            }
+
+            // if rules cidrs are different, we can skip port ranges verification
+            boolean duplicatedCidrs = false;
+            // Verify that the rules have different cidrs
+            List<String> ruleCidrList = rule.getSourceCidrList();
+            List<String> newRuleCidrList = newRule.getSourceCidrList();
+
+            if (ruleCidrList == null || newRuleCidrList == null) {
+                continue;
+            }
+
+            Collection<String> similar = new HashSet<String>(ruleCidrList);
+            similar.retainAll(newRuleCidrList);
+
+            if (similar.size() > 0) {
+                duplicatedCidrs = true;
+            }
+            
+
+            if (newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO) && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())) {
+                if (newRule.getIcmpCode().longValue() == rule.getIcmpCode().longValue() 
+                        && newRule.getIcmpType().longValue() == rule.getIcmpType().longValue()
+                        && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()) && duplicatedCidrs) {
+                    throw new InvalidParameterValueException("New network ACL conflicts with existing network ACL id=" + rule.getId());
+                }
+            }
+
+            boolean notNullPorts = (newRule.getSourcePortStart() != null && newRule.getSourcePortEnd() != null && 
+                    rule.getSourcePortStart() != null && rule.getSourcePortEnd() != null);
+            if (!notNullPorts) {
+                continue;
+            } else if (duplicatedCidrs
+                    && ((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue() && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue())
+                            || (rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue() && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortEnd().intValue())
+                            || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortStart().intValue() && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortStart().intValue())
+                            || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortEnd().intValue() && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortEnd().intValue()))) {
+
+                throw new NetworkRuleConflictException("The range specified, " + newRule.getSourcePortStart() + "-" 
+                            + newRule.getSourcePortEnd() + ", conflicts with rule " + rule.getId()
+                            + " which has " + rule.getSourcePortStart() + "-" + rule.getSourcePortEnd());
+                
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("No network rule conflicts detected for " + newRule + " against " + (rules.size() - 1) + " existing network ACLs");
+        }
+    }
+    
+    @Override
+    public boolean revokeNetworkACL(long ruleId, boolean apply) {
+        Account caller = UserContext.current().getCaller();
+        long userId = UserContext.current().getCallerUserId();
+        return revokeNetworkACL(ruleId, apply, caller, userId);
+    }
+    
+    @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true)
+    protected boolean revokeNetworkACL(long ruleId, boolean apply, Account caller, long userId) {
+
+        FirewallRuleVO rule = _firewallDao.findById(ruleId);
+        if (rule == null || rule.getPurpose() != Purpose.NetworkACL) {
+            throw new InvalidParameterValueException("Unable to find " + ruleId + " having purpose " + Purpose.NetworkACL);
+        }
+
+        _accountMgr.checkAccess(caller, null, true, rule);
+
+        _firewallMgr.revokeRule(rule, caller, userId, false);
+
+        boolean success = false;
+
+        if (apply) {
+            List<FirewallRuleVO> rules = _firewallDao.listByNetworkAndPurpose(rule.getNetworkId(), Purpose.NetworkACL);
+            return _firewallMgr.applyFirewallRules(rules, false, caller);
+        } else {
+            success = true;
+        }
+
+        return success;
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
index 805657b..84221c4 100755
--- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
+++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
@@ -819,7 +819,7 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
         boolean success = true;
 
         try {
-            _firewallMgr.detectRulesConflict(newRule, ipAddr);
+            _firewallMgr.detectRulesConflict(newRule);
             if (!_firewallDao.setStateToAdd(newRule)) {
                 throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
             }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index ee13718..be5d4b6 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -61,6 +61,7 @@ import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
 import com.cloud.agent.api.routing.SavePasswordCommand;
 import com.cloud.agent.api.routing.SetFirewallRulesCommand;
 import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
+import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand;
 import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
 import com.cloud.agent.api.routing.VmDataCommand;
 import com.cloud.agent.api.routing.VpnUsersCfgCommand;
@@ -2533,7 +2534,14 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
             }
         }
 
-        SetPortForwardingRulesCommand cmd = new SetPortForwardingRulesCommand(rulesTO);
+        SetPortForwardingRulesCommand cmd = null;
+        
+        if (router.getVpcId() != null) {
+            cmd = new SetPortForwardingRulesVpcCommand(rulesTO);
+        } else {
+            cmd = new SetPortForwardingRulesCommand(rulesTO);
+        }
+        
         cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId()));
         cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(guestNetworkId, router.getId()));
         cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/374a6007/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java
index 6816413..3d756bf 100644
--- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java
+++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java
@@ -19,7 +19,9 @@ import com.cloud.deploy.DeployDestination;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.Network;
 import com.cloud.network.VpcVirtualNetworkApplianceService;
+import com.cloud.network.rules.NetworkACL;
 import com.cloud.network.vpc.Vpc;
 import com.cloud.user.Account;
 import com.cloud.vm.DomainRouterVO;
@@ -44,4 +46,14 @@ public interface VpcVirtualNetworkApplianceManager extends VirtualNetworkApplian
             throws InsufficientCapacityException, ConcurrentOperationException,
             ResourceUnavailableException;
 
+    /**
+     * @param network
+     * @param rules
+     * @param routers
+     * @return
+     * @throws ResourceUnavailableException
+     */
+    boolean applyNetworkACLs(Network network, List<? extends NetworkACL> rules, List<? extends VirtualRouter> routers) 
+            throws ResourceUnavailableException;
+
 }