Adding changes to use and support connecting tracking. By default SG
authorraveek <raveek@hp.com>
Thu, 7 Jan 2016 05:03:00 +0000 (10:33 +0530)
committerSam Hague <shague@redhat.com>
Tue, 12 Jan 2016 19:50:44 +0000 (19:50 +0000)
will push flows with out conntrack match and action, but user can modify
default-config.xml to enable conntrack.

Patch 2: after fixing the review comments
Patch 3: Fixed the test failure

Change-Id: I71d8fd23d66caad97e406507889ebba38bd80d27
Signed-off-by: raveek <raveek@hp.com>
15 files changed:
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/OF13Provider.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/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/IngressAclServiceTest.java
openstack/net-virt/src/main/config/default-config.xml
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/ConfigActivator.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/NetvirtProvider.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/Constants.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/IngressAclProvider.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/SecurityServicesManager.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SecurityServicesImpl.java
openstack/net-virt/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/netvirt/impl/rev150513/NetvirtImplModule.java
openstack/net-virt/src/main/yang/netvirt-impl.yang
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/MatchUtils.java

index f27e742e46d531b70055e3cf78bd4875399fbf00..55271c54eac3f010177d4bc924dd54597d00031f 100644 (file)
@@ -1022,7 +1022,7 @@ public class OF13Provider implements ConfigInterface, NetworkingProvider {
                 }
             }
             ingressAclProvider.programFixedSecurityGroup(dpid, segmentationId, dhcpPort.getMacAddress(), localPort,
-                                                       isLastPortinSubnet, isComputePort, write);
+                                                       isLastPortinSubnet, isComputePort, attachedMac, write);
             egressAclProvider.programFixedSecurityGroup(dpid, segmentationId, attachedMac, localPort,
                                                       srcAddressList, isLastPortinBridge, isComputePort,write);
             /* If the network type is tunnel based (VXLAN/GRRE/etc) with Neutron Port Security ACLs */
index 710995ba285eef591bb0d3b36b5acbc963a3f749..a3f1d0f5c0f6ea45a5970fbb2400873120ddc4fe 100644 (file)
@@ -20,6 +20,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
@@ -29,13 +30,25 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.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.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.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;
@@ -228,7 +241,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         }
         flowId = flowId + "_Permit";
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
-        syncFlow(flowId, nodeBuilder, matchBuilder, priority, write, false);
+        syncFlow(flowId, nodeBuilder, matchBuilder, priority, write, false, securityServicesManager.isConntrackEnabled());
     }
 
     @Override
