General clean-ups
[netvirt.git] / openstack / net-virt-providers / src / main / java / org / opendaylight / netvirt / openstack / netvirt / providers / openflow13 / services / EgressAclService.java
index a531f4d82be2931b12d40e20fe0c15c21c6d4a18..a8ef5445f687c03a14b76dc809abfa0ff89de545 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2014 - 2016 Red Hat, Inc. and others. All rights reserved.
+ * Copyright © 2014, 2017 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,
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -8,14 +8,21 @@
 
 package org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.services;
 
 
 package org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.services;
 
-import com.google.common.collect.Lists;
-
-import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
+import java.math.BigInteger;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 import org.opendaylight.netvirt.openstack.netvirt.api.Constants;
 import org.opendaylight.netvirt.openstack.netvirt.api.EgressAclProvider;
 import org.opendaylight.netvirt.openstack.netvirt.api.Constants;
 import org.opendaylight.netvirt.openstack.netvirt.api.EgressAclProvider;
+import org.opendaylight.netvirt.openstack.netvirt.api.LearnConstants;
 import org.opendaylight.netvirt.openstack.netvirt.api.SecurityGroupCacheManger;
 import org.opendaylight.netvirt.openstack.netvirt.api.SecurityServicesManager;
 import org.opendaylight.netvirt.openstack.netvirt.providers.ConfigInterface;
 import org.opendaylight.netvirt.openstack.netvirt.api.SecurityGroupCacheManger;
 import org.opendaylight.netvirt.openstack.netvirt.api.SecurityServicesManager;
 import org.opendaylight.netvirt.openstack.netvirt.providers.ConfigInterface;
+import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
 import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.Service;
 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityGroup;
 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityRule;
 import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.Service;
 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityGroup;
 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityRule;
@@ -37,19 +44,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.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.Icmpv6MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
 public class EgressAclService extends AbstractServiceInstance implements EgressAclProvider, ConfigInterface {
 
     private static final Logger LOG = LoggerFactory.getLogger(EgressAclService.class);
 public class EgressAclService extends AbstractServiceInstance implements EgressAclProvider, ConfigInterface {
 
     private static final Logger LOG = LoggerFactory.getLogger(EgressAclService.class);
@@ -75,7 +78,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
 
     @Override
     public void programPortSecurityGroup(Long dpid, String segmentationId, String attachedMac, long localPort,
 
     @Override
     public void programPortSecurityGroup(Long dpid, String segmentationId, String attachedMac, long localPort,
-                                       NeutronSecurityGroup securityGroup, String portUuid, boolean write) {
+                                       NeutronSecurityGroup securityGroup, String portUuid, NodeId nodeId, boolean write) {
 
         LOG.trace("programPortSecurityGroup: neutronSecurityGroup: {} ", securityGroup);
         if (securityGroup == null || getSecurityRulesforGroup(securityGroup) == null) {
 
         LOG.trace("programPortSecurityGroup: neutronSecurityGroup: {} ", securityGroup);
         if (securityGroup == null || getSecurityRulesforGroup(securityGroup) == null) {
@@ -114,7 +117,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                                                     localPort, portSecurityRule, vmIp, write);
                         }
                         if (write) {
                                                     localPort, portSecurityRule, vmIp, write);
                         }
                         if (write) {
-                            securityGroupCacheManger.addToCache(portSecurityRule.getSecurityRemoteGroupID(), portUuid);
+                            securityGroupCacheManger.addToCache(portSecurityRule.getSecurityRemoteGroupID(), portUuid, nodeId);
                         } else {
                             securityGroupCacheManger.removeFromCache(portSecurityRule.getSecurityRemoteGroupID(),
                                                                      portUuid);
                         } else {
                             securityGroupCacheManger.removeFromCache(portSecurityRule.getSecurityRemoteGroupID(),
                                                                      portUuid);
@@ -141,57 +144,77 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         boolean isIpv6 = NeutronSecurityRule.ETHERTYPE_IPV6.equals(securityRuleEtherType);
         if (!isIpv6 && !NeutronSecurityRule.ETHERTYPE_IPV4.equals(securityRuleEtherType)) {
             LOG.debug("programPortSecurityRule: SecurityRuleEthertype {} does not match IPv4/v6.",
         boolean isIpv6 = NeutronSecurityRule.ETHERTYPE_IPV6.equals(securityRuleEtherType);
         if (!isIpv6 && !NeutronSecurityRule.ETHERTYPE_IPV4.equals(securityRuleEtherType)) {
             LOG.debug("programPortSecurityRule: SecurityRuleEthertype {} does not match IPv4/v6.",
-                      securityRuleEtherType);
+                securityRuleEtherType);
             return;
         }
 
             return;
         }
 
+
+        String ipaddress = null;
+        if (null != vmIp) {
+            ipaddress = vmIp.getIpAddress();
+            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);
+                    return;
+                }
+            } catch (UnknownHostException e) {
+                LOG.warn("Invalid IP address {}", ipaddress, e);
+                return;
+            }
+        }
         if (null == portSecurityRule.getSecurityRuleProtocol()) {
             /* TODO Rework on the priority values */
             egressAclIp(dpid, isIpv6, segmentationId, attachedMac,
         if (null == portSecurityRule.getSecurityRuleProtocol()) {
             /* TODO Rework on the priority values */
             egressAclIp(dpid, isIpv6, segmentationId, attachedMac,
-                          write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
-        } else {
-            String ipaddress = null;
-            if (null != vmIp) {
-                ipaddress = vmIp.getIpAddress();
-                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);
-                        return;
-                    }
-                } catch (UnknownHostException e) {
-                    LOG.warn("Invalid IP address {}", ipaddress, e);
-                    return;
-                }
+                portSecurityRule, ipaddress,
+                write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY, false);
+            if(!isIpv6) {
+                portSecurityRule.setSecurityRuleProtocol(MatchUtils.TCP);
+                portSecurityRule.setSecurityRulePortMin(PORT_RANGE_MIN);
+                portSecurityRule.setSecurityRulePortMax(PORT_RANGE_MAX);
+                egressAclTcp(dpid, segmentationId, attachedMac,
+                        portSecurityRule,ipaddress, write,
+                        Constants.PROTO_PORT_MATCH_PRIORITY, false);
+                portSecurityRule.setSecurityRuleProtocol(MatchUtils.UDP);
+                egressAclUdp(dpid, segmentationId, attachedMac,
+                        portSecurityRule, ipaddress, write,
+                        Constants.PROTO_PORT_MATCH_PRIORITY, false);
+                portSecurityRule.setSecurityRuleProtocol(MatchUtils.ICMP);
+                portSecurityRule.setSecurityRulePortMin(null);
+                portSecurityRule.setSecurityRulePortMax(null);
+                egressAclIcmp(dpid, segmentationId, attachedMac,
+                        portSecurityRule, ipaddress,write,
+                        Constants.PROTO_PORT_MATCH_PRIORITY, false);
+                portSecurityRule.setSecurityRuleProtocol(null);
             }
             }
-
-            switch (portSecurityRule.getSecurityRuleProtocol()) {
+        } else {
+            switch (portSecurityRule.getSecurityRuleProtocol() == null ? "" : portSecurityRule.getSecurityRuleProtocol()) {
                 case MatchUtils.TCP:
                     LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
                     egressAclTcp(dpid, segmentationId, attachedMac,
                 case MatchUtils.TCP:
                     LOG.debug("programPortSecurityRule: Rule matching TCP", portSecurityRule);
                     egressAclTcp(dpid, segmentationId, attachedMac,
-                             portSecurityRule,ipaddress, write,
-                             Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                        portSecurityRule,ipaddress, write,
+                        Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY, false);
                     break;
                 case MatchUtils.UDP:
                     LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
                     egressAclUdp(dpid, segmentationId, attachedMac,
                     break;
                 case MatchUtils.UDP:
                     LOG.debug("programPortSecurityRule: Rule matching UDP", portSecurityRule);
                     egressAclUdp(dpid, segmentationId, attachedMac,
-                             portSecurityRule, ipaddress, write,
-                             Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY);
+                        portSecurityRule, ipaddress, write,
+                        Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY, false);
                     break;
                 case MatchUtils.ICMP:
                 case MatchUtils.ICMPV6:
                     LOG.debug("programPortSecurityRule: Rule matching ICMP", portSecurityRule);
                     egressAclIcmp(dpid, segmentationId, attachedMac,
                     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);
+                        portSecurityRule, ipaddress,write,
+                        Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY, false);
                     break;
                 default:
                     LOG.info("programPortSecurityAcl: Protocol is not TCP/UDP/ICMP but other "
                             + "protocol = ", portSecurityRule.getSecurityRuleProtocol());
                     egressOtherProtocolAclHandler(dpid, segmentationId, attachedMac,
                     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);
+                        portSecurityRule, ipaddress, write,
+                        Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY, isIpv6);
                     break;
             }
         }
                     break;
             }
         }
