ACL services for OS/OVS 65/10565/7
authorBrent Salisbury <brent.salisbury@gmail.com>
Mon, 1 Sep 2014 01:41:31 +0000 (21:41 -0400)
committerBrent Salisbury <brent.salisbury@gmail.com>
Thu, 4 Sep 2014 01:27:13 +0000 (21:27 -0400)
Patch #1:Ingress ACLs
Patch #2:Egress ACLs
Patch #3:Rebase and typos
Patch #4:Service exports patching
Patch #5:Added IngressACL Interface and verified flowmods
Patch #6:Deleted random .diff file in last commit

TODO:
-Break egress out of the IngressACLService into EgressACLService
Easier to tshoot colapsed.
-CRUD updates and deletes.
-Refactor GOTO instructs w/the pipeline mutator fromt the abstract
services parent for Egress ACL (completed for Ingress)

Change-Id: I2a7bea87e7d75b6b02c8ff6a43b60f881c4ade02
Signed-off-by: Brent Salisbury <brent.salisbury@gmail.com>
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/Activator.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/AbstractServiceInstance.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/OF13Provider.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/IngressAclService.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/Activator.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/IngressAclProvider.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/SecurityServicesManager.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SecurityServicesImpl.java [new file with mode: 0644]
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/MatchUtils.java

