applied to incoming (ingress) traffic for that instance.
An egress rule is applied to traffic leaving the instance.";
}
+ leaf deleted {
+ type boolean;
+ default false;
+ description "True when ACE is deleted; false otherwise.";
+ }
}
augment "/ietf-if:interfaces/ietf-if:interface" {
protected void programAceRule(List<FlowEntity> flowEntries, AclInterface port, String aclName, Ace ace,
int addOrRemove) {
SecurityRuleAttr aceAttr = AclServiceUtils.getAccessListAttributes(ace);
+ 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());
List<Ace> addedAceRules = getChangedAceList(aclAfter, aclBefore);
// Find and update deleted ace rules in acl
- List<Ace> deletedAceRules = getChangedAceList(aclBefore, aclAfter);
+ List<Ace> deletedAceRules = getDeletedAceList(aclAfter);
if (aclClusterUtil.isEntityOwner()) {
LOG.debug("On update event, remove Ace rules: {} for ACL: {}", deletedAceRules, aclName);
updateAceRules(interfacesBefore, aclName, deletedAceRules, AclServiceManager.Action.REMOVE);
+ if (null != deletedAceRules && !deletedAceRules.isEmpty()) {
+ aclServiceUtils.deleteAcesFromConfigDS(aclName, deletedAceRules);
+ }
}
updateAclCaches(aclBefore, aclAfter, interfacesBefore);
}
return updatedAceList;
}
+
+ private List<Ace> getDeletedAceList(Acl acl) {
+ if (acl == null || acl.getAccessListEntries() == null || acl.getAccessListEntries().getAce() == null) {
+ return null;
+ }
+ List<Ace> aceList = acl.getAccessListEntries().getAce();
+ List<Ace> deletedAceList = new ArrayList<>();
+ for (Ace ace: aceList) {
+ if (ace.augmentation(SecurityRuleAttr.class).isDeleted()) {
+ deletedAceList.add(ace);
+ }
+ }
+ return deletedAceList;
+ }
}
String ACL_SYNC_KEY_EXT = "-acl";
int JOB_MAX_RETRIES = 3;
+ int ACEDELETE_MAX_RETRIES = 3;
int FLOWS_PER_TRANSACTION = 30;
+ int ACES_PER_TRANSACTION = 30;
String ACL_JOB_KEY_PREFIX = "ACL-";
package org.opendaylight.netvirt.aclservice.utils;
import static org.opendaylight.controller.md.sal.binding.api.WriteTransaction.CREATE_MISSING_PARENTS;
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
import static org.opendaylight.genius.infra.Datastore.OPERATIONAL;
import com.google.common.base.Optional;
import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
import org.opendaylight.netvirt.aclservice.api.AclServiceManager.MatchCriteria;
import org.opendaylight.netvirt.aclservice.api.utils.AclInterface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.AccessLists;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.Ipv4Acl;
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.AclKey;
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;
OPERATIONAL, tx -> tx.delete(id)), LOG, "Failed to delete subnet info for port: " + portId);
}
+ public void deleteAcesFromConfigDS(String aclName, List<Ace> deletedAceRules) {
+ List<List<Ace>> acesParts = Lists.partition(deletedAceRules, AclConstants.ACES_PER_TRANSACTION);
+ for (List<Ace> acePart : acesParts) {
+ jobCoordinator.enqueueJob(aclName,
+ () -> Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+ tx -> {
+ for (Ace ace: acePart) {
+ InstanceIdentifier<Ace> id = InstanceIdentifier.builder(AccessLists.class)
+ .child(Acl.class, new AclKey(aclName, Ipv4Acl.class)).child(AccessListEntries.class)
+ .child(Ace.class, ace.key()).build();
+ tx.delete(id);
+ }
+ })), AclConstants.ACEDELETE_MAX_RETRIES);
+ }
+ }
+
public static Integer allocateId(IdManagerService idManager, String poolName, String idKey, Integer defaultId) {
AllocateIdInput getIdInput = new AllocateIdInputBuilder().setPoolName(poolName).setIdKey(idKey).build();
try {
protected void add(InstanceIdentifier<SecurityRule> instanceIdentifier, SecurityRule securityRule) {
LOG.trace("added securityRule: {}", securityRule);
try {
- Ace ace = toAceBuilder(securityRule).build();
+ Ace ace = toAceBuilder(securityRule, false).build();
InstanceIdentifier<Ace> identifier = getAceInstanceIdentifier(securityRule);
MDSALUtil.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION, identifier, ace);
} catch (Exception ex) {
.build();
}
- private AceBuilder toAceBuilder(SecurityRule securityRule) {
+ private AceBuilder toAceBuilder(SecurityRule securityRule, boolean isDeleted) {
AceIpBuilder aceIpBuilder = new AceIpBuilder();
SecurityRuleAttrBuilder securityRuleAttrBuilder = new SecurityRuleAttrBuilder();
DestinationPortRangeBuilder destinationPortRangeBuilder = new DestinationPortRangeBuilder();
aceIpBuilder.setProtocol(PROTOCOL_MAP.get(protocol.getIdentityref()));
}
}
+ securityRuleAttrBuilder.setDeleted(isDeleted);
MatchesBuilder matchesBuilder = new MatchesBuilder();
matchesBuilder.setAceType(aceIpBuilder.build());
@SuppressWarnings("checkstyle:IllegalCatch")
protected void remove(InstanceIdentifier<SecurityRule> instanceIdentifier, SecurityRule securityRule) {
LOG.trace("removed securityRule: {}", securityRule);
+ InstanceIdentifier<Ace> identifier = getAceInstanceIdentifier(securityRule);
try {
- InstanceIdentifier<Ace> identifier = getAceInstanceIdentifier(securityRule);
- MDSALUtil.syncDelete(dataBroker, LogicalDatastoreType.CONFIGURATION, identifier);
+ Ace ace = toAceBuilder(securityRule, true).build();
+ MDSALUtil.syncUpdate(dataBroker, LogicalDatastoreType.CONFIGURATION, identifier, ace);
} catch (Exception ex) {
LOG.error("Exception occured while removing acl for security rule: {}. ", securityRule, ex);
}