Port update with no security groups
[netvirt.git] / aclservice / impl / src / main / java / org / opendaylight / netvirt / aclservice / AbstractAclServiceImpl.java
index 3b78577f1c6f8cc046c461b53478508d0d3cdd2d..b579086e2e38a08d3c5e4d05815f172ab93e3f8b 100644 (file)
@@ -21,6 +21,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.SortedSet;
+import java.util.concurrent.ConcurrentMap;
 import java.util.stream.Collectors;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
@@ -52,7 +53,6 @@ import org.opendaylight.netvirt.aclservice.utils.AclDataUtil;
 import org.opendaylight.netvirt.aclservice.utils.AclServiceOFFlowBuilder;
 import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.Acl;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.AccessListEntries;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.Ace;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Matches;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.matches.ace.type.AceIp;
@@ -63,9 +63,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.ser
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionBase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.DirectionEgress;
 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.SecurityRuleAttr;
 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.interfaces._interface.SubnetInfo;
+import org.opendaylight.yangtools.yang.common.Uint64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -117,27 +119,34 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
             LOG.error("port cannot be null");
             return false;
         }
-        if (port.getSecurityGroups() == null) {
-            LOG.info("Port {} without SGs", port.getInterfaceId());
-            return false;
-        }
         BigInteger dpId = port.getDpId();
+        String portId = port.getInterfaceId();
         if (dpId == null || port.getLPortTag() == null) {
-            LOG.error("Unable to find DpId from ACL interface with id {}", port.getInterfaceId());
+            LOG.error("Unable to find DpId from ACL interface with id {}", portId);
             return false;
         }
+
         LOG.debug("Applying ACL on port {} with DpId {}", port, dpId);
         List<FlowEntity> flowEntries = new ArrayList<>();
-        programAcl(flowEntries, port, Action.ADD, NwConstants.ADD_FLOW);
-        updateRemoteAclFilterTable(flowEntries, port, NwConstants.ADD_FLOW);
-        programFlows(AclConstants.ACL_JOB_KEY_PREFIX + port.getInterfaceId(), flowEntries, NwConstants.ADD_FLOW);
+        if (port.getInterfaceType() == InterfaceType.DhcpService) {
+            programDhcpService(flowEntries, port, Action.ADD, NwConstants.ADD_FLOW);
+        } else {
+            if (port.getSecurityGroups() == null) {
+                LOG.info("Port {} without SGs", portId);
+                return false;
+            }
+            programAclWithAllowedAddress(flowEntries, port, port.getAllowedAddressPairs(),
+                    Action.ADD, NwConstants.ADD_FLOW);
+            updateRemoteAclFilterTable(port, NwConstants.ADD_FLOW);
+        }
+        programFlows(AclConstants.ACL_JOB_KEY_PREFIX + portId, flowEntries, NwConstants.ADD_FLOW);
         return true;
     }
 
     @Override
     public boolean bindAcl(AclInterface port) {
-        if (port == null || port.getSecurityGroups() == null) {
-            LOG.error("Port and port security groups cannot be null for binding ACL service, port={}", port);
+        if (port == null) {
+            LOG.error("Port cannot be null for binding ACL service");
             return false;
         }
         bindService(port);
@@ -180,11 +189,32 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
             // Acls has been updated, find added/removed Acls and act accordingly.
             processInterfaceUpdate(portBefore, portAfter);
             LOG.debug("On ACL update, ACL has been updated for {}", portAfter.getInterfaceId());
+        } else if (portAfter.getInterfaceType() == InterfaceType.DhcpService) {
+            processDhcpServiceInterfaceUpdate(portBefore, portAfter);
         }
 
         return result;
     }
 