@@ -199,36 +222,89 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
 
     private void egressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String srcMac,
                                                NeutronSecurityRule portSecurityRule, String dstAddress,
 
     private void egressOtherProtocolAclHandler(Long dpidLong, String segmentationId, String srcMac,
                                                NeutronSecurityRule portSecurityRule, String dstAddress,
-                                               boolean write, Integer priority) {
-        MatchBuilder matchBuilder = new MatchBuilder();
-        String flowId = "Egress_Other_" + segmentationId + "_" + srcMac + "_";
-        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,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 != dstAddress) {
-            flowId = flowId + dstAddress;
-            matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder, null,
-                                                         MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
-
-        } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
-            flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
-            matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder, null,
-                    new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
+                                               boolean write, Integer priority, boolean isIpv6) {
+        if(null == portSecurityRule.getSecurityRuleProtocol() || portSecurityRule.getSecurityRuleProtocol().equals(MatchUtils.ANY_PROTOCOL)) {
+            egressAclIp(dpidLong, isIpv6, segmentationId, srcMac,
+                    portSecurityRule, dstAddress,
+                    write, Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY - 1, true);
+            if(!isIpv6) {
+                portSecurityRule.setSecurityRuleProtocol(MatchUtils.TCP);
+                portSecurityRule.setSecurityRulePortMin(PORT_RANGE_MIN);
+                portSecurityRule.setSecurityRulePortMax(PORT_RANGE_MAX);
+                egressAclTcp(dpidLong, segmentationId, srcMac,
+                        portSecurityRule,dstAddress, write,
+                        Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY, true);
+                portSecurityRule.setSecurityRuleProtocol(MatchUtils.UDP);
+                egressAclUdp(dpidLong, segmentationId, srcMac,
+                        portSecurityRule, dstAddress, write,
+                        Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY, true);
+                portSecurityRule.setSecurityRulePortMin(null);
+                portSecurityRule.setSecurityRulePortMax(null);
+                portSecurityRule.setSecurityRuleProtocol(MatchUtils.ICMP);
+                egressAclIcmp(dpidLong, segmentationId, srcMac,
+                        portSecurityRule, dstAddress,write,
+                        Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY, true);
+                portSecurityRule.setSecurityRuleProtocol(null);
+            }
+        } else {
+            switch (portSecurityRule.getSecurityRuleProtocol()) {
+                case MatchUtils.TCP_PROTOCOL:
+                    portSecurityRule.setSecurityRulePortMin(PORT_RANGE_MIN);
+                    portSecurityRule.setSecurityRulePortMax(PORT_RANGE_MAX);
+                    egressAclTcp(dpidLong, segmentationId, srcMac,
+                            portSecurityRule, dstAddress, write,
+                            Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY, false);
+                    break;
+                case MatchUtils.UDP_PROTOCOL:
+                    portSecurityRule.setSecurityRulePortMin(PORT_RANGE_MIN);
+                    portSecurityRule.setSecurityRulePortMax(PORT_RANGE_MAX);
+                    egressAclUdp(dpidLong, segmentationId, srcMac,
+                            portSecurityRule, dstAddress, write,
+                            Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY, false);
+                    break;
+                case MatchUtils.ICMP_PROTOCOL:
+                    egressAclIcmp(dpidLong, segmentationId, srcMac,
+                            portSecurityRule, dstAddress, write,
+                            Constants.PROTO_PORT_PREFIX_MATCH_PRIORITY, false);
+                    break;
+                default:
+                    MatchBuilder matchBuilder = new MatchBuilder();
+                    String flowId = "Egress_Other_" + segmentationId + "_" + srcMac + "_";
+                    matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder, srcMac, null,
+                            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.createIpProtocolAndEthMatch(matchBuilder, proto, srcMac, null);
+                    if (null != dstAddress) {
+                        flowId = flowId + dstAddress;
+                        matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder, null,
+                                MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
+                    } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+                        flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+                        if (isIpv6) {
+                            matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder, null,
+                                    new Ipv6Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
+                        } else {
+                            if (!portSecurityRule.getSecurityRuleRemoteIpPrefix().contains("/0")) {
+                                matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder, null,
+                                        new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
+                            }
+                        }
+                    }
+                    flowId = flowId + "_Permit";
+                    NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+                    FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, priority, matchBuilder, getTable());
+                    addInstructionWithConntrackCommit(flowBuilder, false);
+                    syncFlow(flowBuilder, nodeBuilder, write);
+                    break;
+            }
         }
         }
