Added conntrack matches and Refactored code
authorAswin Suryanarayanan <aswinsuryan@gmail.com>
Sat, 19 Mar 2016 17:07:40 +0000 (22:37 +0530)
committerAswin Suryanarayanan <aswinsuryan@gmail.com>
Tue, 29 Mar 2016 19:10:31 +0000 (00:40 +0530)
1)Added conntrack match for invalid and related packets.
2)Refactored IngressAclService and EgressAclService.

Change-Id: I03e94f56a6fbad5d85fcbec5b8ace2dc47a9b2cf
Signed-off-by: Aswin Suryanarayanan <aswinsuryan@gmail.com>
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/EgressAclService.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/IngressAclService.java
openstack/net-virt-providers/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/EgressAclServiceTest.java
openstack/net-virt-providers/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/IngressAclServiceTest.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/Constants.java
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/ActionUtils.java
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/FlowUtils.java
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/InstructionUtils.java
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/MatchUtils.java

index 68ae031e9f7808e999a7d22f67f3471af6ae4568..f7936b5116d4419078e59993b3975ec7cdde0496 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015 Red Hat, Inc. and others. All rights reserved.
+ * Copyright (c) 2014 - 2016 Red Hat, Inc. and others. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -28,23 +28,14 @@ import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
 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.Ipv6Prefix;
 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.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
 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.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
@@ -101,9 +92,9 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
              *
              */
 
-            if (portSecurityRule == null ||
-                    portSecurityRule.getSecurityRuleEthertype() == null ||
-                    portSecurityRule.getSecurityRuleDirection() == null) {
+            if (portSecurityRule == null
+                    || portSecurityRule.getSecurityRuleEthertype() == null
+                    || portSecurityRule.getSecurityRuleDirection() == null) {
                 continue;
             }
 
@@ -146,13 +137,14 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         String securityRuleEtherType = portSecurityRule.getSecurityRuleEthertype();
         boolean isIpv6 = NeutronSecurityRule.ETHERTYPE_IPV6.equals(securityRuleEtherType);
         if (!isIpv6 && !NeutronSecurityRule.ETHERTYPE_IPV4.equals(securityRuleEtherType)) {
-            LOG.debug("programPortSecurityRule: SecurityRuleEthertype {} does not match IPv4/v6.", securityRuleEtherType);
+            LOG.debug("programPortSecurityRule: SecurityRuleEthertype {} does not match IPv4/v6.",
+                      securityRuleEtherType);
             return;
         }
 
         if (null == portSecurityRule.getSecurityRuleProtocol()) {
             /* TODO Rework on the priority values */
-            egressAclIP(dpid, isIpv6, segmentationId, attachedMac,
+            egressAclIp(dpid, isIpv6, segmentationId, attachedMac,
                           write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
         } else {
             String ipaddress = null;
@@ -161,7 +153,8 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                 try {
                     InetAddress address = InetAddress.getByName(ipaddress);
                     if ((isIpv6 && (address instanceof Inet4Address)) || (!isIpv6 && address instanceof Inet6Address)) {
-                        LOG.debug("programPortSecurityRule: Remote vmIP {} does not match with SecurityRuleEthertype {}.", ipaddress, securityRuleEtherType);
+                        LOG.debug("programPortSecurityRule: Remote vmIP {} does not match with "
+                                + "SecurityRuleEthertype {}.", ipaddress, securityRuleEtherType);
                         return;
                     }
                 } catch (UnknownHostException e) {
@@ -171,32 +164,32 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
             }
 
             switch (portSecurityRule.getSecurityRuleProtocol()) {
-              case MatchUtils.TCP:
-                  LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
-                  egressAclTcp(dpid, segmentationId, attachedMac,
-                               portSecurityRule,ipaddress, write,
-                               Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                  break;
-              case MatchUtils.UDP:
-                  LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
-                  egressAclUdp(dpid, segmentationId, attachedMac,
-                               portSecurityRule, ipaddress, write,
-                               Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                  break;
-              case MatchUtils.ICMP:
-              case MatchUtils.ICMPV6:
-                  LOG.debug("programPortSecurityRule: Rule matching ICMP", portSecurityRule);
-                  egressAclIcmp(dpid, segmentationId, attachedMac,
-                                portSecurityRule, ipaddress,write,
-                                Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                  break;
-              default:
-                  LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other " +
-                          "protocol = ", portSecurityRule.getSecurityRuleProtocol());
-                  egressOtherProtocolAclHandler(dpid, segmentationId, attachedMac,
-                                      portSecurityRule, ipaddress, write,
-                                      Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                  break;
+                case MatchUtils.TCP:
+                    LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
+                    egressAclTcp(dpid, segmentationId, attachedMac,
+                             portSecurityRule,ipaddress, write,
+                             Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                    break;
+                case MatchUtils.UDP:
+                    LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
+                    egressAclUdp(dpid, segmentationId, attachedMac,
+                             portSecurityRule, ipaddress, write,
+                             Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                    break;
+                case MatchUtils.ICMP:
+                case MatchUtils.ICMPV6:
+                    LOG.debug("programPortSecurityRule: Rule matching ICMP", portSecurityRule);
+                    egressAclIcmp(dpid, segmentationId, attachedMac,
+                              portSecurityRule, ipaddress,write,
+                              Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                    break;
+                default:
+                    LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other "
+                            + "protocol = ", portSecurityRule.getSecurityRuleProtocol());
+                    egressOtherProtocolAclHandler(dpid, segmentationId, attachedMac,
+                                              portSecurityRule, ipaddress, write,
+                                              Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                    break;
             }
         }
     }
@@ -206,7 +199,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                                boolean write, Integer priority) {
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Egress_Other_" + segmentationId + "_" + srcMac + "_";
-        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null);
+        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
 
         short proto = 0;
         try {
@@ -230,7 +223,9 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         }
         flowId = flowId + "_Permit";
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
-        syncFlow(flowId, nodeBuilder, matchBuilder, priority, write, false, securityServicesManager.isConntrackEnabled());
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, priority, matchBuilder, getTable());
+        addInstructionWithConntrackCommit(flowBuilder, false);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     @Override
@@ -239,9 +234,9 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                         boolean isLastPortinBridge, boolean isComputePort ,boolean write) {
         // If it is the only port in the bridge add the rule to allow any DHCP client traffic
         //if (isLastPortinBridge) {
-            egressAclDhcpAllowClientTrafficFromVm(dpid, write, Constants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY);
-            egressAclDhcpv6AllowClientTrafficFromVm(dpid, write, Constants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY);
-       // }
+        egressAclDhcpAllowClientTrafficFromVm(dpid, write, Constants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY);
+        egressAclDhcpv6AllowClientTrafficFromVm(dpid, write, Constants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY);
+        // }
         if (isComputePort) {
             programArpRule(dpid, segmentationId, localPort, attachedMac, write);
             if (securityServicesManager.isConntrackEnabled()) {
@@ -265,7 +260,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                         egressAclAllowTrafficFromVmIpV6MacPair(dpid, localPort, attachedMac, addressWithPrefix,
                                                                Constants.PROTO_VM_IP_MAC_MATCH_PRIORITY,write);
                     }
-                } catch(UnknownHostException e) {
+                } catch (UnknownHostException e) {
                     LOG.warn("Invalid IP address {}", srcAddress.getIpAddress(), e);
                 }
             }
@@ -273,155 +268,125 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
     }
 
     private void programArpRule(Long dpid, String segmentationId, long localPort, String attachedMac, boolean write) {
-        String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpid;
         MatchBuilder matchBuilder = new MatchBuilder();
-        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         String flowId = "Egress_ARP_" + segmentationId + "_" + localPort + "_";
+        MatchUtils.createV4EtherMatchWithType(matchBuilder,null,null,MatchUtils.ETHERTYPE_ARP);
+        MatchUtils.addArpMacMatch(matchBuilder, attachedMac, null);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, Constants.PROTO_MATCH_PRIORITY,
+                                                              matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpid);
+        syncFlow(flowBuilder ,nodeBuilder, write);
+    }
 
-        EthernetMatchBuilder ethernetType = new EthernetMatchBuilder();
-        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
-        ethTypeBuilder.setType(new EtherType(0x0806L));
-        ethernetType.setEthernetType(ethTypeBuilder.build());
-        matchBuilder.setEthernetMatch(ethernetType.build());
+    private void programEgressAclFixedConntrackRule(Long dpid,
+                                             String segmentationId, long localPort, String attachMac, boolean write) {
+        try {
+            programConntrackUntrackRule(dpid, segmentationId, localPort,attachMac,
+                                        Constants.CT_STATE_UNTRACKED_PRIORITY, write );
+            programConntrackTrackedPlusEstRule(dpid, segmentationId, localPort,
+                                               Constants.CT_STATE_TRACKED_EXIST_PRIORITY, write );
+            programConntrackTrackedPlusRelRule(dpid, segmentationId, localPort,
+                                               Constants.CT_STATE_TRACKED_EXIST_PRIORITY, write );
+            programConntrackNewDropRule(dpid, segmentationId, localPort,
+                                        Constants.CT_STATE_NEW_PRIORITY_DROP, write );
+            programConntrackInvDropRule(dpid, segmentationId, localPort,
+                                        Constants.CT_STATE_NEW_PRIORITY_DROP, write );
+            LOG.info("programEgressAclFixedConntrackRule :  default connection tracking rule are added.");
+        } catch (Exception e) {
+            LOG.error("Failed to add default conntrack rules : " , e);
+        }
+    }
+
+    private void programConntrackUntrackRule(Long dpidLong, String segmentationId,
+                                             long localPort, String attachMac, Integer priority, boolean write) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+        String flowName = "Egress_Fixed_Conntrk_Untrk_" + segmentationId + "_" + localPort + "_";
+        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder, attachMac, null,MatchUtils.ETHERTYPE_IPV4);
+        matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.UNTRACKED_CT_STATE,
+                                             MatchUtils.UNTRACKED_CT_STATE_MASK);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addInstructionWithConntrackRecirc(flowBuilder);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
+    }
 