index 8638b34b5ae43d4e6ba6804869a4dde43a096891..ae68d15fb7cf1ec20e5f2aa2ebcad7ca32545e58 100644 (file)
@@ -21,10 +21,12 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.ArpProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.InboundNatProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.L3ForwardingProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.OutboundNatProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.RoutingProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow10.OF10Provider;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
@@ -160,9 +162,13 @@ public class Activator extends ComponentActivatorAbstractBase {
             c.add(createServiceDependency()
                           .setService(TenantNetworkManager.class)
                           .setRequired(true));
+            c.add(createServiceDependency()
+                    .setService(SecurityServicesManager.class)
+                    .setRequired(true));
             c.add(createServiceDependency().setService(OvsdbConfigurationService.class).setRequired(true));
             c.add(createServiceDependency().setService(OvsdbConnectionService.class).setRequired(true));
             c.add(createServiceDependency().setService(MdsalConsumer.class).setRequired(true));
+            c.add(createServiceDependency().setService(IngressAclProvider.class).setRequired(true));
         }
 
         if (imp.equals(PipelineOrchestratorImpl.class)) {
@@ -206,7 +212,8 @@ public class Activator extends ComponentActivatorAbstractBase {
             Properties properties = new Properties();
             properties.put(AbstractServiceInstance.SERVICE_PROPERTY, Service.INGRESS_ACL);
             properties.put(Constants.PROVIDER_NAME_PROPERTY, OF13Provider.NAME);
-            c.setInterface(AbstractServiceInstance.class.getName(), properties);
+            c.setInterface(new String[]{AbstractServiceInstance.class.getName(),
+                                        IngressAclProvider.class.getName()}, properties);
         }
 
         if (imp.equals(LoadBalancerService.class)) {
@@ -246,13 +253,6 @@ public class Activator extends ComponentActivatorAbstractBase {
             c.setInterface(AbstractServiceInstance.class.getName(), properties);
         }
 
-        if (imp.equals(IngressAclService.class)) {
-            Properties properties = new Properties();
-            properties.put(AbstractServiceInstance.SERVICE_PROPERTY, Service.INGRESS_ACL);
-            properties.put(Constants.PROVIDER_NAME_PROPERTY, OF13Provider.NAME);
-            c.setInterface(AbstractServiceInstance.class.getName(), properties);
-        }
-
         if (imp.equals(OutboundNatService.class)) {
             Properties properties = new Properties();
             properties.put(AbstractServiceInstance.SERVICE_PROPERTY, Service.OUTBOUND_NAT);
index 9fdc6fb3cb17b7c57b9d59c697a6f45f25eb6ce0..efc39c0a6666fb1085388740a0f2dc39c237f9d3 100644 (file)
@@ -120,7 +120,7 @@ public abstract class AbstractServiceInstance implements OpendaylightInventoryLi
         thread.start();
     }
 
-    private NodeBuilder createNodeBuilder(String nodeId) {
+    public NodeBuilder createNodeBuilder(String nodeId) {
         NodeBuilder builder = new NodeBuilder();
         builder.setId(new NodeId(nodeId));
         builder.setKey(new NodeKey(builder.getId()));
index 6483858665486398a5990da3caa5826c46233d65..6248a95abb94130149b489a28abd6a97b562020b 100644 (file)
@@ -9,8 +9,13 @@
  */
 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13;
 
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutionException;
+
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
@@ -18,25 +23,28 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.utils.HexEncode;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.ovsdb.lib.notation.Row;
 import org.opendaylight.ovsdb.lib.notation.UUID;
-import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler;
 import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
 import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
-import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
-import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
 import org.opendaylight.ovsdb.plugin.api.StatusWithUuid;
 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
 import org.opendaylight.ovsdb.schema.openvswitch.Port;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase;
@@ -84,19 +92,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ExecutionException;
+import com.google.common.util.concurrent.CheckedFuture;
 
 /**
  * Open vSwitch OpenFlow 1.3 Networking Provider for OpenStack Neutron
@@ -116,6 +119,8 @@ public class OF13Provider implements NetworkingProvider {
     private volatile OvsdbConfigurationService ovsdbConfigurationService;
     private volatile OvsdbConnectionService connectionService;
     private volatile MdsalConsumer mdsalConsumer;
+    private volatile SecurityServicesManager securityServicesManager;
+    private volatile IngressAclProvider ingressAclProvider;
 
     public static final String NAME = "OF13Provider";
 
@@ -822,7 +827,19 @@ public class OF13Provider implements NetworkingProvider {
             if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
                 logger.debug("Program local vlan rules for interface {}", intf.getName());
                 programLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort);
-            } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) ||
+            }
+            /* If the network type is tunnel based (VXLAN/GRRE/etc) with Neutron Port Security ACLs */
+            if ((networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) || networkType.equalsIgnoreCase
+                    (NetworkHandler.NETWORK_TYPE_VXLAN)) && securityServicesManager.isPortSecurityReady(intf)) {
+                logger.debug("Neutron port has a Port Security Group");
+                /* Retrieve the security group UUID from the Neutron Port */
+                NeutronSecurityGroup securityGroupInPort = securityServicesManager.getSecurityGroupInPort(intf);
+                logger.debug("Program Local rules for networkType: {} does contain a Port Security Group: {} " +
+                        "to be installed on DPID: {}", networkType, securityGroupInPort, dpid);
+                ingressAclProvider.programPortSecurityACL(node, dpid, segmentationId, attachedMac, localPort,
+                        securityGroupInPort);
+            }
+            else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) ||
                        networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) {
                 logger.debug("Program local bridge rules for interface {}", intf.getName());
                 programLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort);
index b77643a713edbdfae7c81936b127c9d837a72a44..b8ceb95207c018eeaf2a2aa4cbc9fba070d52228 100644 (file)
@@ -9,10 +9,59 @@
  */
 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
 
+import java.math.BigInteger;
+import java.util.List;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+
+public class IngressAclService extends AbstractServiceInstance implements IngressAclProvider {
+
+    static final Logger logger = LoggerFactory.getLogger(IngressAclService.class);
+    public static final Integer PROTO_MATCH_PRIORITY_DROP = 36006;
+    public static final Integer PROTO_PORT_MATCH_PRIORITY_DROP = 36005;
+    public static final Integer PREFIX_MATCH_PRIORITY_DROP = 36004;
+    public static final Integer PROTO_PREFIX_MATCH_PRIORITY_DROP = 36003;
+    public static final Integer PREFIX_PORT_MATCH_PRIORITY_DROP = 36002;
+    public static final Integer PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP = 36001;
+
+    public static final Integer PROTO_MATCH_PRIORITY = 61010;
+    public static final Integer PREFIX_MATCH_PRIORITY = 61009;
+    public static final Integer PROTO_PREFIX_MATCH_PRIORITY = 61008;
+    public static final Integer PROTO_PORT_MATCH_PRIORITY = 61007;
+    public static final Integer PROTO_PORT_PREFIX_MATCH_PRIORITY = 61007;
+
+    public static final int TCP_SYN = 0x002;
+    public static final short INGRESS_ACL = 40; // Flows Destined to the VM Port go here
+    // TODO: break out egress to the egress table and create a parent for both ingress/egress
+    public static final short EGRESS_ACL = 100; // Flows Sourced from the VM Port go here
+    public static final short OUTBOUND_SNAT = 110; // Ingress ACL table drains traffic to this table
+
+    private static final String OPENFLOW = "openflow:";
+    private static Long groupId = 1L;
 
-public class IngressAclService extends AbstractServiceInstance {
     public IngressAclService() {
         super(Service.INGRESS_ACL);
     }
@@ -22,7 +71,820 @@ public class IngressAclService extends AbstractServiceInstance {
     }
 
     @Override
-    public boolean isBridgeInPipeline (String nodeId) {
+    public boolean isBridgeInPipeline(String nodeId) {
         return true;
     }
-}
\ No newline at end of file
+
+    @Override
+    public void programPortSecurityACL(Node node, Long dpid, String segmentationId, String attachedMac,
+            long localPort, NeutronSecurityGroup securityGroup) {
+
+        logger.trace("programLocalBridgeRulesWithSec neutronSecurityGroup: {} ", securityGroup);
+        List<NeutronSecurityRule> portSecurityList = securityGroup.getSecurityRules();
+        /* Iterate over the Port Security Rules in the Port Security Group bound to the port*/
+        for (NeutronSecurityRule portSecurityRule : portSecurityList) {
+            /**
+             * Neutron Port Security ACL "ingress" and "IPv4"
+             *
+             * Check that the base conditions for flow based Port Security are true:
+             * Port Security Rule Direction ("ingress") and Protocol ("IPv4")
+             * Neutron defines the direction "ingress" as the vSwitch to the VM as defined in:
+             * http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
+             *
+             */
+            if (portSecurityRule.getSecurityRuleEthertype().equalsIgnoreCase("IPv4") &&
+                    portSecurityRule.getSecurityRuleDirection().equalsIgnoreCase("ingress")) {
+                logger.debug("ACL Rule matching IPv4 and ingress is: {} ", portSecurityRule);
+                /**
+                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (True)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
+                        !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
+                        (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
+                                !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
+                                        .equalsIgnoreCase("0.0.0.0/0"))) {
+                    logger.debug("Rule #1 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
+                            PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
+                            true);
+                    ingressACLTcpPortWithPrefix(dpid, segmentationId,
+                            attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                    continue;
+                }
+                /**
+                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (True)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
+                        !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
+                        (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
+                                !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
+                                        .equalsIgnoreCase("0.0.0.0/0"))) {
+                    logger.debug("Rule #2 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
+                            PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
+                            true);
+                    ingressACLTcpPortWithPrefix(dpid, segmentationId,
+                            attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                    continue;
+                }
+                /**
+                 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
+                        !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
+                    logger.debug("Rule #3 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PROTO_PREFIX_MATCH_PRIORITY_DROP,
+                            true);
+                    ingressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), PROTO_PREFIX_MATCH_PRIORITY);
+                    continue;
+                }
+                /**
+                 * TCP Proto (False), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
+                                !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
+                                        .equalsIgnoreCase("0.0.0.0/0"))) {
+                    logger.debug("Rule #4 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PREFIX_MATCH_PRIORITY_DROP, true);
+                    ingressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), PREFIX_MATCH_PRIORITY);
+                    continue;
+                }
+                /**
+                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (False)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
+                        !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
+                    logger.debug("Rule #5 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PROTO_PORT_MATCH_PRIORITY_DROP,
+                            true);
+                    ingressACLTcpSyn(dpid, segmentationId,
+                            attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
+                            PREFIX_PORT_MATCH_PRIORITY_DROP);
+                    continue;
+                }
+                /**
+                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (False)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
+                        !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
+                    logger.debug("Rule #6 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
+                            PROTO_PORT_MATCH_PRIORITY_DROP, true);
+                    ingressACLTcpSyn(dpid, segmentationId, attachedMac, true,
+                            portSecurityRule.getSecurityRulePortMin(), PROTO_PORT_MATCH_PRIORITY);
+                    continue;
+                }
+                /**
+                 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (False or 0.0.0.0/0)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
+                        ((String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) ||
+                                String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
+                                        .equalsIgnoreCase("0.0.0.0/0"))) {
+                    logger.debug("Rule #7 ingress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    // No need to drop until UDP/ICMP are implemented
+                    // ingressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PROTO_MATCH_PRIORITY_DROP, true);
+                    handleIngressAllowProto(dpid, segmentationId, attachedMac, true,
+                            portSecurityRule.getSecurityRuleProtocol(), PROTO_MATCH_PRIORITY);
+                    continue;
+                }
+                logger.debug("Ingress ACL Match combination not found for rule: {}", portSecurityRule);
+            }
+
+            /**
+             * Neutron Port Security ACL "egress" and "IPv4"
+             *
+             * Check that the base conditions for flow based Port Security are true:
+             * Port Security Rule Direction ("egress") and Protocol ("IPv4")
+             * Neutron defines the direction "ingress" as the vSwitch to the VM as defined in:
+             * http://docs.openstack.org/api/openstack-network/2.0/content/security_groups.html
+             *
+             */
+            if (portSecurityRule.getSecurityRuleEthertype().equalsIgnoreCase("IPv4") &&
+                    portSecurityRule.getSecurityRuleDirection().equalsIgnoreCase("egress")) {
+                logger.debug("Egress IPV4 ACL  Port Security Rule: {} ", portSecurityRule);
+                // TODO Move to EgressAclService and Implement Port Range
+
+                /**
+                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (True)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
+                        !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
+                        (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
+                                !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
+                                        .equalsIgnoreCase("0.0.0.0/0"))) {
+                    logger.debug("Rule #1 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
+                            PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
+                            true);
+                    egressACLTcpPortWithPrefix(dpid, segmentationId,
+                            attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                    continue;
+                }
+                /**
+                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (True)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
+                        !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
+                        (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
+                                !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
+                                        .equalsIgnoreCase("0.0.0.0/0"))) {
+                    logger.debug("Rule #2 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
+                            PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP,
+                            true);
+                    egressACLTcpPortWithPrefix(dpid, segmentationId,
+                            attachedMac, true, portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                    continue;
+                }
+                /**
+                 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
+                        !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
+                    logger.debug("Rule #3 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PROTO_PREFIX_MATCH_PRIORITY_DROP,
+                            true);
+                    egressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), PROTO_PREFIX_MATCH_PRIORITY);
+                    continue;
+                }
+                /**
+                 * TCP Proto (False), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (True)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        (!String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null") &&
+                                !String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
+                                        .equalsIgnoreCase("0.0.0.0/0"))) {
+                    logger.debug("Rule #4 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PREFIX_MATCH_PRIORITY_DROP, true);
+                    egressACLPermitAllProto(dpid, segmentationId, attachedMac, true,
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix(), PREFIX_MATCH_PRIORITY);
+                    continue;
+                }
+                /**
+                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (True), IP Prefix (False)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
+                        !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        !String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
+                    logger.debug("Rule #5 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PROTO_PORT_MATCH_PRIORITY_DROP,
+                            true);
+                    egressACLTcpSyn(dpid, segmentationId,
+                            attachedMac, true, portSecurityRule.getSecurityRulePortMin(), PROTO_PORT_MATCH_PRIORITY);
+                    continue;
+                }
+                /**
+                 * TCP Proto (True), TCP Port Minimum (True), TCP Port Max (False), IP Prefix (False)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
+                        !String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) {
+                    logger.debug("Rule #6 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac,
+                            PROTO_PORT_MATCH_PRIORITY_DROP, true);
+                    egressACLTcpSyn(dpid, segmentationId, attachedMac, true,
+                            portSecurityRule.getSecurityRulePortMin(), PROTO_PORT_MATCH_PRIORITY);
+                    continue;
+                }
+                /**
+                 * TCP Proto (True), TCP Port Minimum (False), TCP Port Max (False), IP Prefix (False or 0.0.0.0/0)
+                 */
+                if (String.valueOf(portSecurityRule.getSecurityRuleProtocol()).equalsIgnoreCase("tcp") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMin()).equalsIgnoreCase("null") &&
+                        String.valueOf(portSecurityRule.getSecurityRulePortMax()).equalsIgnoreCase("null") &&
+                        ((String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix()).equalsIgnoreCase("null")) ||
+                                String.valueOf(portSecurityRule.getSecurityRuleRemoteIpPrefix())
+                                        .equalsIgnoreCase("0.0.0.0/0"))) {
+                    logger.debug("Rule #7 egress PortSec Rule Matches -> TCP Protocol: {}, TCP Port Min: {}, TCP Port Max: {}, IP Prefix: {}",
+                            portSecurityRule.getSecurityRuleProtocol(), portSecurityRule.getSecurityRulePortMin(),
+                            portSecurityRule.getSecurityRulePortMax(),
+                            portSecurityRule.getSecurityRuleRemoteIpPrefix());
+                    // No need to drop until UDP/ICMP are implemented
+                    // egressACLDefaultTcpDrop(dpid, segmentationId, attachedMac, PROTO_MATCH_PRIORITY_DROP, true);
+                    egressAllowProto(dpid, segmentationId, attachedMac, true,
+                            portSecurityRule.getSecurityRuleProtocol(), PROTO_MATCH_PRIORITY);
+                    continue;
+                }
+                logger.debug("ACL Match combination not found for rule: {}", portSecurityRule);
+
+            }
+        }
+    }
+
+    public void ingressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
+            Integer securityRulePortMin, Integer protoPortMatchPriority) {
+
+        String nodeName = OPENFLOW + dpidLong;
+        PortNumber tcpPort = new PortNumber(securityRulePortMin);
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        flowBuilder.setMatch(MatchUtils.createDmacTcpSynMatch(matchBuilder, attachedMac, tcpPort,
+                TCP_SYN, segmentationId).build());
+
+        logger.debug("ingressACLTcpSyn MatchBuilder contains:  {}", flowBuilder.getMatch());
+        String flowId = "UcastOut_ACL2" + segmentationId + "_" + attachedMac + securityRulePortMin;
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(false);
+        flowBuilder.setPriority(protoPortMatchPriority);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(INGRESS_ACL);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            // Instantiate the Builders for the OF Actions and Instructions
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructionsList = Lists.newArrayList();
+
+            ib = this.getMutablePipelineInstructionBuilder();
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructionsList.add(ib.build());
+            isb.setInstruction(instructionsList);
+
+            logger.debug("Instructions are: {}", ib.getInstruction());
+            // Add InstructionsBuilder to FlowBuilder
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            // removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    public void ingressACLTcpPortWithPrefix(Long dpidLong, String segmentationId, String attachedMac,
+            boolean write, Integer securityRulePortMin, String securityRuleIpPrefix,
+            Integer protoPortPrefixMatchPriority) {
+
+        String nodeName = OPENFLOW + dpidLong;
+        PortNumber tcpPort = new PortNumber(securityRulePortMin);
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = this.createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+        Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
+
+        flowBuilder.setMatch(MatchUtils
+                .createDmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
+                        tcpPort, TCP_SYN, segmentationId, srcIpPrefix).build());
+
+        logger.debug(" MatchBuilder contains:  {}", flowBuilder.getMatch());
+        String flowId = "UcastOut2_" + segmentationId + "_" + attachedMac +
+                securityRulePortMin + securityRuleIpPrefix;
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(false);
+        flowBuilder.setPriority(protoPortPrefixMatchPriority);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(INGRESS_ACL);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            // Instantiate the Builders for the OF Actions and Instructions
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+
+            List<Instruction> instructionsList = Lists.newArrayList();
+            ib = this.getMutablePipelineInstructionBuilder();
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructionsList.add(ib.build());
+            isb.setInstruction(instructionsList);
+
+            logger.debug("Instructions contain: {}", ib.getInstruction());
+            // Add InstructionsBuilder to FlowBuilder
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            // removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    public void handleIngressAllowProto(Long dpidLong, String segmentationId, String attachedMac, boolean write,
+            String securityRuleProtcol, Integer protoMatchPriority) {
+
+        String nodeName = OPENFLOW + dpidLong;
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        flowBuilder.setMatch(MatchUtils
+                .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
+        flowBuilder.setMatch(MatchUtils
+                .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
+        logger.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
+
+        String flowId = "UcastOut_" + segmentationId + "_" +
+                attachedMac + "_AllowTCPSynPrefix_" + securityRuleProtcol;
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(false);
+        flowBuilder.setPriority(protoMatchPriority);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(INGRESS_ACL);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            // Instantiate the Builders for the OF Actions and Instructions
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructionsList = Lists.newArrayList();
+
+            ib = this.getMutablePipelineInstructionBuilder();
+            ib.setOrder(1);
+            ib.setKey(new InstructionKey(1));
+            instructionsList.add(ib.build());
+            isb.setInstruction(instructionsList);
+            logger.debug("Instructions contain: {}", ib.getInstruction());
+
+            // Add InstructionsBuilder to FlowBuilder
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            // removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+
+    public void ingressACLDefaultTcpDrop(Long dpidLong, String segmentationId, String attachedMac,
+            int priority, boolean write) {
+
+        String nodeName = OPENFLOW + dpidLong;
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        flowBuilder.setMatch(MatchUtils.createDmacTcpPortWithFlagMatch(matchBuilder,
+                attachedMac, TCP_SYN, segmentationId).build());
+
+        logger.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
+        String flowId = "PortSec_TCP_Syn_Default_Drop_" + attachedMac;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(false);
+        flowBuilder.setPriority(priority);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(INGRESS_ACL);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            // Instantiate the Builders for the OF Actions and Instructions
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+
+            // Instructions List Stores Individual Instructions
+            List<Instruction> instructions = Lists.newArrayList();
+
+            // Set the Output Port/Iface
+            InstructionUtils.createDropInstructions(ib);
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructions.add(ib.build());
+
+            // Add InstructionBuilder to the Instruction(s)Builder List
+            isb.setInstruction(instructions);
+            logger.debug("Instructions contain: {}", ib.getInstruction());
+            // Add InstructionsBuilder to FlowBuilder
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            // removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    public void ingressACLPermitAllProto(Long dpidLong, String segmentationId, String attachedMac,
+            boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
+
+        String nodeName = OPENFLOW + dpidLong;
+        Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
+                .build());
+        if (securityRuleIpPrefix != null) {
+            flowBuilder.setMatch(MatchUtils
+                    .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
+                    .build());
+        } else {
+            flowBuilder.setMatch(MatchUtils
+                    .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
+                    .build());
+        }
+
+        logger.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
+        String flowId = "IngressProto_ACL_" + segmentationId + "_" +
+                attachedMac + "_Permit_" + securityRuleIpPrefix;
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(false);
+        flowBuilder.setPriority(protoPortMatchPriority);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(INGRESS_ACL);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            // Instantiate the Builders for the OF Actions and Instructions
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructionsList = Lists.newArrayList();
+
+            ib = this.getMutablePipelineInstructionBuilder();
+            ib.setOrder(1);
+            ib.setKey(new InstructionKey(0));
+            instructionsList.add(ib.build());
+            isb.setInstruction(instructionsList);
+
+            logger.debug("Instructions contain: {}", ib.getInstruction());
+            // Add InstructionsBuilder to FlowBuilder
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            // // removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    public void egressACLDefaultTcpDrop(Long dpidLong, String segmentationId, String attachedMac,
+            int priority, boolean write) {
+
+        String nodeName = OPENFLOW + dpidLong;
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        flowBuilder.setMatch(MatchUtils.createSmacTcpPortWithFlagMatch(matchBuilder,
+                attachedMac, TCP_SYN, segmentationId).build());
+        logger.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
+
+        String flowId = "TCP_Syn_Egress_Default_Drop_" + attachedMac;
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(false);
+        flowBuilder.setPriority(priority);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(EGRESS_ACL);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            // Instantiate the Builders for the OF Actions and Instructions
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructions = Lists.newArrayList();
+
+            InstructionUtils.createDropInstructions(ib);
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructions.add(ib.build());
+            // Add InstructionBuilder to the Instruction(s)Builder List
+            isb.setInstruction(instructions);
+
+            logger.debug("Instructions contain: {}", ib.getInstruction());
+            // Add InstructionsBuilder to FlowBuilder
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            // TODO Add // removeFlow to AnstractServiceInstance
+            //// removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    public void egressACLTcpPortWithPrefix(Long dpidLong, String segmentationId, String attachedMac, boolean write,
+            Integer securityRulePortMin, String securityRuleIpPrefix, Integer protoPortPrefixMatchPriority) {
+
+        String nodeName = OPENFLOW + dpidLong;
+        PortNumber tcpPort = new PortNumber(securityRulePortMin);
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+        Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
+
+        flowBuilder.setMatch(MatchUtils
+                .createSmacTcpSynDstIpPrefixTcpPort(matchBuilder, new MacAddress(attachedMac),
+                        tcpPort, TCP_SYN, segmentationId, srcIpPrefix).build());
+
+        logger.debug(" MatchBuilder contains:  {}", flowBuilder.getMatch());
+        String flowId = "UcastEgress_" + segmentationId + "_" + attachedMac +
+                securityRulePortMin + securityRuleIpPrefix;
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(false);
+        flowBuilder.setPriority(protoPortPrefixMatchPriority);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(EGRESS_ACL);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            // Instantiate the Builders for the OF Actions and Instructions
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructionsList = Lists.newArrayList();
+
+            InstructionUtils.createGotoTableInstructions(ib, OUTBOUND_SNAT);
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructionsList.add(ib.build());
+            isb.setInstruction(instructionsList);
+
+            logger.debug("Instructions contain: {}", ib.getInstruction());
+            // Add InstructionsBuilder to FlowBuilder
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            // TODO Add // removeFlow to AnstractServiceInstance
+            //// removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+
+
+    public void egressAllowProto(Long dpidLong, String segmentationId, String attachedMac, boolean write,
+            String securityRuleProtcol, Integer protoMatchPriority) {
+
+        String nodeName = OPENFLOW + dpidLong;
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        flowBuilder.setMatch(MatchUtils
+                .createDmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null).build());
+        flowBuilder.setMatch(MatchUtils
+                .createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build());
+
+        logger.debug("MatchBuilder contains:  {}", flowBuilder.getMatch());
+        String flowId = "EgressAllProto_" + segmentationId + "_" +
+                attachedMac + "_AllowEgressTCPSyn_" + securityRuleProtcol;
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(false);
+        flowBuilder.setPriority(protoMatchPriority);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(EGRESS_ACL);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            // Instantiate the Builders for the OF Actions and Instructions
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructionsList = Lists.newArrayList();
+
+            InstructionUtils.createGotoTableInstructions(ib, OUTBOUND_SNAT);
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructionsList.add(ib.build());
+            isb.setInstruction(instructionsList);
+
+            logger.debug("Instructions contain: {}", ib.getInstruction());
+            // Add InstructionsBuilder to FlowBuilder
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            // removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+    public void egressACLPermitAllProto(Long dpidLong, String segmentationId, String attachedMac,
+            boolean write, String securityRuleIpPrefix, Integer protoPortMatchPriority) {
+
+        String nodeName = OPENFLOW + dpidLong;
+        Ipv4Prefix srcIpPrefix = new Ipv4Prefix(securityRuleIpPrefix);
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId))
+                .build());
+        if (securityRuleIpPrefix != null) {
+            flowBuilder.setMatch(MatchUtils
+                    .createSmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, srcIpPrefix)
+                    .build());
+        } else {
+            flowBuilder.setMatch(MatchUtils
+                    .createSmacIpTcpSynMatch(matchBuilder, new MacAddress(attachedMac), null, null)
+                    .build());
+        }
+        logger.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
+        String flowId = "Egress_Proto_ACL" + segmentationId + "_" +
+                attachedMac + "_Permit_" + securityRuleIpPrefix;
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(false);
+        flowBuilder.setPriority(protoPortMatchPriority);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(EGRESS_ACL);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            // Instantiate the Builders for the OF Actions and Instructions
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructionsList = Lists.newArrayList();
+
+            InstructionUtils.createGotoTableInstructions(ib, OUTBOUND_SNAT);
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructionsList.add(ib.build());
+            isb.setInstruction(instructionsList);
+
+            logger.debug("Instructions contain: {}", ib.getInstruction());
+            // Add InstructionsBuilder to FlowBuilder
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            // removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+
+
+    public void egressACLTcpSyn(Long dpidLong, String segmentationId, String attachedMac, boolean write,
+            Integer securityRulePortMin, Integer protoPortMatchPriority) {
+
+        String nodeName = OPENFLOW + dpidLong;
+        PortNumber tcpPort = new PortNumber(securityRulePortMin);
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
+        FlowBuilder flowBuilder = new FlowBuilder();
+
+        flowBuilder.setMatch(MatchUtils.createSmacTcpSyn(matchBuilder, attachedMac, tcpPort,
+                TCP_SYN, segmentationId).build());
+
+        logger.debug("MatchBuilder contains: {}", flowBuilder.getMatch());
+        String flowId = "Ucast_Egress_ACL" + segmentationId + "_" + attachedMac + securityRulePortMin;
+        // Add Flow Attributes
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setStrict(false);
+        flowBuilder.setPriority(protoPortMatchPriority);
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(EGRESS_ACL);
+        flowBuilder.setKey(key);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        if (write) {
+            // Instantiate the Builders for the OF Actions and Instructions
+            InstructionBuilder ib = new InstructionBuilder();
+            InstructionsBuilder isb = new InstructionsBuilder();
+            List<Instruction> instructionsList = Lists.newArrayList();
+
+            InstructionUtils.createGotoTableInstructions(ib, OUTBOUND_SNAT);
+            ib.setOrder(0);
+            ib.setKey(new InstructionKey(0));
+            instructionsList.add(ib.build());
+            isb.setInstruction(instructionsList);
+
+            logger.debug("Instructions contain: {}", ib.getInstruction());
+            // Add InstructionsBuilder to FlowBuilder
+            flowBuilder.setInstructions(isb.build());
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            // removeFlow(flowBuilder, nodeBuilder);
+        }
+    }
+}
index 907aeaa32026f7752f36ef5b49a1aeb1a9110d4e..5e38d1507743d191ebb373d13c45a803ea535b5a 100644 (file)
@@ -42,6 +42,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProviderManager;
 import org.opendaylight.ovsdb.openstack.netvirt.api.OutboundNatProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.RoutingProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
 import org.opendaylight.ovsdb.openstack.netvirt.api.VlanConfigurationCache;
 import org.opendaylight.ovsdb.openstack.netvirt.impl.BridgeConfigurationManagerImpl;
