*/
package org.opendaylight.netvirt.aclservice;
-import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
import com.google.common.collect.Lists;
import java.math.BigInteger;
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.ActionInfo;
import org.opendaylight.genius.mdsalutil.FlowEntity;
import org.opendaylight.genius.mdsalutil.InstructionInfo;
import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState;
import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
import org.opendaylight.netvirt.aclservice.api.AclInterfaceCache;
import org.opendaylight.netvirt.aclservice.api.AclServiceListener;
import org.opendaylight.netvirt.aclservice.api.AclServiceManager.Action;
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;
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;
}
programDhcpService(flowEntries, port, Action.ADD, NwConstants.ADD_FLOW);
} else {
if (port.getSecurityGroups() == null) {
- LOG.info("Port {} without SGs", port.getInterfaceId());
+ LOG.info("Port {} without SGs", portId);
return false;
}
- programAcl(flowEntries, port, Action.ADD, NwConstants.ADD_FLOW);
- updateRemoteAclFilterTable(flowEntries, port, NwConstants.ADD_FLOW);
+ programAclWithAllowedAddress(flowEntries, port, port.getAllowedAddressPairs(),
+ Action.ADD, NwConstants.ADD_FLOW);
+ updateRemoteAclFilterTable(port, NwConstants.ADD_FLOW);
}
- programFlows(AclConstants.ACL_JOB_KEY_PREFIX + port.getInterfaceId(), flowEntries, NwConstants.ADD_FLOW);
+ programFlows(AclConstants.ACL_JOB_KEY_PREFIX + portId, flowEntries, NwConstants.ADD_FLOW);
return true;
}
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.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);
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);
}
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) {
Uint64 dpId = Uint64.valueOf(port.getDpId());
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;
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);
+ ace == null ? null : ace.getRuleName(), aclName);
return;
}
if (addOrRemove == NwConstants.ADD_FLOW && aceAttr.isDeleted()) {
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";
if (port.getInterfaceType() == InterfaceType.DhcpService) {
programDhcpService(flowEntries, port, Action.REMOVE, NwConstants.DEL_FLOW);
} else {
- programAcl(flowEntries, port, Action.REMOVE, NwConstants.DEL_FLOW);
- updateRemoteAclFilterTable(flowEntries, port, NwConstants.DEL_FLOW);
+ 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;
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,
.filter(AclServiceUtils::isNotIpAllNetwork).collect(Collectors.toSet());
Integer aclTag = aclServiceUtils.getAclTag(remoteAclId);
+ if (aclTag == null || aclTag == AclConstants.INVALID_ACL_TAG) {
+ LOG.error("aclTag={} is null or invalid for remoteAclId={}", aclTag, remoteAclId);
+ continue;
+ }
if (addOrRemove == NwConstants.ADD_FLOW) {
for (BigInteger dpn : dpns) {
for (AllowedAddressPairs aap : aaps) {
}
}
- 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;
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();
- });
+ if (aclTag == null || aclTag == AclConstants.INVALID_ACL_TAG) {
+ LOG.error("aclTag={} is null or invalid for aclId={}", aclTag, aclId);
+ continue;
}
+ 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) {
+ 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;
+ }
+ List<FlowEntity> flowEntries = new ArrayList<>();
syncRemoteAclTableFromOtherDpns(flowEntries, port, remoteAclId, addOrRemove);
+ programFlows(AclConstants.ACL_JOB_KEY_PREFIX + remoteAclId.getValue(), flowEntries, addOrRemove);
}
}
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)) {
if (!aclInterfaces.isEmpty() && isFirstPortInDpnWithRemoteAclId(port, remoteAclId)) {
Integer aclTag = aclServiceUtils.getAclTag(remoteAclId);
+ if (aclTag == null || aclTag == AclConstants.INVALID_ACL_TAG) {
+ LOG.error("aclTag={} is null or invalid for remoteAclId={}", aclTag, remoteAclId);
+ return;
+ }
for (AclInterface aclInterface : aclInterfaces) {
if (port.getInterfaceId().equals(aclInterface.getInterfaceId())) {
continue;
}
String flowName =
- this.directionString + "_Fixed_Conntrk_" + dpId.toString() + "_"
+ 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,