-        ArpMatchBuilder arpDstMatch = new ArpMatchBuilder();
-        ArpSourceHardwareAddressBuilder arpSrc = new ArpSourceHardwareAddressBuilder();
-        arpSrc.setAddress(new MacAddress(attachedMac));
-        arpDstMatch.setArpSourceHardwareAddress(arpSrc.build());
-        matchBuilder.setLayer3Match(arpDstMatch.build());
+    private void programConntrackTrackedPlusEstRule(Long dpidLong, String segmentationId,
+                                                    long localPort,Integer priority, boolean write) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+        String flowName = "Egress_Fixed_Conntrk_TrkEst_" + segmentationId + "_" + localPort + "_";
+        matchBuilder = MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
+        matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.TRACKED_EST_CT_STATE,
+                                             MatchUtils.TRACKED_CT_STATE_MASK);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
+    }
 
-        syncFlow(flowId, nodeBuilder, matchBuilder, Constants.PROTO_MATCH_PRIORITY, write, false, false);
+    private void programConntrackTrackedPlusRelRule(Long dpidLong, String segmentationId,
+                                                    long localPort,Integer priority, boolean write) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+        String flowName = "Egress_Fixed_Conntrk_TrkRel_" + segmentationId + "_" + localPort + "_";
+        matchBuilder = MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
+        matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.TRACKED_REL_CT_STATE,
+                                             MatchUtils.TRACKED_CT_STATE_MASK);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
-    private void programEgressAclFixedConntrackRule(Long dpid,
-            String segmentationId, long localPort, String attachMac, boolean write) {
-         try {
-             String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpid;
-             programConntrackUntrackRule(nodeName, segmentationId, localPort,attachMac,
-                                         Constants.CT_STATE_UNTRACKED_PRIORITY, write );
-             programConntrackTrackedPlusEstRule(nodeName, dpid, segmentationId, localPort,
-                                         Constants.CT_STATE_TRACKED_EST_PRIORITY, write );
-             programConntrackNewDropRule(nodeName, dpid, segmentationId, localPort,
-                                              Constants.CT_STATE_NEW_PRIORITY_DROP, write );
-             LOG.info("programEgressAclFixedConntrackRule :  default connection tracking rule are added.");
-         } catch (Exception e) {
-             LOG.error("Failed to add default conntrack rules : " , e);
-         }
-     }
-
-     private void programConntrackUntrackRule(String nodeName, String segmentationId,
-                                              long localPort, String attachMac, Integer priority, boolean write) {
-         MatchBuilder matchBuilder = new MatchBuilder();
-         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
-         String flowName = "Egress_Fixed_Conntrk_Untrk_" + segmentationId + "_" + localPort + "_";
-         matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder, attachMac, null);
-         matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.UNTRACKED_CT_STATE,
-                                              MatchUtils.UNTRACKED_CT_STATE_MASK);
-         FlowBuilder flowBuilder = new FlowBuilder();
-         flowBuilder.setMatch(matchBuilder.build());
-         FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(priority);
-         if (write) {
-             InstructionBuilder ib = new InstructionBuilder();
-             List<Instruction> instructionsList = Lists.newArrayList();
-             InstructionsBuilder isb = new InstructionsBuilder();
-             ActionBuilder ab = new ActionBuilder();
-             ab.setAction(ActionUtils.nxConntrackAction(0, 0L, 0, (short)0x0));
-             // 0xff means no table, 0x0 is table = 0
-             ab.setOrder(0);
-             ab.setKey(new ActionKey(0));
-             List<Action> actionList = Lists.newArrayList();
-             actionList.add(ab.build());
-             ApplyActionsBuilder aab = new ApplyActionsBuilder();
-             aab.setAction(actionList);
-             ib.setOrder(0);
-             ib.setKey(new InstructionKey(0));
-             ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
-             instructionsList.add(ib.build());
-             isb.setInstruction(instructionsList);
-             flowBuilder.setInstructions(isb.build());
-             writeFlow(flowBuilder, nodeBuilder);
-             LOG.info("EGRESS:default programConntrackUntrackRule() flows are written");
-         } else {
-             removeFlow(flowBuilder, nodeBuilder);
-         }
-     }
-
-     private void programConntrackTrackedPlusEstRule(String nodeName, Long dpid, String segmentationId,
-                                                   long localPort,Integer priority, boolean write) {
-         MatchBuilder matchBuilder = new MatchBuilder();
-         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
-         String flowName = "Egress_Fixed_Conntrk_TrkEst_" + segmentationId + "_" + localPort + "_";
-         matchBuilder = MatchUtils.createInPortMatch(matchBuilder, dpid, localPort);
-         matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.TRACKED_EST_CT_STATE,
-                                              MatchUtils.TRACKED_EST_CT_STATE_MASK);
-         FlowBuilder flowBuilder = new FlowBuilder();
-         flowBuilder.setMatch(matchBuilder.build());
-         FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(priority);
-         if (write) {
-             InstructionBuilder ib = new InstructionBuilder();
-             List<Instruction> instructionsList = Lists.newArrayList();
-             InstructionsBuilder isb = new InstructionsBuilder();
-             // got to next table instruction
-             ib = this.getMutablePipelineInstructionBuilder();
-             ib.setOrder(0);
-             ib.setKey(new InstructionKey(0));
-             instructionsList.add(ib.build());
-             isb.setInstruction(instructionsList);
-             flowBuilder.setInstructions(isb.build());
-             writeFlow(flowBuilder, nodeBuilder);
-             LOG.info("EGRESS:default programConntrackTrackedPlusEstRule() flows are written");
-         } else {
-             removeFlow(flowBuilder, nodeBuilder);
-         }
-     }
-
-     private void programConntrackNewDropRule(String nodeName, Long dpid, String segmentationId,
-                                              long localPort, Integer priority, boolean write) {
-         MatchBuilder matchBuilder = new MatchBuilder();
-         NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
-         String flowName = "Egress_Fixed_Conntrk_NewDrop_" + segmentationId + "_" + localPort + "_";
-         matchBuilder = MatchUtils.createInPortMatch(matchBuilder, dpid, localPort);
-         matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.NEW_CT_STATE, MatchUtils.NEW_CT_STATE_MASK);
-         FlowBuilder flowBuilder = new FlowBuilder();
-         flowBuilder.setMatch(matchBuilder.build());
-         FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(priority);
-         if (write) {
-             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());
-             isb.setInstruction(instructions);
-             LOG.debug("Instructions contain: {}", ib.getInstruction());
-             flowBuilder.setInstructions(isb.build());
-             writeFlow(flowBuilder, nodeBuilder);
-             LOG.info("EGRESS:default programConntrackNewDropRule() flows are written");
-         } else {
-             removeFlow(flowBuilder, nodeBuilder);
-         }
-     }
+    private void programConntrackNewDropRule(Long dpidLong, String segmentationId,
+                                             long localPort, Integer priority, boolean write) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+
+        String flowName = "Egress_Fixed_Conntrk_NewDrop_" + segmentationId + "_" + localPort + "_";
+        matchBuilder = MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
+        matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.TRACKED_NEW_CT_STATE,
+                                             MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, true);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
+    }
+
+    private void programConntrackInvDropRule(Long dpidLong, String segmentationId,
+                                             long localPort, Integer priority, boolean write) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+        String flowName = "Egress_Fixed_Conntrk_InvDrop_" + segmentationId + "_" + localPort + "_";
+        matchBuilder = MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
+        matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.TRACKED_INV_CT_STATE,
+                                             MatchUtils.TRACKED_INV_CT_STATE_MASK);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, true);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
+    }
 
     /**
      * Allows IPv4/v6 packet egress from the src mac address.
      * @param dpidLong the dpid
+     * @param isIpv6 whether the rule is for ipv6
      * @param segmentationId the segementation id
      * @param srcMac the src mac address
      * @param write add or remove
      * @param protoPortMatchPriority the protocol match priority.
      */