-        flowId = flowId + "_Permit";
-        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
-        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, priority, matchBuilder, getTable());
-        addInstructionWithConntrackCommit(flowBuilder, false);
-        syncFlow(flowBuilder ,nodeBuilder, write);
     }
 
     @Override
     }
 
     @Override
@@ -243,23 +319,55 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         if (securityServicesManager.isConntrackEnabled()) {
             programEgressAclFixedConntrackRule(dpid, segmentationId, localPort, attachedMac, write);
         } else {
         if (securityServicesManager.isConntrackEnabled()) {
             programEgressAclFixedConntrackRule(dpid, segmentationId, localPort, attachedMac, write);
         } else {
-            // add rule to drop tcp syn packets from the vm
-            addTcpSynFlagMatchDrop(dpid, segmentationId, attachedMac, write,
-                                                         Constants.PROTO_TCP_SYN_MATCH_PRIORITY_DROP);
+            egressVMDrop(dpid, segmentationId, attachedMac, write,Constants.PROTO_TCP_SYN_MATCH_PRIORITY_DROP);
+            egressVMRegex(dpid, segmentationId, attachedMac, write,Constants.PROTO_REG6_MATCH_PRIORITY);
         }
         }
-        // add rule to drop the DHCP server traffic originating from the vm.
         egressAclDhcpDropServerTrafficfromVm(dpid, localPort, write,
                                              Constants.PROTO_DHCP_CLIENT_SPOOF_MATCH_PRIORITY_DROP);
         egressAclDhcpv6DropServerTrafficfromVm(dpid, localPort, write,
                                                Constants.PROTO_DHCP_CLIENT_SPOOF_MATCH_PRIORITY_DROP);
     }
         egressAclDhcpDropServerTrafficfromVm(dpid, localPort, write,
                                              Constants.PROTO_DHCP_CLIENT_SPOOF_MATCH_PRIORITY_DROP);
         egressAclDhcpv6DropServerTrafficfromVm(dpid, localPort, write,
                                                Constants.PROTO_DHCP_CLIENT_SPOOF_MATCH_PRIORITY_DROP);
     }
+    private void egressVMRegex(Long dpidLong, String segmentationId, String srcMac,
+            boolean write, Integer priority) {
+        String flowName = "Egress_Regx_" + segmentationId + "_" + srcMac;
+        MatchBuilder matchBuilder = new MatchBuilder();
+        matchBuilder = MatchUtils.createV4EtherMatchWithoutType(matchBuilder,srcMac,null);
+        MatchUtils.addNxRegMatch(matchBuilder,
+                new MatchUtils.RegMatch(ClassifierService.REG_FIELD_6, ClassifierService.REG_VALUE_FROM_LOCAL));
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder, nodeBuilder, write);
+    }
 
 
-    private void addTcpSynFlagMatchDrop(Long dpidLong, String segmentationId, String srcMac,
+    private void addTcpSynFlagMatchIpv4Drop(Long dpidLong, String segmentationId, String srcMac,
                                   boolean write, Integer priority) {
                                   boolean write, Integer priority) {
-        String flowName = "Egress_TCP_" + segmentationId + "_" + srcMac + "_DROP_";
+        String flowName = "Egress_TCP_Ipv4_" + segmentationId + "_" + srcMac + "_DROP";
+        MatchBuilder matchBuilder = new MatchBuilder();
+        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
+        matchBuilder = MatchUtils.addTcpSynMatch(matchBuilder);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, true);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder, nodeBuilder, write);
+    }
+    private void egressVMDrop(Long dpidLong, String segmentationId, String srcMac,
+            boolean write, Integer priority) {
+        String flowName = "Egress_Drop_" + segmentationId + "_" + srcMac + "_DROP";
+        MatchBuilder matchBuilder = new MatchBuilder();
+        matchBuilder = MatchUtils.createV4EtherMatchWithoutType(matchBuilder,srcMac,null);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, true);
+        NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
+        syncFlow(flowBuilder, nodeBuilder, write);
+    }
+
+    private void addTcpSynFlagMatchIpv6Drop(Long dpidLong, String segmentationId, String srcMac,
+                                        boolean write, Integer priority) {
+        String flowName = "Egress_TCP_Ipv6_" + segmentationId + "_" + srcMac + "_DROP";
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchBuilder matchBuilder = new MatchBuilder();
-        flowName = flowName + "_";
-        matchBuilder = MatchUtils.createTcpSynWithProtoMatch(matchBuilder);
+        matchBuilder = MatchUtils.createV6EtherMatchWithType(matchBuilder,srcMac,null);
+        matchBuilder = MatchUtils.addTcpSynMatch(matchBuilder);
         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
         addPipelineInstruction(flowBuilder, null, true);
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowName, priority, matchBuilder, getTable());
         addPipelineInstruction(flowBuilder, null, true);
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
@@ -370,10 +478,12 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
      * @param segmentationId the segementation id
      * @param srcMac the src mac address
      * @param write add or remove
      * @param segmentationId the segementation id
      * @param srcMac the src mac address
      * @param write add or remove