+    private void processDhcpServiceInterfaceUpdate(AclInterface portBefore, AclInterface portAfter) {
+        List<FlowEntity> addFlowEntries = new ArrayList<>();
+        List<FlowEntity> deleteFlowEntries = new ArrayList<>();
+        List<AllowedAddressPairs> addedAaps = AclServiceUtils
+                .getUpdatedAllowedAddressPairs(portAfter.getAllowedAddressPairs(), portBefore.getAllowedAddressPairs());
+        List<AllowedAddressPairs> deletedAaps = AclServiceUtils
+                .getUpdatedAllowedAddressPairs(portBefore.getAllowedAddressPairs(), portAfter.getAllowedAddressPairs());
+        if (!deletedAaps.isEmpty()) {
+            processDhcpServiceUpdate(deleteFlowEntries, portBefore, deletedAaps, NwConstants.DEL_FLOW);
+        }
+        if (!addedAaps.isEmpty()) {
+            processDhcpServiceUpdate(addFlowEntries, portAfter, addedAaps, NwConstants.ADD_FLOW);
+        }
+        programFlows(AclConstants.ACL_JOB_KEY_PREFIX + portAfter.getInterfaceId(), deleteFlowEntries,
+                NwConstants.DEL_FLOW);
+        programFlows(AclConstants.ACL_JOB_KEY_PREFIX + portAfter.getInterfaceId(), addFlowEntries,
+                NwConstants.ADD_FLOW);
+    }
+
     private void processInterfaceUpdate(AclInterface portBefore, AclInterface portAfter) {
         List<FlowEntity> addFlowEntries = new ArrayList<>();
         List<FlowEntity> deleteFlowEntries = new ArrayList<>();
@@ -192,16 +222,14 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
                 .getUpdatedAllowedAddressPairs(portAfter.getAllowedAddressPairs(), portBefore.getAllowedAddressPairs());
         List<AllowedAddressPairs> deletedAaps = AclServiceUtils
                 .getUpdatedAllowedAddressPairs(portBefore.getAllowedAddressPairs(), portAfter.getAllowedAddressPairs());
-        if (deletedAaps != null && !deletedAaps.isEmpty()) {
+        if (!deletedAaps.isEmpty()) {
             programAclWithAllowedAddress(deleteFlowEntries, portBefore, deletedAaps, Action.UPDATE,
                     NwConstants.DEL_FLOW);
-            updateRemoteAclFilterTable(deleteFlowEntries, portBefore, portBefore.getSecurityGroups(), deletedAaps,
-                    NwConstants.DEL_FLOW);
+            updateRemoteAclFilterTable(portBefore, portBefore.getSecurityGroups(), deletedAaps, NwConstants.DEL_FLOW);
         }
-        if (addedAaps != null && !addedAaps.isEmpty()) {
+        if (!addedAaps.isEmpty()) {
             programAclWithAllowedAddress(addFlowEntries, portAfter, addedAaps, Action.UPDATE, NwConstants.ADD_FLOW);
-            updateRemoteAclFilterTable(addFlowEntries, portAfter, portAfter.getSecurityGroups(), addedAaps,
-                    NwConstants.ADD_FLOW);
+            updateRemoteAclFilterTable(portAfter, portAfter.getSecurityGroups(), addedAaps, NwConstants.ADD_FLOW);
         }
         if (portAfter.getSubnetInfo() != null && portBefore.getSubnetInfo() == null) {
             programBroadcastRules(addFlowEntries, portAfter, Action.UPDATE, NwConstants.ADD_FLOW);
@@ -244,7 +272,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
             int addOrRemove) {
         int operationForAclRules = addOrRemove == NwConstants.DEL_FLOW ? NwConstants.MOD_FLOW : addOrRemove;
         programAclRules(flowEntries, port, aclList, operationForAclRules);
-        updateRemoteAclFilterTable(flowEntries, port, aclList, port.getAllowedAddressPairs(), addOrRemove);
+        updateRemoteAclFilterTable(port, aclList, port.getAllowedAddressPairs(), addOrRemove);
         programAclDispatcherTable(flowEntries, port, addOrRemove);
     }
 
@@ -279,7 +307,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
             List<InstructionInfo> instructions =
                     AclServiceOFFlowBuilder.getGotoInstructionInfo(getAclRuleBasedFilterTable());
             instructions.add(AclServiceUtils.getWriteMetadataForRemoteAclTag(remoteAclTag));
-            addFlowEntryToList(flowEntries, port.getDpId(), getAclFilterCumDispatcherTable(), flowId,
+            addFlowEntryToList(flowEntries, Uint64.valueOf(port.getDpId()), getAclFilterCumDispatcherTable(), flowId,
                     AclConstants.ACE_GOTO_NEXT_REMOTE_ACL_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches,
                     instructions, addOrRemove);
 
@@ -297,7 +325,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
         List<InstructionInfo> instructions =
                 AclServiceOFFlowBuilder.getGotoInstructionInfo(getAclRuleBasedFilterTable());
         instructions.add(AclServiceUtils.getWriteMetadataForRemoteAclTag(firstRemoteAclTag));
-        addFlowEntryToList(flowEntries, port.getDpId(), getAclFilterCumDispatcherTable(), flowId,
+        addFlowEntryToList(flowEntries, Uint64.valueOf(port.getDpId()), getAclFilterCumDispatcherTable(), flowId,
                 AclConstants.ACE_FIRST_REMOTE_ACL_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions,
                 addOrRemove);
     }
@@ -311,18 +339,14 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
                 + lastRemoteAclTag;
 
         List<InstructionInfo> instructions = AclServiceOFFlowBuilder.getDropInstructionInfo();
-        addFlowEntryToList(flowEntries, port.getDpId(), getAclFilterCumDispatcherTable(), flowId,
+        addFlowEntryToList(flowEntries, Uint64.valueOf(port.getDpId()), getAclFilterCumDispatcherTable(), flowId,
                 AclConstants.ACE_LAST_REMOTE_ACL_PRIORITY, 0, 0, AclServiceUtils.getDropFlowCookie(port.getLPortTag()),
                 matches, instructions, addOrRemove);
     }
 
-    private void programAcl(List<FlowEntity> flowEntries, AclInterface port, Action action, int addOrRemove) {
-        programAclWithAllowedAddress(flowEntries, port, port.getAllowedAddressPairs(), action, addOrRemove);
-    }
-
     private void programAclWithAllowedAddress(List<FlowEntity> flowEntries, AclInterface port,
             List<AllowedAddressPairs> allowedAddresses, Action action, int addOrRemove) {
-        BigInteger dpId = port.getDpId();
+        Uint64 dpId = Uint64.valueOf(port.getDpId());
         int lportTag = port.getLPortTag();
         LOG.debug("Applying ACL Allowed Address on DpId {}, lportTag {}, Action {}", dpId, lportTag, action);
         String portId = port.getInterfaceId();
@@ -358,11 +382,8 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
                 LOG.warn("The ACL {} not found in cache", aclUuid.getValue());
                 continue;
             }
-            AccessListEntries accessListEntries = acl.getAccessListEntries();
-            if (accessListEntries != null && accessListEntries.getAce() != null) {
-                for (Ace ace: accessListEntries.getAce()) {
-                    programAceRule(flowEntries, port, aclUuid.getValue(), ace, addOrRemove);
-                }
+            for (Ace ace : AclServiceUtils.aceList(acl)) {
+                programAceRule(flowEntries, port, aclUuid.getValue(), ace, addOrRemove);
             }
         }
         return true;
@@ -380,6 +401,11 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
     protected void programAceRule(List<FlowEntity> flowEntries, AclInterface port, String aclName, Ace ace,
             int addOrRemove) {
         SecurityRuleAttr aceAttr = AclServiceUtils.getAccessListAttributes(ace);
+        if (aceAttr == null) {
+            LOG.error("Ace {} of Acl {} is either null or not having SecurityRuleAttr",
+                    ace == null ? null : ace.getRuleName(), aclName);
+            return;
+        }
         if (addOrRemove == NwConstants.ADD_FLOW && aceAttr.isDeleted()) {
             LOG.trace("Ignoring {} rule which is already deleted", ace.getRuleName());
             return;
@@ -424,8 +450,8 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
                     + ace.key().getRuleName();
 
             int operation = addOrRemove == NwConstants.MOD_FLOW ? NwConstants.DEL_FLOW : addOrRemove;
-            addFlowEntryToList(flowEntries, port.getDpId(), getAclFilterCumDispatcherTable(), flowId, flowPriority,
-                    0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions, operation);
+            addFlowEntryToList(flowEntries, Uint64.valueOf(port.getDpId()), getAclFilterCumDispatcherTable(),
+                    flowId, flowPriority, 0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions, operation);
 
             if (addOrRemove != NwConstants.DEL_FLOW) {
                 programAclForExistingTrafficTable(port, ace, addOrRemove, flowName, matches, flowPriority);
@@ -456,8 +482,8 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
                     + ace.key().getRuleName();
 
             int operation = addOrRemove == NwConstants.MOD_FLOW ? NwConstants.DEL_FLOW : addOrRemove;
-            addFlowEntryToList(flowEntries, port.getDpId(), getAclRuleBasedFilterTable(), flowId, flowPriority, 0, 0,
-                    AclConstants.COOKIE_ACL_BASE, matches, instructions, operation);
+            addFlowEntryToList(flowEntries, Uint64.valueOf(port.getDpId()), getAclRuleBasedFilterTable(), flowId,
+                    flowPriority, 0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions, operation);
 
             if (addOrRemove != NwConstants.DEL_FLOW) {
                 programAclForExistingTrafficTable(port, ace, addOrRemove, flowName, matches, flowPriority);
@@ -467,6 +493,11 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
 
     private void programAclForExistingTrafficTable(AclInterface port, Ace ace, int addOrRemove, String flowName,
             List<MatchInfoBase> matches, Integer priority) {
+        if (port == null || port.getElanId() == null) {
+            LOG.debug("Acl interface or elan id is null, No need to update traffic flow table.");
+            return;
+        }
+
         AceIp acl = (AceIp) ace.getMatches().getAceType();
         final String newFlowName = flowName + this.directionString + "_" + port.getDpId() + "_" + port.getLPortTag()
                 + "_" + (acl.getAceIpVersion() instanceof AceIpv4 ? "_IPv4" : "_IPv6") + "_FlowAfterRuleDeleted";
@@ -482,8 +513,8 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
         // Reversing the flow add/delete operation for this table.
         List<FlowEntity> flowEntries = new ArrayList<>();
         int operation = addOrRemove == NwConstants.ADD_FLOW ? NwConstants.DEL_FLOW : NwConstants.ADD_FLOW;
-        addFlowEntryToList(flowEntries, port.getDpId(), getAclForExistingTrafficTable(), newFlowName, priority, 0,
-                AclServiceUtils.getHardTimoutForApplyStatefulChangeOnExistingTraffic(ace, aclServiceUtils),
+        addFlowEntryToList(flowEntries, Uint64.valueOf(port.getDpId()), getAclForExistingTrafficTable(), newFlowName,
+                priority, 0, AclServiceUtils.getHardTimoutForApplyStatefulChangeOnExistingTraffic(ace, aclServiceUtils),
                 AclConstants.COOKIE_ACL_BASE, newMatches, instructions, operation);
         programFlows(AclConstants.ACL_JOB_KEY_PREFIX + port.getInterfaceId(), flowEntries, operation);
     }
@@ -495,8 +526,13 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
             return false;
         }
         List<FlowEntity> flowEntries = new ArrayList<>();
-        programAcl(flowEntries, port, Action.REMOVE, NwConstants.DEL_FLOW);
-        updateRemoteAclFilterTable(flowEntries, port, NwConstants.DEL_FLOW);
+        if (port.getInterfaceType() == InterfaceType.DhcpService) {
+            programDhcpService(flowEntries, port, Action.REMOVE, NwConstants.DEL_FLOW);
+        } else {
+            programAclWithAllowedAddress(flowEntries, port, port.getAllowedAddressPairs(),
+                    Action.REMOVE, NwConstants.DEL_FLOW);
+            updateRemoteAclFilterTable(port, NwConstants.DEL_FLOW);
+        }
         programFlows(AclConstants.ACL_JOB_KEY_PREFIX + port.getInterfaceId(), flowEntries, NwConstants.DEL_FLOW);
         return true;
     }
@@ -542,6 +578,28 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
      */
     protected abstract void unbindService(AclInterface aclInterface);
 
+    /**
+     * Programs DHCP Service flows.
+     *
+     * @param flowEntries the flow entries
+     * @param port the acl interface
+     * @param action add/modify/remove action
+     * @param addOrRemove addorRemove
+     */
+    protected abstract void programDhcpService(List<FlowEntity> flowEntries, AclInterface port,
+            Action action, int addOrRemove);
+
+    /**
+     * Programs DHCP service flows.
+     *
+     * @param flowEntries the flow entries
+     * @param port the acl interface
+     * @param allowedAddresses the allowed addresses
+     * @param addOrRemove addorRemove
+     */
+    protected abstract void processDhcpServiceUpdate(List<FlowEntity> flowEntries, AclInterface port,
+            List<AllowedAddressPairs> allowedAddresses, int addOrRemove);
+
     /**
      * Programs the anti-spoofing rules.
      *
@@ -602,8 +660,8 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
      * @param addOrRemove
      *            add or remove the entries.
      */
-    protected void addFlowEntryToList(List<FlowEntity> flowEntries, BigInteger dpId, short tableId, String flowId,
-            int priority, int idleTimeOut, int hardTimeOut, BigInteger cookie, List<? extends MatchInfoBase> matches,
+    protected void addFlowEntryToList(List<FlowEntity> flowEntries, Uint64 dpId, short tableId, String flowId,
+            int priority, int idleTimeOut, int hardTimeOut, Uint64 cookie, List<? extends MatchInfoBase> matches,
             List<InstructionInfo> instructions, int addOrRemove) {
         List<InstructionInfo> instructionInfos = null;
         if (addOrRemove == NwConstants.ADD_FLOW) {
@@ -676,22 +734,33 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
         List<FlowEntity> addFlowEntries = new ArrayList<>();
         List<FlowEntity> deleteFlowEntries = new ArrayList<>();
         if (!remoteAclsAdded.isEmpty() || !remoteAclsDeleted.isEmpty()) {
-            // delete and add flows in ACL dispatcher table for all applicable
-            // ports
+            // delete and add flows in ACL dispatcher table for all applicable ports
             for (AclInterface portBefore : portsBefore) {
-                programAclDispatcherTable(deleteFlowEntries, portBefore, NwConstants.DEL_FLOW);
+                if (portBefore.getDpId() != null) {
+                    programAclDispatcherTable(deleteFlowEntries, portBefore, NwConstants.DEL_FLOW);
+                } else {
+                    LOG.debug("Skip ACL dispatcher table update as DP ID for interface {} is not present.",
+                            portBefore.getInterfaceId());
+                }
             }
             for (AclInterface port : interfaceList) {
                 programAclDispatcherTable(addFlowEntries, port, NwConstants.ADD_FLOW);
             }
         }
-        Set<BigInteger> dpns = interfaceList.stream().map(AclInterface::getDpId).collect(Collectors.toSet());
+        Set<BigInteger> dpns = interfaceList.stream().filter(port -> {
+            if (port.getDpId() == null) {
+                LOG.debug("Skip remote ACL table update as DP ID for interface {} is not present.",
+                        port.getInterfaceId());
+                return false;
+            }
+            return true;
+        }).map(AclInterface::getDpId).collect(Collectors.toSet());
 
         programRemoteAclTable(deleteFlowEntries, aclName, remoteAclsDeleted, dpns, NwConstants.DEL_FLOW);
         programRemoteAclTable(addFlowEntries, aclName, remoteAclsAdded, dpns, NwConstants.ADD_FLOW);
 
-        programFlows(aclName, deleteFlowEntries, NwConstants.DEL_FLOW);
-        programFlows(aclName, addFlowEntries, NwConstants.ADD_FLOW);
+        programFlows(AclConstants.ACL_JOB_KEY_PREFIX + aclName, deleteFlowEntries, NwConstants.DEL_FLOW);
+        programFlows(AclConstants.ACL_JOB_KEY_PREFIX + aclName, addFlowEntries, NwConstants.ADD_FLOW);
     }
 
     private void programRemoteAclTable(List<FlowEntity> flowEntries, String aclName, Set<Uuid> remoteAclIds,
@@ -709,7 +778,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
             if (addOrRemove == NwConstants.ADD_FLOW) {
                 for (BigInteger dpn : dpns) {
                     for (AllowedAddressPairs aap : aaps) {
-                        programRemoteAclTableFlow(flowEntries, dpn, aclTag, aap, addOrRemove);
+                        programRemoteAclTableFlow(flowEntries, Uint64.valueOf(dpn), aclTag, aap, addOrRemove);
                     }
                 }
             } else if (addOrRemove == NwConstants.DEL_FLOW) {
@@ -730,20 +799,19 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
 
                 for (BigInteger dpn : dpnsToOperate) {
                     for (AllowedAddressPairs aap : aaps) {
-                        programRemoteAclTableFlow(flowEntries, dpn, aclTag, aap, addOrRemove);
+                        programRemoteAclTableFlow(flowEntries, Uint64.valueOf(dpn), aclTag, aap, addOrRemove);
                     }
                 }
             }
         }
     }
 
-    private void updateRemoteAclFilterTable(List<FlowEntity> flowEntries, AclInterface port, int addOrRemove) {
-        updateRemoteAclFilterTable(flowEntries, port, port.getSecurityGroups(), port.getAllowedAddressPairs(),
-                addOrRemove);
+    private void updateRemoteAclFilterTable(AclInterface port, int addOrRemove) {
+        updateRemoteAclFilterTable(port, port.getSecurityGroups(), port.getAllowedAddressPairs(), addOrRemove);
     }
 
-    private void updateRemoteAclFilterTable(List<FlowEntity> flowEntries, AclInterface port, List<Uuid> aclList,
-            List<AllowedAddressPairs> aaps, int addOrRemove) {
+    private void updateRemoteAclFilterTable(AclInterface port, List<Uuid> aclList, List<AllowedAddressPairs> aaps,
+            int addOrRemove) {
         if (aclList == null) {
             LOG.debug("Port {} without SGs", port.getInterfaceId());
             return;
@@ -751,32 +819,42 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
         String portId = port.getInterfaceId();
         LOG.trace("updateRemoteAclFilterTable for portId={}, aclList={}, aaps={}, addOrRemove={}", portId, aclList,
                 aaps, addOrRemove);
+
+        ConcurrentMap<Uuid, Map<String, Set<AclInterface>>> mapOfAclWithInterfacesList =
+                aclDataUtil.getRemoteAclInterfaces(aclList, this.direction);
         for (Uuid aclId : aclList) {
+            Map<String, Set<AclInterface>> mapAclWithPortSet = mapOfAclWithInterfacesList.get(aclId);
             if (aclDataUtil.getRemoteAcl(aclId, this.direction) != null) {
                 Integer aclTag = aclServiceUtils.getAclTag(aclId);
-                if (addOrRemove == NwConstants.ADD_FLOW) {
-                    syncRemoteAclTable(flowEntries, portId, aclId, aclTag, aaps, addOrRemove);
-                }
-                else if (addOrRemove == NwConstants.DEL_FLOW) {
-                    jobCoordinator.enqueueJob(aclId.getValue(), () -> {
-                        List<FlowEntity> remoteTableFlowEntries = new ArrayList<>();
-                        syncRemoteAclTable(remoteTableFlowEntries, portId, aclId, aclTag, aaps, addOrRemove);
-                        programFlows(AclConstants.ACL_JOB_KEY_PREFIX + aclId.getValue(),
-                                remoteTableFlowEntries, NwConstants.DEL_FLOW);
-                        return Collections.emptyList();
-                    });
-                }
+                jobCoordinator.enqueueJob(aclId.getValue().intern(), () -> {
+                    List<FlowEntity> flowEntries = new ArrayList<>();
+                    syncRemoteAclTable(flowEntries, portId, aclId, aclTag, aaps, mapAclWithPortSet, addOrRemove);
+                    programFlows(AclConstants.ACL_JOB_KEY_PREFIX + aclId.getValue(), flowEntries, addOrRemove);
+                    return Collections.emptyList();
+                });
             }
         }
         Set<Uuid> remoteAclIds = aclServiceUtils.getRemoteAclIdsByDirection(aclList, direction);
         for (Uuid remoteAclId : remoteAclIds) {
-            syncRemoteAclTableFromOtherDpns(flowEntries, port, remoteAclId, addOrRemove);
+            List<Uuid> aclIds = new ArrayList<Uuid>(port.getSecurityGroups());
+            aclIds.removeAll(aclList);
+            if (addOrRemove == NwConstants.DEL_FLOW && aclServiceUtils.doesRemoteAclIdExistsInAcls(aclIds, remoteAclId,
+                    this.direction)) {
+                LOG.debug("Skipping delete as remoteAclId {} is used with other ACE configured with port {}",
+                        remoteAclId, portId);
+                return;
+            }
+            jobCoordinator.enqueueJob(remoteAclId.getValue().intern(), () -> {
+                List<FlowEntity> flowEntries = new ArrayList<>();
+                syncRemoteAclTableFromOtherDpns(flowEntries, port, remoteAclId, addOrRemove);
+                programFlows(AclConstants.ACL_JOB_KEY_PREFIX + remoteAclId.getValue(), flowEntries, addOrRemove);
+                return Collections.emptyList();
+            });
         }
     }
 
     private void syncRemoteAclTable(List<FlowEntity> flowEntries, String portId, Uuid acl, Integer aclTag,
-            List<AllowedAddressPairs> aaps, int addOrRemove) {
-        Map<String, Set<AclInterface>> mapAclWithPortSet = aclDataUtil.getRemoteAclInterfaces(acl, this.direction);
+            List<AllowedAddressPairs> aaps, Map<String, Set<AclInterface>> mapAclWithPortSet, int addOrRemove) {
         Set<BigInteger> dpns = collectDpns(mapAclWithPortSet);
         for (AllowedAddressPairs aap : aaps) {
             if (!AclServiceUtils.isNotIpAllNetwork(aap)) {
@@ -789,7 +867,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
                 continue;
             }
             for (BigInteger dpId : dpns) {
-                programRemoteAclTableFlow(flowEntries, dpId, aclTag, aap, addOrRemove);
+                programRemoteAclTableFlow(flowEntries, Uint64.valueOf(dpId), aclTag, aap, addOrRemove);
             }
         }
     }
@@ -806,7 +884,8 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
                 }
                 for (AllowedAddressPairs aap : aclInterface.getAllowedAddressPairs()) {
                     if (AclServiceUtils.isNotIpAllNetwork(aap)) {
-                        programRemoteAclTableFlow(flowEntries, port.getDpId(), aclTag, aap, addOrRemove);
+                        programRemoteAclTableFlow(flowEntries, Uint64.valueOf(port.getDpId()),
+                            aclTag, aap, addOrRemove);
                     }
                 }
             }
@@ -833,7 +912,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
         return true;
     }
 
-    protected abstract void programRemoteAclTableFlow(List<FlowEntity> flowEntries, BigInteger dpId, Integer aclTag,
+    protected abstract void programRemoteAclTableFlow(List<FlowEntity> flowEntries, Uint64 dpId, Integer aclTag,
             AllowedAddressPairs aap, int addOrRemove);
 
     protected Set<BigInteger> collectDpns(@Nullable Map<String, Set<AclInterface>> mapAclWithPortSet) {
@@ -863,7 +942,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
      * @param action the action
      * @param write whether to add or remove the flow.
      */
-    protected void programAclPortSpecificFixedRules(List<FlowEntity> flowEntries, BigInteger dpId,
+    protected void programAclPortSpecificFixedRules(List<FlowEntity> flowEntries, Uint64 dpId,
             List<AllowedAddressPairs> allowedAddresses, int lportTag, String portId, Action action, int write) {
         programGotoClassifierTableRules(flowEntries, dpId, allowedAddresses, lportTag, write);
         if (action == Action.ADD || action == Action.REMOVE) {
@@ -875,7 +954,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
                 action, write);
     }
 
-    protected abstract void programGotoClassifierTableRules(List<FlowEntity> flowEntries, BigInteger dpId,
+    protected abstract void programGotoClassifierTableRules(List<FlowEntity> flowEntries, Uint64 dpId,
             List<AllowedAddressPairs> aaps, int lportTag, int addOrRemove);
 
     /**
@@ -888,7 +967,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
      * @param portId the portId
      * @param addOrRemove whether to add or remove the flow
      */
-    protected void programConntrackRecircRules(List<FlowEntity> flowEntries, BigInteger dpId,
+    protected void programConntrackRecircRules(List<FlowEntity> flowEntries, Uint64 dpId,
             List<AllowedAddressPairs> aaps, int lportTag, String portId, int addOrRemove) {
         if (AclServiceUtils.doesIpv4AddressExists(aaps)) {
             programConntrackRecircRule(flowEntries, dpId, lportTag, portId, MatchEthernetType.IPV4, addOrRemove);
@@ -898,7 +977,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
         }
     }
 
-    protected void programConntrackRecircRule(List<FlowEntity> flowEntries, BigInteger dpId, int lportTag,
+    protected void programConntrackRecircRule(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
             String portId, MatchEthernetType matchEtherType, int addOrRemove) {
         List<MatchInfoBase> matches = new ArrayList<>();
         matches.add(matchEtherType);
@@ -918,7 +997,8 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
         }
 
         String flowName =
-                this.directionString + "_Fixed_Conntrk_" + dpId + "_" + lportTag + "_" + matchEtherType + "_Recirc";
+                this.directionString + "_Fixed_Conntrk_" + dpId + "_"
+                    + lportTag + "_" + matchEtherType + "_Recirc";
         addFlowEntryToList(flowEntries, dpId, getAclConntrackSenderTable(), flowName,
                 AclConstants.ACL_DEFAULT_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions,
                 addOrRemove);
@@ -932,7 +1012,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
      * @param lportTag the lport tag
      * @param addOrRemove whether to add or remove the flow
      */
-    protected void programPortSpecificDropRules(List<FlowEntity> flowEntries, BigInteger dpId, int lportTag,
+    protected void programPortSpecificDropRules(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
             int addOrRemove) {
         LOG.debug("Programming Drop Rules: DpId={}, lportTag={}, addOrRemove={}", dpId, lportTag, addOrRemove);
         programConntrackInvalidDropRule(flowEntries, dpId, lportTag, addOrRemove);
@@ -947,13 +1027,14 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
      * @param lportTag the lport tag
      * @param addOrRemove whether to add or remove the flow
      */
-    protected void programConntrackInvalidDropRule(List<FlowEntity> flowEntries, BigInteger dpId, int lportTag,
+    protected void programConntrackInvalidDropRule(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
             int addOrRemove) {
         List<MatchInfoBase> matches = AclServiceOFFlowBuilder.addLPortTagMatches(lportTag,
                 AclConstants.TRACKED_INV_CT_STATE, AclConstants.TRACKED_INV_CT_STATE_MASK, serviceMode);
         List<InstructionInfo> instructions = AclServiceOFFlowBuilder.getDropInstructionInfo();
 
-        String flowId = this.directionString + "_Fixed_Conntrk_Drop" + dpId + "_" + lportTag + "_Tracked_Invalid";
+        String flowId = this.directionString + "_Fixed_Conntrk_Drop" + dpId.toString()
+                            + "_" + lportTag + "_Tracked_Invalid";
         addFlowEntryToList(flowEntries, dpId, getAclFilterCumDispatcherTable(), flowId,
                 AclConstants.CT_STATE_TRACKED_INVALID_PRIORITY, 0, 0, AclServiceUtils.getDropFlowCookie(lportTag),
                 matches, instructions, addOrRemove);
@@ -967,13 +1048,13 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
      * @param lportTag the lport tag
      * @param addOrRemove the add or remove
      */
-    protected void programAclRuleMissDropRule(List<FlowEntity> flowEntries, BigInteger dpId, int lportTag,
+    protected void programAclRuleMissDropRule(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
             int addOrRemove) {
         List<MatchInfoBase> matches = new ArrayList<>();
         matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
         List<InstructionInfo> instructions = AclServiceOFFlowBuilder.getDropInstructionInfo();
 
-        String flowId = this.directionString + "_Fixed_Acl_Rule_Miss_Drop_" + dpId + "_" + lportTag;
+        String flowId = this.directionString + "_Fixed_Acl_Rule_Miss_Drop_" + dpId.toString() + "_" + lportTag;
         addFlowEntryToList(flowEntries, dpId, getAclFilterCumDispatcherTable(), flowId,
                 AclConstants.ACL_PORT_SPECIFIC_DROP_PRIORITY, 0, 0, AclServiceUtils.getDropFlowCookie(lportTag),
                 matches, instructions, addOrRemove);
@@ -988,7 +1069,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
      * @param portId the port id
      * @param addOrRemove the add or remove
      */
-    protected void programAclCommitRules(List<FlowEntity> flowEntries, BigInteger dpId, int lportTag, String portId,
+    protected void programAclCommitRules(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag, String portId,
             int addOrRemove) {
         programAclCommitRuleForConntrack(flowEntries, dpId, lportTag, portId, MatchEthernetType.IPV4, addOrRemove);
         programAclCommitRuleForConntrack(flowEntries, dpId, lportTag, portId, MatchEthernetType.IPV6, addOrRemove);
@@ -1005,7 +1086,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
      * @param matchEtherType the match ether type
      * @param addOrRemove the add or remove
      */
-    protected void programAclCommitRuleForConntrack(List<FlowEntity> flowEntries, BigInteger dpId, int lportTag,
+    protected void programAclCommitRuleForConntrack(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
             String portId, MatchEthernetType matchEtherType, int addOrRemove) {
         List<MatchInfoBase> matches = new ArrayList<>();
         matches.add(matchEtherType);
@@ -1027,7 +1108,8 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
         }
         List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions(actionsInfos);
 
-        String flowName = directionString + "_Acl_Commit_Conntrack_" + dpId + "_" + lportTag + "_" + matchEtherType;
+        String flowName = directionString + "_Acl_Commit_Conntrack_" + dpId.toString()
+                            + "_" + lportTag + "_" + matchEtherType;
         // Flow for conntrack traffic to commit and resubmit to dispatcher
         addFlowEntryToList(flowEntries, dpId, getAclCommitterTable(), flowName, AclConstants.ACL_DEFAULT_PRIORITY,
                 0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
@@ -1041,7 +1123,7 @@ public abstract class AbstractAclServiceImpl implements AclServiceListener {
      * @param lportTag the lport tag
      * @param addOrRemove the add or remove
      */
-    protected void programAclCommitRuleForNonConntrack(List<FlowEntity> flowEntries, BigInteger dpId, int lportTag,
+    protected void programAclCommitRuleForNonConntrack(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
             int addOrRemove) {
         List<MatchInfoBase> matches = new ArrayList<>();
         matches.addAll(AclServiceUtils.buildMatchesForLPortTagAndConntrackClassifierType(lportTag,