-    private void egressAclIP(Long dpidLong, boolean isIpv6, String segmentationId, String srcMac,
+    private void egressAclIp(Long dpidLong, boolean isIpv6, String segmentationId, String srcMac,
                                boolean write, Integer protoPortMatchPriority ) {
-        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Egress_IP" + segmentationId + "_" + srcMac + "_Permit_";
         if (isIpv6) {
             matchBuilder = MatchUtils.createV6EtherMatchWithType(matchBuilder,srcMac,null);
         } else {
-            matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null);
+            matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
         }
-        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, false);
+        addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
+        addInstructionWithConntrackCommit(flowBuilder, false);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     /**
@@ -446,7 +411,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         if (isIpv6) {
             matchBuilder = MatchUtils.createV6EtherMatchWithType(matchBuilder,srcMac,null);
         } else {
-            matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null);
+            matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
         }
 
         /* Custom TCP Match */
@@ -494,11 +459,19 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                 rangeflowId = rangeflowId + "_Permit";
                 MatchUtils.addLayer4MatchWithMask(matchBuilder, MatchUtils.TCP_SHORT,
                                                   0, port, portMaskMap.get(port));
-                syncFlow(rangeflowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
+                addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+                FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(rangeflowId, protoPortMatchPriority,
+                                                                      matchBuilder, getTable());
+                addInstructionWithConntrackCommit(flowBuilder, false);
+                syncFlow(flowBuilder ,nodeBuilder, write);
             }
         } else {
             flowId = flowId + "_Permit";
-            syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
+            addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+            FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority,
+                                                                  matchBuilder, getTable());
+            addInstructionWithConntrackCommit(flowBuilder, false);
+            syncFlow(flowBuilder ,nodeBuilder, write);
         }
     }
 
@@ -508,9 +481,11 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
 
         boolean isIpv6 = NeutronSecurityRule.ETHERTYPE_IPV6.equals(portSecurityRule.getSecurityRuleEthertype());
         if (isIpv6) {
-            egressAclIcmpV6(dpidLong, segmentationId, srcMac, portSecurityRule, dstAddress, write, protoPortMatchPriority);
+            egressAclIcmpV6(dpidLong, segmentationId, srcMac, portSecurityRule, dstAddress, write,
+                            protoPortMatchPriority);
         } else {
-            egressAclIcmpV4(dpidLong, segmentationId, srcMac, portSecurityRule, dstAddress, write, protoPortMatchPriority);
+            egressAclIcmpV4(dpidLong, segmentationId, srcMac, portSecurityRule, dstAddress, write,
+                            protoPortMatchPriority);
         }
     }
 
@@ -532,10 +507,10 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
 
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Egress_ICMP_" + segmentationId + "_" + srcMac + "_";
-        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null);
+        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
         /*Custom ICMP Match */
-        if (portSecurityRule.getSecurityRulePortMin() != null &&
-                             portSecurityRule.getSecurityRulePortMax() != null) {
+        if (portSecurityRule.getSecurityRulePortMin() != null
+                && portSecurityRule.getSecurityRulePortMax() != null) {
             flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
                     + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
             matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
@@ -558,8 +533,11 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
             }
         }
         flowId = flowId + "_Permit";
+        addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
-        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
+        addInstructionWithConntrackCommit(flowBuilder, false);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     /**
@@ -583,8 +561,8 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         matchBuilder = MatchUtils.createV6EtherMatchWithType(matchBuilder,srcMac,null);
 
         /*Custom ICMP Match */
-        if (portSecurityRule.getSecurityRulePortMin() != null &&
-                             portSecurityRule.getSecurityRulePortMax() != null) {
+        if (portSecurityRule.getSecurityRulePortMin() != null
+                && portSecurityRule.getSecurityRulePortMax() != null) {
             flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
                     + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
             matchBuilder = MatchUtils.createICMPv6Match(matchBuilder,
@@ -605,8 +583,11 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                     new Ipv6Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
         }
         flowId = flowId + "_Permit";
+        addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
-        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, false);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
+        addInstructionWithConntrackCommit(flowBuilder, false);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     /**
@@ -631,7 +612,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         if (isIpv6) {
             matchBuilder = MatchUtils.createV6EtherMatchWithType(matchBuilder,srcMac,null);
         } else {
-            matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null);
+            matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
         }
 
         /* Custom UDP Match */
@@ -681,11 +662,19 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                 rangeflowId = rangeflowId + "_Permit";
                 MatchUtils.addLayer4MatchWithMask(matchBuilder, MatchUtils.UDP_SHORT,
                                                   0, port, portMaskMap.get(port));
-                syncFlow(rangeflowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
+                addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+                FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(rangeflowId, protoPortMatchPriority,
+                                                                      matchBuilder, getTable());
+                addInstructionWithConntrackCommit(flowBuilder, false);
+                syncFlow(flowBuilder ,nodeBuilder, write);
             }
         } else {
             flowId = flowId + "_Permit";
-            syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
+            addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+            FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority,
+                                                                  matchBuilder, getTable());
+            addInstructionWithConntrackCommit(flowBuilder, false);
+            syncFlow(flowBuilder ,nodeBuilder, write);
         }
     }
 
@@ -702,7 +691,9 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         String flowName = "Egress_DHCP_Client"  + "_Permit_";
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createDhcpMatch(matchBuilder, DHCP_DESTINATION_PORT, DHCP_SOURCE_PORT);
-        syncFlow(flowName, nodeBuilder, matchBuilder, priority, write, false, false);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     /**
@@ -718,7 +709,9 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         String flowName = "Egress_DHCPv6_Client"  + "_Permit_";
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createDhcpv6Match(matchBuilder, DHCPV6_DESTINATION_PORT, DHCPV6_SOURCE_PORT);
-        syncFlow(flowName, nodeBuilder, matchBuilder, priority, write, false, false);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     /**
@@ -731,13 +724,14 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
      */
     private void egressAclDhcpDropServerTrafficfromVm(Long dpidLong, long localPort,
                                                       boolean write, Integer priority) {
-
-        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
         String flowName = "Egress_DHCP_Server" + "_" + localPort + "_DROP_";
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
         MatchUtils.createDhcpMatch(matchBuilder, DHCP_SOURCE_PORT, DHCP_DESTINATION_PORT);
-        syncFlow(flowName, nodeBuilder, matchBuilder, priority, write, true, false);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, true);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     /**
@@ -751,12 +745,14 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
     private void egressAclDhcpv6DropServerTrafficfromVm(Long dpidLong, long localPort,
                                                         boolean write, Integer priority) {
 
-        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
         String flowName = "Egress_DHCPv6_Server" + "_" + localPort + "_DROP_";
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
         MatchUtils.createDhcpv6Match(matchBuilder, DHCPV6_SOURCE_PORT, DHCPV6_DESTINATION_PORT);
-        syncFlow(flowName, nodeBuilder, matchBuilder, priority, write, true, false);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, true);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     /**
@@ -772,13 +768,15 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
     private void egressAclAllowTrafficFromVmIpMacPair(Long dpidLong, long localPort,
                                                       String attachedMac, String srcIp,
                                                       Integer priority, boolean write) {
-        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
-        String flowName = "Egress_Allow_VM_IP_MAC" + "_" + localPort + attachedMac + "_Permit_";
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createSrcL3Ipv4MatchWithMac(matchBuilder, new Ipv4Prefix(srcIp),new MacAddress(attachedMac));
         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
         LOG.debug("egressAclAllowTrafficFromVmIpMacPair: MatchBuilder contains: {}", matchBuilder);
-        syncFlow(flowName, nodeBuilder, matchBuilder, priority, write, false, false);
+        String flowName = "Egress_Allow_VM_IP_MAC" + "_" + localPort + attachedMac + "_Permit_";
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     /**
@@ -794,72 +792,91 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
     private void egressAclAllowTrafficFromVmIpV6MacPair(Long dpidLong, long localPort,
                                                         String attachedMac, String srcIp,
                                                         Integer priority, boolean write) {
-        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
-        String flowName = "Egress_Allow_VM_IPv6_MAC" + "_" + localPort + attachedMac + "_Permit_";
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createSrcL3Ipv6MatchWithMac(matchBuilder, new Ipv6Prefix(srcIp),new MacAddress(attachedMac));
         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
         LOG.debug("egressAclAllowTrafficFromVmIpMacPair: MatchBuilder contains: {}", matchBuilder);
-        syncFlow(flowName, nodeBuilder, matchBuilder, priority, write, false, false);
+        String flowName = "Egress_Allow_VM_IPv6_MAC" + "_" + localPort + attachedMac + "_Permit_";
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
+    }
+
+    private void addConntrackMatch(MatchBuilder matchBuilder, int state, int mask) {
+        if (securityServicesManager.isConntrackEnabled()) {
+            MatchUtils.addCtState(matchBuilder, state, mask );
+        }
+
+    }
+
+    private FlowBuilder addInstructionWithConntrackCommit( FlowBuilder flowBuilder , boolean isDrop) {
+        InstructionBuilder instructionBuilder = null;
+        if (securityServicesManager.isConntrackEnabled()) {
+            Action conntrackAction = ActionUtils.nxConntrackAction(1, 0L, 0, (short)0xff);
+            instructionBuilder = InstructionUtils
+                    .createInstructionBuilder(ActionUtils.conntrackActionBuilder(conntrackAction), 1, false);
+        }
+        return addPipelineInstruction(flowBuilder,instructionBuilder, isDrop);
+    }
+
+    private FlowBuilder addInstructionWithConntrackRecirc( FlowBuilder flowBuilder) {
+        InstructionBuilder instructionBuilder = null;
+        if (securityServicesManager.isConntrackEnabled()) {
+            Action conntrackAction = ActionUtils.nxConntrackAction(0, 0L, 0, (short)0x0);
+
+            instructionBuilder = InstructionUtils
+                    .createInstructionBuilder(ActionUtils.conntrackActionBuilder(conntrackAction), 1, false);
+            List<Instruction> instructionsList = Lists.newArrayList();
+            instructionsList.add(instructionBuilder.build());
+            InstructionsBuilder isb = new InstructionsBuilder();
+            isb.setInstruction(instructionsList);
+            flowBuilder.setInstructions(isb.build());
+        }
+        return flowBuilder;
+    }
+
+    private FlowBuilder addPipelineInstruction( FlowBuilder flowBuilder ,
+                                                InstructionBuilder instructionBuilder,boolean isDrop) {
+        InstructionBuilder pipeLineIndstructionBuilder = createPipleLineInstructionBuilder(isDrop);
+        List<Instruction> instructionsList = Lists.newArrayList();
+        instructionsList.add(pipeLineIndstructionBuilder.build());
+        if (null != instructionBuilder) {
+            instructionsList.add(instructionBuilder.build());
+        }
+        InstructionsBuilder isb = new InstructionsBuilder();
+        isb.setInstruction(instructionsList);
+        flowBuilder.setInstructions(isb.build());
+        return flowBuilder;
     }
 
+    private InstructionBuilder createPipleLineInstructionBuilder(boolean drop) {
+        InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
+        if (drop) {
+            InstructionUtils.createDropInstructions(ib);
+        }
+        ib.setOrder(0);
+        List<Instruction> instructionsList = Lists.newArrayList();
+        ib.setKey(new InstructionKey(0));
+        instructionsList.add(ib.build());
+        return ib;
+    }
     /**
      * Add or remove flow to the node.
-     *
-     * @param flowName the the flow id
+     * @param flowBuilder the flow builder
      * @param nodeBuilder the node builder
-     * @param matchBuilder the matchbuilder
-     * @param priority the protocol priority
      * @param write whether it is a write
-     * @param drop whether it is a drop or forward
-     * @param isCtCommit commit the connection or CT to track
      */