+     * @param isRegMatchReq add Reg MAtch or not
      * @param protoPortMatchPriority the protocol match priority.
      */
     private void egressAclIp(Long dpidLong, boolean isIpv6, String segmentationId, String srcMac,
      * @param protoPortMatchPriority the protocol match priority.
      */
     private void egressAclIp(Long dpidLong, boolean isIpv6, String segmentationId, String srcMac,
-                               boolean write, Integer protoPortMatchPriority ) {
+                             NeutronSecurityRule portSecurityRule, String srcAddress,
+                               boolean write, Integer protoPortMatchPriority, boolean isRegMatchReq ) {
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Egress_IP" + segmentationId + "_" + srcMac + "_Permit_";
         if (isIpv6) {
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Egress_IP" + segmentationId + "_" + srcMac + "_Permit_";
         if (isIpv6) {
@@ -381,6 +491,41 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         } else {
             matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
         }
         } else {
             matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
         }
+        if (isRegMatchReq) {
+            flowId = flowId + "_regEx_";
+            MatchUtils.addNxRegMatch(matchBuilder,
+                    new MatchUtils.RegMatch(ClassifierService.REG_FIELD_6, ClassifierService.REG_VALUE_FROM_LOCAL_0));
+        }
+        if (null != srcAddress) {
+            flowId = flowId + srcAddress;
+            if (isIpv6) {
+                matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder,
+                        MatchUtils.iPv6PrefixFromIPv6Address(srcAddress),null);
+            } else {
+                matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,
+                        MatchUtils.iPv4PrefixFromIPv4Address(srcAddress),null);
+            }
+        } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+            flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+            if (isIpv6) {
+                matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder,null,
+                        new Ipv6Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
+            } else {
+                // Fix: Bug 6473
+                // IP match removed if CIDR created as 0.0.0.0/0 in openstack security rule
+                if (!portSecurityRule.getSecurityRuleRemoteIpPrefix().contains("/0")) {
+                    matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
+                            new Ipv4Prefix(portSecurityRule
+                                           .getSecurityRuleRemoteIpPrefix()));
+                 }
+            }
+        } else {
+            if (isIpv6) {
+                flowId = flowId + "Ipv6";
+            } else {
+                flowId = flowId + "Ipv4";
+            }
+        }
         addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
         FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
         addInstructionWithConntrackCommit(flowBuilder, 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);
@@ -398,11 +543,12 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
      * @param portSecurityRule the security rule in the SG
      * @param dstAddress the destination IP address
      * @param write add or delete
      * @param portSecurityRule the security rule in the SG
      * @param dstAddress the destination IP address
      * @param write add or delete
+     * @param isRegMatchReq add Reg MAtch or not
      * @param protoPortMatchPriority the protocol match priroty
      */
     private void egressAclTcp(Long dpidLong, String segmentationId, String srcMac,
                               NeutronSecurityRule portSecurityRule, String dstAddress,
      * @param protoPortMatchPriority the protocol match priroty
      */
     private void egressAclTcp(Long dpidLong, String segmentationId, String srcMac,
                               NeutronSecurityRule portSecurityRule, String dstAddress,
-                              boolean write, Integer protoPortMatchPriority) {
+                              boolean write, Integer protoPortMatchPriority, boolean isRegMatchReq) {
         boolean portRange = false;
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Egress_TCP_" + segmentationId + "_" + srcMac + "_";
         boolean portRange = false;
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Egress_TCP_" + segmentationId + "_" + srcMac + "_";
@@ -412,18 +558,23 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         } else {
             matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
         }
         } else {
             matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
         }
+        if (isRegMatchReq) {
+            flowId = flowId + "_regEx_";
+            MatchUtils.addNxRegMatch(matchBuilder,
+                    new MatchUtils.RegMatch(ClassifierService.REG_FIELD_6, ClassifierService.REG_VALUE_FROM_LOCAL_0));
+        }
 
         /* Custom TCP Match */
 
         /* Custom TCP Match */
-        if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
-            flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
-            matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
-                                                     portSecurityRule.getSecurityRulePortMin());
-        } else {
-            /* All TCP Match */
-            if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
+        if (portSecurityRule.getSecurityRulePortMin() != null && portSecurityRule.getSecurityRulePortMax() != null) {
+            if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
+                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
+                matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0,
+                        portSecurityRule.getSecurityRulePortMin());
+            } else if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
                     && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
                     && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
+                /* All TCP Match */
                 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
                 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
-                            + portSecurityRule.getSecurityRulePortMax() + "_";
+                        + portSecurityRule.getSecurityRulePortMax() + "_";
                 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
             } else {
                 portRange = true;
                 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.TCP_SHORT, 0, 0);
             } else {
                 portRange = true;
@@ -444,8 +595,13 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                 matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder,null,
                         new Ipv6Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
             } else {
                 matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder,null,
                         new Ipv6Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
             } else {
-                matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
-                        new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
+                // Fix: Bug 6473
+                // IP match removed if CIDR created as 0.0.0.0/0 in openstack security rule
+                if (!portSecurityRule.getSecurityRuleRemoteIpPrefix().contains("/0")) {
+                    matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
+                            new Ipv4Prefix(portSecurityRule
+                                           .getSecurityRuleRemoteIpPrefix()));
+                 }
             }
         }
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
             }
         }
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
@@ -459,40 +615,38 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                 MatchUtils.addLayer4MatchWithMask(matchBuilder, MatchUtils.TCP_SHORT,
                                                   0, port, portMaskMap.get(port));
                 addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
                 MatchUtils.addLayer4MatchWithMask(matchBuilder, MatchUtils.TCP_SHORT,
                                                   0, port, portMaskMap.get(port));
                 addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
-                addTcpSynMatch(matchBuilder);
                 FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(rangeflowId, protoPortMatchPriority,
                                                                       matchBuilder, getTable());
                 FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(rangeflowId, protoPortMatchPriority,
                                                                       matchBuilder, getTable());
-                addInstructionWithConntrackCommit(flowBuilder, false);
+                addInstructionWithLearnConntrackCommit(portSecurityRule, flowBuilder, null, null);
                 syncFlow(flowBuilder ,nodeBuilder, write);
             }
         } else {
             flowId = flowId + "_Permit";
             addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
                 syncFlow(flowBuilder ,nodeBuilder, write);
             }
         } else {
             flowId = flowId + "_Permit";
             addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
-            addTcpSynMatch(matchBuilder);
             FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority,
                                                                   matchBuilder, getTable());
             FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority,
                                                                   matchBuilder, getTable());