@@ -236,10 +249,14 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                         long localPort, List<Neutron_IPs> srcAddressList,
                                         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) {
+        //if (isLastPortinBridge) {
             egressAclDhcpAllowClientTrafficFromVm(dpid, write, Constants.PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY);
-        }
+       // }
         if (isComputePort) {
+            programArpRule(dpid, segmentationId, localPort, attachedMac, write);
+            if (securityServicesManager.isConntrackEnabled()) {
+                programEgressAclFixedConntrackRule(dpid, segmentationId, localPort, attachedMac, write);
+            }
             // add rule to drop the DHCP server traffic originating from the vm.
             egressAclDhcpDropServerTrafficfromVm(dpid, localPort, write,
                                                  Constants.PROTO_DHCP_CLIENT_SPOOF_MATCH_PRIORITY_DROP);
@@ -262,6 +279,135 @@ 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 + "_";
+
+        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();
+        ArpSourceHardwareAddressBuilder arpSrc = new ArpSourceHardwareAddressBuilder();
+        arpSrc.setAddress(new MacAddress(attachedMac));
+        arpDstMatch.setArpSourceHardwareAddress(arpSrc.build());
+        matchBuilder.setLayer3Match(arpDstMatch.build());
+
+        syncFlow(flowId, nodeBuilder, matchBuilder, Constants.PROTO_MATCH_PRIORITY, write, false, false);
+    }
+
+    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.createEtherMatchWithType(matchBuilder, attachMac, null);
+         matchBuilder = MatchUtils.addCtState(matchBuilder,0x00,0X80);
+         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,0x82, 0x82);
+         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,0x01, 0x01);
+         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);
+         }
+     }
+
     /**
      * Allows IPv4 packet egress from the src mac address.
      * @param dpidLong the dpid
@@ -276,7 +422,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Egress_IP" + segmentationId + "_" + srcMac + "_Permit_";
         matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,srcMac,null);
-        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, false);
     }
 
     /**
@@ -335,11 +481,11 @@ 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);
+                syncFlow(rangeflowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
             }
         } else {
             flowId = flowId + "_Permit";
-            syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+            syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
         }
     }
 
@@ -381,12 +527,14 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                     MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
         } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
             flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
-            matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
+            if (!portSecurityRule.getSecurityRuleRemoteIpPrefix().contains("/0")) {
+                matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
                     new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
+            }
         }
         flowId = flowId + "_Permit";
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
-        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
     }
 
     /**
@@ -445,11 +593,11 @@ 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);
+                syncFlow(rangeflowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
             }
         } else {
             flowId = flowId + "_Permit";
-            syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+            syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
         }
     }
 
@@ -625,7 +773,7 @@ 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);
+        syncFlow(flowName, nodeBuilder, matchBuilder, priority, write, false, false);
     }
 
     /**
@@ -644,7 +792,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         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);
+        syncFlow(flowName, nodeBuilder, matchBuilder, priority, write, true, false);
     }
 
     /**
@@ -666,7 +814,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         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);
+        syncFlow(flowName, nodeBuilder, matchBuilder, priority, write, false, false);
     }
 
     /**
@@ -678,16 +826,24 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
      * @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 write, boolean drop, boolean isCtCommit) {
+        MatchBuilder matchBuilder1 = matchBuilder;
+        if (isCtCommit) {
+            matchBuilder1 = MatchUtils.addCtState(matchBuilder1,0x81, 0x81);
+        }
         FlowBuilder flowBuilder = new FlowBuilder();
-        flowBuilder.setMatch(matchBuilder.build());
+        flowBuilder.setMatch(matchBuilder1.build());
         FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(priority);
 
         if (write) {
             InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
+            InstructionBuilder ib1 = new InstructionBuilder();
+            ActionBuilder ab = new ActionBuilder();
+            ApplyActionsBuilder aab = new ApplyActionsBuilder();
             if (drop) {
                 InstructionUtils.createDropInstructions(ib);
             }
@@ -696,6 +852,19 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
             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);
index 0a31568f188cd8bb21a216473e8571c0401476ca..e5d0a4c7d754c6a2e7ee92ad361d8c94e6c0c628 100644 (file)
@@ -20,6 +20,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
 import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.FlowUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils;
 import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
@@ -29,6 +30,9 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.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.flow.inventory.rev130819.tables.table.FlowBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
@@ -37,7 +41,14 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.M
 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;
@@ -218,18 +229,161 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
           }
           NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
           flowId = flowId + "_Permit";
-          syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+          syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
     }
 
     @Override
     public void programFixedSecurityGroup(Long dpid, String segmentationId, String dhcpMacAddress,
                                         long localPort, boolean isLastPortinSubnet,
-                                        boolean isComputePort, boolean write) {
+                                        boolean isComputePort, String attachMac, boolean write) {
         //If this port is the only port in the compute node add the DHCP server rule.
         if (isLastPortinSubnet && isComputePort ) {
             ingressAclDhcpAllowServerTraffic(dpid, segmentationId,dhcpMacAddress,
                                              write,Constants.PROTO_DHCP_SERVER_MATCH_PRIORITY);
         }
+        if (isComputePort) {
+            if (securityServicesManager.isConntrackEnabled()) {
+                programIngressAclFixedConntrackRule(dpid, segmentationId, attachMac, localPort, write);
+            }
+            programArpRule(dpid, segmentationId, localPort, attachMac, write);
+        }
+    }
+
+    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());
+    }
+
+    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,
+                                        Constants.CT_STATE_UNTRACKED_PRIORITY, write );
+            programConntrackTrackedPlusEstRule(nodeName, segmentationId, localPort, attachMac,
+                                        Constants.CT_STATE_TRACKED_EST_PRIORITY, write );
+            programConntrackNewDropRule(nodeName, segmentationId, localPort, attachMac,
+                                             Constants.CT_STATE_NEW_PRIORITY_DROP, write );
+            LOG.info("programIngressAclFixedConntrackRule :  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 = "Ingress_Fixed_Conntrk_Untrk_" + segmentationId + "_" + localPort + "_";
+        matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,attachMac);
+        matchBuilder = MatchUtils.addCtState(matchBuilder,0x00, 0x80);
+        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);
+        }
+    }
+
+    private void programConntrackTrackedPlusEstRule(String nodeName, 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.createEtherMatchWithType(matchBuilder,null,attachMac);
+        matchBuilder = MatchUtils.addCtState(matchBuilder,0x82, 0x82);
+        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();
+
+            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 programConntrackNewDropRule(String nodeName, 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.createEtherMatchWithType(matchBuilder,null,attachMac);
+        matchBuilder = MatchUtils.addCtState(matchBuilder,0x01, 0x01);
+        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();
+
+            // 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);
+        }
     }
 
     /**
@@ -246,7 +400,7 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Ingress_IP" + segmentationId + "_" + dstMac + "_Permit_";
         matchBuilder = MatchUtils.createEtherMatchWithType(matchBuilder,null,dstMac);
-        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
 
     }
     /**
@@ -306,11 +460,11 @@ 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);
+                syncFlow(rangeflowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
             }
         } else {
             flowId = flowId + "_Permit";
-            syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+            syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
         }
     }
 
@@ -371,11 +525,11 @@ 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);
+                syncFlow(rangeflowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
             }
         } else {
             flowId = flowId + "_Permit";
-            syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+            syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
         }
     }
 
@@ -418,13 +572,14 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
                                                         MatchUtils.iPv4PrefixFromIPv4Address(srcAddress), null);
         } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
             flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
-            matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
-                                                        new Ipv4Prefix(portSecurityRule
-                                                                       .getSecurityRuleRemoteIpPrefix()),null);
+            if (!portSecurityRule.getSecurityRuleRemoteIpPrefix().contains("/0")) {
+                matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+                                         new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()),null);
+            }
         }
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
         flowId = flowId + "_Permit";
-        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false);
+        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, securityServicesManager.isConntrackEnabled());
     }
 
 
@@ -696,7 +851,7 @@ 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);
+        syncFlow(flowId, nodeBuilder, matchBuilder, protoPortMatchPriority, write, false, false);
     }
 
     /**
@@ -708,16 +863,24 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
      * @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 write, boolean drop, boolean isCtCommit) {
+        MatchBuilder matchBuilder1 = matchBuilder;
+        if (isCtCommit) {
+            matchBuilder1 = MatchUtils.addCtState(matchBuilder1,0x81, 0x81);
+        }
         FlowBuilder flowBuilder = new FlowBuilder();
-        flowBuilder.setMatch(matchBuilder.build());
+        flowBuilder.setMatch(matchBuilder1.build());
         FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable()).setPriority(priority);
 
         if (write) {
             InstructionBuilder ib = this.getMutablePipelineInstructionBuilder();
+            InstructionBuilder ib1 = new InstructionBuilder();
+            ActionBuilder ab = new ActionBuilder();
+            ApplyActionsBuilder aab = new ApplyActionsBuilder();
             if (drop) {
                 InstructionUtils.createDropInstructions(ib);
             }
@@ -726,6 +889,19 @@ public class IngressAclService extends AbstractServiceInstance implements Ingres
             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);
index e2b41f68bcdb995d3d02cb121a023a36e94802af..8bd7184f285dcc20791961bcd4f5d2badbc3e1ca 100644 (file)
@@ -969,7 +969,7 @@ public class IngressAclServiceTest {
      */
     @Test
     public void testProgramFixedSecurityACLAdd1() throws Exception {
-        ingressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, false, false, true);
+        ingressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, false, false, null, true);
 
         verify(writeTransaction, times(0)).put(any(LogicalDatastoreType.class), any(InstanceIdentifier.class), any(Node.class), eq(true));
         verify(writeTransaction, times(0)).submit();