-    private void syncFlow(String flowName, NodeBuilder nodeBuilder,
-                          MatchBuilder matchBuilder, Integer priority,
-                          boolean write, boolean drop, boolean isCtCommit) {
-        MatchBuilder matchBuilder1 = matchBuilder;
-        if (isCtCommit) {
-            matchBuilder1 = MatchUtils.addCtState(matchBuilder1, MatchUtils.TRACKED_NEW_CT_STATE,
-                                                  MatchUtils.TRACKED_NEW_CT_STATE_MASK);
-        }
-        FlowBuilder flowBuilder = new FlowBuilder();
-        flowBuilder.setMatch(matchBuilder1.build());
-        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(priority);
-
+    private void syncFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder,
+                          boolean write) {
         if (write) {
-            InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
-            InstructionBuilder ib1 = new InstructionBuilder();
-            ActionBuilder ab = new ActionBuilder();
-            ApplyActionsBuilder aab = new ApplyActionsBuilder();
-            if (drop) {
-                InstructionUtils.createDropInstructions(ib);
-            }
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
-            InstructionsBuilder isb = new InstructionsBuilder();
-            List<Instruction> instructionsList = Lists.newArrayList();
-            instructionsList.add(ib.build());
-            if (isCtCommit) {
-                LOG.info("Adding Conntarck rule, flowname = " + flowName);
-                ab.setAction(ActionUtils.nxConntrackAction(1, 0L, 0, (short)0xff));
-                ab.setOrder(0);
-                ab.setKey(new ActionKey(0));
-                List<Action> actionList = Lists.newArrayList();
-                actionList.add(ab.build());
-                aab.setAction(actionList);
-                ib1.setOrder(1);
-                ib1.setKey(new InstructionKey(1));
-                ib1.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
-                instructionsList.add(ib1.build());
-            }
-            isb.setInstruction(instructionsList);
-            flowBuilder.setInstructions(isb.build());
             writeFlow(flowBuilder, nodeBuilder);
         } else {
             removeFlow(flowBuilder, nodeBuilder);
         }
     }
 
+
     @Override
     public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
         super.setDependencies(bundleContext.getServiceReference(EgressAclProvider.class.getName()), this);
index f7c393a38e726ddcffdc1477392c8ef2d0c21680..abe75570a3476c9eb4904e4ca41675b1a66f3c0e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2015 Red Hat, Inc. and others. All rights reserved.
+ * Copyright (c) 2014 - 2016 Red Hat, Inc. and others. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -25,37 +25,21 @@ import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
 import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefixBuilder;
 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.Ipv6Prefix;
-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.action.types.rev131112.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
 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.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.math.BigInteger;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -101,9 +85,9 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
              *
              */
 
