You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by mu...@apache.org on 2013/01/31 15:22:59 UTC

[45/50] [abbrv] git commit: refs/heads/events-framework - CLOUDSTACK-299: Egress firewall rules feature for guest network on VR

CLOUDSTACK-299: Egress firewall rules feature for guest network on VR


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

Branch: refs/heads/events-framework
Commit: b6727e564654da2604e17ca477e21d03d4afeb05
Parents: 48fdc25
Author: Jayapal <ja...@citrix.com>
Authored: Thu Jan 31 11:20:23 2013 +0530
Committer: Abhinandan Prateek <ap...@apache.org>
Committed: Thu Jan 31 11:20:47 2013 +0530

----------------------------------------------------------------------
 api/src/com/cloud/agent/api/to/FirewallRuleTO.java |   20 ++-
 api/src/com/cloud/network/Network.java             |    8 +-
 api/src/com/cloud/network/NetworkProfile.java      |    4 +
 .../cloud/network/firewall/FirewallService.java    |    6 +-
 .../user/firewall/CreateFirewallRuleCmd.java       |    4 +-
 .../user/firewall/CreatePortForwardingRuleCmd.java |    2 +-
 .../user/firewall/ListFirewallRulesCmd.java        |    4 +
 .../loadbalancer/CreateLoadBalancerRuleCmd.java    |    2 +-
 .../user/nat/CreateIpForwardingRuleCmd.java        |    2 +-
 .../cloudstack/api/response/FirewallResponse.java  |    7 +
 client/tomcatconf/commands.properties.in           |    5 +
 .../virtualnetwork/VirtualRoutingResource.java     |   11 +-
 .../debian/config/etc/iptables/iptables-router     |    4 +-
 .../debian/config/opt/cloud/bin/ipassoc.sh         |    6 +-
 .../hypervisor/vmware/resource/VmwareResource.java |   27 ++-
 .../xen/resource/CitrixResourceBase.java           |   10 +-
 .../element/JuniperSRXExternalFirewallElement.java |    1 +
 scripts/network/domr/call_firewall.sh              |   21 +-
 server/src/com/cloud/api/ApiResponseHelper.java    |   13 +-
 .../src/com/cloud/network/NetworkManagerImpl.java  |   67 ++++--
 .../com/cloud/network/dao/FirewallRulesDao.java    |    3 +-
 .../cloud/network/dao/FirewallRulesDaoImpl.java    |   22 ++-
 .../network/element/VirtualRouterElement.java      |    2 +
 .../network/firewall/FirewallManagerImpl.java      |  189 ++++++++++-----
 .../network/lb/LoadBalancingRulesManagerImpl.java  |    7 +-
 .../router/VirtualNetworkApplianceManagerImpl.java |   48 +++-
 .../com/cloud/network/rules/FirewallManager.java   |    6 +-
 .../com/cloud/network/rules/FirewallRuleVO.java    |   11 +-
 .../com/cloud/network/rules/RulesManagerImpl.java  |    4 +-
 .../network/vpn/RemoteAccessVpnManagerImpl.java    |    4 +-
 .../src/com/cloud/upgrade/dao/Upgrade40to41.java   |  113 +++++++++-
 .../com/cloud/network/MockFirewallManagerImpl.java |   79 ++++---
 32 files changed, 535 insertions(+), 177 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/api/src/com/cloud/agent/api/to/FirewallRuleTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/FirewallRuleTO.java b/api/src/com/cloud/agent/api/to/FirewallRuleTO.java
