Remove GENIUS UTIL references in AclService Module
[netvirt.git] / aclservice / impl / src / main / java / org / opendaylight / netvirt / aclservice / IngressAclServiceImpl.java
index 5727a6d19f7b8e6d8a32c86162515527ae2ad15d..395c95e8c7043c5b00668e4562e45de0077bf7a5 100644 (file)
@@ -7,17 +7,16 @@
  */
 package org.opendaylight.netvirt.aclservice;
 
-import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
-import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
 
-import java.math.BigInteger;
+import com.google.common.collect.Lists;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.genius.mdsalutil.FlowEntity;
 import org.opendaylight.genius.mdsalutil.InstructionInfo;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
+import org.opendaylight.genius.mdsalutil.MatchInfo;
 import org.opendaylight.genius.mdsalutil.MatchInfoBase;
 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
 import org.opendaylight.genius.mdsalutil.NwConstants;
@@ -25,10 +24,14 @@ import org.opendaylight.genius.mdsalutil.instructions.InstructionGotoTable;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetDestination;
 import org.opendaylight.genius.mdsalutil.matches.MatchEthernetType;
+import org.opendaylight.genius.mdsalutil.matches.MatchIcmpv4;
+import org.opendaylight.genius.mdsalutil.matches.MatchIcmpv6;
+import org.opendaylight.genius.mdsalutil.matches.MatchIpProtocol;
 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchRegister;
 import org.opendaylight.genius.utils.ServiceIndex;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.netvirt.aclservice.api.AclInterfaceCache;
 import org.opendaylight.netvirt.aclservice.api.AclServiceManager;
 import org.opendaylight.netvirt.aclservice.api.AclServiceManager.Action;
@@ -45,11 +48,13 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.ser
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.service.bindings.services.info.BoundServices;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionIngress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.InterfaceAcl.InterfaceType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.IpPrefixOrAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.AllowedAddressPairs;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.port.subnets.port.subnet.SubnetInfo;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.interfaces._interface.SubnetInfo;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.Uint64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -101,12 +106,11 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
                     AclServiceUtils.getBoundServices(String.format("%s.%s.%s", "acl", "egressacl", interfaceName),
                             serviceIndex, flowPriority, AclConstants.COOKIE_ACL_BASE, instructions);
             InstanceIdentifier<BoundServices> path = AclServiceUtils.buildServiceId(interfaceName,
-                    ServiceIndex.getIndex(NwConstants.EGRESS_ACL_SERVICE_NAME, NwConstants.EGRESS_ACL_SERVICE_INDEX),
-                    serviceMode);
+                    serviceIndex, serviceMode);
 
             return Collections.singletonList(
-                    txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.put(
-                            path, serviceInfo, CREATE_MISSING_PARENTS)));
+                    txRunner.callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.mergeParentStructurePut(
+                            path, serviceInfo)));
         });
     }
 
@@ -127,35 +131,74 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
                 .callWithNewWriteOnlyTransactionAndSubmit(CONFIGURATION, tx -> tx.delete(path))));
     }
 