-            if (portSecurityRule == null ||
-                    portSecurityRule.getSecurityRuleEthertype() == null ||
-                    portSecurityRule.getSecurityRuleDirection() == null) {
+            if (portSecurityRule == null
+                    || portSecurityRule.getSecurityRuleEthertype() == null
+                    || portSecurityRule.getSecurityRuleDirection() == null) {
                 continue;
             }
 
@@ -145,12 +129,13 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         String securityRuleEtherType = portSecurityRule.getSecurityRuleEthertype();
         boolean isIpv6 = NeutronSecurityRule.ETHERTYPE_IPV6.equals(securityRuleEtherType);
         if (!isIpv6 && !NeutronSecurityRule.ETHERTYPE_IPV4.equals(securityRuleEtherType)) {
-            LOG.debug("programPortSecurityRule: SecurityRuleEthertype {} does not match IPv4/v6.", securityRuleEtherType);
+            LOG.debug("programPortSecurityRule: SecurityRuleEthertype {} does not match IPv4/v6.",
+                      securityRuleEtherType);
             return;
         }
 
         if (null == portSecurityRule.getSecurityRuleProtocol()) {
-            ingressAclIP(dpid, isIpv6, segmentationId, attachedMac,
+            ingressAclIp(dpid, isIpv6, segmentationId, attachedMac,
                          write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
         } else {
             String ipaddress = null;
@@ -159,38 +144,39 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
                 try {
                     InetAddress address = InetAddress.getByName(vmIp.getIpAddress());
                     if ((isIpv6 && (address instanceof Inet4Address)) || (!isIpv6 && address instanceof Inet6Address)) {
-                        LOG.debug("programPortSecurityRule: Remote vmIP {} does not match with SecurityRuleEthertype {}.", ipaddress, securityRuleEtherType);
+                        LOG.debug("programPortSecurityRule: Remote vmIP {} does not match "
+                                + "with SecurityRuleEthertype {}.", ipaddress, securityRuleEtherType);
                         return;
                     }
-                } catch(UnknownHostException e) {
+                } catch (UnknownHostException e) {
                     LOG.warn("Invalid IP address {}", ipaddress, e);
                     return;
                 }
             }
 
             switch (portSecurityRule.getSecurityRuleProtocol()) {
-              case MatchUtils.TCP:
-                  LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
-                  ingressAclTcp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
+                case MatchUtils.TCP:
+                    LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
+                    ingressAclTcp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
                               write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                  break;
-              case MatchUtils.UDP:
-                  LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
-                  ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
+                    break;
+                case MatchUtils.UDP:
+                    LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
+                    ingressAclUdp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
                                 write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                  break;
-              case MatchUtils.ICMP:
-              case MatchUtils.ICMPV6:
-                  LOG.debug("programPortSecurityRule: Rule matching ICMP", portSecurityRule);
-                  ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
+                    break;
+                case MatchUtils.ICMP:
+                case MatchUtils.ICMPV6:
+                    LOG.debug("programPortSecurityRule: Rule matching ICMP", portSecurityRule);
+                    ingressAclIcmp(dpid, segmentationId, attachedMac, portSecurityRule, ipaddress,
                                  write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                  break;
-              default:
-                  LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other " +
-                          "protocol = ", portSecurityRule.getSecurityRuleProtocol());
-                  ingressOtherProtocolAclHandler(dpid, segmentationId, attachedMac, portSecurityRule,
+                    break;
+                default:
+                    LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other "
+                            + "protocol = ", portSecurityRule.getSecurityRuleProtocol());
+                    ingressOtherProtocolAclHandler(dpid, segmentationId, attachedMac, portSecurityRule,
                               null, write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-                  break;
+                    break;
             }
         }
     }
@@ -198,31 +184,33 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
     private void ingressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String dstMac,
           NeutronSecurityRule portSecurityRule, String srcAddress,
           boolean write, Integer protoPortMatchPriority) {
-
-          MatchBuilder matchBuilder = new MatchBuilder();
-          String flowId = "Ingress_Other_" + segmentationId + "_" + dstMac + "_";
-          matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,dstMac);
-          short proto = 0;
-          try {
-              Integer protocol = new Integer(portSecurityRule.getSecurityRuleProtocol());
-              proto = protocol.shortValue();
-              flowId = flowId + proto;
-          } catch (NumberFormatException e) {
-              LOG.error("Protocol vlaue conversion failure", e);
-          }
-          matchBuilder = MatchUtils.createIpProtocolMatch(matchBuilder, proto);
-          if (null != srcAddress) {
-              flowId = flowId + srcAddress;
-              matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
-                                        MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
-          } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
-              flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
-              matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
-                                        new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
-          }
-          NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
-          flowId = flowId + "_Permit";
-          syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
+        MatchBuilder matchBuilder = new MatchBuilder();
+        String flowId = "Ingress_Other_" + segmentationId + "_" + dstMac + "_";
+        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,dstMac,MatchUtils.ETHERTYPE_IPV4);
+        short proto = 0;
+        try {
+            Integer protocol = new Integer(portSecurityRule.getSecurityRuleProtocol());
+            proto = protocol.shortValue();
+            flowId = flowId + proto;
+        } catch (NumberFormatException e) {
+            LOG.error("Protocol vlaue conversion failure", e);
+        }
+        matchBuilder = MatchUtils.createIpProtocolMatch(matchBuilder, proto);
+        if (null != srcAddress) {
+            flowId = flowId + srcAddress;
+            matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+                                                        MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
+        } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+            flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+            matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+                                           new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
+        }
+        flowId = flowId + "_Permit";
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority,
+                                                              matchBuilder, getTable());
+        addInstructionWithConntrackCommit(flowBuilder, false);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     @Override
@@ -245,33 +233,30 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
     }
 
     private void programArpRule(Long dpid, String segmentationId, long localPort, String attachMac, boolean write) {
-        String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpid;
         MatchBuilder matchBuilder = new MatchBuilder();
-        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         String flowId = "Ingress_ARP_" + segmentationId + "_" + localPort + "_";
-        EthernetMatchBuilder ethernetType = new EthernetMatchBuilder();
-        EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
-        ethTypeBuilder.setType(new EtherType(0x0806L));
-        ethernetType.setEthernetType(ethTypeBuilder.build());
-        matchBuilder.setEthernetMatch(ethernetType.build());
-
-        ArpMatchBuilder arpDstMatch = new ArpMatchBuilder();
-        ArpTargetHardwareAddressBuilder arpDst = new ArpTargetHardwareAddressBuilder();
-        arpDst.setAddress(new MacAddress(attachMac));
-        arpDstMatch.setArpTargetHardwareAddress(arpDst.build());
-        matchBuilder.setLayer3Match(arpDstMatch.build());
-        syncFlow(flowId, nodeBuilder, matchBuilder, Constants.PROTO_MATCH_PRIORITY, write, false, securityServicesManager.isConntrackEnabled());
+        MatchUtils.createV4EtherMatchWithType(matchBuilder,null,null,MatchUtils.ETHERTYPE_ARP);
+        MatchUtils.addArpMacMatch(matchBuilder, null, attachMac);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, Constants.PROTO_MATCH_PRIORITY,
+                                                              matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpid);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     private void programIngressAclFixedConntrackRule(Long dpid,
            String segmentationId, String attachMac, long localPort, boolean write) {
         try {
             String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpid;
-            programConntrackUntrackRule(nodeName, segmentationId, localPort, attachMac,
+            programConntrackUntrackRule(dpid, segmentationId, localPort, attachMac,
                                         Constants.CT_STATE_UNTRACKED_PRIORITY, write );
-            programConntrackTrackedPlusEstRule(nodeName, segmentationId, localPort, attachMac,
-                                        Constants.CT_STATE_TRACKED_EST_PRIORITY, write );
-            programConntrackNewDropRule(nodeName, segmentationId, localPort, attachMac,
+            programConntrackTrackedPlusEstRule(dpid, segmentationId, localPort, attachMac,
+                                        Constants.CT_STATE_TRACKED_EXIST_PRIORITY, write );
+            programConntrackTrackedPlusRelRule(dpid, segmentationId, localPort, attachMac,
+                                               Constants.CT_STATE_TRACKED_EXIST_PRIORITY, write );
+            programConntrackInvDropRule(dpid, segmentationId, localPort, attachMac,
+                                        Constants.CT_STATE_NEW_PRIORITY_DROP, write );
+            programConntrackNewDropRule(dpid, segmentationId, localPort, attachMac,
                                              Constants.CT_STATE_NEW_PRIORITY_DROP, write );
             LOG.info("programIngressAclFixedConntrackRule :  default connection tracking rule are added.");
         } catch (Exception e) {
@@ -279,129 +264,95 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         }
     }
 
-    private void programConntrackUntrackRule(String nodeName, String segmentationId,
+    private void programConntrackUntrackRule(Long dpidLong, String segmentationId,
                                              long localPort, String attachMac, Integer priority, boolean write) {
         MatchBuilder matchBuilder = new MatchBuilder();
-        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         String flowName = "Ingress_Fixed_Conntrk_Untrk_" + segmentationId + "_" + localPort + "_";
-        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,attachMac);
+        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,attachMac,MatchUtils.ETHERTYPE_IPV4);
         matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.UNTRACKED_CT_STATE,
                                              MatchUtils.UNTRACKED_CT_STATE_MASK);
-        FlowBuilder flowBuilder = new FlowBuilder();
-        flowBuilder.setMatch(matchBuilder.build());
-        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(priority);
-        if (write) {
-            InstructionBuilder ib = new InstructionBuilder();
-            List<Instruction> instructionsList = Lists.newArrayList();
-            InstructionsBuilder isb = new InstructionsBuilder();
-            ActionBuilder ab = new ActionBuilder();
-            ab.setAction(ActionUtils.nxConntrackAction(0, 0L, 0, (short)0x0));
-            // 0xff means no table, 0x0 is table = 0
-            // nxConntrackAction(Integer flags, Long zoneSrc,Integer conntrackZone, Short recircTable)
-            ab.setOrder(0);
-            ab.setKey(new ActionKey(0));
-            List<Action> actionList = Lists.newArrayList();
-            actionList.add(ab.build());
-            ApplyActionsBuilder aab = new ApplyActionsBuilder();
-            aab.setAction(actionList);
-
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
-            ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
-            instructionsList.add(ib.build());
-            isb.setInstruction(instructionsList);
-            flowBuilder.setInstructions(isb.build());
-            writeFlow(flowBuilder, nodeBuilder);
-            LOG.info("INGRESS:default programConntrackUntrackRule() flows are written");
-        } else {
-            removeFlow(flowBuilder, nodeBuilder);
-        }
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addInstructionWithConntrackRecirc(flowBuilder);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
-    private void programConntrackTrackedPlusEstRule(String nodeName, String segmentationId,
+    private void programConntrackTrackedPlusEstRule(Long dpidLong, String segmentationId,
                                                   long localPort, String attachMac,Integer priority, boolean write) {
         MatchBuilder matchBuilder = new MatchBuilder();
-        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
         String flowName = "Ingress_Fixed_Conntrk_TrkEst_" + segmentationId + "_" + localPort + "_";
-        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,attachMac);
+        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,attachMac,MatchUtils.ETHERTYPE_IPV4);
         matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.TRACKED_EST_CT_STATE,
-                                             MatchUtils.TRACKED_EST_CT_STATE_MASK);
-        FlowBuilder flowBuilder = new FlowBuilder();
-        flowBuilder.setMatch(matchBuilder.build());
-        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(priority);
-        if (write) {
-            InstructionBuilder ib = new InstructionBuilder();
-            List<Instruction> instructionsList = Lists.newArrayList();
-            InstructionsBuilder isb = new InstructionsBuilder();
+                                             MatchUtils.TRACKED_CT_STATE_MASK);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
+    }
 
-            ib = this.getMutablePipelineInstructionBuilder();
-            ib.setOrder(0);
-            ib.setKey(new InstructionKey(0));
-            instructionsList.add(ib.build());
-             isb.setInstruction(instructionsList);
-            flowBuilder.setInstructions(isb.build());
-            writeFlow(flowBuilder, nodeBuilder);
-            LOG.info("INGRESS:default programConntrackTrackedPlusEstRule() flows are written");
-        } else {
-            removeFlow(flowBuilder, nodeBuilder);
-        }
+    private void programConntrackTrackedPlusRelRule(Long dpidLong, String segmentationId,
+                                                    long localPort, String attachMac,Integer priority, boolean write) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+        String flowName = "Ingress_Fixed_Conntrk_TrkRel_" + segmentationId + "_" + localPort + "_";
+        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,attachMac,MatchUtils.ETHERTYPE_IPV4);
+        matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.TRACKED_REL_CT_STATE,
+                                             MatchUtils.TRACKED_CT_STATE_MASK);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
-    private void programConntrackNewDropRule(String nodeName, String segmentationId,
+    private void programConntrackNewDropRule(Long dpidLong, String segmentationId,
                                              long localPort, String attachMac, Integer priority, boolean write) {
         MatchBuilder matchBuilder = new MatchBuilder();
-        NodeBuilder nodeBuilder = createNodeBuilder(nodeName);
-        String flowName = "Ingress_Fixed_Conntrk_NewDrop_" + segmentationId + "_" + localPort + "_";
-        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,attachMac);
-        matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.NEW_CT_STATE, MatchUtils.NEW_CT_STATE_MASK);
-        FlowBuilder flowBuilder = new FlowBuilder();
-        flowBuilder.setMatch(matchBuilder.build());
-        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(priority);
-        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();
+        String flowName = "Ingress_Fixed_Conntrk_NewDrop_" + segmentationId + "_" + localPort + "_";
+        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,attachMac,0x0800L);
+        matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.TRACKED_NEW_CT_STATE,
+                                             MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, true);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
+    }
 