-            addInstructionWithConntrackCommit(flowBuilder, false);
+            addInstructionWithLearnConntrackCommit(portSecurityRule, flowBuilder, null, null);
             syncFlow(flowBuilder ,nodeBuilder, write);
         }
     }
 
     private void addTcpSynMatch(MatchBuilder matchBuilder) {
         if (!securityServicesManager.isConntrackEnabled()) {
             syncFlow(flowBuilder ,nodeBuilder, write);
         }
     }
 
     private void addTcpSynMatch(MatchBuilder matchBuilder) {
         if (!securityServicesManager.isConntrackEnabled()) {
-            MatchUtils.createTcpSynWithProtoMatch(matchBuilder);
+            MatchUtils.createTcpProtoSynMatch(matchBuilder);
         }
     }
 
     private void egressAclIcmp(Long dpidLong, String segmentationId, String srcMac,
             NeutronSecurityRule portSecurityRule, String dstAddress,
         }
     }
 
     private void egressAclIcmp(Long dpidLong, String segmentationId, String srcMac,
             NeutronSecurityRule portSecurityRule, String dstAddress,
-            boolean write, Integer protoPortMatchPriority) {
+            boolean write, Integer protoPortMatchPriority, boolean isRegMatchReq) {
 
         boolean isIpv6 = NeutronSecurityRule.ETHERTYPE_IPV6.equals(portSecurityRule.getSecurityRuleEthertype());
         if (isIpv6) {
             egressAclIcmpV6(dpidLong, segmentationId, srcMac, portSecurityRule, dstAddress, write,
 
         boolean isIpv6 = NeutronSecurityRule.ETHERTYPE_IPV6.equals(portSecurityRule.getSecurityRuleEthertype());
         if (isIpv6) {
             egressAclIcmpV6(dpidLong, segmentationId, srcMac, portSecurityRule, dstAddress, write,
-                            protoPortMatchPriority);
+                            protoPortMatchPriority, isRegMatchReq);
         } else {
             egressAclIcmpV4(dpidLong, segmentationId, srcMac, portSecurityRule, dstAddress, write,
         } else {
             egressAclIcmpV4(dpidLong, segmentationId, srcMac, portSecurityRule, dstAddress, write,
-                            protoPortMatchPriority);
+                            protoPortMatchPriority, isRegMatchReq);
         }
     }
 
         }
     }
 
@@ -506,13 +660,15 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
      * @param portSecurityRule the security rule in the SG
      * @param dstAddress the source IP address
      * @param write add or delete
      * @param portSecurityRule the security rule in the SG
      * @param dstAddress the source IP address
      * @param write add or delete
+     * @param isRegMatchReq add Reg MAtch or not
      * @param protoPortMatchPriority the protocol match priority
      */
     private void egressAclIcmpV4(Long dpidLong, String segmentationId, String srcMac,
                                  NeutronSecurityRule portSecurityRule, String dstAddress,
      * @param protoPortMatchPriority the protocol match priority
      */
     private void egressAclIcmpV4(Long dpidLong, String segmentationId, String srcMac,
                                  NeutronSecurityRule portSecurityRule, String dstAddress,
-                                 boolean write, Integer protoPortMatchPriority) {
+                                 boolean write, Integer protoPortMatchPriority, boolean isRegMatchReq) {
 
         MatchBuilder matchBuilder = new MatchBuilder();
 
         MatchBuilder matchBuilder = new MatchBuilder();
+        boolean isIcmpAll = false;
         String flowId = "Egress_ICMP_" + segmentationId + "_" + srcMac + "_";
         matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
         /*Custom ICMP Match */
         String flowId = "Egress_ICMP_" + segmentationId + "_" + srcMac + "_";
         matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
         /*Custom ICMP Match */
@@ -524,10 +680,16 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                     portSecurityRule.getSecurityRulePortMin().shortValue(),
                     portSecurityRule.getSecurityRulePortMax().shortValue());
         } else {
                     portSecurityRule.getSecurityRulePortMin().shortValue(),
                     portSecurityRule.getSecurityRulePortMax().shortValue());
         } else {
+            isIcmpAll = true;
             /* All ICMP Match */ // We are getting from neutron NULL for both min and max
             flowId = flowId + "all" + "_" ;
             matchBuilder = MatchUtils.createICMPv4Match(matchBuilder, MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
         }
             /* All ICMP Match */ // We are getting from neutron NULL for both min and max
             flowId = flowId + "all" + "_" ;
             matchBuilder = MatchUtils.createICMPv4Match(matchBuilder, MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
         }
+        if (isRegMatchReq) {
+            flowId = flowId + "_regEx_";
+            MatchUtils.addNxRegMatch(matchBuilder,
+                    new MatchUtils.RegMatch(ClassifierService.REG_FIELD_6, ClassifierService.REG_VALUE_FROM_LOCAL_0));
+        }
         if (null != dstAddress) {
             flowId = flowId + dstAddress;
             matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
         if (null != dstAddress) {
             flowId = flowId + dstAddress;
             matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
@@ -539,12 +701,71 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                     new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
             }
         }
                     new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
             }
         }