@@ -981,7 +981,7 @@ public class IngressAclServiceTest {
     @Test
     public void testProgramFixedSecurityACLRemove1() throws Exception {
 
-        ingressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, false, false, false);
+        ingressAclServiceSpy.programFixedSecurityGroup(Long.valueOf(1554), "2", MAC_ADDRESS, 1, false, false, null, false);
 
         verify(writeTransaction, times(0)).delete(any(LogicalDatastoreType.class), any(InstanceIdentifier.class));
         verify(writeTransaction, times(0)).submit();
index e99fbca132a7f3d64aafebfba0a5702ecb40437f..819fb3ee3c1bcee458d355a145a4c064365b1292 100644 (file)
@@ -12,6 +12,7 @@
         <module>
           <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:netvirt:impl">prefix:netvirt-impl</type>
           <name>netvirt-default</name>
+          <conntrack-enabled>false</conntrack-enabled>
           <broker>
             <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">binding:binding-broker-osgi-registry</type>
             <name>binding-osgi-broker</name>
index 504202cc15f00e7e38e5eb2d8d2166cc42a31bf3..94b0f5a25f763072a17b98654a15190e70b5a101 100644 (file)
@@ -102,6 +102,7 @@ public class ConfigActivator implements BundleActivator {
     private List<ServiceRegistration<?>> translatorCRUDRegistrations = new ArrayList<>();
     private List<Pair<Object, ServiceRegistration>> servicesAndRegistrations = new ArrayList<>();
     private ProviderContext providerContext;
+    private boolean conntrackEnabled = false;
 
     public ConfigActivator(ProviderContext providerContext) {
         this.providerContext = providerContext;
@@ -169,7 +170,7 @@ public class ConfigActivator implements BundleActivator {
                 new Class[] {INeutronSecurityRuleAware.class, INeutronSecurityGroupAware.class},
                 AbstractEvent.HandlerType.NEUTRON_PORT_SECURITY, portSecurityHandler);
 
-        final SecurityServicesImpl securityServices = new SecurityServicesImpl();
+        final SecurityServicesImpl securityServices = new SecurityServicesImpl(conntrackEnabled);
         registerService(context,
                 new String[]{SecurityServicesManager.class.getName()}, null, securityServices);
 
@@ -327,4 +328,8 @@ public class ConfigActivator implements BundleActivator {
         servicesAndRegistrations.add(Pair.of(impl, serviceRegistration));
         return serviceRegistration;
     }
+
+    public void setConntrackEnabled(boolean conntrackEnabled) {
+        this.conntrackEnabled = conntrackEnabled;
+    }
 }
index a6367872f8c41d0dcfbd6025d521032e2ba8f03d..1542cec28c794e51ad38161daeeb443c2061c53f 100644 (file)
@@ -31,6 +31,7 @@ public class NetvirtProvider implements BindingAwareProvider, AutoCloseable {
     private static EntityOwnershipService entityOwnershipService;
     private static final Entity ownerInstanceEntity = new Entity(
             Constants.NETVIRT_OWNER_ENTITY_TYPE, Constants.NETVIRT_OWNER_ENTITY_TYPE);
+    private boolean conntrackEnabled = false;
 
     public NetvirtProvider(BundleContext bundleContext, EntityOwnershipService eos) {
         LOG.info("NetvirtProvider: bundleContext: {}", bundleContext);
@@ -56,11 +57,21 @@ public class NetvirtProvider implements BindingAwareProvider, AutoCloseable {
     public void onSessionInitiated(ProviderContext providerContext) {
         dataBroker = providerContext.getSALService(DataBroker.class);
         LOG.info("NetvirtProvider: onSessionInitiated dataBroker: {}", dataBroker);
+        LOG.info("NetvirtProvider: onSessionInitiated isConntrackEnabled: {}", this.conntrackEnabled);
         this.activator = new ConfigActivator(providerContext);
+        activator.setConntrackEnabled(this.conntrackEnabled);
         try {
             activator.start(bundleContext);
         } catch (Exception e) {
             LOG.warn("Failed to start Netvirt: ", e);
         }
     }
+
+    public boolean isConntrackEnabled() {
+        return conntrackEnabled;
+    }
+
+    public void setConntrackEnabled(boolean conntackEnabled) {
+        this.conntrackEnabled = conntackEnabled;
+    }
 }
index 2c9858f2ca3ba440448220bf8c9c6fb9f430cd16..ccdf55bab6cf4f871b39e7f777141baef010cdb9 100644 (file)
@@ -82,7 +82,6 @@ public final class Constants {
     public static final Integer PREFIX_MATCH_PRIORITY_DROP = 36004;
     public static final Integer PROTO_PREFIX_MATCH_PRIORITY_DROP = 36003;
     public static final Integer PREFIX_PORT_MATCH_PRIORITY_DROP = 36002;
-    public static final Integer PROTO_PORT_PREFIX_MATCH_PRIORITY_DROP = 36001;
 
     public static final Integer PROTO_DHCP_CLIENT_TRAFFIC_MATCH_PRIORITY = 61012;
     public static final Integer PROTO_MATCH_PRIORITY = 61010;
@@ -92,6 +91,10 @@ public final class Constants {
     public static final Integer PROTO_PORT_PREFIX_MATCH_PRIORITY = 61007;
     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_NEW_PRIORITY = 62010;
+    public static final Integer CT_STATE_NEW_PRIORITY_DROP = 36007;
 
     public static final int TCP_SYN = 0x002;
     public static final short INGRESS_ACL = 40; // Flows Destined to the VM Port go here
index 6121adaf1b7e48d9608996f902e1572b8c9ee6a3..bb4e7593152959023ba53518e5f7eb6637392dcb 100644 (file)
@@ -50,12 +50,13 @@ public interface IngressAclProvider {
      * *
      * @param dpid the dpid
      * @param segmentationId the segmentation id
-     * @param attachedMac the attached mac
+     * @param attachedMac the dhcp mac
      * @param localPort the local port
      * @param isLastPortinSubnet is this the last port in the subnet
      * @param isComputePort indicates whether this port is a compute port or not
+     * @param attachedMac2 the src mac
      * @param write is this flow writing or deleting
      */
     void programFixedSecurityGroup(Long dpid, String segmentationId, String attachedMac, long localPort,
-                                  boolean isLastPortinSubnet, boolean isComputePort, boolean write);
+                                  boolean isLastPortinSubnet, boolean isComputePort, String attachedMac2, boolean write);
 }
\ No newline at end of file
index f6dcea1a857e373585a926764eb709ca5c4f5c4a..843116c9173f1455c739a76f5ae2bc3903eab7a3 100644 (file)
@@ -104,4 +104,9 @@ public interface SecurityServicesManager {
      * @param write whether to add/delete flow.
      */
     void syncSecurityRule(NeutronPort port, NeutronSecurityRule securityRule,Neutron_IPs vmIp, boolean write);
+    /**
+     * Is connection tracking enabled or not by the user (default is false).
+     * @return whether connection tracking enabled.
+     */
+    boolean isConntrackEnabled();
 }
\ No newline at end of file
index f59980e36fdf2ae475f790dfd96fd478b2e593cc..dc482a130b4ce757acde47f6ded896a38281ccf1 100644 (file)
@@ -36,6 +36,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 public class SecurityServicesImpl implements ConfigInterface, SecurityServicesManager {
+
     private static final Logger LOG = LoggerFactory.getLogger(TenantNetworkManagerImpl.class);
     private volatile INeutronPortCRUD neutronPortCache;
     private volatile INeutronSubnetCRUD neutronSubnetCache;
@@ -44,6 +45,16 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
     private volatile ConfigurationService configurationService;
     private volatile IngressAclProvider ingressAclProvider;
     private volatile EgressAclProvider egressAclProvider;
+    private boolean isConntrackEnabled = false;
+
+    public SecurityServicesImpl() {
+        super();
+    }
+
+    public SecurityServicesImpl(boolean isConntrack) {
+        super();
+        this.isConntrackEnabled = isConntrack;
+    }
 
     @Override
     public boolean isPortSecurityReady(OvsdbTerminationPointAugmentation terminationPointAugmentation) {
@@ -507,4 +518,9 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
             egressAclProvider = (EgressAclProvider) impl;
         }
     }
+
+    @Override
+    public boolean isConntrackEnabled() {
+        return isConntrackEnabled;
+    }
 }
index 8a43c9c8596b19c2450a9a9012abab4470842dd8..cd5dac96dacc9d7183469ed35ba36d4c4feb0f07 100644 (file)
@@ -23,6 +23,7 @@ public class NetvirtImplModule extends org.opendaylight.yang.gen.v1.urn.opendayl
     @Override
     public java.lang.AutoCloseable createInstance() {
         NetvirtProvider provider = new NetvirtProvider(bundleContext, getClusteringEntityOwnershipServiceDependency());
+        provider.setConntrackEnabled(getConntrackEnabled());
         BindingAwareBroker localBroker = getBrokerDependency();
         localBroker.registerProvider(provider);
         return provider;
index 73042641c2297da4000b751f3daaffacf5a8d404..20572577205066daf3d1525ec0efeaac77e84f75 100644 (file)
@@ -39,6 +39,9 @@ module netvirt-impl {
                     }
                 }
             }
+            leaf conntrack-enabled {
+                type boolean;
+            }
         }
     }
-}
+}
\ No newline at end of file
index c3b878c593b0a00402facf842654f15d68438114..403e2e00aeaf2d041ca0c03f01a5bcd6d08a20c9 100644 (file)
@@ -35,12 +35,39 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxHashFields;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxMpAlgorithm;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.DstChoice;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxArpShaCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxArpThaCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc1CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshc2CaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIdCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxTunIpv4DstCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpOpCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpSpaCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpTpaCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfEthDstCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegLoadNodesNodeGroupBucketsBucketActionsCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegMoveNodesNodeGroupBucketsBucketActionsCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackNodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionMultipathNodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegMoveNodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionResubmitNodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionSetNshc1NodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionSetNshc2NodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionSetNshc3NodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionSetNshc4NodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionSetNsiNodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionSetNspNodesNodeTableFlowApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.NxConntrack;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.NxConntrackBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.multipath.grouping.NxMultipath;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.multipath.grouping.NxMultipathBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputReg;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.NxOutputRegBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
@@ -49,6 +76,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMove;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.NxRegMoveBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.move.grouping.nx.reg.move.SrcBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmit;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.resubmit.grouping.NxResubmitBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._1.grouping.NxSetNshc1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._1.grouping.NxSetNshc1Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._2.grouping.NxSetNshc2;
@@ -57,6 +86,10 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._3.grouping.NxSetNshc3Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._4.grouping.NxSetNshc4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nshc._4.grouping.NxSetNshc4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nsi.grouping.NxSetNsi;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nsi.grouping.NxSetNsiBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nsp.grouping.NxSetNsp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.set.nsp.grouping.NxSetNspBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.SrcChoice;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxArpShaCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxNshc1CaseBuilder;
@@ -403,6 +436,17 @@ public final class ActionUtils {
         return new NxActionMultipathNodesNodeTableFlowApplyActionsCaseBuilder().setNxMultipath(r).build();
     }
 