-            // 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);
-            LOG.debug("Instructions contain: {}", ib.getInstruction());
-            // Add InstructionsBuilder to FlowBuilder
-            flowBuilder.setInstructions(isb.build());
-            writeFlow(flowBuilder, nodeBuilder);
-            LOG.info("INGRESS:default programConntrackNewDropRule flows are written");
-        } else {
-            removeFlow(flowBuilder, nodeBuilder);
-        }
+    private void programConntrackInvDropRule(Long dpidLong, String segmentationId,
+                                             long localPort, String attachMac, Integer priority, boolean write) {
+        MatchBuilder matchBuilder = new MatchBuilder();
+        String flowName = "Ingress_Fixed_Conntrk_InvDrop_" + segmentationId + "_" + localPort + "_";
+        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,attachMac, MatchUtils.ETHERTYPE_IPV4);
+        matchBuilder = MatchUtils.addCtState(matchBuilder,MatchUtils.TRACKED_INV_CT_STATE,
+                                             MatchUtils.TRACKED_INV_CT_STATE_MASK);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, true);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     /**
      * Allows an IPv4/v6 packet ingress to the destination mac address.
      * @param dpidLong the dpid
+     * @param isIpv6 indicates whether this is an Ipv
      * @param segmentationId the segementation id
      * @param dstMac the destination mac address
      * @param write add or remove
      * @param protoPortMatchPriority the protocol match priority.
      */
-    private void ingressAclIP(Long dpidLong, boolean isIpv6, String segmentationId, String dstMac,
+    private void ingressAclIp(Long dpidLong, boolean isIpv6, String segmentationId, String dstMac,
                               boolean write, Integer protoPortMatchPriority ) {
-        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Ingress_IP" + segmentationId + "_" + dstMac + "_Permit_";
         if (isIpv6) {
             matchBuilder = MatchUtils.createV6EtherMatchWithType(matchBuilder,null,dstMac);
-        }else {
-            matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,dstMac);
+        } else {
+            matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,dstMac,MatchUtils.ETHERTYPE_IPV4);
         }
-        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
+        addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
+        addInstructionWithConntrackCommit(flowBuilder, false);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     /**
@@ -426,7 +377,7 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         if (isIpv6) {
             matchBuilder = MatchUtils.createV6EtherMatchWithType(matchBuilder,null,dstMac);
         } else {
-            matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,dstMac);
+            matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,dstMac,MatchUtils.ETHERTYPE_IPV4);
         }
 
         /* Custom TCP Match*/
@@ -476,11 +427,19 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
                 rangeflowId = rangeflowId + "_Permit";
                 MatchUtils.addLayer4MatchWithMask(matchBuilder, MatchUtils.TCP_SHORT,
                                                   0, port, portMaskMap.get(port));
-                syncFlow(rangeflowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
+                addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+                FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(rangeflowId, protoPortMatchPriority,
+                                                                      matchBuilder, getTable());
+                addInstructionWithConntrackCommit(flowBuilder, false);
+                syncFlow(flowBuilder ,nodeBuilder, write);
             }
         } else {
             flowId = flowId + "_Permit";
-            syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
+            addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+            FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority,
+                                                                  matchBuilder, getTable());
+            addInstructionWithConntrackCommit(flowBuilder, false);
+            syncFlow(flowBuilder ,nodeBuilder, write);
         }
     }
 
@@ -505,8 +464,8 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         String flowId = "Ingress_UDP_" + segmentationId + "_" + dstMac + "_";
         if (isIpv6)  {
             matchBuilder = MatchUtils.createV6EtherMatchWithType(matchBuilder,null,dstMac);
-        }else {
-            matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,dstMac);
+        } else {
+            matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,dstMac,MatchUtils.ETHERTYPE_IPV4);
         }
 
         /* Custom UDP Match */
@@ -556,11 +515,19 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
                 rangeflowId = rangeflowId + "_Permit";
                 MatchUtils.addLayer4MatchWithMask(matchBuilder, MatchUtils.UDP_SHORT,
                                                    0, port, portMaskMap.get(port));
-                syncFlow(rangeflowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
+                addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+                FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(rangeflowId, protoPortMatchPriority,
+                                                                      matchBuilder, getTable());
+                addInstructionWithConntrackCommit(flowBuilder, false);
+                syncFlow(flowBuilder ,nodeBuilder, write);
             }
         } else {
             flowId = flowId + "_Permit";
-            syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
+            addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+            FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority,
+                                                                  matchBuilder, getTable());
+            addInstructionWithConntrackCommit(flowBuilder, false);
+            syncFlow(flowBuilder ,nodeBuilder, write);
         }
     }
 
@@ -570,9 +537,11 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
 
         boolean isIpv6 = NeutronSecurityRule.ETHERTYPE_IPV6.equals(portSecurityRule.getSecurityRuleEthertype());
         if (isIpv6) {
-            ingressAclIcmpV6(dpidLong, segmentationId, dstMac, portSecurityRule, srcAddress, write, protoPortMatchPriority);
+            ingressAclIcmpV6(dpidLong, segmentationId, dstMac, portSecurityRule, srcAddress,
+                             write, protoPortMatchPriority);
         } else {
-            ingressAclIcmpV4(dpidLong, segmentationId, dstMac, portSecurityRule, srcAddress, write, protoPortMatchPriority);
+            ingressAclIcmpV4(dpidLong, segmentationId, dstMac, portSecurityRule, srcAddress,
+                             write, protoPortMatchPriority);
         }
     }
 
@@ -594,11 +563,11 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
 
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Ingress_ICMP_" + segmentationId + "_" + dstMac + "_";
-        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,dstMac);
+        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,null,dstMac,MatchUtils.ETHERTYPE_IPV4);
 
         /* Custom ICMP Match */