@@ -50,6 +51,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.impl.EventDispatcherImpl;
 import org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter;
 import org.opendaylight.ovsdb.openstack.netvirt.impl.OpenstackRouter;
 import org.opendaylight.ovsdb.openstack.netvirt.impl.ProviderNetworkManagerImpl;
+import org.opendaylight.ovsdb.openstack.netvirt.impl.SecurityServicesImpl;
 import org.opendaylight.ovsdb.openstack.netvirt.impl.TenantNetworkManagerImpl;
 import org.opendaylight.ovsdb.openstack.netvirt.impl.VlanConfigurationCacheImpl;
 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
@@ -108,7 +110,8 @@ public class Activator extends ComponentActivatorAbstractBase {
                         LBaaSHandler.class,
                         LBaaSPoolMemberHandler.class,
                         NeutronL3Adapter.class,
-                        OpenstackRouter.class};
+                        OpenstackRouter.class,
+                        SecurityServicesImpl.class};
         return res;
     }
 
@@ -275,11 +278,16 @@ public class Activator extends ComponentActivatorAbstractBase {
             Properties portSecurityHandlerProperties = new Properties();
             portSecurityHandlerProperties.put(Constants.EVENT_HANDLER_TYPE_PROPERTY,
                                               AbstractEvent.HandlerType.NEUTRON_PORT_SECURITY);
-            c.setInterface(new String[] {INeutronSecurityRuleAware.class.getName(),
-                                         INeutronSecurityGroupAware.class.getName(),
-                                         AbstractHandler.class.getName()},
+            c.setInterface(new String[]{INeutronSecurityRuleAware.class.getName(),
+                                        INeutronSecurityGroupAware.class.getName(),
+                            AbstractHandler.class.getName()},
                            portSecurityHandlerProperties);
             c.add(createServiceDependency().setService(EventDispatcher.class).setRequired(true));
+            c.add(createServiceDependency().setService(SecurityServicesManager.class).setRequired(true));
+        }
+
+        if (imp.equals(SecurityServicesImpl.class)) {
+            c.setInterface(new String[] {SecurityServicesManager.class.getName()}, null);
         }
 
         if (imp.equals(FWaasHandler.class)) {
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/IngressAclProvider.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/IngressAclProvider.java
new file mode 100644 (file)
index 0000000..f61cc1e
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.api;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup;
+import org.opendaylight.controller.sal.core.Node;
+
+/**
+ *  This interface allows Port Security flows to be written to devices
+ */
+public interface IngressAclProvider {
+
+    /**
+     * Program port security ACL.
+     *
+     * @param node the node
+     * @param dpid the dpid
+     * @param segmentationId the segmentation id
+     * @param attachedMac the attached mac
+     * @param localPort the local port
+     * @param securityGroup the security group
+     */
+    public void programPortSecurityACL(Node node, Long dpid, String segmentationId, String attachedMac,
+            long localPort, NeutronSecurityGroup securityGroup);
+}
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/SecurityServicesManager.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/SecurityServicesManager.java
new file mode 100644 (file)
index 0000000..7904dbf
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ *
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.api;
+
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.schema.openvswitch.Interface;
+
+/**
+ * Open vSwitch isolates Tenant Networks using VLANs on the Integration Bridge
+ * This class manages the provisioning of these VLANs
+ */
+public interface SecurityServicesManager {
+    /**
+     * Is port security ready.
+     *
+     * @param intf the intf
+     * @return the boolean
+     */
+    public boolean isPortSecurityReady(Interface intf);
+    /**
+     * Gets security group in port.
+     *
+     * @param intf the intf
+     * @return the security group in port
+     */
+    public NeutronSecurityGroup getSecurityGroupInPort(Interface intf);
+
+}
\ No newline at end of file
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SecurityServicesImpl.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SecurityServicesImpl.java
new file mode 100644 (file)
index 0000000..cf912dc
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.ovsdb.openstack.netvirt.impl;
+
+import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
+
+import org.opendaylight.ovsdb.schema.openvswitch.Interface;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Map;
+
+public class SecurityServicesImpl implements SecurityServicesManager {
+
+    static final Logger logger = LoggerFactory.getLogger(TenantNetworkManagerImpl.class);
+
+    public SecurityServicesImpl() {
+    }
+
+    /**
+     * Is security group ready.
+     *
+     * @param intf the intf
+     * @return the boolean
+     */
+    public boolean isPortSecurityReady(Interface intf) {
+        logger.trace("getTenantNetworkForInterface for {}", intf);
+        if (intf == null) return false;
+        Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
+        logger.trace("externalIds {}", externalIds);
+        if (externalIds == null) return false;
+        String neutronPortId = externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID);
+        if (neutronPortId == null) return false;
+        INeutronPortCRUD neutronPortService = (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class,
+                this);
+        NeutronPort neutronPort = neutronPortService.getPort(neutronPortId);
+        String deviceOwner = neutronPort.getDeviceOwner();
+        if (!deviceOwner.contains("compute")) {
+            logger.debug("Port {} is not a compute host, it is a: {}", neutronPortId, deviceOwner);
+        }
+        logger.debug("isPortSecurityReady() is a {} ", deviceOwner);
+        List<NeutronSecurityGroup> securityGroups = neutronPort.getSecurityGroups();
+        if (securityGroups.isEmpty()) {
+            logger.debug("Check for device: {} does not contain a Security Group for port: {}", deviceOwner,
+                    neutronPortId);
+            return false;
+        }
+        try {
+            String vmPort = externalIds.get("attached-mac");
+        } catch(Exception e) {
+            logger.debug("Error VMID did *NOT* work");
+        }
+        logger.debug("Security Group Check {} DOES contain a Neutron Security Group", neutronPortId);
+        return true;
+    }
+
+    /**
+     * Gets security group in port.
+     *
+     * @param intf the intf
+     * @return the security group in port
+     */
+    public NeutronSecurityGroup getSecurityGroupInPort(Interface intf) {
+        logger.trace("getTenantNetworkForInterface for {}", intf);
+        if (intf == null) return null;
+        Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
+        logger.trace("externalIds {}", externalIds);
+        if (externalIds == null) return null;
+        String neutronPortId = externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID);
+        if (neutronPortId == null) return null;
+        INeutronPortCRUD neutronPortService = (INeutronPortCRUD)
+                ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
+        NeutronPort neutronPort = neutronPortService.getPort(neutronPortId);
+        List<NeutronSecurityGroup> neutronSecurityGroups = neutronPort.getSecurityGroups();
+        NeutronSecurityGroup neutronSecurityGroup = (NeutronSecurityGroup) neutronSecurityGroups.toArray()[0];
+        return neutronSecurityGroup;
+    }
+}
index 22f78f14c211e152dbbf9dbf7ed19e4c1f11d68f..8ad2aace18e118be5fc72fb67b941e67ae610db4 100644 (file)
@@ -73,6 +73,12 @@ import com.google.common.collect.Lists;
 
 public class MatchUtils {
     private static final Logger logger = LoggerFactory.getLogger(MatchUtils.class);
+    public static final short ICMP_SHORT = 1;
+    public static final short TCP_SHORT = 6;
+    public static final short UDP_SHORT = 17;
+    public static final String TCP = "tcp";
+    public static final String UDP = "udp";
+    private static final int TCP_SYN = 0x0002;
 
     /**
      * Create Ingress Port Match dpidLong, inPort
@@ -365,6 +371,473 @@ public class MatchUtils {
         return matchBuilder;
     }
 
+    /**
+     * Create  TCP Port Match
+     *
+     * @param matchBuilder @param matchbuilder MatchBuilder Object without a match yet
+     * @param tcpport      Integer representing a source TCP port
+     * @return matchBuilder Map MatchBuilder Object with a match
+     */
+    public static MatchBuilder createIpProtocolMatch(MatchBuilder matchBuilder, short ipProtocol) {
+
+        EthernetMatchBuilder ethType = new EthernetMatchBuilder();
+        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
+        ethTypeBuilder.setType(new EtherType(0x0800L));
+        ethType.setEthernetType(ethTypeBuilder.build());
+        matchBuilder.setEthernetMatch(ethType.build());
+
+        IpMatchBuilder ipMmatch = new IpMatchBuilder();
+        if (ipProtocol == TCP_SHORT) {
+            ipMmatch.setIpProtocol(TCP_SHORT);
+        }
+        else if (ipProtocol == UDP_SHORT) {
+            ipMmatch.setIpProtocol(UDP_SHORT);
+        }
+        else if (ipProtocol == ICMP_SHORT) {
+            ipMmatch.setIpProtocol(ICMP_SHORT);
+        }
+        matchBuilder.setIpMatch(ipMmatch.build());
+        return matchBuilder;
+    }
+
+    /**
+     * Create tcp syn with proto match.
+     *
+     * @param matchBuilder the match builder
+     * @return matchBuilder match builder
+     */
+    public static MatchBuilder createTcpSynWithProtoMatch(MatchBuilder matchBuilder) {
+
+        // Ethertype match
+        EthernetMatchBuilder ethernetType = new EthernetMatchBuilder();
+        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
+        ethTypeBuilder.setType(new EtherType(0x0800L));
+        ethernetType.setEthernetType(ethTypeBuilder.build());
+        matchBuilder.setEthernetMatch(ethernetType.build());
+
+        // TCP Protocol Match
+        IpMatchBuilder ipMatch = new IpMatchBuilder(); // ipv4 version
+        ipMatch.setIpProtocol((short) 6);
+        matchBuilder.setIpMatch(ipMatch.build());
+
+        TcpFlagMatchBuilder tcpFlagMatch = new TcpFlagMatchBuilder();
+        tcpFlagMatch.setTcpFlag(TCP_SYN);
+        matchBuilder.setTcpFlagMatch(tcpFlagMatch.build());
+        return matchBuilder;
+    }
+
+    /**
+     * Create tcp proto syn match.
+     *
+     * @param matchBuilder the match builder
+     * @return matchBuilder match builder
+     */
+    public static MatchBuilder createTcpProtoSynMatch(MatchBuilder matchBuilder) {
+
+        // TCP Protocol Match
+        IpMatchBuilder ipMatch = new IpMatchBuilder(); // ipv4 version
+        ipMatch.setIpProtocol((short) 6);
+        matchBuilder.setIpMatch(ipMatch.build());
+
+        TcpFlagMatchBuilder tcpFlagMatch = new TcpFlagMatchBuilder();
+        tcpFlagMatch.setTcpFlag(TCP_SYN);
+        matchBuilder.setTcpFlagMatch(tcpFlagMatch.build());
+        return matchBuilder;
+    }
+
+    /**
+     * Create dmac tcp port with flag match.
+     *
+     * @param matchBuilder the match builder
+     * @param attachedMac the attached mac
+     * @param tcpFlag the tcp flag
+     * @param tunnelID the tunnel iD
+     * @return match containing TCP_Flag (), IP Protocol (TCP), TCP_Flag (SYN)
+     */
+    public static MatchBuilder createDmacTcpPortWithFlagMatch(MatchBuilder matchBuilder,
+            String attachedMac, Integer tcpFlag, String tunnelID) {
+
+        EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
+        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
+        ethTypeBuilder.setType(new EtherType(0x0800L));
+        ethernetMatch.setEthernetType(ethTypeBuilder.build());
+
+        EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
+        ethDestinationBuilder.setAddress(new MacAddress(attachedMac));
+        ethernetMatch.setEthernetDestination(ethDestinationBuilder.build());
+        matchBuilder.setEthernetMatch(ethernetMatch.build());
+
+        // TCP Protocol Match
+        IpMatchBuilder ipMatch = new IpMatchBuilder(); // ipv4 version
+        ipMatch.setIpProtocol(TCP_SHORT);
+        matchBuilder.setIpMatch(ipMatch.build());
+
+        TcpFlagMatchBuilder tcpFlagMatch = new TcpFlagMatchBuilder();
+        tcpFlagMatch.setTcpFlag(tcpFlag);
+        matchBuilder.setTcpFlagMatch(tcpFlagMatch.build());
+
+        TunnelBuilder tunnelBuilder = new TunnelBuilder();
+        tunnelBuilder.setTunnelId(new BigInteger(tunnelID));
+        matchBuilder.setTunnel(tunnelBuilder.build());
+
+        return matchBuilder;
+    }
+
+    /**
+     * Create dmac tcp syn match.
+     *
+     * @param matchBuilder the match builder
+     * @param attachedMac the attached mac
+     * @param tcpPort the tcp port
+     * @param tcpFlag the tcp flag
+     * @param tunnelID the tunnel iD
+     * @return the match builder
+     */
+    public static MatchBuilder createDmacTcpSynMatch(MatchBuilder matchBuilder,
+            String attachedMac, PortNumber tcpPort, Integer tcpFlag, String tunnelID) {
+
+        EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
+        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
+        ethTypeBuilder.setType(new EtherType(0x0800L));
+        ethernetMatch.setEthernetType(ethTypeBuilder.build());
+
+        EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
+        ethDestinationBuilder.setAddress(new MacAddress(attachedMac));
+        ethernetMatch.setEthernetDestination(ethDestinationBuilder.build());
+        matchBuilder.setEthernetMatch(ethernetMatch.build());
+
+        // TCP Protocol Match
+        IpMatchBuilder ipMatch = new IpMatchBuilder(); // ipv4 version
+        ipMatch.setIpProtocol((short) 6);
+        matchBuilder.setIpMatch(ipMatch.build());
+
+        // TCP Port Match
+        PortNumber dstPort = new PortNumber(tcpPort);
+        TcpMatchBuilder tcpMatch = new TcpMatchBuilder();
+        tcpMatch.setTcpDestinationPort(dstPort);
+        matchBuilder.setLayer4Match(tcpMatch.build());
+
+        TcpFlagMatchBuilder tcpFlagMatch = new TcpFlagMatchBuilder();
+        tcpFlagMatch.setTcpFlag(tcpFlag);
+        matchBuilder.setTcpFlagMatch(tcpFlagMatch.build());
+
+        TunnelBuilder tunnelBuilder = new TunnelBuilder();
+        tunnelBuilder.setTunnelId(new BigInteger(tunnelID));
+        matchBuilder.setTunnel(tunnelBuilder.build());
+
+        return matchBuilder;
+    }
+
+    /**
+     * Create dmac tcp syn dst ip prefix tcp port.
+     *
+     * @param matchBuilder the match builder
+     * @param attachedMac the attached mac
+     * @param tcpPort the tcp port
+     * @param tcpFlag the tcp flag
+     * @param segmentationId the segmentation id
+     * @param dstIp the dst ip
+     * @return the match builder
+     */
+    public static MatchBuilder createDmacTcpSynDstIpPrefixTcpPort(MatchBuilder matchBuilder,
+            MacAddress attachedMac, PortNumber tcpPort,  Integer tcpFlag, String segmentationId,
+            Ipv4Prefix dstIp) {
+
+        EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
+        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
+        ethTypeBuilder.setType(new EtherType(0x0800L));
+        ethernetMatch.setEthernetType(ethTypeBuilder.build());
+
+        EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
+        ethDestinationBuilder.setAddress(new MacAddress(attachedMac));
+        ethernetMatch.setEthernetDestination(ethDestinationBuilder.build());
+
+        matchBuilder.setEthernetMatch(ethernetMatch.build());
+
+        Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
+        ipv4match.setIpv4Destination(dstIp);
+        matchBuilder.setLayer3Match(ipv4match.build());
+
+        // TCP Protocol Match
+        IpMatchBuilder ipMatch = new IpMatchBuilder(); // ipv4 version
+        ipMatch.setIpProtocol(TCP_SHORT);
+        matchBuilder.setIpMatch(ipMatch.build());
+
+        // TCP Port Match
+        PortNumber dstPort = new PortNumber(tcpPort);
+        TcpMatchBuilder tcpMatch = new TcpMatchBuilder();
+        tcpMatch.setTcpDestinationPort(dstPort);
+        matchBuilder.setLayer4Match(tcpMatch.build());
+
+        TcpFlagMatchBuilder tcpFlagMatch = new TcpFlagMatchBuilder();
+        tcpFlagMatch.setTcpFlag(tcpFlag);
+        matchBuilder.setTcpFlagMatch(tcpFlagMatch.build());
+
+        TunnelBuilder tunnelBuilder = new TunnelBuilder();
+        tunnelBuilder.setTunnelId(new BigInteger(segmentationId));
+        matchBuilder.setTunnel(tunnelBuilder.build());
+
+        return matchBuilder;
+    }
+
+    /**
+     * Create dmac ip tcp syn match.
+     *
+     * @param matchBuilder the match builder
+     * @param dMacAddr the d mac addr
+     * @param mask the mask
+     * @param ipPrefix the ip prefix
+     * @return MatchBuilder containing the metadata match values
+     */
+    public static MatchBuilder createDmacIpTcpSynMatch(MatchBuilder matchBuilder,
+            MacAddress dMacAddr, MacAddress mask, Ipv4Prefix ipPrefix) {
+
+        EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
+        EthernetDestinationBuilder ethDestBuilder = new EthernetDestinationBuilder();
+        ethDestBuilder.setAddress(new MacAddress(dMacAddr));
+        if (mask != null) {
+            ethDestBuilder.setMask(mask);
+        }
+        ethernetMatch.setEthernetDestination(ethDestBuilder.build());
+        matchBuilder.setEthernetMatch(ethernetMatch.build());
+        // Ethertype match
+        EthernetMatchBuilder ethernetType = new EthernetMatchBuilder();
+        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
+        ethTypeBuilder.setType(new EtherType(0x0800L));
+        ethernetType.setEthernetType(ethTypeBuilder.build());
+        matchBuilder.setEthernetMatch(ethernetType.build());
+        if (ipPrefix != null) {
+            Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
+            ipv4match.setIpv4Destination(ipPrefix);
+            matchBuilder.setLayer3Match(ipv4match.build());
+        }
+        // TCP Protocol Match
+        IpMatchBuilder ipMatch = new IpMatchBuilder(); // ipv4 version
+        ipMatch.setIpProtocol(TCP_SHORT);
+        matchBuilder.setIpMatch(ipMatch.build());
+        // TCP Flag Match
+        TcpFlagMatchBuilder tcpFlagMatch = new TcpFlagMatchBuilder();
+        tcpFlagMatch.setTcpFlag(TCP_SYN);
+        matchBuilder.setTcpFlagMatch(tcpFlagMatch.build());
+
+        return matchBuilder;
+    }
+
+    /**
+     * Create smac tcp syn dst ip prefix tcp port.
+     *
+     * @param matchBuilder the match builder
+     * @param attachedMac the attached mac
+     * @param tcpPort the tcp port
+     * @param tcpFlag the tcp flag
+     * @param segmentationId the segmentation id
+     * @param dstIp the dst ip
+     * @return the match builder
+     */
+    public static MatchBuilder createSmacTcpSynDstIpPrefixTcpPort(MatchBuilder matchBuilder, MacAddress attachedMac,
+            PortNumber tcpPort, Integer tcpFlag, String segmentationId, Ipv4Prefix dstIp) {
+
+        EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
+        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
+        ethTypeBuilder.setType(new EtherType(0x0800L));
+        ethernetMatch.setEthernetType(ethTypeBuilder.build());
+
+        EthernetSourceBuilder ethSourceBuilder = new EthernetSourceBuilder();
+        ethSourceBuilder.setAddress(new MacAddress(attachedMac));
+        ethernetMatch.setEthernetSource(ethSourceBuilder.build());
+
+        matchBuilder.setEthernetMatch(ethernetMatch.build());
+
+        Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
+        ipv4match.setIpv4Destination(dstIp);
+        matchBuilder.setLayer3Match(ipv4match.build());
+
+        // TCP Protocol Match
+        IpMatchBuilder ipMatch = new IpMatchBuilder(); // ipv4 version
+        ipMatch.setIpProtocol(TCP_SHORT);
+        matchBuilder.setIpMatch(ipMatch.build());
+
+        // TCP Port Match
+        PortNumber dstPort = new PortNumber(tcpPort);
+        TcpMatchBuilder tcpMatch = new TcpMatchBuilder();
+        tcpMatch.setTcpDestinationPort(dstPort);
+        matchBuilder.setLayer4Match(tcpMatch.build());
+
+        TcpFlagMatchBuilder tcpFlagMatch = new TcpFlagMatchBuilder();
+        tcpFlagMatch.setTcpFlag(tcpFlag);
+        matchBuilder.setTcpFlagMatch(tcpFlagMatch.build());
+
+        TunnelBuilder tunnelBuilder = new TunnelBuilder();
+        tunnelBuilder.setTunnelId(new BigInteger(segmentationId));
+        matchBuilder.setTunnel(tunnelBuilder.build());
+
+        return matchBuilder;
+    }
+
+    /**
+     * Create smac tcp port with flag match.
+     *
+     * @param matchBuilder the match builder
+     * @param attachedMac the attached mac
+     * @param tcpFlag the tcp flag
+     * @param tunnelID the tunnel iD
+     * @return matchBuilder
+     */
+    public static MatchBuilder createSmacTcpPortWithFlagMatch(MatchBuilder matchBuilder, String attachedMac,
+            Integer tcpFlag, String tunnelID) {
+
+        EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
+        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
+        ethTypeBuilder.setType(new EtherType(0x0800L));
+        ethernetMatch.setEthernetType(ethTypeBuilder.build());
+
+        EthernetSourceBuilder ethSrcBuilder = new EthernetSourceBuilder();
+        ethSrcBuilder.setAddress(new MacAddress(attachedMac));
+        ethernetMatch.setEthernetSource(ethSrcBuilder.build());
+        matchBuilder.setEthernetMatch(ethernetMatch.build());
+
+        // TCP Protocol Match
+        IpMatchBuilder ipMatch = new IpMatchBuilder(); // ipv4 version
+        ipMatch.setIpProtocol(TCP_SHORT);
+        matchBuilder.setIpMatch(ipMatch.build());
+
+        TcpFlagMatchBuilder tcpFlagMatch = new TcpFlagMatchBuilder();
+        tcpFlagMatch.setTcpFlag(tcpFlag);
+        matchBuilder.setTcpFlagMatch(tcpFlagMatch.build());
+
+        TunnelBuilder tunnelBuilder = new TunnelBuilder();
+        tunnelBuilder.setTunnelId(new BigInteger(tunnelID));
+        matchBuilder.setTunnel(tunnelBuilder.build());
+
+        return matchBuilder;
+    }
+
+    /**
+     * Create smac ip tcp syn match.
+     *
+     * @param matchBuilder the match builder
+     * @param dMacAddr the d mac addr
+     * @param mask the mask
+     * @param ipPrefix the ip prefix
+     * @return MatchBuilder containing the metadata match values
+     */
+    public static MatchBuilder createSmacIpTcpSynMatch(MatchBuilder matchBuilder, MacAddress dMacAddr,
+            MacAddress mask, Ipv4Prefix ipPrefix) {
+
+        EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
+        EthernetSourceBuilder ethSrcBuilder = new EthernetSourceBuilder();
+        ethSrcBuilder.setAddress(new MacAddress(dMacAddr));
+        if (mask != null) {
+            ethSrcBuilder.setMask(mask);
+        }
+        ethernetMatch.setEthernetSource(ethSrcBuilder.build());
+        matchBuilder.setEthernetMatch(ethernetMatch.build());
+        // Ethertype match
+        EthernetMatchBuilder ethernetType = new EthernetMatchBuilder();
+        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
+        ethTypeBuilder.setType(new EtherType(0x0800L));
+        ethernetType.setEthernetType(ethTypeBuilder.build());
+        matchBuilder.setEthernetMatch(ethernetType.build());
+        if (ipPrefix != null) {
+            Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
+            ipv4match.setIpv4Destination(ipPrefix);
+            matchBuilder.setLayer3Match(ipv4match.build());
+        }
+        // TCP Protocol Match
+        IpMatchBuilder ipMatch = new IpMatchBuilder(); // ipv4 version
+        ipMatch.setIpProtocol(TCP_SHORT);
+        matchBuilder.setIpMatch(ipMatch.build());
+        // TCP Flag Match
+        TcpFlagMatchBuilder tcpFlagMatch = new TcpFlagMatchBuilder();
+        tcpFlagMatch.setTcpFlag(TCP_SYN);
+        matchBuilder.setTcpFlagMatch(tcpFlagMatch.build());
+
+        return matchBuilder;
+    }
+
+    /**
+     * Create smac tcp syn.
+     *
+     * @param matchBuilder the match builder
+     * @param attachedMac the attached mac
+     * @param tcpPort the tcp port
+     * @param tcpFlag the tcp flag
+     * @param tunnelID the tunnel iD
+     * @return the match builder
+     */
+    public static MatchBuilder createSmacTcpSyn(MatchBuilder matchBuilder,
+            String attachedMac, PortNumber tcpPort, Integer tcpFlag, String tunnelID) {
+
+        EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
+        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
+        ethTypeBuilder.setType(new EtherType(0x0800L));
+        ethernetMatch.setEthernetType(ethTypeBuilder.build());
+
+        EthernetSourceBuilder ethSrcBuilder = new EthernetSourceBuilder();
+        ethSrcBuilder.setAddress(new MacAddress(attachedMac));
+        ethernetMatch.setEthernetSource(ethSrcBuilder.build());
+        matchBuilder.setEthernetMatch(ethernetMatch.build());
+
+        // TCP Protocol Match
+        IpMatchBuilder ipMatch = new IpMatchBuilder(); // ipv4 version
+        ipMatch.setIpProtocol((short) 6);
+        matchBuilder.setIpMatch(ipMatch.build());
+
+        // TCP Port Match
+        PortNumber dstPort = new PortNumber(tcpPort);
+        TcpMatchBuilder tcpMatch = new TcpMatchBuilder();
+        tcpMatch.setTcpDestinationPort(dstPort);
+        matchBuilder.setLayer4Match(tcpMatch.build());
+
+
+        TcpFlagMatchBuilder tcpFlagMatch = new TcpFlagMatchBuilder();
+        tcpFlagMatch.setTcpFlag(tcpFlag);
+        matchBuilder.setTcpFlagMatch(tcpFlagMatch.build());
+
+        TunnelBuilder tunnelBuilder = new TunnelBuilder();
+        tunnelBuilder.setTunnelId(new BigInteger(tunnelID));
+        matchBuilder.setTunnel(tunnelBuilder.build());
+
+        return matchBuilder;
+    }
+
+    /**
+     * @return MatchBuilder containing the metadata match values
+     */
+    public static MatchBuilder createMacSrcIpTcpSynMatch(MatchBuilder matchBuilder,
+            MacAddress dMacAddr,  MacAddress mask, Ipv4Prefix ipPrefix) {
+
+        EthernetMatchBuilder ethernetMatch = new EthernetMatchBuilder();
+        EthernetDestinationBuilder ethDestinationBuilder = new EthernetDestinationBuilder();
+        ethDestinationBuilder.setAddress(new MacAddress(dMacAddr));
+        if (mask != null) {
+            ethDestinationBuilder.setMask(mask);
+        }
+        ethernetMatch.setEthernetDestination(ethDestinationBuilder.build());
+        matchBuilder.setEthernetMatch(ethernetMatch.build());
+        // Ethertype match
+        EthernetMatchBuilder ethernetType = new EthernetMatchBuilder();
+        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
+        ethTypeBuilder.setType(new EtherType(0x0800L));
+        ethernetType.setEthernetType(ethTypeBuilder.build());
+        matchBuilder.setEthernetMatch(ethernetType.build());
+        if (ipPrefix != null) {
+            Ipv4MatchBuilder ipv4match = new Ipv4MatchBuilder();
+            ipv4match.setIpv4Source(ipPrefix);
+            matchBuilder.setLayer3Match(ipv4match.build());
+        }
+        // TCP Protocol Match
+        IpMatchBuilder ipMatch = new IpMatchBuilder(); // ipv4 version
+        ipMatch.setIpProtocol(TCP_SHORT);
+        matchBuilder.setIpMatch(ipMatch.build());
+        // TCP Flag Match
+        TcpFlagMatchBuilder tcpFlagMatch = new TcpFlagMatchBuilder();
+        tcpFlagMatch.setTcpFlag(TCP_SYN);
+        matchBuilder.setTcpFlagMatch(tcpFlagMatch.build());
+
+        return matchBuilder;
+    }
+
     public static class RegMatch {
         final Class<? extends NxmNxReg> reg;
         final Long value;