-        flowId = flowId + "_Permit";
-        addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
-        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
-        addInstructionWithConntrackCommit(flowBuilder, false);
+        //matchBuilder = MatchUtils.createICMPv4Match(matchBuilder, portSecurityRule.getSecurityRulePortMin().shortValue(), portSecurityRule.getSecurityRulePortMax().shortValue());
+        if(isIcmpAll)
+        {
+            Map<Integer, String> map = LearnConstants.ICMP_TYPE_MAP;
+            for(Map.Entry<Integer, String> entry : map.entrySet()) {
+                Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
+                icmpv4match.setIcmpv4Type(entry.getKey().shortValue());
+                icmpv4match.setIcmpv4Code((short)0);
+                matchBuilder.setIcmpv4Match(icmpv4match.build());
+                String rangeflowId = flowId + "_" + entry.getKey() + "_" + entry.getValue();
+                addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+                FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(rangeflowId, protoPortMatchPriority, matchBuilder, getTable());
+                addInstructionWithLearnConntrackCommit(portSecurityRule, flowBuilder, entry.getValue(), "0");
+                syncFlow(flowBuilder ,nodeBuilder, write);
+            }
+            addIcmpFlow(nodeBuilder, portSecurityRule, segmentationId, srcMac, dstAddress, write, isRegMatchReq);
+        } else {
+            flowId = flowId + "_Permit";
+            addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+            FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority, matchBuilder, getTable());
+             String icmpType = LearnConstants.ICMP_TYPE_MAP.get(portSecurityRule.getSecurityRulePortMin());
+            if (icmpType == null){
+                icmpType = Integer.toString(portSecurityRule.getSecurityRulePortMin());
+            }
+            addInstructionWithLearnConntrackCommit(portSecurityRule, flowBuilder, icmpType,
+                    Integer.toString(portSecurityRule.getSecurityRulePortMax()));
+            syncFlow(flowBuilder ,nodeBuilder, write);
+        }
+    }
+
+    private void addIcmpFlow(NodeBuilder nodeBuilder, NeutronSecurityRule portSecurityRule, String segmentationId, String srcMac,
+            String dstAddress, boolean write, boolean isRegMatchReq){
+        MatchBuilder matchBuilder = new MatchBuilder();
+        InstructionBuilder instructionBuilder = null;
+        short learnTableId=getTable(Service.ACL_LEARN_SERVICE);
+        short resubmitId=getTable(Service.LOAD_BALANCER);
+        String flowId = "Ingress_ICMP_" + segmentationId + "_" + srcMac + "_";
+        matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
+        flowId = flowId + "all" + "_" ;
+        matchBuilder = MatchUtils.createICMPv4Match(matchBuilder, MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
+        if (null != dstAddress) {
+            flowId = flowId + dstAddress;
+            matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
+                    MatchUtils.iPv4PrefixFromIPv4Address(dstAddress));
+        } else if (null != portSecurityRule.getSecurityRuleRemoteIpPrefix()) {
+            flowId = flowId + portSecurityRule.getSecurityRuleRemoteIpPrefix();
+            if (!portSecurityRule.getSecurityRuleRemoteIpPrefix().contains("/0")) {
+                matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder,null,
+                    new Ipv4Prefix(portSecurityRule.getSecurityRuleRemoteIpPrefix()));
+            }
+        }
+        if (isRegMatchReq) {
+            flowId = flowId + "_regEx_";
+            MatchUtils.addNxRegMatch(matchBuilder,
+                    new MatchUtils.RegMatch(ClassifierService.REG_FIELD_6, ClassifierService.REG_VALUE_FROM_LOCAL_0));
+        }
+        Icmpv4MatchBuilder icmpv4match = new Icmpv4MatchBuilder();
+        matchBuilder.setIcmpv4Match(icmpv4match.build());
+        String rangeflowId = flowId;
+        addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
+        FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(rangeflowId, Constants.PROTO_PORT_ICMP_MATCH_PRIORITY, matchBuilder, getTable());
+        addPipelineInstruction(flowBuilder, null, false);
         syncFlow(flowBuilder ,nodeBuilder, write);
         syncFlow(flowBuilder ,nodeBuilder, write);
