package org.opendaylight.netvirt.aclservice.listeners;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Iterator;
import java.util.List;
-
+import javax.annotation.PostConstruct;
+import javax.inject.Inject;
+import javax.inject.Singleton;
import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
import org.opendaylight.netvirt.aclservice.api.AclServiceManager;
import org.opendaylight.netvirt.aclservice.api.utils.AclInterface;
+import org.opendaylight.netvirt.aclservice.utils.AclClusterUtil;
+import org.opendaylight.netvirt.aclservice.utils.AclConstants;
import org.opendaylight.netvirt.aclservice.utils.AclDataUtil;
+import org.opendaylight.netvirt.aclservice.utils.AclServiceUtils;
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.access.lists.Acl;
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.yang.types.rev130715.Uuid;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.aclservice.rev160608.SecurityRuleAttr;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+@Singleton
public class AclEventListener extends AsyncDataTreeChangeListenerBase<Acl, AclEventListener> implements
ClusteredDataTreeChangeListener<Acl> {
private static final Logger LOG = LoggerFactory.getLogger(AclEventListener.class);
+
private final AclServiceManager aclServiceManager;
+ private final AclClusterUtil aclClusterUtil;
private final DataBroker dataBroker;
+ private final AclDataUtil aclDataUtil;
+ private final AclServiceUtils aclServiceUtils;
- public AclEventListener(final AclServiceManager aclServiceManager, DataBroker dataBroker) {
+ @Inject
+ public AclEventListener(AclServiceManager aclServiceManager, AclClusterUtil aclClusterUtil, DataBroker dataBroker,
+ AclDataUtil aclDataUtil, AclServiceUtils aclServicUtils) {
super(Acl.class, AclEventListener.class);
this.aclServiceManager = aclServiceManager;
+ this.aclClusterUtil = aclClusterUtil;
this.dataBroker = dataBroker;
+ this.aclDataUtil = aclDataUtil;
+ this.aclServiceUtils = aclServicUtils;
}
- public void start() {
+ @Override
+ @PostConstruct
+ public void init() {
LOG.info("{} start", getClass().getSimpleName());
registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
}
}
@Override
- protected void remove(InstanceIdentifier<Acl> key, Acl accessListEntry) {
- // no need to handle here as Acl will be removed from AclInterfaceListener
+ protected void remove(InstanceIdentifier<Acl> key, Acl acl) {
+ if (!AclServiceUtils.isOfAclInterest(acl)) {
+ LOG.trace("{} does not have SecurityRuleAttr augmentation", acl.getAclName());
+ return;
+ }
+
+ LOG.trace("On remove event, remove ACL: {}", acl);
+ this.aclServiceUtils.releaseAclTag(acl.getAclName());
+ updateRemoteAclCache(acl.getAccessListEntries().getAce(), acl.getAclName(), AclServiceManager.Action.REMOVE);
}
@Override
protected void update(InstanceIdentifier<Acl> key, Acl aclBefore, Acl aclAfter) {
- List<AclInterface> interfaceList = AclDataUtil.getInterfaceList(new Uuid(aclAfter.getAclName()));
- if (interfaceList == null || interfaceList.isEmpty()) {
- LOG.debug("acl {} is not associated with any interface.", aclAfter.getAclName());
+ if (!AclServiceUtils.isOfAclInterest(aclAfter) && !AclServiceUtils.isOfAclInterest(aclBefore)) {
+ LOG.trace("before {} and after {} does not have SecurityRuleAttr augmentation",
+ aclBefore.getAclName(), aclAfter.getAclName());
return;
}
+
+ String aclName = aclAfter.getAclName();
+ Collection<AclInterface> interfaceList = aclDataUtil.getInterfaceList(new Uuid(aclName));
// find and update added ace rules in acl
List<Ace> addedAceRules = getChangedAceList(aclAfter, aclBefore);
- updateAceRules(interfaceList, addedAceRules, AclServiceManager.Action.ADD);
+ updateRemoteAclCache(addedAceRules, aclName, AclServiceManager.Action.ADD);
+ if (interfaceList != null && aclClusterUtil.isEntityOwner()) {
+ LOG.debug("On update event, add Ace rules: {} for ACL: {}", addedAceRules, aclName);
+ updateAceRules(interfaceList, aclName, addedAceRules, AclServiceManager.Action.ADD);
+ }
// find and update deleted ace rules in acl
List<Ace> deletedAceRules = getChangedAceList(aclBefore, aclAfter);
- updateAceRules(interfaceList, deletedAceRules, AclServiceManager.Action.REMOVE);
-
+ if (interfaceList != null && aclClusterUtil.isEntityOwner()) {
+ LOG.debug("On update event, remove Ace rules: {} for ACL: {}", deletedAceRules, aclName);
+ updateAceRules(interfaceList, aclName, deletedAceRules, AclServiceManager.Action.REMOVE);
+ }
+ updateRemoteAclCache(deletedAceRules, aclName, AclServiceManager.Action.REMOVE);
}
- private void updateAceRules(List<AclInterface> interfaceList, List<Ace> aceList, AclServiceManager.Action action) {
+ private void updateAceRules(Collection<AclInterface> interfaceList, String aclName, List<Ace> aceList,
+ AclServiceManager.Action action) {
if (null != aceList && !aceList.isEmpty()) {
LOG.trace("update ace rules - action: {} , ace rules: {}", action.name(), aceList);
for (AclInterface port : interfaceList) {
for (Ace aceRule : aceList) {
- aclServiceManager.notifyAce(port, action, aceRule);
+ aclServiceManager.notifyAce(port, action, aclName, aceRule);
}
}
}
}
@Override
- protected void add(InstanceIdentifier<Acl> key, Acl dataObjectModification) {
- // no need to handle here as Acl will be added from AclInterfaceListener
+ protected void add(InstanceIdentifier<Acl> key, Acl acl) {
+ String aclName = acl.getAclName();
+ if (!AclServiceUtils.isOfAclInterest(acl)) {
+ LOG.trace("{} does not have SecurityRuleAttr augmentation", aclName);
+ return;
+ }
+
+ LOG.trace("On add event, add ACL: {}", acl);
+ Integer aclTag = this.aclServiceUtils.allocateAclTag(aclName);
+ if (aclTag != null && aclTag != AclConstants.INVALID_ACL_TAG) {
+ this.aclDataUtil.addAclTag(aclName, aclTag);
+ }
+
+ updateRemoteAclCache(acl.getAccessListEntries().getAce(), aclName, AclServiceManager.Action.ADD);
+ }
+
+ /**
+ * Update remote acl cache.
+ *
+ * @param aceList the ace list
+ * @param aclName the acl name
+ * @param action the action
+ */
+ private void updateRemoteAclCache(List<Ace> aceList, String aclName, AclServiceManager.Action action) {
+ if (null == aceList) {
+ return;
+ }
+ for (Ace ace : aceList) {
+ SecurityRuleAttr aceAttributes = ace.getAugmentation(SecurityRuleAttr.class);
+ if (aceAttributes != null && aceAttributes.getRemoteGroupId() != null) {
+ if (action == AclServiceManager.Action.ADD) {
+ aclDataUtil.addRemoteAclId(aceAttributes.getRemoteGroupId(), new Uuid(aclName));
+ } else {
+ aclDataUtil.removeRemoteAclId(aceAttributes.getRemoteGroupId(), new Uuid(aclName));
+ }
+ }
+ }
}
@Override
return updatedAceList;
}
List<Ace> currentAceList = new ArrayList<>(currentAcl.getAccessListEntries().getAce());
- for (Iterator<Ace> iterator = updatedAceList.iterator(); iterator.hasNext(); ) {
+ for (Iterator<Ace> iterator = updatedAceList.iterator(); iterator.hasNext();) {
Ace ace1 = iterator.next();
for (Ace ace2 : currentAceList) {
if (ace1.getRuleName().equals(ace2.getRuleName())) {