summaryrefslogtreecommitdiffstats
path: root/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclCustomizer.java
diff options
context:
space:
mode:
Diffstat (limited to 'acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclCustomizer.java')
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclCustomizer.java73
1 files changed, 71 insertions, 2 deletions
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclCustomizer.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclCustomizer.java
index ee6a9aeed..70fdbdea2 100644
--- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclCustomizer.java
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclCustomizer.java
@@ -16,6 +16,13 @@
package io.fd.hc2vpp.acl.write;
+import static com.google.common.base.Preconditions.checkState;
+import static io.fd.hc2vpp.acl.write.VppAclCustomizer.AclReferenceCheck.checkAclReferenced;
+import static java.lang.String.format;
+import static java.util.Collections.emptyList;
+import static java.util.Optional.ofNullable;
+
+import com.google.common.base.Optional;
import io.fd.hc2vpp.acl.util.AclContextManager;
import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
import io.fd.hc2vpp.acl.util.acl.AclDataExtractor;
@@ -26,9 +33,24 @@ import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer;
import io.fd.honeycomb.translate.write.WriteContext;
import io.fd.honeycomb.translate.write.WriteFailedException;
import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AclBase;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl;
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.AclKey;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.InterfaceAclAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.VppAclInterfaceAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.VppAclsBaseAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.VppMacipAclsBaseAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.Egress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.Ingress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppAcl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppMacipAcl;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
public class VppAclCustomizer extends FutureJVppAclCustomizer
@@ -91,10 +113,14 @@ public class VppAclCustomizer extends FutureJVppAclCustomizer
@Override
public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataBefore,
@Nonnull final WriteContext writeContext) throws WriteFailedException {
- // According to VPP team, acl references should be removed before trying to remove ACL
- // For mac-ip, reference should be removed during removal of mac-ip, so no need to check in hc
validateAcl(dataBefore);
+ final List<Interface> references = checkAclReferenced(writeContext, dataBefore);
+ // references must be check, to not leave dead references in configuration
+ checkState(references.isEmpty(),
+ "%s cannot be removed, it is referenced in following interfaces %s", dataBefore,
+ references);
+
final MappingContext mappingContext = writeContext.getMappingContext();
if (isStandardAcl(dataBefore)) {
@@ -107,4 +133,47 @@ public class VppAclCustomizer extends FutureJVppAclCustomizer
new IllegalArgumentException("Unsupported acl option"));
}
}
+
+ static final class AclReferenceCheck {
+
+ static List<Interface> checkAclReferenced(@Nonnull final WriteContext writeContext,
+ @Nonnull final Acl acl) {
+ final Optional<Interfaces> readAfter = writeContext.readAfter(InstanceIdentifier.create(Interfaces.class));
+ if (!readAfter.isPresent() || readAfter.get().getInterface() == null) {
+ return Collections.emptyList();
+ }
+
+ final List<Interface> interfaces = readAfter.get().getInterface();
+ final Class<? extends AclBase> aclType = acl.getAclType();
+ final String aclName = acl.getAclName();
+
+ if (aclType.equals(VppAcl.class)) {
+ return interfaces.stream()
+ .filter(iface -> ofNullable(iface.getAugmentation(VppAclInterfaceAugmentation.class))
+ .map(InterfaceAclAttributes::getAcl)
+ .filter(references ->
+ checkVppAcls(references.getIngress(), aclName) ||
+ checkVppAcls(references.getEgress(), aclName)).isPresent()
+ ).collect(Collectors.toList());
+ } else if (aclType.equals(VppMacipAcl.class)) {
+ return interfaces.stream()
+ .filter(iface -> ofNullable(iface.getAugmentation(VppAclInterfaceAugmentation.class))
+ .map(InterfaceAclAttributes::getAcl)
+ .map(aclAttr -> aclAttr.getIngress())
+ .map(VppMacipAclsBaseAttributes::getVppMacipAcl)
+ .filter(vppMacipAcl -> vppMacipAcl.getName().equals(aclName))
+ .isPresent())
+ .collect(Collectors.toList());
+ } else {
+ throw new IllegalArgumentException(format("Acl type %s not supported", aclType));
+ }
+ }
+
+ static boolean checkVppAcls(@Nullable final VppAclsBaseAttributes attrs, @Nonnull final String name) {
+ return ofNullable(attrs).map(VppAclsBaseAttributes::getVppAcls)
+ .orElse(emptyList())
+ .stream().anyMatch(acl -> acl.getName().equals(name));
+
+ }
+ }
}