+
     }
 
     /**
     }
 
     /**
@@ -557,11 +778,12 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
      * @param portSecurityRule the security rule in the SG
      * @param dstAddress the source IP address
      * @param write add or delete
      * @param portSecurityRule the security rule in the SG
      * @param dstAddress the source IP address
      * @param write add or delete
+     * @param isRegMatchReq add Reg MAtch or not
      * @param protoPortMatchPriority the protocol match priority
      */
     private void egressAclIcmpV6(Long dpidLong, String segmentationId, String srcMac,
                                  NeutronSecurityRule portSecurityRule, String dstAddress,
      * @param protoPortMatchPriority the protocol match priority
      */
     private void egressAclIcmpV6(Long dpidLong, String segmentationId, String srcMac,
                                  NeutronSecurityRule portSecurityRule, String dstAddress,
-                                 boolean write, Integer protoPortMatchPriority) {
+                                 boolean write, Integer protoPortMatchPriority, boolean isRegMatchReq) {
 
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Egress_ICMP_" + segmentationId + "_" + srcMac + "_";
 
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Egress_ICMP_" + segmentationId + "_" + srcMac + "_";
@@ -580,6 +802,11 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
             flowId = flowId + "all" + "_" ;
             matchBuilder = MatchUtils.createICMPv6Match(matchBuilder, MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
         }
             flowId = flowId + "all" + "_" ;
             matchBuilder = MatchUtils.createICMPv6Match(matchBuilder, MatchUtils.ALL_ICMP, MatchUtils.ALL_ICMP);
         }
+        if (isRegMatchReq) {
+            flowId = flowId + "_regEx_";
+            MatchUtils.addNxRegMatch(matchBuilder,
+                    new MatchUtils.RegMatch(ClassifierService.REG_FIELD_6, ClassifierService.REG_VALUE_FROM_LOCAL_0));
+        }
         if (null != dstAddress) {
             flowId = flowId + dstAddress;
             matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder,null,
         if (null != dstAddress) {
             flowId = flowId + dstAddress;
             matchBuilder = MatchUtils.addRemoteIpv6Prefix(matchBuilder,null,
@@ -607,11 +834,12 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
      * @param portSecurityRule the security rule in the SG
      * @param dstAddress the source IP address
      * @param write add or delete
      * @param portSecurityRule the security rule in the SG
      * @param dstAddress the source IP address
      * @param write add or delete
+     * @param isRegMatchReq add Reg MAtch or not
      * @param protoPortMatchPriority the protocol match priroty
      */
     private void egressAclUdp(Long dpidLong, String segmentationId, String srcMac,
                               NeutronSecurityRule portSecurityRule, String dstAddress,
      * @param protoPortMatchPriority the protocol match priroty
      */
     private void egressAclUdp(Long dpidLong, String segmentationId, String srcMac,
                               NeutronSecurityRule portSecurityRule, String dstAddress,
-                              boolean write, Integer protoPortMatchPriority) {
+                              boolean write, Integer protoPortMatchPriority, boolean isRegMatchReq) {
         boolean portRange = false;
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Egress_UDP_" + segmentationId + "_" + srcMac + "_";
         boolean portRange = false;
         MatchBuilder matchBuilder = new MatchBuilder();
         String flowId = "Egress_UDP_" + segmentationId + "_" + srcMac + "_";
@@ -621,18 +849,23 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         } else {
             matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
         }
         } else {
             matchBuilder = MatchUtils.createV4EtherMatchWithType(matchBuilder,srcMac,null,MatchUtils.ETHERTYPE_IPV4);
         }
+        if (isRegMatchReq) {
+            flowId = flowId + "_regEx_";
+            MatchUtils.addNxRegMatch(matchBuilder,
+                    new MatchUtils.RegMatch(ClassifierService.REG_FIELD_6, ClassifierService.REG_VALUE_FROM_LOCAL_0));
+        }
 
         /* Custom UDP Match */
 
         /* Custom UDP Match */
-        if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
-            flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
-            matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
-                                                     portSecurityRule.getSecurityRulePortMin());
-        } else {
-            /* All UDP Match */
-            if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
+        if (portSecurityRule.getSecurityRulePortMin() != null && portSecurityRule.getSecurityRulePortMax() != null) {
+            if (portSecurityRule.getSecurityRulePortMin().equals(portSecurityRule.getSecurityRulePortMax())) {
+                flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_";
+                matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0,
+                        portSecurityRule.getSecurityRulePortMin());
+            } else if (portSecurityRule.getSecurityRulePortMin().equals(PORT_RANGE_MIN)
                     && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
                     && portSecurityRule.getSecurityRulePortMax().equals(PORT_RANGE_MAX)) {
+                /* All UDP Match */
                 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
                 flowId = flowId + portSecurityRule.getSecurityRulePortMin() + "_"
-                    + portSecurityRule.getSecurityRulePortMax() + "_";
+                        + portSecurityRule.getSecurityRulePortMax() + "_";
                 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0, 0);
             } else {
                 portRange = true;
                 matchBuilder = MatchUtils.addLayer4Match(matchBuilder, MatchUtils.UDP_SHORT, 0, 0);
             } else {
                 portRange = true;
@@ -654,9 +887,11 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                         new Ipv6Prefix(portSecurityRule
                                        .getSecurityRuleRemoteIpPrefix()));
             } else {
                         new Ipv6Prefix(portSecurityRule
                                        .getSecurityRuleRemoteIpPrefix()));
             } else {
+                if (!portSecurityRule.getSecurityRuleRemoteIpPrefix().contains("/0")) {
                 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder, null,
                         new Ipv4Prefix(portSecurityRule
                                        .getSecurityRuleRemoteIpPrefix()));
                 matchBuilder = MatchUtils.addRemoteIpPrefix(matchBuilder, null,
                         new Ipv4Prefix(portSecurityRule
                                        .getSecurityRuleRemoteIpPrefix()));
+                }
             }
         }
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
             }
         }
         NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
@@ -672,7 +907,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
                 addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
                 FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(rangeflowId, protoPortMatchPriority,
                                                                       matchBuilder, getTable());
                 addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
                 FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(rangeflowId, protoPortMatchPriority,
                                                                       matchBuilder, getTable());
-                addInstructionWithConntrackCommit(flowBuilder, false);
+                addInstructionWithLearnConntrackCommit(portSecurityRule, flowBuilder, null, null);
                 syncFlow(flowBuilder ,nodeBuilder, write);
             }
         } else {
                 syncFlow(flowBuilder ,nodeBuilder, write);
             }
         } else {
@@ -680,7 +915,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
             addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
             FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority,
                                                                   matchBuilder, getTable());
             addConntrackMatch(matchBuilder, MatchUtils.TRACKED_NEW_CT_STATE,MatchUtils.TRACKED_NEW_CT_STATE_MASK);
             FlowBuilder flowBuilder = FlowUtils.createFlowBuilder(flowId, protoPortMatchPriority,
                                                                   matchBuilder, getTable());
-            addInstructionWithConntrackCommit(flowBuilder, false);
+            addInstructionWithLearnConntrackCommit(portSecurityRule, flowBuilder, null, null);
             syncFlow(flowBuilder ,nodeBuilder, write);
         }
     }
             syncFlow(flowBuilder ,nodeBuilder, write);
         }
     }