-        if (portSecurityRule.getSecurityRulePortMin() != null &&
-                portSecurityRule.getSecurityRulePortMax() != null) {
+        if (portSecurityRule.getSecurityRulePortMin() != null
+                && portSecurityRule.getSecurityRulePortMax() != null) {
             flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
                     + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
             matchBuilder = MatchUtils.createICMPv4Match(matchBuilder,
@@ -620,9 +589,12 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
                                          new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
             }
         }
-        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
         flowId = flowId + "_Permit";
-        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
+        addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
+        addInstructionWithConntrackCommit(flowBuilder, false);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     /**
@@ -646,8 +618,8 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         matchBuilder = MatchUtils.createV6EtherMatchWithType(matchBuilder,null,dstMac);
 
         /* Custom ICMP Match */
-        if (portSecurityRule.getSecurityRulePortMin() != null &&
-                portSecurityRule.getSecurityRulePortMax() != null) {
+        if (portSecurityRule.getSecurityRulePortMin() != null
+                && portSecurityRule.getSecurityRulePortMax() != null) {
             flowId = flowId + portSecurityRule.getSecurityRulePortMin().shortValue() + "_"
                     + portSecurityRule.getSecurityRulePortMax().shortValue() + "_";
             matchBuilder = MatchUtils.createICMPv6Match(matchBuilder,
@@ -668,9 +640,12 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
                     new Ipv6Prefix(portSecurityRule
                                    .getSecurityRuleRemoteIpPrefix()),null);
         }
+        addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
         flowId = flowId + "_Permit";
-        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, false);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
+        addInstructionWithConntrackCommit(flowBuilder, false);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     /**
@@ -689,7 +664,9 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createDhcpServerMatch(matchBuilder, dhcpMacAddress, 67, 68).build();
         String flowId = "Ingress_DHCP_Server" + segmentationId + "_" + dhcpMacAddress + "_Permit_";
-        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, false);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
+        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     /**
@@ -708,60 +685,77 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createDhcpv6ServerMatch(matchBuilder, dhcpMacAddress, 547, 546).build();
         String flowId = "Ingress_DHCPv6_Server" + segmentationId + "_" + dhcpMacAddress + "_Permit_";
-        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, false);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
+        syncFlow(flowBuilder ,nodeBuilder, write);
+    }
+
+    private void addConntrackMatch(MatchBuilder matchBuilder, int state, int mask) {
+        if (securityServicesManager.isConntrackEnabled()) {
+            MatchUtils.addCtState(matchBuilder, state, mask );
+        }
+
+    }
+
+    private FlowBuilder addInstructionWithConntrackCommit( FlowBuilder flowBuilder , boolean isDrop) {
+        InstructionBuilder instructionBuilder = null;
+        if (securityServicesManager.isConntrackEnabled()) {
+            Action conntrackAction = ActionUtils.nxConntrackAction(1, 0L, 0, (short)0xff);
+            instructionBuilder = InstructionUtils
+                    .createInstructionBuilder(ActionUtils.conntrackActionBuilder(conntrackAction), 1, false);
+        }
+        return addPipelineInstruction(flowBuilder,instructionBuilder, isDrop);
+    }
+
+    private FlowBuilder addInstructionWithConntrackRecirc( FlowBuilder flowBuilder) {
+        InstructionBuilder instructionBuilder = null;
+        if (securityServicesManager.isConntrackEnabled()) {
+            Action conntrackAction = ActionUtils.nxConntrackAction(0, 0L, 0, (short)0x0);
+            instructionBuilder = InstructionUtils
+                    .createInstructionBuilder(ActionUtils.conntrackActionBuilder(conntrackAction), 1, false);
+            List<Instruction> instructionsList = Lists.newArrayList();
+            instructionsList.add(instructionBuilder.build());
+            InstructionsBuilder isb = new InstructionsBuilder();
+            isb.setInstruction(instructionsList);
+            flowBuilder.setInstructions(isb.build());
+        }
+        return flowBuilder;
     }
 
+    private FlowBuilder addPipelineInstruction( FlowBuilder flowBuilder , InstructionBuilder instructionBuilder,
+                                                boolean isDrop) {
+        InstructionBuilder pipeLineIndstructionBuilder = createPipleLineInstructionBuilder(isDrop);
+        List<Instruction> instructionsList = Lists.newArrayList();
+        instructionsList.add(pipeLineIndstructionBuilder.build());
+        if (null != instructionBuilder) {
+            instructionsList.add(instructionBuilder.build());
+        }
+        InstructionsBuilder isb = new InstructionsBuilder();
+        isb.setInstruction(instructionsList);
+        flowBuilder.setInstructions(isb.build());
+        return flowBuilder;
+    }
+
+    private InstructionBuilder createPipleLineInstructionBuilder(boolean drop) {
+        InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
+        if (drop) {
+            InstructionUtils.createDropInstructions(ib);
+        }
+        ib.setOrder(0);
+        List<Instruction> instructionsList = Lists.newArrayList();
+        ib.setKey(new InstructionKey(0));
+        instructionsList.add(ib.build());
+        return ib;
+    }
     /**
      * Add or remove flow to the node.
-     *
-     * @param flowName the the flow id
+     * @param flowBuilder the flow builder
      * @param nodeBuilder the node builder
-     * @param matchBuilder the matchbuilder
-     * @param priority the protocol priority
      * @param write whether it is a write
-     * @param drop whether it is a drop or forward
-     * @param isCtCommit commit the connection or CT to track
      */
-    private void syncFlow(String flowName, NodeBuilder nodeBuilder,
-                          MatchBuilder matchBuilder, Integer priority,
-                          boolean write, boolean drop, boolean isCtCommit) {
-        MatchBuilder matchBuilder1 = matchBuilder;
-        if (isCtCommit) {
-            matchBuilder1 = MatchUtils.addCtState(matchBuilder1,MatchUtils.TRACKED_NEW_CT_STATE,
-                                                  MatchUtils.TRACKED_NEW_CT_STATE_MASK);
-        }
-        FlowBuilder flowBuilder = new FlowBuilder();
-        flowBuilder.setMatch(matchBuilder1.build());
-        FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(priority);
-
+    private void syncFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder,
+                          boolean write) {
         if (write) {
-            InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
-            InstructionBuilder ib1 = new InstructionBuilder();
-            ActionBuilder ab = new ActionBuilder();
-            ApplyActionsBuilder aab = new ApplyActionsBuilder();
-            if (drop) {
-                InstructionUtils.createDropInstructions(ib);
-            }
-            ib.setOrder(0);
-            InstructionsBuilder isb = new InstructionsBuilder();
-            List<Instruction> instructionsList = Lists.newArrayList();
-            ib.setKey(new InstructionKey(0));
-            instructionsList.add(ib.build());
-            if (isCtCommit) {
-                LOG.info("Adding Conntarck rule, flowname = " + flowName);
-                ab.setAction(ActionUtils.nxConntrackAction(1, 0L, 0, (short)0xff));
-                ab.setOrder(0);
-                ab.setKey(new ActionKey(0));
-                List<Action> actionList = Lists.newArrayList();
-                actionList.add(ab.build());
-                aab.setAction(actionList);
-                ib1.setOrder(1);
-                ib1.setKey(new InstructionKey(1));
-                ib1.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
-                instructionsList.add(ib1.build());
-            }
-            isb.setInstruction(instructionsList);
-            flowBuilder.setInstructions(isb.build());
             writeFlow(flowBuilder, nodeBuilder);
         } else {
             removeFlow(flowBuilder, nodeBuilder);
index 17c41edeb50b368e20b375342bc0eac2e1457dd2..0fd208e331b080b853989b7de087d8b2b8e1e360 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Inocybe and others.  All rights reserved.
+ * Copyright (c) 2015 - 2016 Inocybe and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -1596,10 +1596,10 @@ public class EgressAclServiceTest {
 
         egressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, false, true, true);
 
-        verify(writeTransaction, times(12)).put(any(LogicalDatastoreType.class),
+        verify(writeTransaction, times(14)).put(any(LogicalDatastoreType.class),
                                                any(InstanceIdentifier.class), any(Node.class), eq(true));
-        verify(writeTransaction, times(12)).submit();
-        verify(commitFuture, times(12)).checkedGet();
+        verify(writeTransaction, times(14)).submit();
+        verify(commitFuture, times(14)).checkedGet();
     }
 
     /**
@@ -1611,9 +1611,9 @@ public class EgressAclServiceTest {
 
         egressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, neutronDestIpList, false, true, false);
 
-        verify(writeTransaction, times(12)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-        verify(writeTransaction, times(12)).submit();
-        verify(commitFuture, times(12)).get();
+        verify(writeTransaction, times(14)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+        verify(writeTransaction, times(14)).submit();
+        verify(commitFuture, times(14)).get();
     }
 
 }
index 74c7f8cb161d080a735d83a272332725927441ff..eccedd995615a163bf9c47d303e119f45f72c880 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Inocybe and others.  All rights reserved.
+ * Copyright (c) 2015 - 2016 Inocybe and others.  All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -1622,9 +1622,9 @@ public class IngressAclServiceTest {
 
         ingressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", DHCP_MAC_ADDRESS, 1, false, true, MAC_ADDRESS, true);
 
-        verify(writeTransaction, times(4)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
-        verify(writeTransaction, times(4)).submit();
-        verify(commitFuture, times(4)).checkedGet();
+        verify(writeTransaction, times(6)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
+        verify(writeTransaction, times(6)).submit();
+        verify(commitFuture, times(6)).checkedGet();
     }
     /**
      *  Test With isConntrackEnabled true isComputeNode true
@@ -1635,9 +1635,9 @@ public class IngressAclServiceTest {
 
         ingressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", DHCP_MAC_ADDRESS, 1, false, true, MAC_ADDRESS, false);
 
-        verify(writeTransaction, times(4)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
-        verify(writeTransaction, times(4)).submit();
-        verify(commitFuture, times(4)).get();
+        verify(writeTransaction, times(6)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
+        verify(writeTransaction, times(6)).submit();
+        verify(commitFuture, times(6)).get();
     }
 
 }
index ccdf55bab6cf4f871b39e7f777141baef010cdb9..f97b8d8774b0383e7d21c457a464849a1da12cb2 100644 (file)
@@ -92,7 +92,7 @@ public final class Constants {
     public static final Integer PROTO_DHCP_SERVER_MATCH_PRIORITY = 61006;
     public static final Integer PROTO_VM_IP_MAC_MATCH_PRIORITY = 36001;
     public static final Integer CT_STATE_UNTRACKED_PRIORITY = 62030;
-    public static final Integer CT_STATE_TRACKED_EST_PRIORITY = 62020;
+    public static final Integer CT_STATE_TRACKED_EXIST_PRIORITY = 62020;
     public static final Integer CT_STATE_TRACKED_NEW_PRIORITY = 62010;
     public static final Integer CT_STATE_NEW_PRIORITY_DROP = 36007;
 
index dfaed3a3ac8a806ba45229a49623ae93aea46867..cf5bd779444fe1c92d37ba5d2339533799b0dcc6 100644 (file)
@@ -8,7 +8,9 @@
 
 package org.opendaylight.ovsdb.utils.mdsal.openflow;
 
+import com.google.common.collect.Lists;
 import com.google.common.net.InetAddresses;
+
 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;
@@ -32,7 +34,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetFieldBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.dst.action._case.SetNwDstActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
@@ -104,6 +109,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfIpSrcCaseBuilder;
 
 import java.math.BigInteger;
+import java.util.List;
 
 public final class ActionUtils {
     public static Action dropAction() {
@@ -449,6 +455,14 @@ public final class ActionUtils {
         return new NxActionMultipathNodesNodeTableFlowApplyActionsCaseBuilder().setNxMultipath(r).build();
     }
 
+    /**
+     * Builds the  conntrack action.
+     * @param flags the flags for the action
+     * @param zoneSrc the zoneSrc
+     * @param conntrackZone the conntrackZone
+     * @param recircTable the recirc table if it is a recirc action
+     * @return the conntrack action.
+     */
     public static Action nxConntrackAction(Integer flags, Long zoneSrc,
                                            Integer conntrackZone, Short recircTable) {
         NxConntrack r = new NxConntrackBuilder()
@@ -460,6 +474,23 @@ public final class ActionUtils {
         return new NxActionConntrackNodesNodeTableFlowApplyActionsCaseBuilder().setNxConntrack(r).build();
     }
 
+    /**
+     * Builds the apply action builder for the action
+     * @param action the conntrack action.
+     * @return the apply action builder.
+     */
+    public static ApplyActionsBuilder conntrackActionBuilder(Action action) {
+        ActionBuilder ab = new ActionBuilder();
+        ab.setAction(action);
+        ab.setOrder(0);
+        ab.setKey(new ActionKey(0));
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actionList =
+                Lists.newArrayList();
+        actionList.add(ab.build());
+        ApplyActionsBuilder aab = new ApplyActionsBuilder();
+        aab.setAction(actionList);
+        return aab;
+    }
     /**
      * Accepts a MAC address and returns the corresponding long, where the
      * MAC bytes are set on the lower order bytes of the long.
index b8bd69a91198c5120e43a29fda23ce37f06ec9d9..1c5329c9f9b84bb8d65a2d896533dcfc968bd911 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Red Hat, Inc. and others. All rights reserved.
+ * Copyright (c) 2015 - 2016 Red Hat, Inc. and others. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -9,7 +9,9 @@
 package org.opendaylight.ovsdb.utils.mdsal.openflow;
 
 import com.google.common.base.Optional;
+
 import java.util.concurrent.ExecutionException;
+
 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
@@ -105,6 +107,21 @@ public class FlowUtils {
                 .setPriority(0);
     }
 
+    /**
+     * Creates a flowBuilder.
+     * @param flowName the flow name
+     * @param priority the priority
+     * @param matchBuilder the match builder
+     * @param tableNo the table no to which flow needs to be inserted.
+     * @return the created flow builder.
+     */
+    public static FlowBuilder createFlowBuilder(String flowName,Integer priority,
+                                                MatchBuilder matchBuilder, short tableNo) {
+        FlowBuilder flowBuilder = new FlowBuilder();
+        flowBuilder.setMatch(matchBuilder.build());
+        initFlowBuilder(flowBuilder, flowName, tableNo).setPriority(priority);
+        return flowBuilder;
+    }
     /**
      * Sets up common defaults for the given flow builder: a flow identifier and key based on the given flow name,
      * strict, no barrier, the given table identifier, no hard timeout and no idle timeout.
index 4c59d45c555d382d70361647de70c6ff9620d4c6..dd3f80be6fe59103605b88bbf0f251bd84786206 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015 Red Hat, Inc. and others. All rights reserved.
+ * Copyright (c) 2013 - 2016 Red Hat, Inc. and others. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -10,6 +10,11 @@ package org.opendaylight.ovsdb.utils.mdsal.openflow;
 
 import static org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils.dropAction;
 
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 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.inet.types.rev100924.Uri;
@@ -69,15 +74,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.TunnelIpv4MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 public class InstructionUtils {
     private static final Logger LOG = LoggerFactory.getLogger(InstructionUtils.class);
     private static final int IPV4 = 0x8100;
@@ -1131,7 +1130,6 @@ public class InstructionUtils {
     /**
      * Get a list of Instructions containing Nicira extensions that can have
      * additional OF/OXM instructions added to the returned Instruction list
-     *
      * @param instructions org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instructions
      * @return instruction list that additional
      */
@@ -1148,4 +1146,23 @@ public class InstructionUtils {
         }
         return ins;
     }
+
+    /**
+     * Create InstructionBuilder with apply action.
+     *
+     * @param aab the apply action Builder.
+     * @param order the position of the instruction in the instruction list.
+     * @param drop indicates whether it is a drop instruction.
+     * @return the instruction builder.
+     */
+    public static InstructionBuilder createInstructionBuilder(ApplyActionsBuilder aab, int order, boolean drop) {
+        InstructionBuilder ib = new InstructionBuilder();
+        ib.setOrder(order);
+        ib.setKey(new InstructionKey(order));
+        ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+        if (drop) {
+            InstructionUtils.createDropInstructions(ib);
+        }
+        return ib;
+    }
 }
index 18ab1c3005e6b3cb34e7f8dcd9474fb98a60f06a..cfcd7cfe32db39f029064ba5cf53c69f4888ede2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015 Red Hat, Inc. and others. All rights reserved.
+ * Copyright (c) 2013 - 2016 Red Hat, Inc. and others. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -23,6 +23,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.M
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 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.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
@@ -50,7 +52,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev14
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmOfEthDst;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
@@ -82,7 +83,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.nsp.grouping.NxmNxNspBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxNsiKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.nsi.grouping.NxmNxNsiBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.of.eth.dst.grouping.NxmOfEthDstBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.of.tcp.src.grouping.NxmOfTcpSrcBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.of.tcp.dst.grouping.NxmOfTcpDstBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.of.udp.dst.grouping.NxmOfUdpDstBuilder;
@@ -107,14 +107,16 @@ public class MatchUtils {
     public static final short ALL_ICMP = -1;
     public static final long ETHERTYPE_IPV4 = 0x0800;
     public static final long ETHERTYPE_IPV6 = 0x86dd;
+    public static final long ETHERTYPE_ARP = 0x0806L;
     public static final int UNTRACKED_CT_STATE = 0x00;
     public static final int UNTRACKED_CT_STATE_MASK = 0x20;
     public static final int TRACKED_EST_CT_STATE = 0x22;
-    public static final int TRACKED_EST_CT_STATE_MASK = 0x22;
+    public static final int TRACKED_REL_CT_STATE = 0x24;
     public static final int TRACKED_NEW_CT_STATE = 0x21;
+    public static final int TRACKED_INV_CT_STATE = 0x30;
+    public static final int TRACKED_INV_CT_STATE_MASK = 0x30;
+    public static final int TRACKED_CT_STATE_MASK = 0x37;
     public static final int TRACKED_NEW_CT_STATE_MASK = 0x21;
-    public static final int NEW_CT_STATE = 0x01;
-    public static final int NEW_CT_STATE_MASK = 0x01;
 
     /**
      * Create Ingress Port Match dpidLong, inPort
@@ -347,6 +349,29 @@ public class MatchUtils {
         return matchBuilder;
     }
 
+    /**
+     * Builds the arp match with src and destintion mac address.
+     * @param matchBuilder the match builder
+     * @param srcMac the src mac address , will not be added to match if null.
+     * @param dstMac the destination mac address, will not be added to match if null.
+     * @return the match builder with the matches
+     */
+    public static MatchBuilder addArpMacMatch(MatchBuilder matchBuilder, String srcMac, String dstMac) {
+        ArpMatchBuilder arpMatch = new ArpMatchBuilder();
+        if (null != srcMac) {
+            ArpSourceHardwareAddressBuilder arpSrc = new ArpSourceHardwareAddressBuilder();
+            arpSrc.setAddress(new MacAddress(srcMac));
+            arpMatch.setArpSourceHardwareAddress(arpSrc.build());
+        }
+        if (null != dstMac) {
+            ArpTargetHardwareAddressBuilder arpDst = new ArpTargetHardwareAddressBuilder();
+            arpDst.setAddress(new MacAddress(dstMac));
+            arpMatch.setArpTargetHardwareAddress(arpDst.build());
+        }
+        matchBuilder.setLayer3Match(arpMatch.build());
+        return matchBuilder;
+    }
+
     /**
      * @param matchBuilder MatchBuilder Object without a match yet
      * @param srcip        String containing an IPv4 prefix
@@ -1203,10 +1228,10 @@ public class MatchUtils {
      * @param dstMac The destination mac address
      * @return matchBuilder Map Object with a match
      */
-    public static MatchBuilder createV4EtherMatchWithType(MatchBuilder matchBuilder,String srcMac, String dstMac)
+    public static MatchBuilder createV4EtherMatchWithType(MatchBuilder matchBuilder,String srcMac, String dstMac, Long type)
     {
         EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
-        ethTypeBuilder.setType(new EtherType(0x0800L));
+        ethTypeBuilder.setType(new EtherType(type));
         EthernetMatchBuilder eth = new EthernetMatchBuilder();
         eth.setEthernetType(ethTypeBuilder.build());
         if (null != srcMac) {