index 95ac57c..38de8d0 100644
--- a/api/src/com/cloud/agent/api/to/FirewallRuleTO.java
+++ b/api/src/com/cloud/agent/api/to/FirewallRuleTO.java
@@ -50,7 +50,7 @@ public class FirewallRuleTO implements InternalIdentity {
     FirewallRule.Purpose purpose;
     private Integer icmpType;
     private Integer icmpCode;
-
+    private FirewallRule.TrafficType trafficType;
 
     protected FirewallRuleTO() {
     }
@@ -85,6 +85,7 @@ public class FirewallRuleTO implements InternalIdentity {
         this.sourceCidrList = sourceCidr;
         this.icmpType = icmpType;
         this.icmpCode = icmpCode;
+        this.trafficType = null;
     }
     public FirewallRuleTO(FirewallRule rule, String srcVlanTag, String srcIp) {
         this(rule.getId(),srcVlanTag, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getState()==State.Revoke, rule.getState()==State.Active, rule.getPurpose(),rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode());
@@ -93,6 +94,23 @@ public class FirewallRuleTO implements InternalIdentity {
     public FirewallRuleTO(FirewallRule rule, String srcIp) {
         this(rule.getId(),null, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getState()==State.Revoke, rule.getState()==State.Active, rule.getPurpose(),rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode());
     }
+    
+    public FirewallRuleTO(FirewallRule rule, String srcVlanTag, String srcIp, FirewallRule.Purpose purpose) {
+        this(rule.getId(),srcVlanTag, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getState()==State.Revoke, rule.getState()==State.Active, purpose,rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode());
+    }
+
+    public FirewallRuleTO(FirewallRule rule, String srcVlanTag, String srcIp, FirewallRule.Purpose purpose, FirewallRule.TrafficType trafficType) {
+        this(rule.getId(),srcVlanTag, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getState()==State.Revoke, rule.getState()==State.Active, purpose,rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode());
+        this.trafficType = trafficType;
+    }
+
+    public FirewallRuleTO(FirewallRule rule, String srcVlanTag, String srcIp, FirewallRule.Purpose purpose, boolean revokeState, boolean alreadyAdded) {
+        this(rule.getId(),srcVlanTag, srcIp, rule.getProtocol(), rule.getSourcePortStart(), rule.getSourcePortEnd(), revokeState, alreadyAdded, purpose,rule.getSourceCidrList(),rule.getIcmpType(),rule.getIcmpCode());
+    }
+
+    public FirewallRule.TrafficType getTrafficType(){
+        return trafficType;
+    }
 
     public long getId() {
         return id;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/api/src/com/cloud/network/Network.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java
index c91f6a9..413b6d9 100644
--- a/api/src/com/cloud/network/Network.java
+++ b/api/src/com/cloud/network/Network.java
@@ -47,8 +47,8 @@ public interface Network extends ControlledEntity, InternalIdentity, Identity {
         public static final Service Dhcp = new Service("Dhcp");
         public static final Service Dns = new Service("Dns", Capability.AllowDnsSuffixModification);
         public static final Service Gateway = new Service("Gateway");
-        public static final Service Firewall = new Service("Firewall", Capability.SupportedProtocols,
-                Capability.MultipleIps, Capability.TrafficStatistics);
+        public static final Service Firewall = new Service("Firewall", Capability.SupportedProtocols, 
+                Capability.MultipleIps, Capability.TrafficStatistics, Capability.SupportedTrafficDirection, Capability.SupportedEgressProtocols);
         public static final Service Lb = new Service("Lb", Capability.SupportedLBAlgorithms, Capability.SupportedLBIsolation,
                 Capability.SupportedProtocols, Capability.TrafficStatistics, Capability.LoadBalancingSupportedIps,
                 Capability.SupportedStickinessMethods, Capability.ElasticLb);
@@ -173,6 +173,8 @@ public interface Network extends ControlledEntity, InternalIdentity, Identity {
         public static final Capability ElasticLb = new Capability("ElasticLb");
         public static final Capability AutoScaleCounters = new Capability("AutoScaleCounters");
         public static final Capability InlineMode = new Capability("InlineMode");
+        public static final Capability SupportedTrafficDirection = new Capability("SupportedTrafficDirection");
+        public static final Capability SupportedEgressProtocols = new Capability("SupportedEgressProtocols");
 
         private String name;
 
@@ -287,6 +289,8 @@ public interface Network extends ControlledEntity, InternalIdentity, Identity {
 
     void setPhysicalNetworkId(Long physicalNetworkId);
 
+    public void setTrafficType(TrafficType type);
+
     ACLType getAclType();
 
     boolean isRestartRequired();

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/api/src/com/cloud/network/NetworkProfile.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/NetworkProfile.java b/api/src/com/cloud/network/NetworkProfile.java
index b5c463d..bb59b04 100644
--- a/api/src/com/cloud/network/NetworkProfile.java
+++ b/api/src/com/cloud/network/NetworkProfile.java
@@ -226,4 +226,8 @@ public class NetworkProfile implements Network {
         return vpcId;
     }
 
+    @Override
+    public void setTrafficType(TrafficType type) {
+        this.trafficType = type;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/api/src/com/cloud/network/firewall/FirewallService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/firewall/FirewallService.java b/api/src/com/cloud/network/firewall/FirewallService.java
index 3858499..419cc6a 100644
--- a/api/src/com/cloud/network/firewall/FirewallService.java
+++ b/api/src/com/cloud/network/firewall/FirewallService.java
@@ -27,7 +27,8 @@ import com.cloud.user.Account;
 import com.cloud.utils.Pair;
 
 public interface FirewallService {
-    FirewallRule createFirewallRule(FirewallRule rule) throws NetworkRuleConflictException;
+    FirewallRule createIngressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException;
+    FirewallRule createEgressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException;
 
     Pair<List<? extends FirewallRule>, Integer> listFirewallRules(ListFirewallRulesCmd cmd);
 
@@ -40,7 +41,8 @@ public interface FirewallService {
      */
     boolean revokeFirewallRule(long ruleId, boolean apply);
 
-    boolean applyFirewallRules(long ipId, Account caller) throws ResourceUnavailableException;
+    boolean applyEgressFirewallRules (FirewallRule rule, Account caller) throws ResourceUnavailableException;
+    boolean applyIngressFirewallRules(long Ipid , Account caller) throws ResourceUnavailableException;
 
     FirewallRule getFirewallRule(long ruleId);
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java
index 0dcba5f..f5d7b1b 100644
--- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/firewall/CreateFirewallRuleCmd.java
@@ -122,7 +122,7 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal
         FirewallRule rule = _entityMgr.findById(FirewallRule.class, getEntityId());
         try {
             UserContext.current().setEventDetails("Rule Id: " + getEntityId());
-            success = _firewallService.applyFirewallRules(rule.getSourceIpAddressId(), callerContext.getCaller());
+            success = _firewallService.applyIngressFirewallRules(rule.getSourceIpAddressId(), callerContext.getCaller());
 
             // State is different after the rule is applied, so get new object here
             rule = _entityMgr.findById(FirewallRule.class, getEntityId());
@@ -238,7 +238,7 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal
         }
 
         try {
-            FirewallRule result = _firewallService.createFirewallRule(this);
+            FirewallRule result = _firewallService.createIngressFirewallRule(this);
             setEntityId(result.getId());
             setEntityUuid(result.getUuid());
         } catch (NetworkRuleConflictException ex) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java
index 7d8dbb0..53348c9 100644
--- a/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/firewall/CreatePortForwardingRuleCmd.java
@@ -163,7 +163,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
             UserContext.current().setEventDetails("Rule Id: " + getEntityId());
 
             if (getOpenFirewall()) {
-                success = success && _firewallService.applyFirewallRules(ipAddressId, callerContext.getCaller());
+                success = success && _firewallService.applyIngressFirewallRules(ipAddressId, callerContext.getCaller());
             }
 
             success = success && _rulesService.applyPortForwardingRules(ipAddressId, callerContext.getCaller());

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java b/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java
index 80581fb..5062a4e 100644
--- a/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/firewall/ListFirewallRulesCmd.java
@@ -56,6 +56,10 @@ public class ListFirewallRulesCmd extends BaseListTaggedResourcesCmd {
         return ipAddressId;
     }
 
+    public FirewallRule.TrafficType getTrafficType () {
+    	return FirewallRule.TrafficType.Ingress;
+    }
+   
     public Long getId() {
         return id;
     }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java
index b42ff4c..28bde8f 100644
--- a/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/loadbalancer/CreateLoadBalancerRuleCmd.java
@@ -245,7 +245,7 @@ public class CreateLoadBalancerRuleCmd extends BaseAsyncCreateCmd  /*implements
             UserContext.current().setEventDetails("Rule Id: " + getEntityId());
 
             if (getOpenFirewall()) {
-                success = success && _firewallService.applyFirewallRules(getSourceIpAddressId(), callerContext.getCaller());
+                success = success && _firewallService.applyIngressFirewallRules(getSourceIpAddressId(), callerContext.getCaller());
             }
 
             // State might be different after the rule is applied, so get new object here

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/api/src/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java b/api/src/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java
index c3894c4..7867f8d 100644
--- a/api/src/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java
+++ b/api/src/org/apache/cloudstack/api/command/user/nat/CreateIpForwardingRuleCmd.java
@@ -115,7 +115,7 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
             UserContext.current().setEventDetails("Rule Id: "+ getEntityId());
 
             if (getOpenFirewall()) {
-                result = result && _firewallService.applyFirewallRules(ipAddressId, UserContext.current().getCaller());
+                result = result && _firewallService.applyIngressFirewallRules(ipAddressId, UserContext.current().getCaller());
             }
 
             result = result && _rulesService.applyStaticNatRules(ipAddressId, UserContext.current().getCaller());

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/api/src/org/apache/cloudstack/api/response/FirewallResponse.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/response/FirewallResponse.java b/api/src/org/apache/cloudstack/api/response/FirewallResponse.java
index 2799256..d399590 100644
--- a/api/src/org/apache/cloudstack/api/response/FirewallResponse.java
+++ b/api/src/org/apache/cloudstack/api/response/FirewallResponse.java
@@ -40,6 +40,9 @@ public class FirewallResponse extends BaseResponse {
     @SerializedName(ApiConstants.IP_ADDRESS_ID) @Param(description="the public ip address id for the firewall rule")
     private Long publicIpAddressId;
 
+    @SerializedName(ApiConstants.NETWORK_ID) @Param(description="the network id of the firewall rule")
+    private Long networkId;
+
     @SerializedName(ApiConstants.IP_ADDRESS) @Param(description="the public ip address for the firewall rule")
     private String publicIpAddress;
 
@@ -82,6 +85,10 @@ public class FirewallResponse extends BaseResponse {
         this.publicIpAddress = publicIpAddress;
     }
 
+    public void setNetworkId(Long networkId) {
+        this.networkId = networkId;
+    }
+
     public void setState(String state) {
         this.state = state;
     }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in
index 69161be..755a5f2 100644
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -351,6 +351,11 @@ createFirewallRule=15
 deleteFirewallRule=15
 listFirewallRules=15
 
+#### 
+createEgressFirewallRule=15
+deleteEgressFirewallRule=15
+listEgressFirewallRules=15
+
 #### hypervisor capabilities commands
 updateHypervisorCapabilities=1
 listHypervisorCapabilities=1

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
index 18a0426..05107e7 100755
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -69,12 +69,14 @@ import com.cloud.agent.api.routing.SetStaticRouteCommand;
 import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
 import com.cloud.agent.api.routing.VmDataCommand;
 import com.cloud.agent.api.routing.VpnUsersCfgCommand;
+import com.cloud.agent.api.to.FirewallRuleTO;
 import com.cloud.agent.api.to.IpAddressTO;
 import com.cloud.agent.api.to.PortForwardingRuleTO;
 import com.cloud.agent.api.to.StaticNatRuleTO;
 import com.cloud.exception.InternalErrorException;
 import com.cloud.network.HAProxyConfigurator;
 import com.cloud.network.LoadBalancerConfigurator;
+import com.cloud.network.rules.FirewallRule;
 import com.cloud.utils.NumbersUtil;
 import com.cloud.utils.component.Manager;
 import com.cloud.utils.net.NetUtils;
@@ -214,11 +216,18 @@ public class VirtualRoutingResource implements Manager {
             return new SetFirewallRulesAnswer(cmd, false, results);
         }
 
+        FirewallRuleTO[] allrules = cmd.getRules();
+        FirewallRule.TrafficType trafficType = allrules[0].getTrafficType();
+
         String[][] rules = cmd.generateFwRules();
         final Script command = new Script(_firewallPath, _timeout, s_logger);
         command.add(routerIp);
         command.add("-F");
-        
+
+        if (trafficType == FirewallRule.TrafficType.Egress){
+            command.add("-E");
+        }
+
         StringBuilder sb = new StringBuilder();
         String[] fwRules = rules[0];
         if (fwRules.length > 0) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/patches/systemvm/debian/config/etc/iptables/iptables-router
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/etc/iptables/iptables-router b/patches/systemvm/debian/config/etc/iptables/iptables-router
index 28469fb..3f5bc5f 100644
--- a/patches/systemvm/debian/config/etc/iptables/iptables-router
+++ b/patches/systemvm/debian/config/etc/iptables/iptables-router
@@ -24,6 +24,7 @@ COMMIT
 :INPUT DROP [0:0]
 :FORWARD DROP [0:0]
 :OUTPUT ACCEPT [0:0]
+:FW_OUTBOUND - [0:0]
 -A INPUT -d 224.0.0.18/32 -j ACCEPT
 -A INPUT -d 225.0.0.50/32 -j ACCEPT
 -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
@@ -37,10 +38,11 @@ COMMIT
 -A INPUT -i eth1 -p tcp -m state --state NEW --dport 3922 -j ACCEPT
 -A INPUT -i eth0 -p tcp -m state --state NEW --dport 80 -j ACCEPT
 -A FORWARD -i eth0 -o eth1 -m state --state RELATED,ESTABLISHED -j ACCEPT
--A FORWARD -i eth0 -o eth2 -j ACCEPT
 -A FORWARD -i eth2 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
 -A FORWARD -i eth0 -o eth0 -m state --state NEW -j ACCEPT
 -A FORWARD -i eth0 -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
+-A FORWARD -i eth0 -o eth2 -j FW_OUTBOUND
+-I FW_OUTBOUND -m state --state RELATED,ESTABLISHED -j ACCEPT
 COMMIT
 *mangle
 :PREROUTING ACCEPT [0:0]

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh b/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh
index 5af5d92..f326fac 100755
--- a/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh
+++ b/patches/systemvm/debian/config/opt/cloud/bin/ipassoc.sh
@@ -212,9 +212,9 @@ add_first_ip() {
   ip_addr_add $ethDev $pubIp
 
   sudo iptables -D FORWARD -i $ethDev -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-  sudo iptables -D FORWARD -i eth0 -o $ethDev  -j ACCEPT
+  sudo iptables -D FORWARD -i eth0 -o $ethDev  -j FW_OUTBOUND
   sudo iptables -A FORWARD -i $ethDev -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-  sudo iptables -A FORWARD -i eth0 -o $ethDev  -j ACCEPT
+  sudo iptables -A FORWARD -i eth0 -o $ethDev  -j FW_OUTBOUND
 
   add_snat $1
   if [ $? -gt 0  -a $? -ne 2 ]
@@ -246,7 +246,7 @@ remove_first_ip() {
   [ "$mask" == "" ] && mask="32"
 
   sudo iptables -D FORWARD -i $ethDev -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-  sudo iptables -D FORWARD -i eth0 -o $ethDev  -j ACCEPT
+  sudo iptables -D FORWARD -i eth0 -o $ethDev  -j FW_OUTBOUND
   remove_snat $1
   
   sudo ip addr del dev $ethDev "$ipNoMask/$mask"

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index dd917f7..96c4348 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -153,6 +153,7 @@ import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer;
 import com.cloud.agent.api.storage.DestroyCommand;
 import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
 import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
+import com.cloud.agent.api.to.FirewallRuleTO;
 import com.cloud.agent.api.to.IpAddressTO;
 import com.cloud.agent.api.to.NicTO;
 import com.cloud.agent.api.to.PortForwardingRuleTO;
@@ -190,6 +191,7 @@ import com.cloud.network.HAProxyConfigurator;
 import com.cloud.network.LoadBalancerConfigurator;
 import com.cloud.network.Networks;
 import com.cloud.network.Networks.BroadcastDomainType;
+import com.cloud.network.rules.FirewallRule;
 import com.cloud.resource.ServerResource;
 import com.cloud.serializer.GsonHelper;
 import com.cloud.storage.Storage;
@@ -618,10 +620,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
     protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) {
 		String controlIp = getRouterSshControlIp(cmd);
 		String[] results = new String[cmd.getRules().length];
+        FirewallRuleTO[] allrules = cmd.getRules();
+        FirewallRule.TrafficType trafficType = allrules[0].getTrafficType();
 
 		String[][] rules = cmd.generateFwRules();
 		String args = "";
 		args += " -F ";
+        if (trafficType == FirewallRule.TrafficType.Egress){
+            args+= " -E ";
+        }
+
 		StringBuilder sb = new StringBuilder();
 		String[] fwRules = rules[0];
 		if (fwRules.length > 0) {
@@ -634,13 +642,28 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
 		try {
 			VmwareManager mgr = getServiceContext().getStockObject(
 					VmwareManager.CONTEXT_STOCK_NAME);
-			Pair<Boolean, String> result = SshHelper.sshExecute(controlIp,
+
+            Pair<Boolean, String> result = null;
+
+            if (trafficType == FirewallRule.TrafficType.Egress){
+                result = SshHelper.sshExecute(controlIp,
+                        DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(),
+                        null, "/root/firewallRule_egress.sh " + args);
+            } else {
+                result = SshHelper.sshExecute(controlIp,
 					DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(),
 					null, "/root/firewall_rule.sh " + args);
+            }
 
-			if (s_logger.isDebugEnabled())
+            if (s_logger.isDebugEnabled()) {
+                if (trafficType == FirewallRule.TrafficType.Egress){
+                    s_logger.debug("Executing script on domain router " + controlIp
+                            + ": /root/firewallRule_egress.sh " + args);
+                } else {
 				s_logger.debug("Executing script on domain router " + controlIp
 						+ ": /root/firewall_rule.sh " + args);
+                 }
+             }
 
 			if (!result.first()) {
 				s_logger.error("SetFirewallRulesCommand failure on setting one rule. args: "

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index 065d3be..e9690eb 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -53,6 +53,8 @@ import javax.ejb.Local;
 import javax.naming.ConfigurationException;
 import javax.xml.parsers.DocumentBuilderFactory;
 
+import com.cloud.agent.api.to.*;
+import com.cloud.network.rules.FirewallRule;
 import org.apache.log4j.Logger;
 import org.apache.xmlrpc.XmlRpcException;
 import org.w3c.dom.Document;
@@ -7182,14 +7184,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         String callResult;
         Connection conn = getConnection();
         String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
-
+        FirewallRuleTO[] allrules = cmd.getRules();
+        FirewallRule.TrafficType trafficType = allrules[0].getTrafficType();
         if (routerIp == null) {
             return new SetFirewallRulesAnswer(cmd, false, results);
         }
 
         String[][] rules = cmd.generateFwRules();
         String args = "";
-        args += routerIp + " -F ";
+        args += routerIp + " -F";
+        if (trafficType == FirewallRule.TrafficType.Egress){
+            args+= " -E";
+        }
         StringBuilder sb = new StringBuilder();
         String[] fwRules = rules[0];
         if (fwRules.length > 0) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java
----------------------------------------------------------------------
diff --git a/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java b/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java
index 5038cc8..c2874aa 100644
--- a/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java
+++ b/plugins/network-elements/juniper-srx/src/com/cloud/network/element/JuniperSRXExternalFirewallElement.java
@@ -277,6 +277,7 @@ public class JuniperSRXExternalFirewallElement extends ExternalFirewallDeviceMan
         firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp");
         firewallCapabilities.put(Capability.MultipleIps, "true");
         firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
+        firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress");
         capabilities.put(Service.Firewall, firewallCapabilities);
 
         // Disabling VPN for Juniper in Acton as it 1) Was never tested 2) probably just doesn't work

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/scripts/network/domr/call_firewall.sh
----------------------------------------------------------------------
diff --git a/scripts/network/domr/call_firewall.sh b/scripts/network/domr/call_firewall.sh
index 08da341..f6ad0be 100755
--- a/scripts/network/domr/call_firewall.sh
+++ b/scripts/network/domr/call_firewall.sh
@@ -46,28 +46,25 @@ then
   exit 1
 fi
 fflag=
-while getopts ':F' OPTION
+eflag=
+while getopts ':FE' OPTION
 do
   case $OPTION in 
   F)    fflag=1
-                ;;
+      	  ;;
+  E) eflag=1
+	  ;;
   \?)  ;;
   esac
 done
 
-if [ -n "$fflag" ]
+if [ -n "$eflag" ]
+then
+	ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/firewallRule_egress.sh $*"
+elif [ -n "$fflag" ]
 then
 	ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/firewall_rule.sh $*"
 else
 	ssh -p 3922 -q -o StrictHostKeyChecking=no -i $cert root@$domRIp "/root/firewall.sh $*"
 fi
 exit $?
-
-
-
-
-
-
-
-
-

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/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 1c8849a..641f25b 100755
--- a/server/src/com/cloud/api/ApiResponseHelper.java
+++ b/server/src/com/cloud/api/ApiResponseHelper.java
@@ -2313,10 +2313,15 @@ public class ApiResponseHelper implements ResponseGenerator {
 
         List<String> cidrs = ApiDBUtils.findFirewallSourceCidrs(fwRule.getId());
         response.setCidrList(StringUtils.join(cidrs, ","));
-
-        IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
-        response.setPublicIpAddressId(ip.getId());
-        response.setPublicIpAddress(ip.getAddress().addr());
+        
+        if (fwRule.getTrafficType() == FirewallRule.TrafficType.Ingress) {
+            IpAddress ip = ApiDBUtils.findIpAddressById(fwRule.getSourceIpAddressId());
+            response.setPublicIpAddressId(ip.getId());
+            response.setPublicIpAddress(ip.getAddress().addr());
+        } else if (fwRule.getTrafficType() == FirewallRule.TrafficType.Egress) {
+            response.setPublicIpAddress(null);
+            response.setNetworkId(fwRule.getNetworkId());
+        }
 
         FirewallRule.State state = fwRule.getState();
         String stateToSet = state.toString();

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/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 6c7377f..0a4851f 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -2285,20 +2285,23 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener {
 
     	boolean success = true;
     	Network network = _networksDao.findById(rules.get(0).getNetworkId());
-
-    	// get the list of public ip's owned by the network
-    	List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
-    	List<PublicIp> publicIps = new ArrayList<PublicIp>();
-    	if (userIps != null && !userIps.isEmpty()) {
-    		for (IPAddressVO userIp : userIps) {
+        FirewallRuleVO.TrafficType trafficType = rules.get(0).getTrafficType();
+         List<PublicIp> publicIps = new ArrayList<PublicIp>();
+
+        if (! (rules.get(0).getPurpose() == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress)) {
+            // get the list of public ip's owned by the network
+            List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
+            if (userIps != null && !userIps.isEmpty()) {
+                for (IPAddressVO userIp : userIps) {
     			PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress()));
     			publicIps.add(publicIp);
-    		}
-    	}
+	                }
+             }
 
     	// rules can not programmed unless IP is associated with network service provider, so run IP assoication for
     	// the network so as to ensure IP is associated before applying rules (in add state)
     	applyIpAssociations(network, false, continueOnError, publicIps);
+	}
     	
     	try {
     		applier.applyRules(network, purpose, rules);
@@ -2310,8 +2313,10 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener {
     		success = false;
     	}
     	
-    	// if all the rules configured on public IP are revoked then dis-associate IP with network service provider
-    	applyIpAssociations(network, true, continueOnError, publicIps);
+        if (! (rules.get(0).getPurpose() == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress) ) {
+            // if all the rules configured on public IP are revoked then dis-associate IP with network service provider
+            applyIpAssociations(network, true, continueOnError, publicIps);
+        }
 
     	return success;
     }
@@ -2460,9 +2465,15 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener {
         }
 
         // apply firewall rules
-        List<FirewallRuleVO> firewallRulesToApply = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.Firewall);
-        if (!_firewallMgr.applyFirewallRules(firewallRulesToApply, false, caller)) {
-            s_logger.warn("Failed to reapply firewall rule(s) as a part of network id=" + networkId + " restart");
+        List<FirewallRuleVO> firewallIngressRulesToApply = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Ingress);
+        if (!_firewallMgr.applyFirewallRules(firewallIngressRulesToApply, false, caller)) {
+            s_logger.warn("Failed to reapply Ingress firewall rule(s) as a part of network id=" + networkId + " restart");
+            success = false;
+        }
+
+        List<FirewallRuleVO> firewallEgressRulesToApply = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Egress);
+        if (!_firewallMgr.applyFirewallRules(firewallEgressRulesToApply, false, caller)) {
+            s_logger.warn("Failed to reapply firewall Egress rule(s) as a part of network id=" + networkId + " restart");
             success = false;
         }
 
@@ -3027,23 +3038,43 @@ public class NetworkManagerImpl implements NetworkManager, Manager, Listener {
         }
 
         // revoke all firewall rules for the network w/o applying them on the DB
-        List<FirewallRuleVO> firewallRules = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.Firewall);
+        List<FirewallRuleVO> firewallRules = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Ingress);
         if (s_logger.isDebugEnabled()) {
-            s_logger.debug("Releasing " + firewallRules.size() + " firewall rules for network id=" + networkId + " as a part of shutdownNetworkRules");
+            s_logger.debug("Releasing " + firewallRules.size() + " firewall ingress rules for network id=" + networkId + " as a part of shutdownNetworkRules");
         }
 
         for (FirewallRuleVO firewallRule : firewallRules) {
-            s_logger.trace("Marking firewall rule " + firewallRule + " with Revoke state");
+            s_logger.trace("Marking firewall ingress rule " + firewallRule + " with Revoke state");
             firewallRule.setState(FirewallRule.State.Revoke);
         }
 
         try {
             if (!_firewallMgr.applyRules(firewallRules, true, false)) {
-                s_logger.warn("Failed to cleanup firewall rules as a part of shutdownNetworkRules");
+                s_logger.warn("Failed to cleanup firewall ingress rules as a part of shutdownNetworkRules");
+                success = false;
+            }
+        } catch (ResourceUnavailableException ex) {
+            s_logger.warn("Failed to cleanup firewall ingress rules as a part of shutdownNetworkRules due to ", ex);
+            success = false;
+        }
+
+        List<FirewallRuleVO> firewallEgressRules = _firewallDao.listByNetworkPurposeTrafficType(networkId, Purpose.Firewall, FirewallRule.TrafficType.Egress);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Releasing " + firewallEgressRules.size() + " firewall egress rules for network id=" + networkId + " as a part of shutdownNetworkRules");
+        }
+
+        for (FirewallRuleVO firewallRule : firewallEgressRules) {
+            s_logger.trace("Marking firewall egress rule " + firewallRule + " with Revoke state");
+            firewallRule.setState(FirewallRule.State.Revoke);
+        }
+
+        try {
+            if (!_firewallMgr.applyRules(firewallEgressRules, true, false)) {
+                s_logger.warn("Failed to cleanup firewall egress rules as a part of shutdownNetworkRules");
                 success = false;
             }
         } catch (ResourceUnavailableException ex) {
-            s_logger.warn("Failed to cleanup firewall rules as a part of shutdownNetworkRules due to ", ex);
+            s_logger.warn("Failed to cleanup firewall egress rules as a part of shutdownNetworkRules due to ", ex);
             success = false;
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/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 cc184c8..b5b7f99 100644
--- a/server/src/com/cloud/network/dao/FirewallRulesDao.java
+++ b/server/src/com/cloud/network/dao/FirewallRulesDao.java
@@ -56,6 +56,7 @@ public interface FirewallRulesDao extends GenericDao<FirewallRuleVO, Long> {
     long countRulesByIpId(long sourceIpId);
     
     List<FirewallRuleVO> listByNetworkPurposeTrafficTypeAndNotRevoked(long networkId, FirewallRule.Purpose purpose, FirewallRule.TrafficType trafficType);
-    
+    List<FirewallRuleVO> listByNetworkPurposeTrafficType(long networkId, FirewallRule.Purpose purpose, FirewallRule.TrafficType trafficType);
+
     List<FirewallRuleVO> listByIpAndPurposeWithState(Long addressId, FirewallRule.Purpose purpose, FirewallRule.State state);
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/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 2fff15a..8bc0c47 100644
--- a/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java
+++ b/server/src/com/cloud/network/dao/FirewallRulesDaoImpl.java
@@ -67,6 +67,7 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
         AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
         AllFieldsSearch.and("networkId", AllFieldsSearch.entity().getNetworkId(), Op.EQ);
         AllFieldsSearch.and("related", AllFieldsSearch.entity().getRelated(), Op.EQ);
+        AllFieldsSearch.and("trafficType", AllFieldsSearch.entity().getTrafficType(), Op.EQ);
         AllFieldsSearch.done();
 
         NotRevokedSearch = createSearchBuilder();
@@ -162,6 +163,20 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
     }
 
     @Override
+    public List<FirewallRuleVO> listByNetworkPurposeTrafficTypeAndNotRevoked(long networkId, FirewallRule.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);
+    }
+
+
+    @Override
     public boolean setStateToAdd(FirewallRuleVO rule) {
         SearchCriteria<FirewallRuleVO> sc = AllFieldsSearch.create();
         sc.setParameters("id", rule.getId());
@@ -275,10 +290,9 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
     }
 
     @Override
-    public List<FirewallRuleVO> listByNetworkPurposeTrafficTypeAndNotRevoked(long networkId, Purpose purpose, TrafficType trafficType) {
-        SearchCriteria<FirewallRuleVO> sc = NotRevokedSearch.create();
+    public List<FirewallRuleVO> listByNetworkPurposeTrafficType(long networkId, Purpose purpose, TrafficType trafficType) {
+        SearchCriteria<FirewallRuleVO> sc = AllFieldsSearch.create();
         sc.setParameters("networkId", networkId);
-        sc.setParameters("state", State.Revoke);
 
         if (purpose != null) {
             sc.setParameters("purpose", purpose);
@@ -288,6 +302,8 @@ public class FirewallRulesDaoImpl extends GenericDaoBase<FirewallRuleVO, Long> i
 
         return listBy(sc);
     }
+
+    @Override
     @DB
     public boolean remove(Long id) {
         Transaction txn = Transaction.currentTxn();

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/server/src/com/cloud/network/element/VirtualRouterElement.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java
index 0ea06e1..8293ad7 100755
--- a/server/src/com/cloud/network/element/VirtualRouterElement.java
+++ b/server/src/com/cloud/network/element/VirtualRouterElement.java
@@ -565,6 +565,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
         Map<Capability, String> firewallCapabilities = new HashMap<Capability, String>();
         firewallCapabilities.put(Capability.TrafficStatistics, "per public ip");
         firewallCapabilities.put(Capability.SupportedProtocols, "tcp,udp,icmp");
+        firewallCapabilities.put(Capability.SupportedEgressProtocols, "tcp,udp,icmp, all");
+        firewallCapabilities.put(Capability.SupportedTrafficDirection, "ingress, egress");
         firewallCapabilities.put(Capability.MultipleIps, "true");
         capabilities.put(Service.Firewall, firewallCapabilities);
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/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 7bab1ba..d4958f3 100644
--- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java
+++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java
@@ -29,6 +29,12 @@ import javax.naming.ConfigurationException;
 import org.apache.cloudstack.api.command.user.firewall.ListFirewallRulesCmd;
 import org.apache.log4j.Logger;
 
+import com.mysql.jdbc.ConnectionPropertiesImpl;
+import org.apache.log4j.Logger;
+
+import org.apache.cloudstack.api.BaseListCmd;
+import org.apache.cloudstack.api.command.user.firewall.ListEgressFirewallRulesCmd;
+import org.apache.cloudstack.api.command.user.firewall.ListFirewallRulesCmd;
 import com.cloud.configuration.Config;
 import com.cloud.configuration.dao.ConfigurationDao;
 import com.cloud.domain.dao.DomainDao;
@@ -43,8 +49,10 @@ import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.network.IPAddressVO;
 import com.cloud.network.IpAddress;
 import com.cloud.network.Network;
+import com.cloud.network.NetworkVO;
 import com.cloud.network.Network.Capability;
 import com.cloud.network.Network.Service;
+import com.cloud.network.Networks.TrafficType;
 import com.cloud.network.NetworkManager;
 import com.cloud.network.NetworkModel;
 import com.cloud.network.NetworkRuleApplier;
@@ -166,32 +174,44 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
     }
 
     @Override
-    public FirewallRule createFirewallRule(FirewallRule rule) throws NetworkRuleConflictException {
+    public FirewallRule createEgressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException {
         Account caller = UserContext.current().getCaller();
 
-        return createFirewallRule(rule.getSourceIpAddressId(), caller, rule.getXid(), rule.getSourcePortStart(), 
+        return createFirewallRule(null, caller, rule.getXid(), rule.getSourcePortStart(), 
                 rule.getSourcePortEnd(), rule.getProtocol(), rule.getSourceCidrList(), rule.getIcmpCode(),
-                rule.getIcmpType(), null, rule.getType(), rule.getNetworkId());
+                rule.getIcmpType(), null, rule.getType(), rule.getNetworkId(), rule.getTrafficType());
     }
 
+    public FirewallRule createIngressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException {
+         Account caller = UserContext.current().getCaller();
+        Long sourceIpAddressId = rule.getSourceIpAddressId();
+ 
+        return createFirewallRule(sourceIpAddressId, caller, rule.getXid(), rule.getSourcePortStart(), 
+                 rule.getSourcePortEnd(), rule.getProtocol(), rule.getSourceCidrList(), rule.getIcmpCode(),
+                rule.getIcmpType(), null, rule.getType(), rule.getNetworkId(), rule.getTrafficType());
+     }
+
     @DB
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true)
-    public FirewallRule createFirewallRule(long ipAddrId, Account caller, String xId, Integer portStart, 
-            Integer portEnd, String protocol, List<String> sourceCidrList, Integer icmpCode, Integer icmpType,
-            Long relatedRuleId, FirewallRule.FirewallRuleType type, long networkId) throws NetworkRuleConflictException {
-        
-        IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId);
-        // Validate ip address
-        if (ipAddress == null && type == FirewallRule.FirewallRuleType.User) {
-            throw new InvalidParameterValueException("Unable to create firewall rule; ip id=" + ipAddrId + 
-                    " doesn't exist in the system");
-        }
-
-        _networkModel.checkIpForService(ipAddress, Service.Firewall, null);  
-
-        validateFirewallRule(caller, ipAddress, portStart, portEnd, protocol, Purpose.Firewall, type);
-
+    public FirewallRule createFirewallRule(Long ipAddrId, Account caller, String xId, Integer portStart,
+             Integer portEnd, String protocol, List<String> sourceCidrList, Integer icmpCode, Integer icmpType,
+            Long relatedRuleId, FirewallRule.FirewallRuleType type, Long networkId, FirewallRule.TrafficType trafficType) throws NetworkRuleConflictException {
+ 
+        IPAddressVO ipAddress = null;
+        if (ipAddrId != null){
+            // this for ingress firewall rule, for egress id is null
+             ipAddress = _ipAddressDao.findById(ipAddrId);
+           // Validate ip address
+           if (ipAddress == null && type == FirewallRule.FirewallRuleType.User) {
+              throw new InvalidParameterValueException("Unable to create firewall rule; " +
+                    "couldn't locate IP address by id in the system");
+           }
+           _networkModel.checkIpForService(ipAddress, Service.Firewall, null);
+        }
+ 
+        validateFirewallRule(caller, ipAddress, portStart, portEnd, protocol, Purpose.Firewall, type, networkId, trafficType);
+ 
         // 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");
@@ -205,15 +225,21 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
         Long domainId = null;
 
         if (ipAddress != null) {
+            //Ingress firewall rule
             accountId = ipAddress.getAllocatedToAccountId();
             domainId = ipAddress.getAllocatedInDomainId();
+        } else if (networkId != null) {
+            //egress firewall rule
+                Network network = _networkModel.getNetwork(networkId);
+                accountId = network.getAccountId();
+                domainId = network.getDomainId();
         }
 
         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, null);
+                accountId, domainId, Purpose.Firewall, sourceCidrList, icmpCode, icmpType, relatedRuleId, trafficType);
         newRule.setType(type);
         newRule = _firewallDao.persist(newRule);
 
@@ -234,7 +260,9 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
     public Pair<List<? extends FirewallRule>, Integer> listFirewallRules(ListFirewallRulesCmd cmd) {
         Long ipId = cmd.getIpAddressId();
         Long id = cmd.getId();
+        Long networkId = null;
         Map<String, String> tags = cmd.getTags();
+        FirewallRule.TrafficType trafficType = cmd.getTrafficType();
 
         Account caller = UserContext.current().getCaller();
         List<Long> permittedAccounts = new ArrayList<Long>();
@@ -258,7 +286,13 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
         _accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
 
         sb.and("id", sb.entity().getId(), Op.EQ);
-        sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ);
+        sb.and("trafficType", sb.entity().getTrafficType(), Op.EQ);
+        if (cmd instanceof ListEgressFirewallRulesCmd ) {
+            networkId =((ListEgressFirewallRulesCmd)cmd).getNetworkId();
+            sb.and("networkId", sb.entity().getNetworkId(), Op.EQ);
+        } else {
+            sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ);
+        }
         sb.and("purpose", sb.entity().getPurpose(), Op.EQ);
 
 
@@ -293,9 +327,14 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
 
         if (ipId != null) {
             sc.setParameters("ip", ipId);
+        } else if (cmd instanceof ListEgressFirewallRulesCmd) {
+            if (networkId != null) {
+                sc.setParameters("networkId", networkId);
+            }
         }
 
         sc.setParameters("purpose", Purpose.Firewall);
+        sc.setParameters("trafficType", trafficType);
 
         Pair<List<FirewallRuleVO>, Integer> result = _firewallDao.searchAndCount(sc, filter);
         return new Pair<List<? extends FirewallRule>, Integer>(result.first(), result.second());
@@ -303,10 +342,17 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
 
     @Override
     public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflictException {
+        List<FirewallRuleVO> rules;
+        if(newRule.getSourceIpAddressId() != null){
+             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.";
+        } else {
+            // fetches only firewall egress rules.
+            rules = _firewallDao.listByNetworkPurposeTrafficTypeAndNotRevoked(newRule.getNetworkId(), Purpose.Firewall, newRule.getTrafficType());
+            assert (rules.size() >= 1);
+        }
 
-        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.";
 
         for (FirewallRuleVO rule : rules) {
             if (rule.getId() == newRule.getId()) {
@@ -394,7 +440,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
 
     @Override
     public void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, 
-            String proto, Purpose purpose, FirewallRuleType type) {
+            String proto, Purpose purpose, FirewallRuleType type, Long networkId, FirewallRule.TrafficType trafficType ) {
         if (portStart != null && !NetUtils.isValidPort(portStart)) {
             throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart);
         }
@@ -411,38 +457,56 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
             return;
         }
 
-        // Validate ip address
-        _accountMgr.checkAccess(caller, null, true, ipAddress);
+        if (ipAddress!=null){
+            if (ipAddress.getAssociatedWithNetworkId() == null) {
+                throw new InvalidParameterValueException("Unable to create firewall rule ; ip with specified id is not associated with any network");
+            } else {
+                networkId = ipAddress.getAssociatedWithNetworkId();
+            }
 
-        Long networkId = null;
+            // Validate ip address
+            _accountMgr.checkAccess(caller, null, true, ipAddress);
 
-        if (ipAddress.getAssociatedWithNetworkId() == null) {
-            throw new InvalidParameterValueException("Unable to create firewall rule ; ip id=" + 
-                    ipAddress.getId() + " is not associated with any network");
-        } else {
-            networkId = ipAddress.getAssociatedWithNetworkId();
-        }
+            Network network = _networkModel.getNetwork(networkId);
+            assert network != null : "Can't create port forwarding rule as network associated with public ip address is null?";
 
-        Network network = _networkModel.getNetwork(networkId);
-        assert network != null : "Can't create port forwarding rule as network associated with public ip address is null?";
+            if (trafficType == FirewallRule.TrafficType.Egress) {
+                _accountMgr.checkAccess(caller, null, true, network);
+            }
 
-        // Verify that the network guru supports the protocol specified
-        Map<Network.Capability, String> caps = null;
+            // Verify that the network guru supports the protocol specified
+            Map<Network.Capability, String> caps = null;
 
-        if (purpose == Purpose.LoadBalancing) {
-            if (!_elbEnabled) {
-                caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Lb);
+            if (purpose == Purpose.LoadBalancing) {
+                if (!_elbEnabled) {
+                    caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Lb);
+                }
+            } else if (purpose == Purpose.PortForwarding) {
+                caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.PortForwarding);
+            }else if (purpose == Purpose.Firewall){
+                caps = _networkModel.getNetworkServiceCapabilities(network.getId(),Service.Firewall);
             }
-        } else if (purpose == Purpose.PortForwarding) {
-            caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.PortForwarding);
-        }
 
-        if (caps != null) {
-            String supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase();
-            if (!supportedProtocols.contains(proto.toLowerCase())) {
-                throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId());
-            } else if (proto.equalsIgnoreCase(NetUtils.ICMP_PROTO) && purpose != Purpose.Firewall) {
-                throw new InvalidParameterValueException("Protocol " + proto + " is currently supported only for rules with purpose " + Purpose.Firewall);
+            if (caps != null) {
+                String supportedProtocols;
+                String supportedTrafficTypes = null;
+                if (purpose == FirewallRule.Purpose.Firewall) {
+                    supportedTrafficTypes = caps.get(Capability.SupportedTrafficDirection).toLowerCase();
+                }
+
+                if (purpose == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress) {
+                    supportedProtocols = caps.get(Capability.SupportedEgressProtocols).toLowerCase();
+                } else {
+                    supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase();
+                }
+
+                if (!supportedProtocols.contains(proto.toLowerCase())) {
+                    throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId());
+                } else if (proto.equalsIgnoreCase(NetUtils.ICMP_PROTO) && purpose != Purpose.Firewall) {
+                    throw new InvalidParameterValueException("Protocol " + proto + " is currently supported only for rules with purpose " + Purpose.Firewall);
+                } else if (purpose == Purpose.Firewall && !supportedTrafficTypes.contains(trafficType.toString().toLowerCase())) {
+                    throw new InvalidParameterValueException("Traffic Type " + trafficType + " is currently supported by Firewall in network " + networkId);
+                }
             }
         }
     }
@@ -536,12 +600,18 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
     }
 
     @Override
-    public boolean applyFirewallRules(long ipId, Account caller) throws ResourceUnavailableException {
+    public boolean applyIngressFirewallRules(long ipId, Account caller) throws ResourceUnavailableException {
         List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(ipId, Purpose.Firewall);
         return applyFirewallRules(rules, false, caller);
     }
 
     @Override
+    public boolean applyEgressFirewallRules (FirewallRule rule, Account caller) throws ResourceUnavailableException {
+                List<FirewallRuleVO> rules = _firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), Purpose.Firewall, FirewallRule.TrafficType.Egress);
+                return applyFirewallRules(rules, false, caller);
+    }
+
+    @Override
     public boolean applyFirewallRules(List<FirewallRuleVO> rules, boolean continueOnError, Account caller) {
 
         if (rules.size() == 0) {
@@ -588,10 +658,19 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
         revokeRule(rule, caller, userId, false);
 
         boolean success = false;
+        Long networkId = rule.getNetworkId();
 
         if (apply) {
-            List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(rule.getSourceIpAddressId(), Purpose.Firewall);
-            return applyFirewallRules(rules, false, caller);
+            // ingress firewall rule
+            if (rule.getSourceIpAddressId() != null){ 
+                //feteches ingress firewall, ingress firewall rules associated with the ip
+                List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(rule.getSourceIpAddressId(), Purpose.Firewall);
+                return applyFirewallRules(rules, false, caller);
+                //egress firewall rule
+            } else if ( networkId != null){
+                List<FirewallRuleVO> rules = _firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), Purpose.Firewall, FirewallRule.TrafficType.Egress);
+                return applyFirewallRules(rules, false, caller);
+            }
         } else {
             success = true;
         }
@@ -686,7 +765,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
         List<String> oneCidr = new ArrayList<String>();
         oneCidr.add(NetUtils.ALL_CIDRS);
         return createFirewallRule(ipAddrId, caller, null, startPort, endPort, protocol, oneCidr, icmpCode, icmpType,
-                relatedRuleId, FirewallRule.FirewallRuleType.User, networkId);
+                relatedRuleId, FirewallRule.FirewallRuleType.User, networkId, FirewallRule.TrafficType.Ingress);
     }
 
     @Override
@@ -778,7 +857,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
         for (Long ipId : ipsToReprogram) {
             s_logger.debug("Applying firewall rules for ip address id=" + ipId + " as a part of vm expunge");
             try {
-                success = success && applyFirewallRules(ipId, _accountMgr.getSystemAccount());
+                success = success && applyIngressFirewallRules(ipId, _accountMgr.getSystemAccount());
             } catch (ResourceUnavailableException ex) {
                 s_logger.warn("Failed to apply port forwarding rules for ip id=" + ipId);
                 success = false;
@@ -794,7 +873,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ne
         for (FirewallRuleVO rule : systemRules) {
             try {
                 this.createFirewallRule(ip.getId(), acct, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(),
-                        rule.getSourceCidrList(), rule.getIcmpCode(), rule.getIcmpType(), rule.getRelated(), FirewallRuleType.System, rule.getNetworkId());
+                        rule.getSourceCidrList(), rule.getIcmpCode(), rule.getIcmpType(), rule.getRelated(), FirewallRuleType.System, rule.getNetworkId(), rule.getTrafficType());
             } catch (Exception e) {
                 s_logger.debug("Failed to add system wide firewall rule, due to:" + e.toString());
             }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/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 dfd5232..482c1fe 100755
--- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
+++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
@@ -1054,9 +1054,6 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
             throw ex;
         }
 
-        _firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(), 
-                Purpose.LoadBalancing, FirewallRuleType.User);
-
         Long networkId = ipAddr.getAssociatedWithNetworkId();
         if (networkId == null) {
             InvalidParameterValueException ex = new InvalidParameterValueException("Unable to create load balancer rule ; specified sourceip id is not associated with any network");
@@ -1064,6 +1061,10 @@ public class LoadBalancingRulesManagerImpl<Type> implements LoadBalancingRulesMa
             throw ex;
 
         }
+
+        _firewallMgr.validateFirewallRule(caller.getCaller(), ipAddr, srcPortStart, srcPortEnd, lb.getProtocol(),
+                Purpose.LoadBalancing, FirewallRuleType.User, networkId, null);
+
         NetworkVO network = _networkDao.findById(networkId);
 
         _accountMgr.checkAccess(caller.getCaller(), null, true, ipAddr);

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/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 156c3a6..132dbaa 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -40,8 +40,8 @@ import java.util.concurrent.TimeUnit;
 
 import javax.ejb.Local;
 import javax.naming.ConfigurationException;
-
 import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
+import com.cloud.agent.api.to.*;
 import org.apache.log4j.Logger;
 
 import com.cloud.agent.AgentManager;
@@ -2224,13 +2224,25 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
         s_logger.debug("Resending ipAssoc, port forwarding, load balancing rules as a part of Virtual router start");
       
         ArrayList<? extends PublicIpAddress> publicIps = getPublicIpsToApply(router, provider, guestNetworkId);
+        List<FirewallRule> firewallRulesEgress = new ArrayList<FirewallRule>();
+
+        //  Fetch firewall Egress rules.
+        if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) {
+            firewallRulesEgress.addAll(_rulesDao.listByNetworkPurposeTrafficType(guestNetworkId, Purpose.Firewall,FirewallRule.TrafficType.Egress));
+        }
+
+        // Re-apply firewall Egress rules
+        s_logger.debug("Found " + firewallRulesEgress.size() + " firewall Egress rule(s) to apply as a part of domR " + router + " start.");
+        if (!firewallRulesEgress.isEmpty()) {
+            createFirewallRulesCommands(firewallRulesEgress, router, cmds, guestNetworkId);
+        }
 
         if (publicIps != null && !publicIps.isEmpty()) {
             List<RemoteAccessVpn> vpns = new ArrayList<RemoteAccessVpn>();
             List<PortForwardingRule> pfRules = new ArrayList<PortForwardingRule>();
             List<FirewallRule> staticNatFirewallRules = new ArrayList<FirewallRule>();
             List<StaticNat> staticNats = new ArrayList<StaticNat>();
-            List<FirewallRule> firewallRules = new ArrayList<FirewallRule>();
+            List<FirewallRule> firewallRulesIngress = new ArrayList<FirewallRule>();
       
             //Get information about all the rules (StaticNats and StaticNatRules; PFVPN to reapply on domR start)
             for (PublicIpAddress ip : publicIps) {
@@ -2241,7 +2253,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
                     staticNatFirewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.StaticNat));
                 }
                 if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) {
-                    firewallRules.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall));
+                    firewallRulesIngress.addAll(_rulesDao.listByIpAndPurpose(ip.getId(), Purpose.Firewall));
                 }
       
                 if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Vpn, provider)) {
@@ -2259,17 +2271,17 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
                     }
                 }
             }
-   
-            //Re-apply static nats
+
+            // Re-apply static nats
             s_logger.debug("Found " + staticNats.size() + " static nat(s) to apply as a part of domR " + router + " start.");
             if (!staticNats.isEmpty()) {
                 createApplyStaticNatCommands(staticNats, router, cmds, guestNetworkId);
             }
-       
-            //Re-apply firewall rules
-            s_logger.debug("Found " + staticNats.size() + " firewall rule(s) to apply as a part of domR " + router + " start.");
-            if (!firewallRules.isEmpty()) {
-                createFirewallRulesCommands(firewallRules, router, cmds, guestNetworkId);
+
+            // Re-apply firewall Ingress rules
+            s_logger.debug("Found " + firewallRulesIngress.size() + " firewall Ingress rule(s) to apply as a part of domR " + router + " start.");
+            if (!firewallRulesIngress.isEmpty()) {
+                createFirewallRulesCommands(firewallRulesIngress, router, cmds, guestNetworkId);
             }
        
             // Re-apply port forwarding rules
@@ -2926,7 +2938,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
             int srcPort = rule.getSourcePortStart();
             List<LbDestination> destinations = rule.getDestinations();
             List<LbStickinessPolicy> stickinessPolicies = rule.getStickinessPolicies();
-            LoadBalancerTO lb = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, false, destinations, stickinessPolicies);
+            LoadBalancerTO lb = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, stickinessPolicies);
             lbs[i++] = lb;
         }
         String routerPublicIp = null;
@@ -3254,9 +3266,17 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
         if (rules != null) {
             rulesTO = new ArrayList<FirewallRuleTO>();
             for (FirewallRule rule : rules) {
-                IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
-                FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr());
-                rulesTO.add(ruleTO);
+                FirewallRule.TrafficType traffictype = rule.getTrafficType();
+                if(traffictype == FirewallRule.TrafficType.Ingress){
+                        IpAddress sourceIp = _networkModel.getIp(rule.getSourceIpAddressId());
+                        FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr(),Purpose.Firewall,traffictype);
+                        rulesTO.add(ruleTO);
+                }
+                else if (rule.getTrafficType() == FirewallRule.TrafficType.Egress){
+                        assert (rule.getSourceIpAddressId()==null) : "ipAddressId should be null for egress firewall rule. ";
+                        FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null,"",Purpose.Firewall,traffictype);
+                        rulesTO.add(ruleTO);
+                }
             }
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/server/src/com/cloud/network/rules/FirewallManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/rules/FirewallManager.java b/server/src/com/cloud/network/rules/FirewallManager.java
index 8473c56..25cce7c 100644
--- a/server/src/com/cloud/network/rules/FirewallManager.java
+++ b/server/src/com/cloud/network/rules/FirewallManager.java
@@ -45,7 +45,7 @@ public interface FirewallManager extends FirewallService {
     void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflictException;
 
     void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto,
-            Purpose purpose, FirewallRuleType type);
+            Purpose purpose, FirewallRuleType type, Long networkid, FirewallRule.TrafficType trafficType);
 
     boolean applyRules(List<? extends FirewallRule> rules, boolean continueOnError, boolean updateRulesInDB) throws ResourceUnavailableException;
 
@@ -68,8 +68,8 @@ public interface FirewallManager extends FirewallService {
      */
     boolean revokeFirewallRule(long ruleId, boolean apply, Account caller, long userId);
 
-    FirewallRule createFirewallRule(long ipAddrId, Account caller, String xId, Integer portStart, Integer portEnd, String protocol, List<String> sourceCidrList, Integer icmpCode, Integer icmpType, Long relatedRuleId,
-            FirewallRule.FirewallRuleType type, long networkId)
+    FirewallRule createFirewallRule(Long ipAddrId, Account caller, String xId, Integer portStart, Integer portEnd, String protocol, List<String> sourceCidrList, Integer icmpCode, Integer icmpType, Long relatedRuleId,
+            FirewallRule.FirewallRuleType type, Long networkId, FirewallRule.TrafficType traffictype)
             throws NetworkRuleConflictException;
 
     FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType, Long relatedRuleId, long networkId) throws NetworkRuleConflictException;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/server/src/com/cloud/network/rules/FirewallRuleVO.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/rules/FirewallRuleVO.java b/server/src/com/cloud/network/rules/FirewallRuleVO.java
index 63ace5b..e493673 100644
--- a/server/src/com/cloud/network/rules/FirewallRuleVO.java
+++ b/server/src/com/cloud/network/rules/FirewallRuleVO.java
@@ -45,7 +45,7 @@ import org.apache.cloudstack.api.InternalIdentity;
 @Table(name="firewall_rules")
 @Inheritance(strategy=InheritanceType.JOINED)
 @DiscriminatorColumn(name="purpose", discriminatorType=DiscriminatorType.STRING, length=32)
-public class FirewallRuleVO implements FirewallRule {
+public class FirewallRuleVO implements Identity, FirewallRule {
     protected final FirewallRulesCidrsDaoImpl _firewallRulesCidrsDao = ComponentLocator.inject(FirewallRulesCidrsDaoImpl.class);
 
     @Id
@@ -87,8 +87,8 @@ public class FirewallRuleVO implements FirewallRule {
     Date created;
 
     @Column(name="network_id")
-    long networkId;
-
+    Long networkId;
+    
     @Column(name="icmp_code")
     Integer icmpCode;
 
@@ -209,11 +209,6 @@ public class FirewallRuleVO implements FirewallRule {
         }
         this.accountId = accountId;
         this.domainId = domainId;
-
-        if (ipAddressId == null) {
-            assert (purpose == Purpose.NetworkACL) : "ipAddressId can be null for " + Purpose.NetworkACL + " only";
-        }
-
         this.sourceIpAddressId = ipAddressId;
         this.sourcePortStart = portStart;
         this.sourcePortEnd = portEnd;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/server/src/com/cloud/network/rules/RulesManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java
index fc12660..fe86a8e 100755
--- a/server/src/com/cloud/network/rules/RulesManagerImpl.java
+++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java
@@ -204,7 +204,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
         
         try {
             _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), 
-                    rule.getProtocol(), Purpose.PortForwarding, FirewallRuleType.User);
+                    rule.getProtocol(), Purpose.PortForwarding, FirewallRuleType.User, networkId, rule.getTrafficType());
 
             Long accountId = ipAddress.getAllocatedToAccountId();
             Long domainId = ipAddress.getAllocatedInDomainId();
@@ -323,7 +323,7 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager {
             throw new NetworkRuleConflictException("Can't do static nat on ip address: " + ipAddress.getAddress());
         }
 
-        _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.StaticNat, FirewallRuleType.User);
+        _firewallMgr.validateFirewallRule(caller, ipAddress, rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), Purpose.StaticNat, FirewallRuleType.User,null, rule.getTrafficType() );
 
         Long networkId = ipAddress.getAssociatedWithNetworkId();
         Long accountId = ipAddress.getAllocatedToAccountId();

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
index 81721ea..e360bca 100755
--- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
+++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java
@@ -269,7 +269,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
                     
                     //now apply vpn rules on the backend
                     s_logger.debug("Reapplying firewall rules for ip id=" + ipId + " as a part of disable remote access vpn");
-                    success = _firewallMgr.applyFirewallRules(ipId, caller);
+                    success = _firewallMgr.applyIngressFirewallRules(ipId, caller);
                 }
                 
                 if (success) {
@@ -383,7 +383,7 @@ public class RemoteAccessVpnManagerImpl implements RemoteAccessVpnService, Manag
         try {
             boolean firewallOpened = true;
             if (openFirewall) {
-                firewallOpened = _firewallMgr.applyFirewallRules(vpn.getServerAddressId(), caller);
+                firewallOpened = _firewallMgr.applyIngressFirewallRules(vpn.getServerAddressId(), caller);
             }
             
             if (firewallOpened) {

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/b6727e56/server/src/com/cloud/upgrade/dao/Upgrade40to41.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/upgrade/dao/Upgrade40to41.java b/server/src/com/cloud/upgrade/dao/Upgrade40to41.java
index cd9e20c..d3a8cd5 100644
--- a/server/src/com/cloud/upgrade/dao/Upgrade40to41.java
+++ b/server/src/com/cloud/upgrade/dao/Upgrade40to41.java
@@ -22,12 +22,22 @@ import com.cloud.utils.script.Script;
 
 import java.io.File;
 import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
 
 /**
  * @author htrippaers
  *
  */
 public class Upgrade40to41 implements DbUpgrade {
+	final static Logger s_logger = Logger.getLogger(Upgrade40to41.class);
 
 	/**
 	 *
@@ -78,7 +88,8 @@ public class Upgrade40to41 implements DbUpgrade {
 	 */
 	@Override
 	public void performDataMigration(Connection conn) {
-
+        upgradeEIPNetworkOfferings(conn);
+        upgradeEgressFirewallRules(conn);
 	}
 
 	/* (non-Javadoc)
@@ -89,4 +100,104 @@ public class Upgrade40to41 implements DbUpgrade {
 		return new File[0];
 	}
 
+    private void upgradeEIPNetworkOfferings(Connection conn) {
+        PreparedStatement pstmt = null;
+        ResultSet rs = null;
+
+        try {
+            pstmt = conn.prepareStatement("select id, elastic_ip_service from `cloud`.`network_offerings` where traffic_type='Guest'");
+            rs = pstmt.executeQuery();
+            while (rs.next()) {
+                long id = rs.getLong(1);
+                // check if elastic IP service is enabled for network offering
+                if (rs.getLong(2) != 0) {
+                    //update network offering with eip_associate_public_ip set to true
+                    pstmt = conn.prepareStatement("UPDATE `cloud`.`network_offerings` set eip_associate_public_ip=? where id=?");
+                    pstmt.setBoolean(1, true);
+                    pstmt.setLong(2, id);
+                    pstmt.executeUpdate();
+                }
+            }
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to set elastic_ip_service for network offerings with EIP service enabled.", e);
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (pstmt != null) {
+                    pstmt.close();
+                }
+            } catch (SQLException e) {
+            }
+        }
+    }
+
+
+    private void upgradeEgressFirewallRules(Connection conn) {
+        PreparedStatement pstmt = null;
+        ResultSet rs = null;
+        ResultSet rsId = null;
+        ResultSet rsNw = null;
+        try {
+            // update the existing ingress rules traffic type
+            pstmt = conn.prepareStatement("update `cloud`.`firewall_rules`  set traffic_type='Ingress' where purpose='Firewall' and ip_address_id is not null and traffic_type is null");
+            s_logger.debug("Updating firewall Ingress rule traffic type: " + pstmt);
+            pstmt.executeUpdate();
+
+            pstmt = conn.prepareStatement("select network_id FROM `cloud`.`ntwk_service_map` where service='Firewall' and provider='VirtualRouter' ");
+            rs = pstmt.executeQuery();
+            while (rs.next()) {
+                    long netId = rs.getLong(1);
+                    //When upgraded from 2.2.14 to 3.0.6 guest_type is updated to Isolated in the 2214to30 clean up sql. clean up executes
+                    //after this. So checking for Isolated OR Virtual
+                    pstmt = conn.prepareStatement("select account_id, domain_id FROM `cloud`.`networks` where (guest_type='Isolated' OR guest_type='Virtual') and traffic_type='Guest' and vpc_id is NULL and (state='implemented' OR state='Shutdown') and id=? ");
+                    pstmt.setLong(1, netId);
+                    s_logger.debug("Getting account_id, domain_id from networks table: " + pstmt);
+                    rsNw = pstmt.executeQuery();
+
+                    if(rsNw.next()) {
+                    long accountId = rsNw.getLong(1);
+                    long domainId = rsNw.getLong(2);
+
+                    //Add new rule for the existing networks
+                    s_logger.debug("Adding default egress firewall rule for network " + netId);
+                    pstmt = conn.prepareStatement("INSERT INTO firewall_rules (uuid, state, protocol, purpose, account_id, domain_id, network_id, xid, created,  traffic_type) VALUES (?, 'Active', 'all', 'Firewall', ?, ?, ?, ?, now(), 'Egress')");
+                    pstmt.setString(1, UUID.randomUUID().toString());
+                    pstmt.setLong(2, accountId);
+                    pstmt.setLong(3, domainId);
+                    pstmt.setLong(4, netId);
+                    pstmt.setString(5, UUID.randomUUID().toString());
+                    s_logger.debug("Inserting default egress firewall rule " + pstmt);
+                    pstmt.executeUpdate();
+
+                    pstmt = conn.prepareStatement("select id from firewall_rules where protocol='all' and network_id=?");
+                    pstmt.setLong(1, netId);
+                    rsId = pstmt.executeQuery();
+
+                    long firewallRuleId;
+                    if(rsId.next()) {
+                        firewallRuleId = rsId.getLong(1);
+                        pstmt = conn.prepareStatement("insert into firewall_rules_cidrs (firewall_rule_id,source_cidr) values (?, '0.0.0.0/0')");
+                        pstmt.setLong(1, firewallRuleId);
+                        s_logger.debug("Inserting rule for cidr 0.0.0.0/0 for the new Firewall rule id=" + firewallRuleId + " with statement " + pstmt);
+                        pstmt.executeUpdate();
+                    }
+                }
+            }
+        } catch (SQLException e) {
+            throw new CloudRuntimeException("Unable to set egress firewall rules ", e);
+        } finally {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                if (pstmt != null) {
+                    pstmt.close();
+                }
+            } catch (SQLException e) {
+            }
+        }
+    }
+
 }