@@ -695,7 +930,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
      */
     private void egressAclDhcpAllowClientTrafficFromVm(Long dpidLong,
                                                        boolean write, long localPort, Integer priority) {
      */
     private void egressAclDhcpAllowClientTrafficFromVm(Long dpidLong,
                                                        boolean write, long localPort, Integer priority) {
-        String flowName = "Egress_DHCP_Client + "_Permit_";
+        String flowName = "Egress_DHCP_Client_"  + localPort + "_Permit_";
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
         MatchUtils.createDhcpMatch(matchBuilder, DHCP_DESTINATION_PORT, DHCP_SOURCE_PORT);
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
         MatchUtils.createDhcpMatch(matchBuilder, DHCP_DESTINATION_PORT, DHCP_SOURCE_PORT);
@@ -715,7 +950,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
      */
     private void egressAclDhcpv6AllowClientTrafficFromVm(Long dpidLong,
                                                          boolean write, long localPort, Integer priority) {
      */
     private void egressAclDhcpv6AllowClientTrafficFromVm(Long dpidLong,
                                                          boolean write, long localPort, Integer priority) {
-        String flowName = "Egress_DHCPv6_Client + "_Permit_";
+        String flowName = "Egress_DHCPv6_Client_"  + localPort + "_Permit_";
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
         MatchUtils.createDhcpv6Match(matchBuilder, DHCPV6_DESTINATION_PORT, DHCPV6_SOURCE_PORT);
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
         MatchUtils.createDhcpv6Match(matchBuilder, DHCPV6_DESTINATION_PORT, DHCPV6_SOURCE_PORT);
@@ -735,7 +970,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
      */
     private void egressAclDhcpDropServerTrafficfromVm(Long dpidLong, long localPort,
                                                       boolean write, Integer priority) {
      */
     private void egressAclDhcpDropServerTrafficfromVm(Long dpidLong, long localPort,
                                                       boolean write, Integer priority) {
-        String flowName = "Egress_DHCP_Server" + "_" + localPort + "_DROP_";
+        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);
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
         MatchUtils.createDhcpMatch(matchBuilder, DHCP_SOURCE_PORT, DHCP_DESTINATION_PORT);
@@ -756,7 +991,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
     private void egressAclDhcpv6DropServerTrafficfromVm(Long dpidLong, long localPort,
                                                         boolean write, Integer priority) {
 
     private void egressAclDhcpv6DropServerTrafficfromVm(Long dpidLong, long localPort,
                                                         boolean write, Integer priority) {
 
-        String flowName = "Egress_DHCPv6_Server" + "_" + localPort + "_DROP_";
+        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);
         MatchBuilder matchBuilder = new MatchBuilder();
         MatchUtils.createInPortMatch(matchBuilder, dpidLong, localPort);
         MatchUtils.createDhcpv6Match(matchBuilder, DHCPV6_SOURCE_PORT, DHCPV6_DESTINATION_PORT);
@@ -830,6 +1065,25 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
         }
         return addPipelineInstruction(flowBuilder,instructionBuilder, isDrop);
     }
         }
         return addPipelineInstruction(flowBuilder,instructionBuilder, isDrop);
     }
+    private FlowBuilder addInstructionWithLearnConntrackCommit(NeutronSecurityRule portSecurityRule, FlowBuilder flowBuilder, String icmpType, String icmpCode) {
+        InstructionBuilder instructionBuilder = null;
+        short learnTableId=getTable(Service.ACL_LEARN_SERVICE);
+        short resubmitId=getTable(Service.LOAD_BALANCER);
+        if (securityServicesManager.isConntrackEnabled()) {
+            Action conntrackAction = ActionUtils.nxConntrackAction(1, 0L, 0, (short)0xff);
+            instructionBuilder = InstructionUtils
+                    .createInstructionBuilder(ActionUtils.conntrackActionBuilder(conntrackAction), 1, false);
+            return addPipelineInstruction(flowBuilder,instructionBuilder, false);
+        }
+        if (portSecurityRule.getSecurityRuleProtocol().equalsIgnoreCase(MatchUtils.TCP) || portSecurityRule.getSecurityRuleProtocol().equalsIgnoreCase(MatchUtils.TCP_PROTOCOL)) {
+            return EgressAclLearnServiceUtil.programEgressAclLearnRuleForTcp(flowBuilder,instructionBuilder,learnTableId,resubmitId);
+        } else if (portSecurityRule.getSecurityRuleProtocol().equalsIgnoreCase(MatchUtils.UDP)  || portSecurityRule.getSecurityRuleProtocol().equalsIgnoreCase(MatchUtils.UDP_PROTOCOL)) {
+            return EgressAclLearnServiceUtil.programEgressAclLearnRuleForUdp(flowBuilder,instructionBuilder,learnTableId,resubmitId);
+        } else if (portSecurityRule.getSecurityRuleProtocol().equalsIgnoreCase(MatchUtils.ICMP)  || portSecurityRule.getSecurityRuleProtocol().equalsIgnoreCase(MatchUtils.ICMP_PROTOCOL)) {
+            return EgressAclLearnServiceUtil.programEgressAclLearnRuleForIcmp(flowBuilder,instructionBuilder, icmpType, icmpCode,learnTableId,resubmitId);
+        }
+        return flowBuilder;
+    }
 
     private FlowBuilder addInstructionWithConntrackRecirc( FlowBuilder flowBuilder) {
         InstructionBuilder instructionBuilder = null;
 
     private FlowBuilder addInstructionWithConntrackRecirc( FlowBuilder flowBuilder) {
         InstructionBuilder instructionBuilder = null;
@@ -838,7 +1092,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
 
             instructionBuilder = InstructionUtils
                     .createInstructionBuilder(ActionUtils.conntrackActionBuilder(conntrackAction), 1, false);
 
             instructionBuilder = InstructionUtils
                     .createInstructionBuilder(ActionUtils.conntrackActionBuilder(conntrackAction), 1, false);
-            List<Instruction> instructionsList = Lists.newArrayList();
+            List<Instruction> instructionsList = new ArrayList<>();
             instructionsList.add(instructionBuilder.build());
             InstructionsBuilder isb = new InstructionsBuilder();
             isb.setInstruction(instructionsList);
             instructionsList.add(instructionBuilder.build());
             InstructionsBuilder isb = new InstructionsBuilder();
             isb.setInstruction(instructionsList);
@@ -850,7 +1104,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
     private FlowBuilder addPipelineInstruction( FlowBuilder flowBuilder ,
                                                 InstructionBuilder instructionBuilder,boolean isDrop) {
         InstructionBuilder pipeLineIndstructionBuilder = createPipleLineInstructionBuilder(isDrop);
     private FlowBuilder addPipelineInstruction( FlowBuilder flowBuilder ,
                                                 InstructionBuilder instructionBuilder,boolean isDrop) {
         InstructionBuilder pipeLineIndstructionBuilder = createPipleLineInstructionBuilder(isDrop);
-        List<Instruction> instructionsList = Lists.newArrayList();
+        List<Instruction> instructionsList = new ArrayList<>();
         instructionsList.add(pipeLineIndstructionBuilder.build());
         if (null != instructionBuilder) {
             instructionsList.add(instructionBuilder.build());
         instructionsList.add(pipeLineIndstructionBuilder.build());
         if (null != instructionBuilder) {
             instructionsList.add(instructionBuilder.build());
@@ -867,7 +1121,7 @@ public class EgressAclService extends AbstractServiceInstance implements EgressA
             InstructionUtils.createDropInstructions(ib);
         }
         ib.setOrder(0);
             InstructionUtils.createDropInstructions(ib);
         }
         ib.setOrder(0);
-        List<Instruction> instructionsList = Lists.newArrayList();
+        List<Instruction> instructionsList = new ArrayList<>();
         ib.setKey(new InstructionKey(0));
         instructionsList.add(ib.build());
         return ib;
         ib.setKey(new InstructionKey(0));
         instructionsList.add(ib.build());
         return ib;