summaryrefslogtreecommitdiffstats
path: root/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write
diff options
context:
space:
mode:
Diffstat (limited to 'acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write')
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/AclCustomizer.java (renamed from acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclCustomizer.java)38
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/AclValidator.java233
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclCustomizer.java155
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclMacIpCustomizer.java69
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclValidator.java178
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/AbstractAclWriterFactory.java6
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/AclWriterFactory.java39
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/InterfaceAclWriterFactory.java35
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/VppAclWriterFactory.java46
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/request/AclAddReplaceRequest.java132
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/request/AclInterfaceAssignmentRequest.java172
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/request/MacIpInterfaceAssignmentRequest.java113
12 files changed, 843 insertions, 373 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/AclCustomizer.java
index 00cd8a56c..1161c09ef 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/AclCustomizer.java
@@ -19,26 +19,25 @@ package io.fd.hc2vpp.acl.write;
import io.fd.hc2vpp.acl.util.AclContextManager;
import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
import io.fd.hc2vpp.acl.util.acl.AclDataExtractor;
-import io.fd.hc2vpp.acl.util.acl.AclWriter;
-import io.fd.honeycomb.translate.MappingContext;
+import io.fd.hc2vpp.acl.write.request.AclAddReplaceRequest;
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 javax.annotation.Nonnull;
-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.access.control.list.rev181001.acls.Acl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.AclKey;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-public class VppAclCustomizer extends FutureJVppAclCustomizer
- implements ListWriterCustomizer<Acl, AclKey>, AclDataExtractor, AclWriter {
+public class AclCustomizer extends FutureJVppAclCustomizer
+ implements ListWriterCustomizer<Acl, AclKey>, AclDataExtractor {
private final AclContextManager standardAclContext;
private final AclContextManager macIpAclContext;
- public VppAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
- @Nonnull final AclContextManager standardAclContext,
- @Nonnull final AclContextManager macIpAclContext) {
+ public AclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
+ @Nonnull final AclContextManager standardAclContext,
+ @Nonnull final AclContextManager macIpAclContext) {
super(jVppAclFacade);
this.standardAclContext = standardAclContext;
this.macIpAclContext = macIpAclContext;
@@ -47,12 +46,11 @@ public class VppAclCustomizer extends FutureJVppAclCustomizer
@Override
public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataAfter,
@Nonnull final WriteContext writeContext) throws WriteFailedException {
- final MappingContext mappingContext = writeContext.getMappingContext();
-
+ AclAddReplaceRequest request = new AclAddReplaceRequest(getjVppAclFacade(), writeContext.getMappingContext());
if (isStandardAcl(dataAfter)) {
- addStandardAcl(getjVppAclFacade(), id, dataAfter, standardAclContext, mappingContext);
+ request.addStandardAcl(id, dataAfter, standardAclContext);
} else if (isMacIpAcl(dataAfter)) {
- addMacIpAcl(getjVppAclFacade(), id, dataAfter, macIpAclContext, mappingContext);
+ request.addMacIpAcl(id, dataAfter, macIpAclContext);
} else {
// double check, first one done by validation
throw new WriteFailedException.CreateFailedException(id, dataAfter,
@@ -64,17 +62,17 @@ public class VppAclCustomizer extends FutureJVppAclCustomizer
public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataBefore,
@Nonnull final Acl dataAfter, @Nonnull final WriteContext writeContext)
throws WriteFailedException {
- final MappingContext mappingContext = writeContext.getMappingContext();
+ AclAddReplaceRequest request = new AclAddReplaceRequest(getjVppAclFacade(), writeContext.getMappingContext());
if (isStandardAcl(dataAfter)) {
- updateStandardAcl(getjVppAclFacade(), id, dataAfter, standardAclContext, mappingContext);
+ request.updateStandardAcl(id, dataAfter, standardAclContext);
} else if (isMacIpAcl(dataAfter)) {
synchronized (macIpAclContext) {
// there is no direct support for update of mac-ip acl, but only one is allowed per interface
// so it is atomic from vpp standpoint. Enclosed in synchronized block to prevent issues with
// multiple threads managing naming context
- deleteMacIpAcl(getjVppAclFacade(), id, dataBefore, macIpAclContext, mappingContext);
- addMacIpAcl(getjVppAclFacade(), id, dataAfter, macIpAclContext, mappingContext);
+ request.deleteMacIpAcl(id, dataBefore, macIpAclContext);
+ request.addMacIpAcl(id, dataAfter, macIpAclContext);
}
} else {
// double check, first one done by validation
@@ -86,12 +84,12 @@ public class VppAclCustomizer extends FutureJVppAclCustomizer
@Override
public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataBefore,
@Nonnull final WriteContext writeContext) throws WriteFailedException {
- final MappingContext mappingContext = writeContext.getMappingContext();
+ AclAddReplaceRequest request = new AclAddReplaceRequest(getjVppAclFacade(), writeContext.getMappingContext());
if (isStandardAcl(dataBefore)) {
- deleteStandardAcl(getjVppAclFacade(), id, dataBefore, standardAclContext, mappingContext);
+ request.deleteStandardAcl(id, dataBefore, standardAclContext);
} else if (isMacIpAcl(dataBefore)) {
- deleteMacIpAcl(getjVppAclFacade(), id, dataBefore, macIpAclContext, mappingContext);
+ request.deleteMacIpAcl(id, dataBefore, macIpAclContext);
} else {
// double check, first one done by validation
throw new WriteFailedException.DeleteFailedException(id,
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/AclValidator.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/AclValidator.java
new file mode 100644
index 000000000..b7aaebcff
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/AclValidator.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.acl.write;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import io.fd.hc2vpp.acl.AclIIds;
+import io.fd.hc2vpp.acl.util.acl.AclDataExtractor;
+import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException;
+import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException;
+import io.fd.honeycomb.translate.write.DataValidationFailedException.UpdateValidationFailedException;
+import io.fd.honeycomb.translate.write.Validator;
+import io.fd.honeycomb.translate.write.WriteContext;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.acl.rev181022.VppAcl;
+import org.opendaylight.yang.gen.v1.http.fd.io.hc2vpp.yang.vpp.acl.rev181022.VppMacipAcl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.AclBase;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.Acl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.AttachmentPoints;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.acl.Aces;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.acl.aces.Ace;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.acl.aces.ace.Matches;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.acl.aces.ace.matches.L3;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.acl.aces.ace.matches.l2.Eth;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.acl.aces.ace.matches.l3.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.acl.aces.ace.matches.l3.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points._interface.acl.AclSets;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points._interface.acl.acl.sets.AclSet;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev181001.acl.ipv4.header.fields.source.network.SourceIpv4Network;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev181001.acl.ipv6.header.fields.source.network.SourceIpv6Network;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public final class AclValidator implements Validator<Acl>, AclDataExtractor {
+
+ private static final Set<Class<? extends AclBase>> SUPPORTED_ACL_TYPES =
+ ImmutableSet.of(VppAcl.class, VppMacipAcl.class);
+
+ @Override
+ public void validateWrite(final InstanceIdentifier<Acl> id, final Acl dataAfter, final WriteContext ctx)
+ throws CreateValidationFailedException {
+ try {
+ validateAcl(dataAfter);
+ } catch (RuntimeException e) {
+ throw new CreateValidationFailedException(id, dataAfter, e);
+ }
+ }
+
+ @Override
+ public void validateUpdate(final InstanceIdentifier<Acl> id, final Acl dataBefore, final Acl dataAfter,
+ final WriteContext ctx) throws UpdateValidationFailedException {
+ try {
+ validateAcl(dataAfter);
+ } catch (RuntimeException e) {
+ throw new UpdateValidationFailedException(id, dataBefore, dataAfter, e);
+ }
+ }
+
+ @Override
+ public void validateDelete(final InstanceIdentifier<Acl> id, final Acl dataBefore, final WriteContext ctx)
+ throws DeleteValidationFailedException {
+ try {
+ validateAcl(dataBefore);
+ final List<String> references = checkAclReferenced(ctx, 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);
+ } catch (RuntimeException e) {
+ throw new DeleteValidationFailedException(id, e);
+ }
+ }
+
+ private static void validateAcl(@Nonnull final Acl acl) {
+ hasAceList(acl);
+ isSupportedAclType(acl);
+ hasConsistentAceTypeForAclType(acl);
+ }
+
+ private static void hasAceList(final Acl acl) {
+ final Aces accessListEntries = acl.getAces();
+ checkArgument(accessListEntries != null, "The access-list-entries container is not defined.");
+ final List<Ace> ace = accessListEntries.getAce();
+ checkArgument(ace != null, "The ace list is not defined.");
+ checkArgument(!ace.isEmpty(), "The ace list is empty.");
+ }
+
+ private static void isSupportedAclType(final Acl acl) {
+ checkArgument(SUPPORTED_ACL_TYPES.contains(acl.getType()),
+ "Unsupported Acl type %s detected for acl %s, allowed types are %s", acl.getType(),
+ acl.getName(), SUPPORTED_ACL_TYPES);
+ }
+
+ private static void hasConsistentAceTypeForAclType(final Acl acl) {
+ Class<? extends AclBase> type = acl.getType();
+ Preconditions.checkNotNull(type, "Cannot resolve Acl type for validation of Acl: {}", acl);
+ Preconditions.checkNotNull(acl.getAces(), "ACEs are missing for validation of Acl: {}", acl);
+ Preconditions.checkNotNull(acl.getAces().getAce(), "List of ACEs is null for validation of Acl: {}", acl);
+ if (type.equals(VppAcl.class)) {
+ Set<Ace> unsupportedVppAcls =
+ acl.getAces().getAce().stream().filter(ace -> !isVppAce(ace)).collect(Collectors.toSet());
+ checkArgument(unsupportedVppAcls.isEmpty(), "Detected unsupported ace types [%s] for ACL %s",
+ unsupportedVppAcls, acl.getName());
+ }
+
+ if (type.equals(VppMacipAcl.class)) {
+ Set<Ace> unsupportedVppMacipAclAcls =
+ acl.getAces().getAce().stream().filter(ace -> !isVppMacipAclAce(ace)).collect(Collectors.toSet());
+ checkArgument(unsupportedVppMacipAclAcls.isEmpty(), "Detected unsupported ace types [%s] for ACL %s",
+ unsupportedVppMacipAclAcls, acl.getName());
+ }
+ }
+
+ private static boolean isVppMacipAclAce(final Ace ace) {
+ Matches matches = Preconditions
+ .checkNotNull(ace.getMatches(), "Cannot validate VppMacipAcl type for Ace: {}, matches are not defined",
+ ace);
+ if (matches.getL2() == null || !(matches.getL2() instanceof Eth)) {
+ return false;
+ }
+
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.acl.aces.ace.matches.l2.eth.Eth
+ eth = ((Eth) matches.getL2()).getEth();
+ if (eth == null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ private static boolean isVppAce(final Ace ace) {
+ Matches matches = Preconditions
+ .checkNotNull(ace.getMatches(), "Cannot validate VppMacipAcl type for Ace: {}, matches are not defined",
+ ace);
+ L3 l3 = matches.getL3();
+ if (l3 == null || (!(l3 instanceof Ipv4)) && (!(l3 instanceof Ipv6))) {
+ return false;
+ }
+
+ if (l3 instanceof Ipv4) {
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.acl.aces.ace.matches.l3.ipv4.Ipv4
+ ipv4 = ((Ipv4) l3).getIpv4();
+ if (ipv4 == null || ipv4.getSourceNetwork() == null ||
+ !(ipv4.getSourceNetwork() instanceof SourceIpv4Network)) {
+ return false;
+ }
+ }
+
+ if (l3 instanceof Ipv6) {
+ org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.acl.aces.ace.matches.l3.ipv6.Ipv6
+ ipv6 = ((Ipv6) l3).getIpv6();
+ if (ipv6 == null || ipv6.getSourceNetwork() == null ||
+ !(ipv6.getSourceNetwork() instanceof SourceIpv6Network)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ @VisibleForTesting
+ static List<String> checkAclReferenced(@Nonnull final WriteContext writeContext, @Nonnull final Acl acl) {
+ Preconditions.checkNotNull(acl.getType(), "Cannot validate acl: {}, type is not set.", acl);
+ if (!acl.getType().equals(VppAcl.class) && !acl.getType().equals(VppMacipAcl.class)) {
+ throw new IllegalArgumentException(String.format("Acl type %s not supported", acl.getType()));
+ }
+
+ Optional<AttachmentPoints> attachmentPointsOpt = writeContext.readAfter(AclIIds.ACLS_AP);
+ if (!attachmentPointsOpt.isPresent() || attachmentPointsOpt.get().getInterface() == null) {
+ return Collections.emptyList();
+ }
+
+ final List<Interface> interfaces = attachmentPointsOpt.get().getInterface();
+ if (interfaces == null) {
+ return Collections.emptyList();
+ }
+ final String aclName = acl.getName();
+
+ HashMap<String, AclSets> sets = getIngressAclSets(interfaces);
+ sets.putAll(getEgressAclSets(interfaces));
+ List<String> referencedIfcs = new ArrayList<>();
+ sets.forEach((ifc, aclSets) -> {
+ if (aclSets.getAclSet() != null) {
+ if (aclSets.getAclSet().stream()
+ .map(AclSet::getName)
+ .filter(Objects::nonNull)
+ .anyMatch(name -> name.equalsIgnoreCase(aclName))) {
+ referencedIfcs.add(ifc);
+ }
+ }
+ });
+ return referencedIfcs.stream().distinct().collect(Collectors.toList());
+ }
+
+ private static HashMap<String, AclSets> getEgressAclSets(final List<Interface> interfaces) {
+ HashMap<String, AclSets> map = new HashMap<>();
+ interfaces.stream().filter(anInterface -> anInterface.getEgress() != null)
+ .forEach(anInterface -> map.put(anInterface.getInterfaceId(), anInterface.getEgress().getAclSets()));
+ return map;
+ }
+
+ private static HashMap<String, AclSets> getIngressAclSets(final List<Interface> interfaces) {
+ HashMap<String, AclSets> map = new HashMap<>();
+ interfaces.stream().filter(anInterface -> anInterface.getIngress() != null)
+ .forEach(anInterface -> map.put(anInterface.getInterfaceId(), anInterface.getIngress().getAclSets()));
+ return map;
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclCustomizer.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclCustomizer.java
index a6ca35af3..622a84d93 100644
--- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclCustomizer.java
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclCustomizer.java
@@ -16,82 +16,177 @@
package io.fd.hc2vpp.acl.write;
+import static io.fd.hc2vpp.acl.write.request.MacIpInterfaceAssignmentRequest.deleteExisting;
import static java.util.stream.Collectors.toList;
import io.fd.hc2vpp.acl.util.AclContextManager;
import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
-import io.fd.hc2vpp.acl.util.iface.acl.AclInterfaceAssignmentRequest;
+import io.fd.hc2vpp.acl.write.request.AclInterfaceAssignmentRequest;
+import io.fd.hc2vpp.acl.write.request.MacIpInterfaceAssignmentRequest;
import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.MappingContext;
import io.fd.honeycomb.translate.spi.write.WriterCustomizer;
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 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._interface.acl.attributes.Acl;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAcls;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points._interface.acl.AclSets;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points._interface.acl.acl.sets.AclSet;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
/**
* Handles acl assignments(only standard ones, mac-ip have dedicated customizer)
*/
-public class InterfaceAclCustomizer extends FutureJVppAclCustomizer implements WriterCustomizer<Acl> {
+public class InterfaceAclCustomizer extends FutureJVppAclCustomizer implements WriterCustomizer<Interface> {
private final NamingContext interfaceContext;
private final AclContextManager standardAclContext;
+ private final AclContextManager macIpAclContext;
public InterfaceAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
@Nonnull final NamingContext interfaceContext,
- @Nonnull final AclContextManager standardAclContext) {
+ @Nonnull final AclContextManager standardAclContext,
+ @Nonnull final AclContextManager macIpAclContext) {
super(jVppAclFacade);
this.interfaceContext = interfaceContext;
this.standardAclContext = standardAclContext;
+ this.macIpAclContext = macIpAclContext;
+ }
+
+ private static List<String> getAclNames(final AclSets acls) {
+ if (acls == null || acls.getAclSet() == null) {
+ return Collections.emptyList();
+ } else {
+ return acls.getAclSet().stream().map(AclSet::getName).collect(toList());
+ }
}
@Override
- public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataAfter,
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Interface> id,
+ @Nonnull final Interface dataAfter,
@Nonnull final WriteContext writeContext) throws WriteFailedException {
- AclInterfaceAssignmentRequest.create(writeContext.getMappingContext())
- .standardAclContext(standardAclContext)
- .interfaceContext(interfaceContext)
- .identifier(id)
- .inputAclNames(getAclNames(dataAfter.getIngress()))
- .outputAclNames(getAclNames(dataAfter.getEgress()))
- .executeAsCreate(getjVppAclFacade());
+ AclSets egress = dataAfter.getEgress() != null ? dataAfter.getEgress().getAclSets() : null;
+ AclSets ingress = dataAfter.getIngress() != null ? dataAfter.getIngress().getAclSets() : null;
+ List<String> macIngress = parseMacRules(getAclNames(ingress), writeContext.getMappingContext());
+ List<String> standardIngress = parseStandardRules(getAclNames(ingress), writeContext.getMappingContext());
+ List<String> standardEgress = parseStandardRules(getAclNames(egress), writeContext.getMappingContext());
+
+ // Process standard ACLs
+ if (!standardIngress.isEmpty() || !standardEgress.isEmpty()) {
+ AclInterfaceAssignmentRequest.create(writeContext.getMappingContext())
+ .standardAclContext(standardAclContext)
+ .interfaceContext(interfaceContext)
+ .identifier(id)
+ .inputAclNames(standardIngress)
+ .outputAclNames(standardEgress)
+ .executeAsCreate(getjVppAclFacade());
+ }
+ // Process mac ACLs
+ if (!macIngress.isEmpty()) {
+ addMacAcls(id, writeContext, macIngress);
+ }
}
@Override
- public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataBefore,
- @Nonnull final Acl dataAfter, @Nonnull final WriteContext writeContext)
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Interface> id,
+ @Nonnull final Interface dataBefore,
+ @Nonnull final Interface dataAfter, @Nonnull final WriteContext writeContext)
throws WriteFailedException {
+ AclSets egress = dataAfter.getEgress() != null ? dataAfter.getEgress().getAclSets() : null;
+ AclSets ingress = dataAfter.getIngress() != null ? dataAfter.getIngress().getAclSets() : null;
+ List<String> standardIngress = parseStandardRules(getAclNames(ingress), writeContext.getMappingContext());
+ List<String> standardEgress = parseStandardRules(getAclNames(egress), writeContext.getMappingContext());
+
+ // update standard ACLs
AclInterfaceAssignmentRequest.create(writeContext.getMappingContext())
.standardAclContext(standardAclContext)
.interfaceContext(interfaceContext)
.identifier(id)
- .inputAclNames(getAclNames(dataAfter.getIngress()))
- .outputAclNames(getAclNames(dataAfter.getEgress()))
+ .inputAclNames(standardIngress)
+ .outputAclNames(standardEgress)
.executeAsUpdate(getjVppAclFacade(), dataBefore, dataAfter);
+
+ // Process mac ACLs
+ AclSets ingressBefore = dataBefore.getIngress() != null ? dataBefore.getIngress().getAclSets() : null;
+ List<String> macIngressAfter = parseMacRules(getAclNames(ingress), writeContext.getMappingContext());
+ List<String> macIngressBefore = parseMacRules(getAclNames(ingressBefore), writeContext.getMappingContext());
+ List<String> added =
+ macIngressAfter.stream().filter(acl -> !macIngressBefore.contains(acl)).collect(Collectors.toList());
+ List<String> removed =
+ macIngressBefore.stream().filter(acl -> !macIngressAfter.contains(acl)).collect(Collectors.toList());
+
+ if (!removed.isEmpty()) {
+ deleteMacACLs(id, writeContext, removed);
+ }
+
+ if (!added.isEmpty()) {
+ addMacAcls(id, writeContext, added);
+ }
}
@Override
- public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataBefore,
- @Nonnull final WriteContext writeContext) throws WriteFailedException {
- AclInterfaceAssignmentRequest.create(writeContext.getMappingContext())
- .standardAclContext(standardAclContext)
- .interfaceContext(interfaceContext)
- .identifier(id)
- .executeAsDelete(getjVppAclFacade());
+ public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Interface> id,
+ @Nonnull final Interface dataBefore, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ AclSets ingress = dataBefore.getIngress() != null ? dataBefore.getIngress().getAclSets() : null;
+ List<String> standardIngress = parseStandardRules(getAclNames(ingress), writeContext.getMappingContext());
+ List<String> macIngress = parseMacRules(getAclNames(ingress), writeContext.getMappingContext());
+
+ //Process standard ACLs
+ if (!standardIngress.isEmpty()) {
+ AclInterfaceAssignmentRequest.create(writeContext.getMappingContext())
+ .standardAclContext(standardAclContext)
+ .interfaceContext(interfaceContext)
+ .identifier(id)
+ .executeAsDelete(getjVppAclFacade());
+ }
+
+ // Process mac ACLs
+ if (!macIngress.isEmpty()) {
+ deleteMacACLs(id, writeContext, macIngress);
+ }
}
- private static List<String> getAclNames(final VppAclsBaseAttributes acls) {
- if (acls == null || acls.getVppAcls() == null) {
- return Collections.emptyList();
- } else {
- return acls.getVppAcls().stream().map(VppAcls::getName).collect(toList());
+ private List<String> parseMacRules(final List<String> ingress, final MappingContext mappingContext) {
+ return ingress.stream()
+ .filter(aclName -> macIpAclContext.containsAcl(aclName, mappingContext)).collect(Collectors.toList());
+ }
+
+ private List<String> parseStandardRules(final List<String> ingress, final MappingContext mappingContext) {
+ return ingress.stream()
+ .filter(aclName -> standardAclContext.containsAcl(aclName, mappingContext))
+ .collect(Collectors.toList());
+ }
+
+
+ private void addMacAcls(@Nonnull final InstanceIdentifier<Interface> id,
+ @Nonnull final WriteContext writeContext, final List<String> added)
+ throws WriteFailedException {
+ for (String macAcl : added) {
+ MacIpInterfaceAssignmentRequest.addNew(writeContext.getMappingContext())
+ .identifier(id)
+ .aclName(macAcl)
+ .macIpAclContext(macIpAclContext)
+ .interfaceContext(interfaceContext)
+ .execute(getjVppAclFacade());
}
}
+ private void deleteMacACLs(@Nonnull final InstanceIdentifier<Interface> id,
+ @Nonnull final WriteContext writeContext, final List<String> macAcls)
+ throws WriteFailedException {
+ for (String macAcl : macAcls) {
+ deleteExisting(writeContext.getMappingContext())
+ .identifier(id)
+ .aclName(macAcl)
+ .macIpAclContext(macIpAclContext)
+ .interfaceContext(interfaceContext)
+ .execute(getjVppAclFacade());
+ }
+ }
}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclMacIpCustomizer.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclMacIpCustomizer.java
deleted file mode 100644
index fc0acd223..000000000
--- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclMacIpCustomizer.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.hc2vpp.acl.write;
-
-import static io.fd.hc2vpp.acl.util.iface.macip.MacIpInterfaceAssignmentRequest.addNew;
-import static io.fd.hc2vpp.acl.util.iface.macip.MacIpInterfaceAssignmentRequest.deleteExisting;
-
-import io.fd.hc2vpp.acl.util.AclContextManager;
-import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
-import io.fd.hc2vpp.common.translate.util.NamingContext;
-import io.fd.honeycomb.translate.spi.write.WriterCustomizer;
-import io.fd.honeycomb.translate.write.WriteContext;
-import io.fd.honeycomb.translate.write.WriteFailedException;
-import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
-import javax.annotation.Nonnull;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.macip.acls.base.attributes.VppMacipAcl;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-public class InterfaceAclMacIpCustomizer extends FutureJVppAclCustomizer implements WriterCustomizer<VppMacipAcl> {
-
- private final AclContextManager macIpAclContext;
- private final NamingContext interfaceContext;
-
- public InterfaceAclMacIpCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
- @Nonnull final AclContextManager macIpAclContext,
- @Nonnull final NamingContext interfaceContext) {
- super(jVppAclFacade);
- this.macIpAclContext = macIpAclContext;
- this.interfaceContext = interfaceContext;
- }
-
- @Override
- public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<VppMacipAcl> id,
- @Nonnull final VppMacipAcl dataAfter,
- @Nonnull final WriteContext writeContext) throws WriteFailedException {
- addNew(writeContext.getMappingContext())
- .identifier(id)
- .aclName(dataAfter.getName())
- .macIpAclContext(macIpAclContext)
- .interfaceContext(interfaceContext)
- .execute(getjVppAclFacade());
- }
-
- @Override
- public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<VppMacipAcl> id,
- @Nonnull final VppMacipAcl dataBefore,
- @Nonnull final WriteContext writeContext) throws WriteFailedException {
- deleteExisting(writeContext.getMappingContext())
- .identifier(id)
- .aclName(dataBefore.getName())
- .macIpAclContext(macIpAclContext)
- .interfaceContext(interfaceContext)
- .execute(getjVppAclFacade());
- }
-}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclValidator.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclValidator.java
deleted file mode 100644
index 942d3bcb3..000000000
--- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclValidator.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (c) 2018 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.hc2vpp.acl.write;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static java.lang.String.format;
-import static java.util.Collections.emptyList;
-import static java.util.Optional.ofNullable;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import io.fd.hc2vpp.acl.util.acl.AclDataExtractor;
-import io.fd.honeycomb.translate.write.DataValidationFailedException.CreateValidationFailedException;
-import io.fd.honeycomb.translate.write.DataValidationFailedException.DeleteValidationFailedException;
-import io.fd.honeycomb.translate.write.DataValidationFailedException.UpdateValidationFailedException;
-import io.fd.honeycomb.translate.write.Validator;
-import io.fd.honeycomb.translate.write.WriteContext;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-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.acl.AccessListEntries;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.Matches;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.matches.AceType;
-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.vpp.acl.rev170615.VppAcl;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev170615.VppMacipAcl;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev170615.access.lists.acl.access.list.entries.ace.matches.ace.type.VppAce;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev170615.access.lists.acl.access.list.entries.ace.matches.ace.type.VppMacipAce;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-public final class VppAclValidator implements Validator<Acl>, AclDataExtractor {
-
- private static final Set<Class<? extends AclBase>> SUPPORTED_ACL_TYPES =
- ImmutableSet.of(VppAcl.class, VppMacipAcl.class);
- private static final Map<Class<? extends AclBase>, Class<? extends AceType>> ACL_ACE_PAIRS =
- ImmutableMap.of(VppAcl.class, VppAce.class, VppMacipAcl.class, VppMacipAce.class);
-
- @Override
- public void validateWrite(final InstanceIdentifier<Acl> id, final Acl dataAfter, final WriteContext ctx)
- throws CreateValidationFailedException {
- try {
- validateAcl(dataAfter);
- } catch (RuntimeException e) {
- throw new CreateValidationFailedException(id, dataAfter, e);
- }
- }
-
- @Override
- public void validateUpdate(final InstanceIdentifier<Acl> id, final Acl dataBefore, final Acl dataAfter,
- final WriteContext ctx) throws UpdateValidationFailedException {
- try {
- validateAcl(dataAfter);
- } catch (RuntimeException e) {
- throw new UpdateValidationFailedException(id, dataBefore, dataAfter, e);
- }
- }
-
- @Override
- public void validateDelete(final InstanceIdentifier<Acl> id, final Acl dataBefore, final WriteContext ctx)
- throws DeleteValidationFailedException {
- try {
- validateAcl(dataBefore);
- final List<Interface> references = checkAclReferenced(ctx, 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);
- } catch (RuntimeException e) {
- throw new DeleteValidationFailedException(id, e);
- }
- }
-
- private static void validateAcl(@Nonnull final Acl acl) {
- hasAceList(acl);
- isSupportedAclType(acl);
- hasConsistentAceTypeForAclType(acl);
- }
-
- private static void hasAceList(final Acl acl) {
- final AccessListEntries accessListEntries = acl.getAccessListEntries();
- checkArgument(accessListEntries != null, "The access-list-entries container is not defined.");
- final List<Ace> ace = accessListEntries.getAce();
- checkArgument(ace != null, "The ace list is not defined.");
- checkArgument(!ace.isEmpty(), "The ace list is empty.");
- }
-
- private static void isSupportedAclType(final Acl acl) {
- checkArgument(SUPPORTED_ACL_TYPES.contains(acl.getAclType()),
- "Unsupported Acl type %s detected for acl %s, allowed types are %s", acl.getAclType(),
- acl.getAclName(), SUPPORTED_ACL_TYPES);
- }
-
- private static void hasConsistentAceTypeForAclType(final Acl acl) {
- checkTypesSame(acl.getAccessListEntries().getAce(), acl.getAclName(),
- checkNotNull(ACL_ACE_PAIRS.get(acl.getAclType()), "Unsupported ACL type %s for ACL %s",
- acl.getAclType(), acl.getAclName()));
- }
-
- private static void checkTypesSame(final List<Ace> aces, final String aclName,
- final Class<? extends AceType> aceType) {
- final Set<AceType> unsupportedAceTypes = aces.stream()
- .map(Ace::getMatches)
- .map(Matches::getAceType)
- .filter(aceType::equals)
- .collect(Collectors.toSet());
- checkArgument(unsupportedAceTypes.isEmpty(), "Detected unsupported ace types [%s] for ACL %s, expected %s",
- unsupportedAceTypes, aclName, aceType);
- }
-
- @VisibleForTesting
- 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.augmentation(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.augmentation(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));
- }
- }
-
- private 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));
- }
-}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/AbstractAclWriterFactory.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/AbstractAclWriterFactory.java
index 37a8de2d1..8944e5977 100644
--- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/AbstractAclWriterFactory.java
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/AbstractAclWriterFactory.java
@@ -26,10 +26,10 @@ import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
/**
* Created by jsrnicek on 12.12.2016.
*/
-class AbstractAclWriterFactory {
+abstract class AbstractAclWriterFactory {
@Inject
- protected FutureJVppAclFacade futureAclFacade;
+ FutureJVppAclFacade futureAclFacade;
@Inject
@Named(AclModule.STANDARD_ACL_CONTEXT_NAME)
@@ -37,7 +37,7 @@ class AbstractAclWriterFactory {
@Inject
@Named(AclModule.MAC_IP_ACL_CONTEXT_NAME)
- protected AclContextManager macIpAClContext;
+ protected AclContextManager macIpAclContext;
@Inject
@Named("interface-context")
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/AclWriterFactory.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/AclWriterFactory.java
new file mode 100644
index 000000000..faab3023d
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/AclWriterFactory.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.acl.write.factory;
+
+import io.fd.hc2vpp.acl.AclIIds;
+import io.fd.hc2vpp.acl.write.AclCustomizer;
+import io.fd.hc2vpp.acl.write.AclValidator;
+import io.fd.honeycomb.translate.impl.write.GenericListWriter;
+import io.fd.honeycomb.translate.write.WriterFactory;
+import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder;
+import javax.annotation.Nonnull;
+
+public class AclWriterFactory extends AbstractAclWriterFactory implements WriterFactory {
+
+ @Override
+ public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) {
+
+ registry.subtreeAddBefore(AclIIds.vppAclChildren(AclIIds.ACL),
+ new GenericListWriter<>(AclIIds.ACLS_ACL,
+ new AclCustomizer(futureAclFacade, standardAclContext, macIpAclContext),
+ new AclValidator()
+ ),
+ AclIIds.aclHandledChildren(AclIIds.IFC_ACL));
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/InterfaceAclWriterFactory.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/InterfaceAclWriterFactory.java
index 12be40a14..c5144b362 100644
--- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/InterfaceAclWriterFactory.java
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/InterfaceAclWriterFactory.java
@@ -17,46 +17,27 @@
package io.fd.hc2vpp.acl.write.factory;
import com.google.common.collect.ImmutableSet;
+import io.fd.hc2vpp.acl.AclIIds;
import io.fd.hc2vpp.acl.write.InterfaceAclCustomizer;
-import io.fd.hc2vpp.acl.write.InterfaceAclMacIpCustomizer;
import io.fd.honeycomb.translate.impl.write.GenericWriter;
import io.fd.honeycomb.translate.write.WriterFactory;
import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder;
import java.util.Set;
import javax.annotation.Nonnull;
-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.VppAclInterfaceAugmentation;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.Acl;
-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._interface.acl.rev161214.vpp.acls.base.attributes.VppAcls;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.macip.acls.base.attributes.VppMacipAcl;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
public class InterfaceAclWriterFactory extends AbstractAclWriterFactory implements WriterFactory {
- static final InstanceIdentifier<Acl> ACL_IID =
- InstanceIdentifier.create(Interfaces.class).child(Interface.class)
- .augmentation(VppAclInterfaceAugmentation.class).child(Acl.class);
- private static final InstanceIdentifier<Interface> IFC_ID =
- InstanceIdentifier.create(Interfaces.class).child(Interface.class);
-
-
@Override
public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) {
- registry.subtreeAddAfter(aclHandledChildren(InstanceIdentifier.create(Acl.class)),
- new GenericWriter<>(ACL_IID,
- new InterfaceAclCustomizer(futureAclFacade, interfaceContext, standardAclContext)), IFC_ID);
-
- registry.addAfter(new GenericWriter<>(ACL_IID.child(Ingress.class).child(VppMacipAcl.class),
- new InterfaceAclMacIpCustomizer(futureAclFacade, macIpAClContext, interfaceContext)), IFC_ID);
+ registry.subtreeAddAfter(AclIIds.aclHandledChildren(AclIIds.IFC_ACL),
+ new GenericWriter<>(AclIIds.ACLS_AP_INT,
+ new InterfaceAclCustomizer(futureAclFacade, interfaceContext, standardAclContext,
+ macIpAclContext)),
+ aclRequiredIids());
}
- static Set<InstanceIdentifier<?>> aclHandledChildren(final InstanceIdentifier<Acl> parentId) {
- return ImmutableSet.of(parentId.child(Ingress.class),
- parentId.child(Ingress.class).child(VppAcls.class),
- parentId.child(Egress.class),
- parentId.child(Egress.class).child(VppAcls.class));
+ static Set<InstanceIdentifier<?>> aclRequiredIids() {
+ return ImmutableSet.of(AclIIds.IFC, AclIIds.IFC_ACL, AclIIds.ACLS_ACL);
}
}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/VppAclWriterFactory.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/VppAclWriterFactory.java
deleted file mode 100644
index 883cf4f1f..000000000
--- a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/VppAclWriterFactory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package io.fd.hc2vpp.acl.write.factory;
-
-import static io.fd.hc2vpp.acl.write.factory.InterfaceAclWriterFactory.ACL_IID;
-import static io.fd.hc2vpp.acl.write.factory.InterfaceAclWriterFactory.aclHandledChildren;
-
-import io.fd.hc2vpp.acl.util.factory.AclFactory;
-import io.fd.hc2vpp.acl.write.VppAclCustomizer;
-import io.fd.hc2vpp.acl.write.VppAclValidator;
-import io.fd.honeycomb.translate.impl.write.GenericListWriter;
-import io.fd.honeycomb.translate.write.WriterFactory;
-import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder;
-import javax.annotation.Nonnull;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.AccessLists;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.Acl;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-
-public class VppAclWriterFactory extends AbstractAclWriterFactory implements WriterFactory, AclFactory {
-
- @Override
- public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) {
- final InstanceIdentifier<AccessLists> rootNode = InstanceIdentifier.create(AccessLists.class);
-
- registry.subtreeAddBefore(vppAclChildren(InstanceIdentifier.create(Acl.class)),
- new GenericListWriter<>(rootNode.child(Acl.class),
- new VppAclCustomizer(futureAclFacade, standardAclContext, macIpAClContext),
- new VppAclValidator()
- ),
- aclHandledChildren(ACL_IID));
- }
-}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/request/AclAddReplaceRequest.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/request/AclAddReplaceRequest.java
new file mode 100644
index 000000000..29a7c7489
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/request/AclAddReplaceRequest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.fd.hc2vpp.acl.write.request;
+
+import io.fd.hc2vpp.acl.util.AclContextManager;
+import io.fd.hc2vpp.acl.util.ace.AceConverter;
+import io.fd.hc2vpp.acl.util.acl.AclDataExtractor;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.honeycomb.translate.MappingContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.acl.dto.AclAddReplace;
+import io.fd.vpp.jvpp.acl.dto.AclAddReplaceReply;
+import io.fd.vpp.jvpp.acl.dto.AclDel;
+import io.fd.vpp.jvpp.acl.dto.MacipAclAdd;
+import io.fd.vpp.jvpp.acl.dto.MacipAclAddReply;
+import io.fd.vpp.jvpp.acl.dto.MacipAclDel;
+import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
+import java.util.List;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.Acl;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.acl.aces.Ace;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class AclAddReplaceRequest implements AclDataExtractor, AceConverter, JvppReplyConsumer {
+
+ int ACL_INDEX_CREATE_NEW = -1;
+ private final FutureJVppAclFacade futureFacade;
+ private final MappingContext mappingContext;
+
+ public AclAddReplaceRequest(@Nonnull final FutureJVppAclFacade futureFacade,
+ @Nonnull final MappingContext mappingContext) {
+ this.futureFacade = futureFacade;
+ this.mappingContext = mappingContext;
+ }
+
+
+ public void addStandardAcl(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
+ @Nonnull final AclContextManager standardAclContext) throws WriteFailedException {
+
+ final AclAddReplace request = new AclAddReplace();
+
+ request.tag = getAclTag(acl);
+ request.aclIndex = ACL_INDEX_CREATE_NEW;
+
+ final List<Ace> aces = getAces(acl);
+ request.r = toStandardAclRules(aces);
+ request.count = request.r.length;
+
+ final AclAddReplaceReply reply =
+ getReplyForWrite(futureFacade.aclAddReplace(request).toCompletableFuture(), id);
+
+ // maps new acl to returned index
+ standardAclContext.addAcl(reply.aclIndex, acl.getName(), aces, mappingContext);
+ }
+
+ // according to vpp team, this was tested extensively, and should work
+ public void updateStandardAcl(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
+ @Nonnull final AclContextManager standardAclContext) throws WriteFailedException {
+
+ final AclAddReplace request = new AclAddReplace();
+
+ request.tag = getAclTag(acl);
+ // by setting existing index, request is resolved as update
+ request.aclIndex = standardAclContext.getAclIndex(acl.getName(), mappingContext);
+
+ final List<Ace> aces = getAces(acl);
+ request.r = toStandardAclRules(aces);
+ request.count = request.r.length;
+
+ final AclAddReplaceReply reply =
+ getReplyForWrite(futureFacade.aclAddReplace(request).toCompletableFuture(), id);
+
+ // overwrites existing acl metadata (aces might have been changed):
+ standardAclContext.addAcl(reply.aclIndex, acl.getName(), aces, mappingContext);
+ }
+
+ public void deleteStandardAcl(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
+ @Nonnull final AclContextManager standardAclContext) throws WriteFailedException {
+
+ final AclDel request = new AclDel();
+ final String aclName = acl.getName();
+ request.aclIndex = standardAclContext.getAclIndex(aclName, mappingContext);
+
+ getReplyForDelete(futureFacade.aclDel(request).toCompletableFuture(), id);
+
+ // removes mapping after successful delete
+ standardAclContext.removeAcl(aclName, mappingContext);
+ }
+
+ public void addMacIpAcl(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
+ @Nonnull final AclContextManager macIpAclContext) throws WriteFailedException {
+ final MacipAclAdd request = new MacipAclAdd();
+
+ request.tag = getAclTag(acl);
+
+ final List<Ace> aces = getAces(acl);
+ request.r = toMacIpAclRules(aces);
+ request.count = request.r.length;
+
+ final MacipAclAddReply reply = getReplyForWrite(futureFacade.macipAclAdd(request).toCompletableFuture(), id);
+
+ // map mac-ip acl to returned index
+ macIpAclContext.addAcl(reply.aclIndex, acl.getName(), aces, mappingContext);
+ }
+
+ public void deleteMacIpAcl(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
+ @Nonnull final AclContextManager macIpAclContext) throws WriteFailedException {
+ final MacipAclDel request = new MacipAclDel();
+ final String aclName = acl.getName();
+ request.aclIndex = macIpAclContext.getAclIndex(aclName, mappingContext);
+
+ getReplyForDelete(futureFacade.macipAclDel(request).toCompletableFuture(), id);
+
+ macIpAclContext.removeAcl(aclName, mappingContext);
+ }
+
+
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/request/AclInterfaceAssignmentRequest.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/request/AclInterfaceAssignmentRequest.java
new file mode 100644
index 000000000..2d7777e35
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/request/AclInterfaceAssignmentRequest.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package io.fd.hc2vpp.acl.write.request;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.collect.ImmutableList;
+import io.fd.hc2vpp.acl.util.AclContextManager;
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.MappingContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.acl.dto.AclInterfaceSetAclList;
+import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Stream;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points.Interface;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Multi-assignment single-request taking advantage from acl_interface_set_acl_list api
+ */
+public class AclInterfaceAssignmentRequest implements JvppReplyConsumer, ByteDataTranslator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AclInterfaceAssignmentRequest.class);
+
+ private final MappingContext mappingContext;
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points.Interface>
+ identifier;
+ private List<String> inputAclNames = Collections.emptyList();
+ private List<String> outputAclNames = Collections.emptyList();
+ private AclContextManager standardAclContext;
+ private NamingContext interfaceContext;
+
+
+ private AclInterfaceAssignmentRequest(final MappingContext mappingContext) {
+ this.mappingContext = checkNotNull(mappingContext, "Mapping context cannot be null");
+ }
+
+ public static AclInterfaceAssignmentRequest create(@Nonnull final MappingContext mappingContext) {
+ return new AclInterfaceAssignmentRequest(mappingContext);
+ }
+
+ public AclInterfaceAssignmentRequest identifier(
+ @Nonnull final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points.Interface> identifier) {
+ this.identifier = identifier;
+ return this;
+ }
+
+ public AclInterfaceAssignmentRequest inputAclNames(@Nonnull final List<String> inputAclNames) {
+ checkNotNull(inputAclNames, "Input ACL names cannot be null");
+ this.inputAclNames = ImmutableList.copyOf(inputAclNames);
+ return this;
+ }
+
+ public AclInterfaceAssignmentRequest outputAclNames(@Nonnull final List<String> outputAclNames) {
+ checkNotNull(outputAclNames, "Output ACL names cannot be null");
+ this.outputAclNames = ImmutableList.copyOf(outputAclNames);
+ return this;
+ }
+
+ public AclInterfaceAssignmentRequest standardAclContext(@Nonnull final AclContextManager standardAclContext) {
+ this.standardAclContext = standardAclContext;
+ return this;
+ }
+
+ public AclInterfaceAssignmentRequest interfaceContext(@Nonnull final NamingContext interfaceContext) {
+ this.interfaceContext = interfaceContext;
+ return this;
+ }
+
+ private void checkValidRequest() {
+ checkNotNull(identifier, "Identifier cannot be null");
+ checkNotNull(standardAclContext, "ACL context cannot be null");
+ checkNotNull(interfaceContext, "Interface context cannot be null");
+ }
+
+ public void executeAsCreate(@Nonnull final FutureJVppAclFacade api) throws WriteFailedException {
+ checkValidRequest();
+ final String interfaceName = identifier.firstKeyOf(Interface.class).getInterfaceId();
+
+ // locking on mapping context, to prevent modifying of mappings (for both contexts) during binding/execution of request
+ synchronized (mappingContext) {
+ LOG.debug(
+ "Executing acl interface assignment write request for interface={}, input ACL's={},output ACL's={}",
+ interfaceName, inputAclNames, outputAclNames);
+
+ getReplyForWrite(api.aclInterfaceSetAclList(createRequest(interfaceName)).toCompletableFuture(),
+ identifier);
+ LOG.debug(
+ "Acl interface assignment write request for interface={}, input ACL's={},output ACL's={} successfully passed",
+ interfaceName, inputAclNames, outputAclNames);
+ }
+ }
+
+ public void executeAsUpdate(@Nonnull final FutureJVppAclFacade api,
+ final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points.Interface before,
+ final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points.Interface after)
+ throws WriteFailedException {
+ checkValidRequest();
+ final String interfaceName = identifier.firstKeyOf(Interface.class).getInterfaceId();
+
+ // locking on mapping context, to prevent modifying of mappings (for both contexts) during binding/execution of request
+ synchronized (mappingContext) {
+ LOG.debug(
+ "Executing acl interface assignment update request for interface={}, input ACL's={},output ACL's={}",
+ interfaceName, inputAclNames, outputAclNames);
+
+ getReplyForUpdate(api.aclInterfaceSetAclList(createRequest(interfaceName)).toCompletableFuture(),
+ identifier, before, after);
+ LOG.debug(
+ "Acl interface assignment update request for interface={}, input ACL's={},output ACL's={} successfully passed",
+ interfaceName, inputAclNames, outputAclNames);
+ }
+ }
+
+ public void executeAsDelete(@Nonnull final FutureJVppAclFacade api) throws WriteFailedException {
+ checkValidRequest();
+ final String interfaceName = identifier.firstKeyOf(Interface.class).getInterfaceId();
+
+ // locking on mapping context, to prevent modifying of mappings (for both contexts) during binding/execution of request
+ synchronized (mappingContext) {
+ LOG.debug(
+ "Executing acl interface assignment delete request for interface={}, input ACL's={},output ACL's={}",
+ interfaceName, inputAclNames, outputAclNames);
+
+ // remove all ACLs, just in case they were set by AclInterfaceAssignmentRequest user
+ inputAclNames = Collections.emptyList();
+ outputAclNames = Collections.emptyList();
+
+ getReplyForDelete(api.aclInterfaceSetAclList(createRequest(interfaceName)).toCompletableFuture(),
+ identifier);
+ LOG.debug(
+ "Acl interface assignment delete request for interface={}, input ACL's={},output ACL's={} successfully passed",
+ interfaceName, inputAclNames, outputAclNames);
+ }
+ }
+
+ // synchronized on higher layer
+ private AclInterfaceSetAclList createRequest(final String interfaceName) {
+
+ AclInterfaceSetAclList request = new AclInterfaceSetAclList();
+ request.swIfIndex = interfaceContext.getIndex(interfaceName, mappingContext);
+ // FIXME (HC2VPP-201): possible overflow
+ request.nInput = (byte) inputAclNames.size();
+ request.count = (byte) (inputAclNames.size() + outputAclNames.size());
+ request.acls = Stream.concat(inputAclNames.stream(), outputAclNames.stream())
+ .mapToInt(aclName -> standardAclContext.getAclIndex(aclName, mappingContext))
+ .toArray();
+ return request;
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/request/MacIpInterfaceAssignmentRequest.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/request/MacIpInterfaceAssignmentRequest.java
new file mode 100644
index 000000000..b7849991b
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/request/MacIpInterfaceAssignmentRequest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2016 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package io.fd.hc2vpp.acl.write.request;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.hc2vpp.acl.util.AclContextManager;
+import io.fd.hc2vpp.common.translate.util.ByteDataTranslator;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.MappingContext;
+import io.fd.honeycomb.translate.write.WriteFailedException;
+import io.fd.vpp.jvpp.acl.dto.MacipAclInterfaceAddDel;
+import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points.Interface;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MacIpInterfaceAssignmentRequest implements ByteDataTranslator, JvppReplyConsumer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(MacIpInterfaceAssignmentRequest.class);
+
+ private final boolean isNew;
+ private final MappingContext mappingContext;
+ private InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points.Interface>
+ identifier;
+ private String aclName;
+ private AclContextManager macIpAclContext;
+ private NamingContext interfaceContext;
+
+
+ private MacIpInterfaceAssignmentRequest(final boolean isNew, final MappingContext mappingContext) {
+ this.isNew = isNew;
+ this.mappingContext = checkNotNull(mappingContext, "Mapping context cannot be null");
+ }
+
+ public static MacIpInterfaceAssignmentRequest addNew(@Nonnull final MappingContext mappingContext) {
+ return new MacIpInterfaceAssignmentRequest(true, mappingContext);
+ }
+
+ public static MacIpInterfaceAssignmentRequest deleteExisting(@Nonnull final MappingContext mappingContext) {
+ return new MacIpInterfaceAssignmentRequest(false, mappingContext);
+ }
+
+ public MacIpInterfaceAssignmentRequest identifier(
+ @Nonnull final InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev181001.acls.attachment.points.Interface> identifier) {
+ this.identifier = identifier;
+ return this;
+ }
+
+ public MacIpInterfaceAssignmentRequest aclName(@Nonnull final String aclName) {
+ this.aclName = aclName;
+ return this;
+ }
+
+ public MacIpInterfaceAssignmentRequest macIpAclContext(@Nonnull final AclContextManager macIpAclContext) {
+ this.macIpAclContext = macIpAclContext;
+ return this;
+ }
+
+ public MacIpInterfaceAssignmentRequest interfaceContext(@Nonnull final NamingContext interfaceContext) {
+ this.interfaceContext = interfaceContext;
+ return this;
+ }
+
+ private void checkValidRequest() {
+ checkNotNull(identifier, "Identifier cannot be null");
+ checkNotNull(aclName, "ACL name cannot be null");
+ checkNotNull(macIpAclContext, "ACL context cannot be null");
+ checkNotNull(interfaceContext, "Interface context cannot be null");
+ }
+
+ public void execute(@Nonnull final FutureJVppAclFacade api)
+ throws WriteFailedException {
+
+ // locking on mapping context, to prevent modifying of mappings (for both contexts) during execution of request
+ synchronized (mappingContext) {
+ checkValidRequest();
+
+ final String interfaceName = identifier.firstKeyOf(Interface.class).getInterfaceId();
+
+ MacipAclInterfaceAddDel request = new MacipAclInterfaceAddDel();
+ request.isAdd = booleanToByte(isNew);
+ request.aclIndex = macIpAclContext.getAclIndex(aclName, mappingContext);
+ request.swIfIndex =
+ interfaceContext.getIndex(interfaceName, mappingContext);
+
+ LOG.debug("Executing mac-ip interface assignment request for isNew={},aclName={},interfaceName={}", isNew,
+ aclName, interfaceName);
+ getReplyForWrite(api.macipAclInterfaceAddDel(request).toCompletableFuture(), identifier);
+ LOG.debug(
+ "Mac-ip interface assignment request for isNew={},aclName={},interfaceName={} successfully passed",
+ isNew, aclName, interfaceName);
+ }
+ }
+}