*/
package org.opendaylight.netvirt.aclservice;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
import com.google.common.collect.Lists;
import java.math.BigInteger;
import java.util.ArrayList;
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;
import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
import org.opendaylight.genius.mdsalutil.NwConstants;
import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack;
import org.opendaylight.genius.mdsalutil.actions.ActionNxConntrack.NxCtAction;
+import org.opendaylight.genius.mdsalutil.actions.ActionNxCtClear;
import org.opendaylight.genius.mdsalutil.actions.ActionNxResubmit;
import org.opendaylight.genius.mdsalutil.instructions.InstructionApplyActions;
import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
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;
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.port.subnets.port.subnet.SubnetInfo;
+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;
private static final Logger LOG = LoggerFactory.getLogger(AbstractAclServiceImpl.class);
protected final IMdsalApiManager mdsalManager;
- protected final DataBroker dataBroker;
protected final ManagedNewTransactionRunner txRunner;
protected final Class<? extends ServiceModeBase> serviceMode;
protected final AclDataUtil aclDataUtil;
public AbstractAclServiceImpl(Class<? extends ServiceModeBase> serviceMode, DataBroker dataBroker,
IMdsalApiManager mdsalManager, AclDataUtil aclDataUtil, AclServiceUtils aclServiceUtils,
JobCoordinator jobCoordinator, AclInterfaceCache aclInterfaceCache) {
- this.dataBroker = dataBroker;
this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
this.mdsalManager = mdsalManager;
this.serviceMode = serviceMode;
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);
- programAcl(port, Action.ADD, NwConstants.ADD_FLOW);
- updateRemoteAclFilterTable(port, NwConstants.ADD_FLOW);
+ List<FlowEntity> flowEntries = new ArrayList<>();
+ 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);
- if (port.getDpId() != null) {
- updateRemoteAclFilterTable(port, NwConstants.ADD_FLOW);
- }
return true;
}
}
if (port.getDpId() != null) {
unbindService(port);
- updateRemoteAclFilterTable(port, NwConstants.DEL_FLOW);
}
return true;
}
// 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<>();
List<AllowedAddressPairs> addedAaps = AclServiceUtils
.getUpdatedAllowedAddressPairs(portAfter.getAllowedAddressPairs(), portBefore.getAllowedAddressPairs());
List<AllowedAddressPairs> deletedAaps = AclServiceUtils
.getUpdatedAllowedAddressPairs(portBefore.getAllowedAddressPairs(), portAfter.getAllowedAddressPairs());
- if (deletedAaps != null && !deletedAaps.isEmpty()) {
- programAclWithAllowedAddress(portBefore, deletedAaps, Action.UPDATE, NwConstants.DEL_FLOW);
+ if (!deletedAaps.isEmpty()) {
+ programAclWithAllowedAddress(deleteFlowEntries, portBefore, deletedAaps, Action.UPDATE,
+ NwConstants.DEL_FLOW);
updateRemoteAclFilterTable(portBefore, portBefore.getSecurityGroups(), deletedAaps, NwConstants.DEL_FLOW);
}
- if (addedAaps != null && !addedAaps.isEmpty()) {
- programAclWithAllowedAddress(portAfter, addedAaps, Action.UPDATE, NwConstants.ADD_FLOW);
+ if (!addedAaps.isEmpty()) {
+ programAclWithAllowedAddress(addFlowEntries, portAfter, addedAaps, Action.UPDATE, NwConstants.ADD_FLOW);
updateRemoteAclFilterTable(portAfter, portAfter.getSecurityGroups(), addedAaps, NwConstants.ADD_FLOW);
}
if (portAfter.getSubnetInfo() != null && portBefore.getSubnetInfo() == null) {
- programBroadcastRules(portAfter, NwConstants.ADD_FLOW);
+ programBroadcastRules(addFlowEntries, portAfter, Action.UPDATE, NwConstants.ADD_FLOW);
}
- handleSubnetChange(portBefore, portAfter);
+ handleSubnetChange(portBefore, portAfter, addFlowEntries, deleteFlowEntries);
List<Uuid> addedAcls = AclServiceUtils.getUpdatedAclList(portAfter.getSecurityGroups(),
portBefore.getSecurityGroups());
List<Uuid> deletedAcls = AclServiceUtils.getUpdatedAclList(portBefore.getSecurityGroups(),
portAfter.getSecurityGroups());
- if (deletedAcls.isEmpty() && addedAcls.isEmpty()) {
- LOG.trace("No change w.r.t ACL list for port={}", portAfter.getInterfaceId());
- return;
+ if (!deletedAcls.isEmpty() || !addedAcls.isEmpty()) {
+ handleAclChange(deleteFlowEntries, portBefore, deletedAcls, NwConstants.DEL_FLOW);
+ handleAclChange(addFlowEntries, portAfter, addedAcls, NwConstants.ADD_FLOW);
}
- handleAclChange(portBefore, deletedAcls, NwConstants.DEL_FLOW);
- handleAclChange(portAfter, addedAcls, 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 handleSubnetChange(AclInterface portBefore, AclInterface portAfter) {
+ private void handleSubnetChange(AclInterface portBefore, AclInterface portAfter,
+ List<FlowEntity> addFlowEntries, List<FlowEntity> deleteFlowEntries) {
List<SubnetInfo> deletedSubnets =
AclServiceUtils.getSubnetDiff(portBefore.getSubnetInfo(), portAfter.getSubnetInfo());
List<SubnetInfo> addedSubnets =
AclServiceUtils.getSubnetDiff(portAfter.getSubnetInfo(), portBefore.getSubnetInfo());
if (deletedSubnets != null && !deletedSubnets.isEmpty()) {
- programIcmpv6RARule(portAfter, deletedSubnets, NwConstants.DEL_FLOW);
+ programIcmpv6RARule(deleteFlowEntries, portAfter, deletedSubnets, NwConstants.DEL_FLOW);
+ programSubnetBroadcastRules(deleteFlowEntries, portAfter, deletedSubnets, NwConstants.DEL_FLOW);
}
if (addedSubnets != null && !addedSubnets.isEmpty()) {
- programIcmpv6RARule(portAfter, addedSubnets, NwConstants.ADD_FLOW);
+ programIcmpv6RARule(addFlowEntries, portAfter, addedSubnets, NwConstants.ADD_FLOW);
+ programSubnetBroadcastRules(addFlowEntries, portAfter, addedSubnets, NwConstants.ADD_FLOW);
}
}
- private void handleAclChange(AclInterface port, List<Uuid> aclList, int addOrRemove) {
- int operationForAclRules = (addOrRemove == NwConstants.DEL_FLOW) ? NwConstants.MOD_FLOW : addOrRemove;
- programAclRules(port, aclList, operationForAclRules);
+ private void handleAclChange(List<FlowEntity> flowEntries, AclInterface port, List<Uuid> aclList,
+ int addOrRemove) {
+ int operationForAclRules = addOrRemove == NwConstants.DEL_FLOW ? NwConstants.MOD_FLOW : addOrRemove;
+ programAclRules(flowEntries, port, aclList, operationForAclRules);
updateRemoteAclFilterTable(port, aclList, port.getAllowedAddressPairs(), addOrRemove);
- programAclDispatcherTable(port, addOrRemove);
+ programAclDispatcherTable(flowEntries, port, addOrRemove);
}
protected SortedSet<Integer> getRemoteAclTags(AclInterface port) {
: port.getEgressRemoteAclTags();
}
- protected void programAclDispatcherTable(AclInterface port, int addOrRemove) {
+ protected void programAclDispatcherTable(List<FlowEntity> flowEntries, AclInterface port, int addOrRemove) {
SortedSet<Integer> remoteAclTags = getRemoteAclTags(port);
if (remoteAclTags.isEmpty()) {
LOG.debug("No {} rules with remote group id for port={}", this.directionString, port.getInterfaceId());
Integer firstRemoteAclTag = remoteAclTags.first();
Integer lastRemoteAclTag = remoteAclTags.last();
- programFirstRemoteAclEntryInDispatcherTable(port, firstRemoteAclTag, addOrRemove);
- programLastRemoteAclEntryInDispatcherTable(port, lastRemoteAclTag, addOrRemove);
+ programFirstRemoteAclEntryInDispatcherTable(flowEntries, port, firstRemoteAclTag, addOrRemove);
+ programLastRemoteAclEntryInDispatcherTable(flowEntries, port, lastRemoteAclTag, addOrRemove);
Integer previousRemoteAclTag = firstRemoteAclTag;
for (Integer remoteAclTag : remoteAclTags) {
List<InstructionInfo> instructions =
AclServiceOFFlowBuilder.getGotoInstructionInfo(getAclRuleBasedFilterTable());
instructions.add(AclServiceUtils.getWriteMetadataForRemoteAclTag(remoteAclTag));
- syncFlow(port.getDpId(), getAclFilterCumDispatcherTable(), flowId,
- AclConstants.ACE_GOTO_NEXT_REMOTE_ACL_PRIORITY, "ACL", 0, 0, AclConstants.COOKIE_ACL_BASE, matches,
+ addFlowEntryToList(flowEntries, Uint64.valueOf(port.getDpId()), getAclFilterCumDispatcherTable(), flowId,
+ AclConstants.ACE_GOTO_NEXT_REMOTE_ACL_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches,
instructions, addOrRemove);
previousRemoteAclTag = remoteAclTag;
}
}
- protected void programFirstRemoteAclEntryInDispatcherTable(AclInterface port, Integer firstRemoteAclTag,
- int addOrRemove) {
+ protected void programFirstRemoteAclEntryInDispatcherTable(List<FlowEntity> flowEntries, AclInterface port,
+ Integer firstRemoteAclTag, int addOrRemove) {
List<MatchInfoBase> matches = new ArrayList<>();
matches.add(AclServiceUtils.buildLPortTagMatch(port.getLPortTag(), serviceMode));
String flowId = this.directionString + "_ACL_Dispatcher_First_" + port.getDpId() + "_" + port.getLPortTag()
List<InstructionInfo> instructions =
AclServiceOFFlowBuilder.getGotoInstructionInfo(getAclRuleBasedFilterTable());
instructions.add(AclServiceUtils.getWriteMetadataForRemoteAclTag(firstRemoteAclTag));
- syncFlow(port.getDpId(), getAclFilterCumDispatcherTable(), flowId, AclConstants.ACE_FIRST_REMOTE_ACL_PRIORITY,
- "ACL", 0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
+ addFlowEntryToList(flowEntries, Uint64.valueOf(port.getDpId()), getAclFilterCumDispatcherTable(), flowId,
+ AclConstants.ACE_FIRST_REMOTE_ACL_PRIORITY, 0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions,
+ addOrRemove);
}
- protected void programLastRemoteAclEntryInDispatcherTable(AclInterface port, Integer lastRemoteAclTag,
- int addOrRemove) {
+ protected void programLastRemoteAclEntryInDispatcherTable(List<FlowEntity> flowEntries, AclInterface port,
+ Integer lastRemoteAclTag, int addOrRemove) {
List<MatchInfoBase> matches = new ArrayList<>();
matches.addAll(AclServiceUtils.buildMatchesForLPortTagAndRemoteAclTag(port.getLPortTag(), lastRemoteAclTag,
serviceMode));
+ lastRemoteAclTag;
List<InstructionInfo> instructions = AclServiceOFFlowBuilder.getDropInstructionInfo();
- syncFlow(port.getDpId(), getAclFilterCumDispatcherTable(), flowId, AclConstants.ACE_LAST_REMOTE_ACL_PRIORITY,
- "ACL", 0, 0, AclServiceUtils.getDropFlowCookie(port.getLPortTag()), matches, instructions, addOrRemove);
- }
-
- private void programAcl(AclInterface port, Action action, int addOrRemove) {
- programAclWithAllowedAddress(port, port.getAllowedAddressPairs(), action, addOrRemove);
+ 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 programAclWithAllowedAddress(AclInterface port, List<AllowedAddressPairs> allowedAddresses,
- Action action, int addOrRemove) {
- BigInteger dpId = port.getDpId();
+ private void programAclWithAllowedAddress(List<FlowEntity> flowEntries, AclInterface port,
+ List<AllowedAddressPairs> allowedAddresses, Action action, int addOrRemove) {
+ 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();
- programAntiSpoofingRules(port, allowedAddresses, action, addOrRemove);
- programAclPortSpecificFixedRules(dpId, allowedAddresses, lportTag, portId, action, addOrRemove);
+ programAntiSpoofingRules(flowEntries, port, allowedAddresses, action, addOrRemove);
+ programAclPortSpecificFixedRules(flowEntries, dpId, allowedAddresses, lportTag, portId, action, addOrRemove);
if (action == Action.ADD || action == Action.REMOVE) {
- programAclRules(port, port.getSecurityGroups(), addOrRemove);
- programAclDispatcherTable(port, addOrRemove);
+ programAclRules(flowEntries, port, port.getSecurityGroups(), addOrRemove);
+ programAclDispatcherTable(flowEntries, port, addOrRemove);
}
}
/**
* Programs the acl custom rules.
*
+ * @param flowEntries the flow entries
* @param port acl interface
* @param aclUuidList the list of acl uuid to be applied
* @param addOrRemove whether to delete or add flow
* @return program succeeded
*/
- protected boolean programAclRules(AclInterface port, List<Uuid> aclUuidList, int addOrRemove) {
+ protected boolean programAclRules(List<FlowEntity> flowEntries, AclInterface port, List<Uuid> aclUuidList,
+ int addOrRemove) {
BigInteger dpId = port.getDpId();
LOG.debug("Applying custom rules on DpId {}, lportTag {}", dpId, port.getLPortTag());
if (aclUuidList == null || dpId == null) {
LOG.warn("The ACL {} not found in cache", aclUuid.getValue());
continue;
}
- AccessListEntries accessListEntries = acl.getAccessListEntries();
- List<Ace> aceList = accessListEntries.getAce();
- for (Ace ace: aceList) {
- programAceRule(port, aclUuid.getValue(), ace, addOrRemove);
+ for (Ace ace : AclServiceUtils.aceList(acl)) {
+ programAceRule(flowEntries, port, aclUuid.getValue(), ace, addOrRemove);
}
}
return true;
/**
* Programs the ace specific rule.
*
+ * @param flowEntries flow entries
* @param port acl interface
* @param aclName the acl name
* @param ace rule to be program
* @param addOrRemove whether to delete or add flow
*/
- protected void programAceRule(AclInterface port, String aclName, Ace ace, int addOrRemove) {
- SecurityRuleAttr aceAttr = AclServiceUtils.getAccesssListAttributes(ace);
+ 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;
+ }
if (!isValidDirection(aceAttr.getDirection())) {
LOG.trace("Ignoring {} direction while processing for {} ACE Rule {}", aceAttr.getDirection(),
this.directionString, ace.getRuleName());
port.getInterfaceId());
Matches matches = ace.getMatches();
- Map<String, List<MatchInfoBase>> flowMap = null;
- if (matches.getAceType() instanceof AceIp) {
- flowMap = AclServiceOFFlowBuilder.programIpFlow(matches);
+ if (matches != null && matches.getAceType() instanceof AceIp) {
+ Map<String, List<MatchInfoBase>> flowMap = AclServiceOFFlowBuilder.programIpFlow(matches);
if (!AclServiceUtils.doesAceHaveRemoteGroupId(aceAttr)) {
// programming for ACE which doesn't have any remote group Id
- programForAceNotHavingRemoteAclId(port, aclName, ace, flowMap, addOrRemove);
+ programForAceNotHavingRemoteAclId(flowEntries, port, aclName, ace, flowMap, addOrRemove);
} else {
Uuid remoteAclId = aceAttr.getRemoteGroupId();
// programming for ACE which have remote group Id
- programAceSpecificFlows(port, aclName, ace, flowMap, remoteAclId, addOrRemove);
+ programAceSpecificFlows(flowEntries, port, aclName, ace, flowMap, remoteAclId, addOrRemove);
}
}
}
- protected void programForAceNotHavingRemoteAclId(AclInterface port, String aclName, Ace ace,
- Map<String, List<MatchInfoBase>> flowMap, int addOrRemove) {
+ protected void programForAceNotHavingRemoteAclId(List<FlowEntity> flowEntries, AclInterface port, String aclName,
+ Ace ace, @Nullable Map<String, List<MatchInfoBase>> flowMap, int addOrRemove) {
if (null == flowMap) {
return;
}
+ ace.key().getRuleName();
int operation = addOrRemove == NwConstants.MOD_FLOW ? NwConstants.DEL_FLOW : addOrRemove;
- syncFlow(port.getDpId(), getAclFilterCumDispatcherTable(), flowId, flowPriority, "ACL", 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);
}
}
- protected void programAceSpecificFlows(AclInterface port, String aclName, Ace ace,
- Map<String, List<MatchInfoBase>> flowMap, Uuid remoteAclId, int addOrRemove) {
+ protected void programAceSpecificFlows(List<FlowEntity> flowEntries, AclInterface port, String aclName, Ace ace,
+ @Nullable Map<String, List<MatchInfoBase>> flowMap, Uuid remoteAclId, int addOrRemove) {
if (null == flowMap) {
return;
}
+ ace.key().getRuleName();
int operation = addOrRemove == NwConstants.MOD_FLOW ? NwConstants.DEL_FLOW : addOrRemove;
- syncFlow(port.getDpId(), getAclRuleBasedFilterTable(), flowId, flowPriority, "ACL", 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);
+ programAclForExistingTrafficTable(port, ace, addOrRemove, flowName, matches, flowPriority);
}
}
}
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";
+ + "_" + (acl.getAceIpVersion() instanceof AceIpv4 ? "_IPv4" : "_IPv6") + "_FlowAfterRuleDeleted";
final List<MatchInfoBase> newMatches =
matches.stream().filter(obj -> !(obj instanceof NxMatchCtState || obj instanceof MatchMetadata))
List<InstructionInfo> instructions =
AclServiceUtils.createCtMarkInstructionForNewState(getAclFilterCumDispatcherTable(), port.getElanId());
// Reversing the flow add/delete operation for this table.
- int operation = (addOrRemove == NwConstants.ADD_FLOW) ? NwConstants.DEL_FLOW : NwConstants.ADD_FLOW;
- syncFlow(port.getDpId(), getAclForExistingTrafficTable(), newFlowName, priority, "ACL", 0,
- AclServiceUtils.getHardTimoutForApplyStatefulChangeOnExistingTraffic(ace, aclServiceUtils),
+ List<FlowEntity> flowEntries = new ArrayList<>();
+ int operation = addOrRemove == NwConstants.ADD_FLOW ? NwConstants.DEL_FLOW : NwConstants.ADD_FLOW;
+ 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);
}
@Override
LOG.warn("Unable to find DP Id from ACL interface with id {}", port.getInterfaceId());
return false;
}
- programAcl(port, Action.REMOVE, NwConstants.DEL_FLOW);
- updateRemoteAclFilterTable(port, NwConstants.DEL_FLOW);
+ List<FlowEntity> flowEntries = new ArrayList<>();
+ 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;
}
if (!port.isPortSecurityEnabled() || port.getDpId() == null) {
return false;
}
- programAceRule(port, aclName, ace, NwConstants.ADD_FLOW);
+ List<FlowEntity> flowEntries = new ArrayList<>();
+ programAceRule(flowEntries, port, aclName, ace, NwConstants.ADD_FLOW);
+ programFlows(AclConstants.ACL_JOB_KEY_PREFIX + port.getInterfaceId(), flowEntries, NwConstants.ADD_FLOW);
return true;
}
if (!port.isPortSecurityEnabled() || port.getDpId() == null) {
return false;
}
- programAceRule(port, aclName, ace, NwConstants.MOD_FLOW);
+ List<FlowEntity> flowEntries = new ArrayList<>();
+ programAceRule(flowEntries, port, aclName, ace, NwConstants.MOD_FLOW);
+ programFlows(AclConstants.ACL_JOB_KEY_PREFIX + port.getInterfaceId(), flowEntries, NwConstants.DEL_FLOW);
return true;
}
*/
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.
*
+ * @param flowEntries the flow entries
* @param port the acl interface
* @param allowedAddresses the allowed addresses
* @param action add/modify/remove action
* @param addOrRemove addorRemove
*/
- protected abstract void programAntiSpoofingRules(AclInterface port, List<AllowedAddressPairs> allowedAddresses,
- Action action, int addOrRemove);
+ protected abstract void programAntiSpoofingRules(List<FlowEntity> flowEntries, AclInterface port,
+ List<AllowedAddressPairs> allowedAddresses, Action action, int addOrRemove);
/**
* Programs broadcast rules.
*
+ * @param flowEntries the flow entries
* @param port the Acl Interface port
* @param addOrRemove whether to delete or add flow
*/
- protected abstract void programBroadcastRules(AclInterface port, int addOrRemove);
+ protected abstract void programBroadcastRules(List<FlowEntity> flowEntries, AclInterface port, Action action,
+ int addOrRemove);
- protected abstract void programIcmpv6RARule(AclInterface port, List<SubnetInfo> subnets, int 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 abstract void programSubnetBroadcastRules(List<FlowEntity> flowEntries, AclInterface port,
+ List<SubnetInfo> subnetInfoList, int addOrRemove);
+
+ protected abstract void programIcmpv6RARule(List<FlowEntity> flowEntries, AclInterface port,
+ List<SubnetInfo> subnets, int addOrRemove);
/**
- * Writes/remove the flow to/from the datastore.
+ * Add Flow to list.
*
* @param dpId
* the dpId
* the flowId
* @param priority
* the priority
- * @param flowName
- * the flow name
* @param idleTimeOut
* the idle timeout
* @param hardTimeOut
* @param addOrRemove
* add or remove the entries.
*/
- protected void syncFlow(BigInteger dpId, short tableId, String flowId, int priority, String flowName,
- 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) {
- jobCoordinator.enqueueJob(flowName, () -> {
- if (addOrRemove == NwConstants.DEL_FLOW) {
- FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
- idleTimeOut, hardTimeOut, cookie, matches, null);
- LOG.trace("Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
-
- return Collections.singletonList(mdsalManager.removeFlow(dpId, flowEntity));
+ List<InstructionInfo> instructionInfos = null;
+ if (addOrRemove == NwConstants.ADD_FLOW) {
+ instructionInfos = instructions;
+ }
+ FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority,
+ flowId, idleTimeOut, hardTimeOut, cookie, matches, instructionInfos);
+ LOG.trace("Adding flow to list: DpnId {}, flowId {}", dpId, flowId);
+ flowEntries.add(flowEntity);
+ }
- } else {
- FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
- idleTimeOut, hardTimeOut, cookie, matches, instructions);
- LOG.trace("Installing DpnId {}, flowId {}", dpId, flowId);
- return Collections.singletonList(mdsalManager.installFlow(dpId, flowEntity));
- }
- });
+ protected void programFlows(String jobName, List<FlowEntity> flowEntries, int addOrRemove) {
+ List<List<FlowEntity>> flowEntityParts = Lists.partition(flowEntries, AclConstants.FLOWS_PER_TRANSACTION);
+ for (List<FlowEntity> part : flowEntityParts) {
+ jobCoordinator.enqueueJob(jobName,
+ () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+ tx -> {
+ if (addOrRemove == NwConstants.ADD_FLOW) {
+ for (FlowEntity flowEntity: part) {
+ mdsalManager.addFlow(tx, flowEntity);
+ }
+ } else {
+ for (FlowEntity flowEntity: part) {
+ mdsalManager.removeFlow(tx, flowEntity);
+ }
+ }
+ })), AclConstants.JOB_MAX_RETRIES);
+ }
}
protected List<InstructionInfo> getDispatcherTableResubmitInstructions() {
protected void handleRemoteAclUpdate(Acl aclBefore, Acl aclAfter, Collection<AclInterface> portsBefore) {
String aclName = aclAfter.getAclName();
Collection<AclInterface> interfaceList = aclDataUtil.getInterfaceList(new Uuid(aclName));
- if (interfaceList == null || interfaceList.isEmpty()) {
+ if (interfaceList.isEmpty()) {
LOG.trace("handleRemoteAclUpdate: No interfaces found with ACL={}", aclName);
return;
}
Set<Uuid> remoteAclsDeleted = new HashSet<>(remoteAclsBefore);
remoteAclsDeleted.removeAll(remoteAclsAfter);
+ 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(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(port, NwConstants.ADD_FLOW);
+ 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(aclName, remoteAclsDeleted, dpns, NwConstants.DEL_FLOW);
- programRemoteAclTable(aclName, remoteAclsAdded, dpns, NwConstants.ADD_FLOW);
+ programRemoteAclTable(deleteFlowEntries, aclName, remoteAclsDeleted, dpns, NwConstants.DEL_FLOW);
+ programRemoteAclTable(addFlowEntries, aclName, remoteAclsAdded, dpns, 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(String aclName, Set<Uuid> remoteAclIds, Set<BigInteger> dpns, int addOrRemove) {
+ private void programRemoteAclTable(List<FlowEntity> flowEntries, String aclName, Set<Uuid> remoteAclIds,
+ Set<BigInteger> dpns, int addOrRemove) {
for (Uuid remoteAclId : remoteAclIds) {
Collection<AclInterface> remoteAclInterfaces = aclDataUtil.getInterfaceList(remoteAclId);
- if (remoteAclInterfaces == null || remoteAclInterfaces.isEmpty()) {
+ if (remoteAclInterfaces.isEmpty()) {
continue;
}
Set<AllowedAddressPairs> aaps =
if (addOrRemove == NwConstants.ADD_FLOW) {
for (BigInteger dpn : dpns) {
for (AllowedAddressPairs aap : aaps) {
- programRemoteAclTableFlow(dpn, aclTag, aap, addOrRemove);
+ programRemoteAclTableFlow(flowEntries, Uint64.valueOf(dpn), aclTag, aap, addOrRemove);
}
}
} else if (addOrRemove == NwConstants.DEL_FLOW) {
for (BigInteger dpn : dpnsToOperate) {
for (AllowedAddressPairs aap : aaps) {
- programRemoteAclTableFlow(dpn, aclTag, aap, addOrRemove);
+ programRemoteAclTableFlow(flowEntries, Uint64.valueOf(dpn), aclTag, aap, addOrRemove);
}
}
}
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(portId, aclId, aclTag, aaps, addOrRemove);
- } else if (addOrRemove == NwConstants.DEL_FLOW) {
- // Synchronizing during delete operation as there are
- // look-ups for AclPortsLookup data.
- synchronized (aclId.getValue().intern()) {
- syncRemoteAclTable(portId, aclId, aclTag, aaps, addOrRemove);
- }
- }
+ 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(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(String portId, Uuid acl, Integer aclTag, List<AllowedAddressPairs> aaps,
- int addOrRemove) {
- Map<String, Set<AclInterface>> mapAclWithPortSet = aclDataUtil.getRemoteAclInterfaces(acl, this.direction);
+ private void syncRemoteAclTable(List<FlowEntity> flowEntries, String portId, Uuid acl, Integer aclTag,
+ List<AllowedAddressPairs> aaps, Map<String, Set<AclInterface>> mapAclWithPortSet, int addOrRemove) {
Set<BigInteger> dpns = collectDpns(mapAclWithPortSet);
for (AllowedAddressPairs aap : aaps) {
if (!AclServiceUtils.isNotIpAllNetwork(aap)) {
continue;
}
for (BigInteger dpId : dpns) {
- programRemoteAclTableFlow(dpId, aclTag, aap, addOrRemove);
+ programRemoteAclTableFlow(flowEntries, Uint64.valueOf(dpId), aclTag, aap, addOrRemove);
}
}
}
- private void syncRemoteAclTableFromOtherDpns(AclInterface port, Uuid remoteAclId, int addOrRemove) {
+ private void syncRemoteAclTableFromOtherDpns(List<FlowEntity> flowEntries, AclInterface port, Uuid remoteAclId,
+ int addOrRemove) {
Collection<AclInterface> aclInterfaces = aclDataUtil.getInterfaceList(remoteAclId);
- if (aclInterfaces != null && !aclInterfaces.isEmpty() && isFirstPortInDpnWithRemoteAclId(port, remoteAclId)) {
+ if (!aclInterfaces.isEmpty() && isFirstPortInDpnWithRemoteAclId(port, remoteAclId)) {
Integer aclTag = aclServiceUtils.getAclTag(remoteAclId);
for (AclInterface aclInterface : aclInterfaces) {
if (port.getInterfaceId().equals(aclInterface.getInterfaceId())) {
}
for (AllowedAddressPairs aap : aclInterface.getAllowedAddressPairs()) {
if (AclServiceUtils.isNotIpAllNetwork(aap)) {
- programRemoteAclTableFlow(port.getDpId(), aclTag, aap, addOrRemove);
+ programRemoteAclTableFlow(flowEntries, Uint64.valueOf(port.getDpId()),
+ aclTag, aap, addOrRemove);
}
}
}
return true;
}
- protected abstract void programRemoteAclTableFlow(BigInteger dpId, Integer aclTag, AllowedAddressPairs aap,
- int addOrRemove);
+ protected abstract void programRemoteAclTableFlow(List<FlowEntity> flowEntries, Uint64 dpId, Integer aclTag,
+ AllowedAddressPairs aap, int addOrRemove);
- protected String getOperAsString(int flowOper) {
- String oper;
- switch (flowOper) {
- case NwConstants.ADD_FLOW:
- oper = "Add";
- break;
- case NwConstants.DEL_FLOW:
- oper = "Del";
- break;
- case NwConstants.MOD_FLOW:
- oper = "Mod";
- break;
- default:
- oper = "UNKNOWN";
- }
- return oper;
- }
-
- protected Set<BigInteger> collectDpns(Map<String, Set<AclInterface>> mapAclWithPortSet) {
+ protected Set<BigInteger> collectDpns(@Nullable Map<String, Set<AclInterface>> mapAclWithPortSet) {
Set<BigInteger> dpns = new HashSet<>();
if (mapAclWithPortSet == null) {
return dpns;
/**
* Programs the port specific fixed rules.
*
+ * @param flowEntries the flow entries
* @param dpId the dp id
* @param allowedAddresses the allowed addresses
* @param lportTag the lport tag
* @param action the action
* @param write whether to add or remove the flow.
*/
- protected void programAclPortSpecificFixedRules(BigInteger dpId, List<AllowedAddressPairs> allowedAddresses,
- int lportTag, String portId, Action action, int write) {
- programGotoClassifierTableRules(dpId, allowedAddresses, lportTag, write);
+ 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) {
- programConntrackRecircRules(dpId, allowedAddresses, lportTag, portId, write);
- programPortSpecificDropRules(dpId, lportTag, write);
- programAclCommitRules(dpId, lportTag, portId, write);
+ programConntrackRecircRules(flowEntries, dpId, allowedAddresses, lportTag, portId, write);
+ programPortSpecificDropRules(flowEntries, dpId, lportTag, write);
+ programAclCommitRules(flowEntries, dpId, lportTag, portId, write);
}
LOG.info("programAclPortSpecificFixedRules: flows for dpId={}, lportId={}, action={}, write={}", dpId, lportTag,
action, write);
}
- protected abstract void programGotoClassifierTableRules(BigInteger dpId, List<AllowedAddressPairs> aaps,
- int lportTag, int addOrRemove);
+ protected abstract void programGotoClassifierTableRules(List<FlowEntity> flowEntries, Uint64 dpId,
+ List<AllowedAddressPairs> aaps, int lportTag, int addOrRemove);
/**
* Adds the rule to send the packet to the netfilter to check whether it is a known packet.
*
+ * @param flowEntries the flow entries
* @param dpId the dpId
* @param aaps the allowed address pairs
* @param lportTag the lport tag
* @param portId the portId
* @param addOrRemove whether to add or remove the flow
*/
- protected void programConntrackRecircRules(BigInteger dpId, List<AllowedAddressPairs> aaps, int lportTag,
- String portId, int addOrRemove) {
+ protected void programConntrackRecircRules(List<FlowEntity> flowEntries, Uint64 dpId,
+ List<AllowedAddressPairs> aaps, int lportTag, String portId, int addOrRemove) {
if (AclServiceUtils.doesIpv4AddressExists(aaps)) {
- programConntrackRecircRule(dpId, lportTag, portId, MatchEthernetType.IPV4, addOrRemove);
+ programConntrackRecircRule(flowEntries, dpId, lportTag, portId, MatchEthernetType.IPV4, addOrRemove);
}
if (AclServiceUtils.doesIpv6AddressExists(aaps)) {
- programConntrackRecircRule(dpId, lportTag, portId, MatchEthernetType.IPV6, addOrRemove);
+ programConntrackRecircRule(flowEntries, dpId, lportTag, portId, MatchEthernetType.IPV6, addOrRemove);
}
}
- protected void programConntrackRecircRule(BigInteger dpId, int lportTag, String portId,
- MatchEthernetType matchEtherType, int addOrRemove) {
+ protected void programConntrackRecircRule(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
+ String portId, MatchEthernetType matchEtherType, int addOrRemove) {
List<MatchInfoBase> matches = new ArrayList<>();
matches.add(matchEtherType);
matches.add(AclServiceUtils.buildLPortTagMatch(lportTag, serviceMode));
}
String flowName =
- this.directionString + "_Fixed_Conntrk_" + dpId + "_" + lportTag + "_" + matchEtherType + "_Recirc";
- syncFlow(dpId, getAclConntrackSenderTable(), flowName, AclConstants.ACL_DEFAULT_PRIORITY, "ACL", 0, 0,
- AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
+ 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);
}
/**
* Adds the rules to drop the unknown/invalid packets .
*
+ * @param flowEntries the flow entries
* @param dpId the dpId
* @param lportTag the lport tag
* @param addOrRemove whether to add or remove the flow
*/
- protected void programPortSpecificDropRules(BigInteger dpId, int lportTag, int addOrRemove) {
+ protected void programPortSpecificDropRules(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
+ int addOrRemove) {
LOG.debug("Programming Drop Rules: DpId={}, lportTag={}, addOrRemove={}", dpId, lportTag, addOrRemove);
- programConntrackInvalidDropRule(dpId, lportTag, addOrRemove);
- programAclRuleMissDropRule(dpId, lportTag, addOrRemove);
+ programConntrackInvalidDropRule(flowEntries, dpId, lportTag, addOrRemove);
+ programAclRuleMissDropRule(flowEntries, dpId, lportTag, addOrRemove);
}
/**
* Adds the rule to drop the conntrack invalid packets .
*
+ * @param flowEntries the flow entries
* @param dpId the dpId
* @param lportTag the lport tag
* @param addOrRemove whether to add or remove the flow
*/
- protected void programConntrackInvalidDropRule(BigInteger dpId, int lportTag, int addOrRemove) {
+ 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";
- syncFlow(dpId, getAclFilterCumDispatcherTable(), flowId, AclConstants.CT_STATE_TRACKED_INVALID_PRIORITY, "ACL",
- 0, 0, AclServiceUtils.getDropFlowCookie(lportTag), matches, instructions, addOrRemove);
+ 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);
}
/**
* Program ACL rule miss drop rule for a port.
*
+ * @param flowEntries the flow entries
* @param dpId the dp id
* @param lportTag the lport tag
* @param addOrRemove the add or remove
*/
- protected void programAclRuleMissDropRule(BigInteger dpId, int lportTag, int addOrRemove) {
+ 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;
- syncFlow(dpId, getAclFilterCumDispatcherTable(), flowId, AclConstants.ACL_PORT_SPECIFIC_DROP_PRIORITY, "ACL", 0,
- 0, AclServiceUtils.getDropFlowCookie(lportTag), matches, instructions, addOrRemove);
+ 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);
}
/**
* Program acl commit rules.
*
+ * @param flowEntries the flow entries
* @param dpId the dp id
* @param lportTag the lport tag
* @param portId the port id
* @param addOrRemove the add or remove
*/
- protected void programAclCommitRules(BigInteger dpId, int lportTag, String portId, int addOrRemove) {
- programAclCommitRuleForConntrack(dpId, lportTag, portId, MatchEthernetType.IPV4, addOrRemove);
- programAclCommitRuleForConntrack(dpId, lportTag, portId, MatchEthernetType.IPV6, addOrRemove);
- programAclCommitRuleForNonConntrack(dpId, lportTag, addOrRemove);
+ 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);
+ programAclCommitRuleForNonConntrack(flowEntries, dpId, lportTag, addOrRemove);
}
/**
* Program acl commit rule for conntrack.
*
+ * @param flowEntries the flow entries
* @param dpId the dp id
* @param lportTag the lport tag
* @param portId the port id
* @param matchEtherType the match ether type
* @param addOrRemove the add or remove
*/
- protected void programAclCommitRuleForConntrack(BigInteger dpId, int lportTag, String portId,
- MatchEthernetType matchEtherType, int addOrRemove) {
+ protected void programAclCommitRuleForConntrack(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
+ String portId, MatchEthernetType matchEtherType, int addOrRemove) {
List<MatchInfoBase> matches = new ArrayList<>();
matches.add(matchEtherType);
matches.addAll(AclServiceUtils.buildMatchesForLPortTagAndConntrackClassifierType(lportTag,
List<NxCtAction> ctActionsList =
Lists.newArrayList(new ActionNxConntrack.NxCtMark(AclConstants.CT_MARK_EST_STATE));
actionsInfos.add(new ActionNxConntrack(2, 1, 0, elanId.intValue(), (short) 255, ctActionsList));
+ actionsInfos.add(new ActionNxCtClear());
}
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
- syncFlow(dpId, getAclCommitterTable(), flowName, AclConstants.ACL_DEFAULT_PRIORITY, "ACL", 0, 0,
- AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
+ addFlowEntryToList(flowEntries, dpId, getAclCommitterTable(), flowName, AclConstants.ACL_DEFAULT_PRIORITY,
+ 0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
}
/**
* Program acl commit rule for non conntrack.
*
+ * @param flowEntries the flow entries
* @param dpId the dp id
* @param lportTag the lport tag
* @param addOrRemove the add or remove
*/
- protected void programAclCommitRuleForNonConntrack(BigInteger dpId, int lportTag, int addOrRemove) {
+ protected void programAclCommitRuleForNonConntrack(List<FlowEntity> flowEntries, Uint64 dpId, int lportTag,
+ int addOrRemove) {
List<MatchInfoBase> matches = new ArrayList<>();
matches.addAll(AclServiceUtils.buildMatchesForLPortTagAndConntrackClassifierType(lportTag,
AclConntrackClassifierType.NON_CONNTRACK_SUPPORTED, serviceMode));
List<InstructionInfo> instructions = getDispatcherTableResubmitInstructions();
String flowName = this.directionString + "_Acl_Commit_Non_Conntrack_" + dpId + "_" + lportTag;
// Flow for non-conntrack traffic to resubmit to dispatcher
- syncFlow(dpId, getAclCommitterTable(), flowName, AclConstants.ACL_DEFAULT_PRIORITY, "ACL", 0, 0,
- AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
+ addFlowEntryToList(flowEntries, dpId, getAclCommitterTable(), flowName, AclConstants.ACL_DEFAULT_PRIORITY,
+ 0, 0, AclConstants.COOKIE_ACL_BASE, matches, instructions, addOrRemove);
}
+ @Nullable
protected Long getElanIdFromAclInterface(String elanInterfaceName) {
AclInterface aclInterface = aclInterfaceCache.get(elanInterfaceName);
if (null != aclInterface) {
protected abstract boolean isValidDirection(Class<? extends DirectionBase> direction);
- protected abstract short getAclAntiSpoofingTable();
-
- protected abstract short getAclConntrackClassifierTable();
-
protected abstract short getAclConntrackSenderTable();
protected abstract short getAclForExistingTrafficTable();