+    /**
+     * Programs DHCP Service flows.
+     *
+     * @param flowEntries the flow entries
+     * @param port the acl interface
+     * @param action add/modify/remove action
+     * @param addOrRemove addorRemove
+     */
+    @Override
+    protected void programDhcpService(List<FlowEntity> flowEntries, AclInterface port,
+            Action action, int addOrRemove) {
+        LOG.info("{} programDhcpService for port {}, action={}, addOrRemove={}", this.directionString,
+                port.getInterfaceId(), action, addOrRemove);
+        Uint64 dpid = Uint64.valueOf(port.getDpId());
+        int lportTag = port.getLPortTag();
+        allowDhcpClientTraffic(flowEntries, dpid, lportTag, addOrRemove);
+        allowDhcpv6ClientTraffic(flowEntries, dpid, lportTag, addOrRemove);
+        programArpRule(flowEntries, dpid, lportTag, addOrRemove);
+        ingressAclIcmpv6AllowedTraffic(flowEntries, port, InterfaceType.DhcpService, addOrRemove);
+        allowIcmpTrafficToDhcpServer(flowEntries, port, port.getAllowedAddressPairs(), addOrRemove);
+        dropTrafficToDhcpServer(flowEntries, dpid, lportTag, addOrRemove);
+        programCommitterDropFlow(flowEntries, dpid, lportTag, addOrRemove);
+    }
+
+    /**
+     * Programs DHCP service flows.
+     *
+     * @param flowEntries the flow entries
+     * @param port the acl interface
+     * @param allowedAddresses the allowed addresses
+     * @param addOrRemove addorRemove
+     */
+    @Override
+    protected void processDhcpServiceUpdate(List<FlowEntity> flowEntries, AclInterface port,
+            List<AllowedAddressPairs> allowedAddresses, int addOrRemove) {
+        allowIcmpTrafficToDhcpServer(flowEntries, port, allowedAddresses, addOrRemove);
+    }
+
     @Override
     protected void programAntiSpoofingRules(List<FlowEntity> flowEntries, AclInterface port,
             List<AllowedAddressPairs> allowedAddresses, Action action, int addOrRemove) {
         LOG.info("{} programAntiSpoofingRules for port {}, AAPs={}, action={}, addOrRemove={}", this.directionString,
                 port.getInterfaceId(), allowedAddresses, action, addOrRemove);
 
-        BigInteger dpid = port.getDpId();
+        Uint64 dpid = Uint64.valueOf(port.getDpId());
         int lportTag = port.getLPortTag();
         if (action == Action.ADD || action == Action.REMOVE) {
             programCommitterDropFlow(flowEntries, dpid, lportTag, addOrRemove);
             ingressAclDhcpAllowServerTraffic(flowEntries, dpid, lportTag, addOrRemove);
             ingressAclDhcpv6AllowServerTraffic(flowEntries, dpid, lportTag, addOrRemove);
-            ingressAclIcmpv6AllowedTraffic(flowEntries, port, addOrRemove);
+            ingressAclIcmpv6AllowedTraffic(flowEntries, port, InterfaceType.AccessPort, addOrRemove);
             programIcmpv6RARule(flowEntries, port, port.getSubnetInfo(), addOrRemove);
 
             programArpRule(flowEntries, dpid, lportTag, addOrRemove);
-            programIpv4BroadcastRule(flowEntries, port, addOrRemove);
+            programIpv4BroadcastRule(flowEntries, port, port.getSubnetInfo(), addOrRemove);
         }
     }
 