+    public static Action nxConntrackAction(Integer flags, Long zoneSrc,
+                                           Integer conntrackZone, Short recircTable) {
+        NxConntrack r = new NxConntrackBuilder()
+            .setFlags(flags)
+            .setZoneSrc(zoneSrc)
+            .setConntrackZone(conntrackZone)
+            .setRecircTable(recircTable)
+            .build();
+        return new NxActionConntrackNodesNodeTableFlowApplyActionsCaseBuilder().setNxConntrack(r).build();
+    }
+
     /**
      * Accepts a MAC address and returns the corresponding long, where the
      * MAC bytes are set on the lower order bytes of the long.
index 33228f9ea40143110a3a8510b9ebc6eb9e93451a..bbb93d8b5532b7363db72a76051b9572f5200604 100644 (file)
@@ -45,6 +45,7 @@ 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;
@@ -53,6 +54,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ge
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxAugMatchNodesNodeTableFlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxCtStateKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxCtZoneKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg0Key;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg1Key;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxReg2Key;
@@ -66,14 +69,17 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmOfTcpSrcKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmOfUdpDstKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmOfUdpSrcKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.ct.state.grouping.NxmNxCtStateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.ct.zone.grouping.NxmNxCtZoneBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.tun.id.grouping.NxmNxTunIdBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.NxmNxNspKey;
 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.tcp.dst.grouping.NxmOfTcpDstBuilder;
+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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.of.udp.src.grouping.NxmOfUdpSrcBuilder;
 import org.slf4j.Logger;
@@ -1161,6 +1167,37 @@ public class MatchUtils {
         return matchBuilder;
     }
 
+    public static MatchBuilder addCtState(MatchBuilder matchBuilder,int ct_state, int mask) {
+        NxmNxCtStateBuilder ctStateBuilder = new NxmNxCtStateBuilder();
+        ctStateBuilder.setCtState((long)ct_state);
+        ctStateBuilder.setMask((long)mask);
+        NxAugMatchNodesNodeTableFlow nxAugMatch = new NxAugMatchNodesNodeTableFlowBuilder()
+        .setNxmNxCtState(ctStateBuilder.build())
+        .build();
+        GeneralAugMatchNodesNodeTableFlow genAugMatch = new GeneralAugMatchNodesNodeTableFlowBuilder()
+        .setExtensionList(ImmutableList.of(new ExtensionListBuilder().setExtensionKey(NxmNxCtStateKey.class)
+                                           .setExtension(new ExtensionBuilder()
+                                           .addAugmentation(NxAugMatchNodesNodeTableFlow.class, nxAugMatch)
+                                                         .build()).build())).build();
+        matchBuilder.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, genAugMatch);
+        return matchBuilder;
+    }
+
+    public static MatchBuilder addCtZone(MatchBuilder matchBuilder,int ct_zone) {
+        NxmNxCtZoneBuilder ctZoneBuilder = new NxmNxCtZoneBuilder();
+        ctZoneBuilder.setCtZone(ct_zone);
+        NxAugMatchNodesNodeTableFlow nxAugMatch = new NxAugMatchNodesNodeTableFlowBuilder()
+        .setNxmNxCtZone(ctZoneBuilder.build())
+        .build();
+        GeneralAugMatchNodesNodeTableFlow genAugMatch = new GeneralAugMatchNodesNodeTableFlowBuilder()
+        .setExtensionList(ImmutableList.of(new ExtensionListBuilder().setExtensionKey(NxmNxCtZoneKey.class)
+                                           .setExtension(new ExtensionBuilder()
+                                           .addAugmentation(NxAugMatchNodesNodeTableFlow.class, nxAugMatch)
+                                                         .build()).build())).build();
+        matchBuilder.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, genAugMatch);
+        return matchBuilder;
+    }
+
     public static class RegMatch {
         final Class<? extends NxmNxReg> reg;
         final Long value;