-    private void programCommitterDropFlow(List<FlowEntity> flowEntries, BigInteger dpId, int lportTag,
+    private void programCommitterDropFlow(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
             int addOrRemove) {
         List<MatchInfoBase> matches = new ArrayList<>();
         List<InstructionInfo> instructions = AclServiceOFFlowBuilder.getDropInstructionInfo();
 
-        BigInteger metaData = MetaDataUtil.METADATA_MASK_ACL_DROP
-                .and(AclConstants.METADATA_DROP_FLAG.shiftLeft(2));
-        BigInteger metaDataMask = MetaDataUtil.METADATA_MASK_ACL_DROP
-                .and(AclConstants.METADATA_DROP_FLAG.shiftLeft(2));
+        Uint64 metaData = Uint64.fromLongBits(MetaDataUtil.METADATA_MASK_ACL_DROP.longValue()
+                & (AclConstants.METADATA_DROP_FLAG.longValue() << 2));
+        Uint64 metaDataMask = Uint64.fromLongBits(MetaDataUtil.METADATA_MASK_ACL_DROP.longValue()
+                & (AclConstants.METADATA_DROP_FLAG.longValue() << 2));
+
         matches.add(new NxMatchRegister(NxmNxReg6.class, MetaDataUtil.getLportTagForReg6(lportTag).longValue(),
                 MetaDataUtil.getLportTagMaskForReg6()));
         matches.add(new MatchMetadata(metaData, metaDataMask));
@@ -167,7 +210,7 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
     }
 
     @Override
-    protected void programGotoClassifierTableRules(List<FlowEntity> flowEntries, BigInteger dpId,
+    protected void programGotoClassifierTableRules(List<FlowEntity> flowEntries, Uint64 dpId,
             List<AllowedAddressPairs> aaps, int lportTag, int addOrRemove) {
         for (AllowedAddressPairs aap : aaps) {
             IpPrefixOrAddress attachIp = aap.getIpAddress();
@@ -181,8 +224,8 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
             List<InstructionInfo> gotoInstructions = new ArrayList<>();
             gotoInstructions.add(new InstructionGotoTable(getAclConntrackClassifierTable()));
 
-            String flowName = "Ingress_Fixed_Goto_Classifier_" + dpId + "_" + lportTag + "_" + mac.getValue() + "_"
-                    + attachIp.stringValue();
+            String flowName = "Ingress_Fixed_Goto_Classifier_" + dpId + "_" + lportTag + "_"
+                    + mac.getValue() + "_" + attachIp.stringValue();
             addFlowEntryToList(flowEntries, dpId, getAclAntiSpoofingTable(), flowName,
                     AclConstants.PROTO_MATCH_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches, gotoInstructions,
                     addOrRemove);
@@ -190,7 +233,7 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
     }
 
     @Override
-    protected void programRemoteAclTableFlow(List<FlowEntity> flowEntries, BigInteger dpId, Integer aclTag,
+    protected void programRemoteAclTableFlow(List<FlowEntity> flowEntries, Uint64 dpId, Integer aclTag,
             AllowedAddressPairs aap, int addOrRemove) {
         List<MatchInfoBase> flowMatches = new ArrayList<>();
         flowMatches.addAll(AclServiceUtils.buildIpAndSrcServiceMatch(aclTag, aap));
@@ -210,7 +253,7 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
      * @param lportTag the lport tag
      * @param addOrRemove is write or delete
      */
-    protected void ingressAclDhcpAllowServerTraffic(List<FlowEntity> flowEntries, BigInteger dpId, int lportTag,
+    protected void ingressAclDhcpAllowServerTraffic(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
             int addOrRemove) {
         final List<MatchInfoBase> matches = AclServiceUtils.buildDhcpMatches(AclConstants.DHCP_SERVER_PORT_IPV4,
                 AclConstants.DHCP_CLIENT_PORT_IPV4, lportTag, serviceMode);
@@ -230,7 +273,7 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
      * @param lportTag the lport tag
      * @param addOrRemove is write or delete
      */
-    protected void ingressAclDhcpv6AllowServerTraffic(List<FlowEntity> flowEntries, BigInteger dpId, int lportTag,
+    protected void ingressAclDhcpv6AllowServerTraffic(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
             int addOrRemove) {
         final List<MatchInfoBase> matches = AclServiceUtils.buildDhcpV6Matches(AclConstants.DHCP_SERVER_PORT_IPV6,
                 AclConstants.DHCP_CLIENT_PORT_IPV6, lportTag, serviceMode);
@@ -248,27 +291,33 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
      *
      * @param flowEntries the flow entries
      * @param port the port
+     * @param port type
      * @param addOrRemove is write or delete
      */
-    private void ingressAclIcmpv6AllowedTraffic(List<FlowEntity> flowEntries, AclInterface port, int addOrRemove) {
-        BigInteger dpId = port.getDpId();
+    private void ingressAclIcmpv6AllowedTraffic(List<FlowEntity> flowEntries, AclInterface port,
+            InterfaceType interfaceType, int addOrRemove) {
+        Uint64 dpId = Uint64.valueOf(port.getDpId());
         int lportTag = port.getLPortTag();
         List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
 
-        // Allow ICMPv6 Multicast Listener Query packets.
-        List<MatchInfoBase> matches = AclServiceUtils.buildIcmpV6Matches(AclConstants.ICMPV6_TYPE_MLD_QUERY, 0,
-                lportTag, serviceMode);
-
         final short tableId = getAclAntiSpoofingTable();
-        String flowName =
-                "Ingress_ICMPv6" + "_" + dpId + "_" + lportTag + "_" + AclConstants.ICMPV6_TYPE_MLD_QUERY + "_Permit_";
-        addFlowEntryToList(flowEntries, dpId, tableId, flowName, AclConstants.PROTO_IPV6_ALLOWED_PRIORITY, 0, 0,
-                AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
+
+        if (interfaceType != InterfaceType.DhcpService) {
+            // Allow ICMPv6 Multicast Listener Query packets.
+            List<MatchInfoBase> matches = AclServiceUtils.buildIcmpV6Matches(AclConstants.ICMPV6_TYPE_MLD_QUERY, 0,
+                    lportTag, serviceMode);
+            String flowName = "Ingress_ICMPv6" + "_" + dpId + "_" + lportTag + "_"
+                    + AclConstants.ICMPV6_TYPE_MLD_QUERY + "_Permit_";
+            addFlowEntryToList(flowEntries, dpId, tableId, flowName, AclConstants.PROTO_IPV6_ALLOWED_PRIORITY, 0, 0,
+                    AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
+        }
 
         // Allow ICMPv6 Neighbor Solicitation packets.
-        matches = AclServiceUtils.buildIcmpV6Matches(AclConstants.ICMPV6_TYPE_NS, 0, lportTag, serviceMode);
+        List<MatchInfoBase> matches = AclServiceUtils.buildIcmpV6Matches(AclConstants.ICMPV6_TYPE_NS, 0, lportTag,
+                serviceMode);
 
-        flowName = "Ingress_ICMPv6" + "_" + dpId + "_" + lportTag + "_" + AclConstants.ICMPV6_TYPE_NS + "_Permit_";
+        String flowName = "Ingress_ICMPv6" + "_" + dpId + "_" + lportTag + "_"
+                + AclConstants.ICMPV6_TYPE_NS + "_Permit_";
         addFlowEntryToList(flowEntries, dpId, tableId, flowName, AclConstants.PROTO_IPV6_ALLOWED_PRIORITY, 0, 0,
                 AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
 
@@ -283,24 +332,27 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
     @Override
     protected void programIcmpv6RARule(List<FlowEntity> flowEntries, AclInterface port, List<SubnetInfo> subnets,
             int addOrRemove) {
-        if (AclServiceUtils.isIpv6Subnet(subnets)) {
-            /* Allow ICMPv6 Router Advertisement packets from external routers as well as internal routers
-             * if subnet is configured with IPv6 version
-             * Allow ICMPv6 Router Advertisement packets if originating from any LinkLocal Address.
-             */
-            List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
-            List<MatchInfoBase> matches =
-                    AclServiceUtils.buildIcmpV6Matches(AclConstants.ICMPV6_TYPE_RA, 0,
-                            port.getLPortTag(), serviceMode);
-            matches.addAll(AclServiceUtils.buildIpMatches(
-                    new IpPrefixOrAddress(IpPrefixBuilder.getDefaultInstance(AclConstants.IPV6_LINK_LOCAL_PREFIX)),
-                    AclServiceManager.MatchCriteria.MATCH_SOURCE));
-            String flowName = "Ingress_ICMPv6" + "_" + port.getDpId() + "_" + port.getLPortTag() + "_"
-                    + AclConstants.ICMPV6_TYPE_RA + "_LinkLocal_Permit_";
-            addFlowEntryToList(flowEntries, port.getDpId(), getAclAntiSpoofingTable(), flowName,
-                    AclConstants.PROTO_IPV6_ALLOWED_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches,
-                    instructions, addOrRemove);
+        if (!AclServiceUtils.isIpv6Subnet(subnets)) {
+            return;
         }
+
+        Uint64 dpid = Uint64.valueOf(port.getDpId());
+        /* Allow ICMPv6 Router Advertisement packets from external routers as well as internal routers
+         * if subnet is configured with IPv6 version
+         * Allow ICMPv6 Router Advertisement packets if originating from any LinkLocal Address.
+         */
+        List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
+        List<MatchInfoBase> matches =
+                AclServiceUtils.buildIcmpV6Matches(AclConstants.ICMPV6_TYPE_RA, 0,
+                        port.getLPortTag(), serviceMode);
+        matches.addAll(AclServiceUtils.buildIpMatches(
+                new IpPrefixOrAddress(IpPrefixBuilder.getDefaultInstance(AclConstants.IPV6_LINK_LOCAL_PREFIX)),
+                AclServiceManager.MatchCriteria.MATCH_SOURCE));
+        String flowName = "Ingress_ICMPv6" + "_" + dpid + "_" + port.getLPortTag() + "_"
+                + AclConstants.ICMPV6_TYPE_RA + "_LinkLocal_Permit_";
+        addFlowEntryToList(flowEntries, dpid, getAclAntiSpoofingTable(), flowName,
+                AclConstants.PROTO_IPV6_ALLOWED_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches,
+                instructions, addOrRemove);
     }
 
     /**
@@ -311,7 +363,7 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
      * @param lportTag the lport tag
      * @param addOrRemove whether to add or remove the flow
      */
-    protected void programArpRule(List<FlowEntity> flowEntries, BigInteger dpId, int lportTag, int addOrRemove) {
+    protected void programArpRule(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag, int addOrRemove) {
         List<MatchInfoBase> matches = new ArrayList<>();
         matches.add(MatchEthernetType.ARP);
         matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
@@ -333,8 +385,22 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
      * @param addOrRemove whether to delete or add flow
      */
     @Override
-    protected void programBroadcastRules(List<FlowEntity> flowEntries, AclInterface port, int addOrRemove) {
-        programIpv4BroadcastRule(flowEntries, port, addOrRemove);
+    protected void programBroadcastRules(List<FlowEntity> flowEntries, AclInterface port, Action action,
+            int addOrRemove) {
+        programIpv4BroadcastRule(flowEntries, port, port.getSubnetInfo(), addOrRemove);
+    }
+
+    /**
+     * Programs broadcast rules.
+     *
+     * @param flowEntries the flow entries
+     * @param port the Acl Interface port
+     * @param subnetInfoList the port subnet info list
+     * @param addOrRemove whether to delete or add flow
+     */
+    protected void programSubnetBroadcastRules(List<FlowEntity> flowEntries, AclInterface port,
+            List<SubnetInfo> subnetInfoList, int addOrRemove) {
+        programIpv4BroadcastRule(flowEntries, port, subnetInfoList, addOrRemove);
     }
 
     /**
@@ -342,13 +408,14 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
      *
      * @param flowEntries the flow entries
      * @param port the Acl Interface port
+     * @param subnetInfoList Port subnet list
      * @param addOrRemove whether to delete or add flow
      */
-    private void programIpv4BroadcastRule(List<FlowEntity> flowEntries, AclInterface port, int addOrRemove) {
-        BigInteger dpId = port.getDpId();
+    private void programIpv4BroadcastRule(List<FlowEntity> flowEntries, AclInterface port,
+            List<SubnetInfo> subnetInfoList, int addOrRemove) {
+        Uint64 dpId = Uint64.valueOf(port.getDpId());
         int lportTag = port.getLPortTag();
         MatchInfoBase lportMatchInfo = AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode);
-        List<SubnetInfo> subnetInfoList = port.getSubnetInfo();
         if (subnetInfoList != null) {
             List<String> broadcastAddresses = AclServiceUtils.getIpBroadcastAddresses(subnetInfoList);
             for (String broadcastAddress : broadcastAddresses) {
@@ -357,7 +424,8 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
                 matches.add(lportMatchInfo);
                 List<InstructionInfo> instructions = new ArrayList<>();
                 instructions.add(new InstructionGotoTable(getAclConntrackClassifierTable()));
-                String flowName = "Ingress_v4_Broadcast_" + dpId + "_" + lportTag + "_" + broadcastAddress + "_Permit";
+                String flowName = "Ingress_v4_Broadcast_" + dpId + "_"
+                                    + lportTag + "_" + broadcastAddress + "_Permit";
                 addFlowEntryToList(flowEntries, dpId, getAclAntiSpoofingTable(), flowName,
                         AclConstants.PROTO_MATCH_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions,
                         addOrRemove);
@@ -367,6 +435,117 @@ public class IngressAclServiceImpl extends AbstractAclServiceImpl {
         }
     }
 
+    /**
+     * Add rule to ensure only DHCP client traffic is allowed.
+     *
+     * @param flowEntries the flow entries
+     * @param dpId the dpid
+     * @param lportTag the lport tag
+     * @param addOrRemove is write or delete
+     */
+    protected void allowDhcpClientTraffic(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
+            int addOrRemove) {
+        final List<MatchInfoBase> matches = AclServiceUtils.buildDhcpMatches(AclConstants.DHCP_CLIENT_PORT_IPV4,
+                AclConstants.DHCP_SERVER_PORT_IPV4, lportTag, serviceMode);
+        List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
+
+        String flowName = "Ingress_DHCP_Service_v4" + dpId + "_" + lportTag + "_Permit_";
+        addFlowEntryToList(flowEntries, dpId, getAclAntiSpoofingTable(), flowName,
+                AclConstants.PROTO_DHCP_SERVER_MATCH_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches,
+                instructions, addOrRemove);
+    }
+
+    /**
+     * Add rule to ensure only DHCPv6 client traffic is allowed.
+     *
+     * @param flowEntries the flow entries
+     * @param dpId the dpid
+     * @param lportTag the lport tag
+     * @param addOrRemove is write or delete
+     */
+    protected void allowDhcpv6ClientTraffic(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
+            int addOrRemove) {
+        final List<MatchInfoBase> matches = AclServiceUtils.buildDhcpV6Matches(AclConstants.DHCP_CLIENT_PORT_IPV6,
+                AclConstants.DHCP_SERVER_PORT_IPV6, lportTag, serviceMode);
+        List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
+
+        String flowName = "Ingress_DHCP_Service_v6" + "_" + dpId + "_" + lportTag + "_Permit_";
+        addFlowEntryToList(flowEntries, dpId, getAclAntiSpoofingTable(), flowName,
+                AclConstants.PROTO_DHCP_SERVER_MATCH_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches,
+                instructions, addOrRemove);
+    }
+
+    /**
+     * Add rules to allow ICMP traffic for DHCP server.
+     * @param flowEntries the flow entries
+     * @param port the Acl Interface port
+     * @param allowedAddresses the allowed addresses
+     * @param addOrRemove the lport tag
+     */
+    protected void allowIcmpTrafficToDhcpServer(List<FlowEntity> flowEntries, AclInterface port,
+            List<AllowedAddressPairs> allowedAddresses, int addOrRemove) {
+        Uint64 dpId = Uint64.valueOf(port.getDpId());
+        int lportTag = port.getLPortTag();
+        for (AllowedAddressPairs allowedAddress : allowedAddresses) {
+            if (AclServiceUtils.isIPv4Address(allowedAddress)) {
+                MatchInfo reqMatchInfo = new MatchIcmpv4((short) AclConstants.ICMPV4_TYPE_ECHO_REQUEST, (short) 0);
+                programIcmpFlow(flowEntries, dpId, lportTag, allowedAddress, MatchIpProtocol.ICMP, reqMatchInfo,
+                        AclConstants.ICMPV4_TYPE_ECHO_REQUEST, addOrRemove);
+                MatchInfo replyMatchInfo = new MatchIcmpv4((short) AclConstants.ICMPV4_TYPE_ECHO_REPLY, (short) 0);
+                programIcmpFlow(flowEntries, dpId, lportTag, allowedAddress, MatchIpProtocol.ICMP, replyMatchInfo,
+                        AclConstants.ICMPV4_TYPE_ECHO_REPLY, addOrRemove);
+            } else {
+                MatchInfo reqMatchInfo = new MatchIcmpv6((short) AclConstants.ICMPV6_TYPE_ECHO_REQUEST, (short) 0);
+                programIcmpFlow(flowEntries, dpId, lportTag, allowedAddress, MatchIpProtocol.ICMPV6, reqMatchInfo,
+                        AclConstants.ICMPV6_TYPE_ECHO_REQUEST, addOrRemove);
+                MatchInfo replyMatchInfo = new MatchIcmpv6((short) AclConstants.ICMPV6_TYPE_ECHO_REPLY, (short) 0);
+                programIcmpFlow(flowEntries, dpId, lportTag, allowedAddress, MatchIpProtocol.ICMPV6, replyMatchInfo,
+                        AclConstants.ICMPV6_TYPE_ECHO_REPLY, addOrRemove);
+            }
+        }
+    }
+
+    private void programIcmpFlow(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
+            AllowedAddressPairs allowedAddress, MatchIpProtocol protocol, MatchInfo icmpTypeMatchInfo,
+            int icmpType, int addOrRemove) {
+        List<MatchInfoBase> matches = new ArrayList<>();
+        matches.add(protocol);
+        matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
+        matches.add(new MatchEthernetDestination(allowedAddress.getMacAddress()));
+        matches.addAll(AclServiceUtils.buildIpMatches(allowedAddress.getIpAddress(), MatchCriteria.MATCH_DESTINATION));
+        matches.add(icmpTypeMatchInfo);
+
+        List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
+        String flowName = "Ingress_DHCP_Service_ICMP_" + dpId + "_" + lportTag + "_" + icmpType + "_Permit_";
+        addFlowEntryToList(flowEntries, dpId, getAclAntiSpoofingTable(), flowName,
+                AclConstants.PROTO_DHCP_SERVER_MATCH_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches,
+                instructions, addOrRemove);
+    }
+
+    /**
+     * Add rule to drop BUM traffic to DHCP Server.
+     *
+     * @param flowEntries the flow entries
+     * @param dpId the dpid
+     * @param lportTag the lport tag
+     * @param addOrRemove is write or delete
+     */
+    protected void dropTrafficToDhcpServer(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
+            int addOrRemove) {
+        InstructionInfo writeMetatdata = AclServiceUtils.getWriteMetadataForDropFlag();
+        List<InstructionInfo> instructions = Lists.newArrayList(writeMetatdata);
+        instructions.addAll(AclServiceOFFlowBuilder.getGotoInstructionInfo(getAclCommitterTable()));
+
+        List<MatchInfoBase> matches = new ArrayList<>();
+        matches.add(new NxMatchRegister(NxmNxReg6.class, MetaDataUtil.getLportTagForReg6(lportTag).longValue(),
+                MetaDataUtil.getLportTagMaskForReg6()));
+
+        String flowName = "Ingress_DHCP_Service_" + dpId + "_" + lportTag + "_Drop";
+        addFlowEntryToList(flowEntries, dpId, getAclAntiSpoofingTable(), flowName,
+                AclConstants.PROTO_DHCP_SERVER_DROP_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches,
+                instructions, addOrRemove);
+    }
+
     @Override
     protected boolean isValidDirection(Class<? extends DirectionBase> direction) {
         return direction.equals(DirectionIngress.class);