summaryrefslogtreecommitdiffstats
path: root/acl/acl-impl/src/main/java/io
diff options
context:
space:
mode:
authorJan Srnicek <jsrnicek@cisco.com>2016-12-16 13:07:56 +0100
committerMarek Gradzki <mgradzki@cisco.com>2016-12-20 13:59:56 +0100
commitf8273e10b19ecc82bdda81feef9982ce28d5de21 (patch)
tree98d2d9686bcf24f64c0c18c633554e8629f2e22e /acl/acl-impl/src/main/java/io
parente3b9212110528217c2477f588ebccc0d76ee31e1 (diff)
HONEYCOMB-310: translation layer for acl plugin
Not covered by this patch (moved to subsequent commits): - postman collection - distinguish ingress/egress ACLs while reading assigned acls - proper support for acl tag - unit tests improvements - read for acls (not necessarily assigned) - initializers Change-Id: I5a198ce1a6e20d0b1d95b4d2d83d0464fb86580c Signed-off-by: Jan Srnicek <jsrnicek@cisco.com> Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
Diffstat (limited to 'acl/acl-impl/src/main/java/io')
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/AclModule.java82
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/JVppAclProvider.java73
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/VppAclCustomizer.java194
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/VppMacIpAclCustomizer.java143
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/factory/InterfaceAclReaderFactory.java85
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/FutureJVppAclCustomizer.java38
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/AceConverter.java94
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/MacIpAceDataExtractor.java83
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/StandardAceDataExtractor.java98
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclDataExtractor.java68
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclValidator.java84
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclWriter.java125
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/acl/AclInterfaceAssignmentRequest.java162
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/macip/MacIpInterfaceAssignmentRequest.java111
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/protocol/ProtoPreBindRuleProducer.java203
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclCustomizer.java98
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclMacIpCustomizer.java78
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclCustomizer.java110
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/AbstractAclWriterFactory.java44
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/InterfaceAclWriterFactory.java59
-rw-r--r--acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/VppAclWriterFactory.java82
21 files changed, 2114 insertions, 0 deletions
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/AclModule.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/AclModule.java
new file mode 100644
index 000000000..f15119be6
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/AclModule.java
@@ -0,0 +1,82 @@
+/*
+ * 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;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.inject.AbstractModule;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.multibindings.Multibinder;
+import com.google.inject.name.Names;
+import io.fd.hc2vpp.acl.read.factory.InterfaceAclReaderFactory;
+import io.fd.hc2vpp.acl.write.factory.InterfaceAclWriterFactory;
+import io.fd.hc2vpp.acl.write.factory.VppAclWriterFactory;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.honeycomb.translate.write.WriterFactory;
+import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
+import javax.annotation.Nonnull;
+import net.jmob.guice.conf.core.ConfigurationModule;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AclModule extends AbstractModule {
+
+ public static final String STANDARD_ACL_CONTEXT_NAME = "standard-acl-context";
+ public static final String STANDARD_LEARNED_ACL_NAME_PREFIX = "standard-learned-acl-";
+ public static final String MAC_IP_ACL_CONTEXT_NAME = "mac-ip-acl-context";
+ public static final String MAC_IP_LEARNED_ACL_NAME_PREFIX = "mac-ip-acl-context";
+
+ private static final Logger LOG = LoggerFactory.getLogger(AclModule.class);
+
+ private final Class<? extends Provider<FutureJVppAclFacade>> jvppAclProviderClass;
+
+ public AclModule() {
+ this(JVppAclProvider.class);
+ }
+
+ @VisibleForTesting
+ AclModule(@Nonnull final Class<? extends Provider<FutureJVppAclFacade>> jvppAclProviderClass) {
+ this.jvppAclProviderClass = jvppAclProviderClass;
+ }
+
+ @Override
+ protected void configure() {
+ LOG.info("Configuring module Acl");
+ install(ConfigurationModule.create());
+
+ // binds JVpp Acl future facade
+ bind(FutureJVppAclFacade.class).toProvider(jvppAclProviderClass).in(Singleton.class);
+
+ bind(NamingContext.class).annotatedWith(Names.named(STANDARD_ACL_CONTEXT_NAME))
+ .toInstance(new NamingContext(STANDARD_LEARNED_ACL_NAME_PREFIX, STANDARD_ACL_CONTEXT_NAME));
+
+ bind(NamingContext.class).annotatedWith(Names.named(MAC_IP_ACL_CONTEXT_NAME))
+ .toInstance(new NamingContext(MAC_IP_LEARNED_ACL_NAME_PREFIX, MAC_IP_ACL_CONTEXT_NAME));
+
+ final Multibinder<WriterFactory> writerFactoryMultibinder =
+ Multibinder.newSetBinder(binder(), WriterFactory.class);
+ writerFactoryMultibinder.addBinding().to(VppAclWriterFactory.class);
+ writerFactoryMultibinder.addBinding().to(InterfaceAclWriterFactory.class);
+
+ final Multibinder<ReaderFactory> readerFactoryMultibinder =
+ Multibinder.newSetBinder(binder(), ReaderFactory.class);
+ readerFactoryMultibinder.addBinding().to(InterfaceAclReaderFactory.class);
+
+ LOG.info("Module Acl successfully configured");
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/JVppAclProvider.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/JVppAclProvider.java
new file mode 100644
index 000000000..b3caa0e9c
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/JVppAclProvider.java
@@ -0,0 +1,73 @@
+/*
+ * 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;
+
+import com.google.inject.Inject;
+import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer;
+import io.fd.honeycomb.infra.distro.ProviderTrait;
+import io.fd.vpp.jvpp.JVppRegistry;
+import io.fd.vpp.jvpp.VppBaseCallException;
+import io.fd.vpp.jvpp.acl.JVppAclImpl;
+import io.fd.vpp.jvpp.acl.dto.AclPluginGetVersion;
+import io.fd.vpp.jvpp.acl.dto.AclPluginGetVersionReply;
+import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
+import java.io.IOException;
+import java.util.concurrent.TimeoutException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+class JVppAclProvider extends ProviderTrait<FutureJVppAclFacade> implements JvppReplyConsumer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(JVppAclProvider.class);
+
+ @Inject
+ private JVppRegistry registry;
+
+ private static JVppAclImpl initAclApi() {
+ final JVppAclImpl jvppAcl = new JVppAclImpl();
+ // Free jvpp-acl plugin's resources on shutdown
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ LOG.info("Unloading jvpp-acl plugin");
+ jvppAcl.close();
+ LOG.info("Successfully unloaded jvpp-acl plugin");
+ }
+ });
+ return jvppAcl;
+ }
+
+ @Override
+ protected FutureJVppAclFacade create() {
+ try {
+ return reportVersionAndGet(initAclApi());
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to open VPP management connection", e);
+ } catch (TimeoutException | VppBaseCallException e) {
+ throw new IllegalStateException("Unable to load ACL plugin version", e);
+ }
+ }
+
+ private FutureJVppAclFacade reportVersionAndGet(final JVppAclImpl jvppAcl)
+ throws IOException, TimeoutException, VppBaseCallException {
+ final FutureJVppAclFacade futureFacade = new FutureJVppAclFacade(registry, jvppAcl);
+ final AclPluginGetVersionReply pluginVersion =
+ getReply(futureFacade.aclPluginGetVersion(new AclPluginGetVersion()).toCompletableFuture());
+ LOG.info("Acl plugin successfully loaded[version {}.{}]", pluginVersion.major, pluginVersion.minor);
+ return futureFacade;
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/VppAclCustomizer.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/VppAclCustomizer.java
new file mode 100644
index 000000000..90f2b2fe2
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/VppAclCustomizer.java
@@ -0,0 +1,194 @@
+/*
+ * 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.read;
+
+
+import com.google.common.base.Optional;
+import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
+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.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.ListReaderCustomizer;
+import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
+import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager.DumpCacheManagerBuilder;
+import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor;
+import io.fd.honeycomb.translate.util.read.cache.EntityDumpPostProcessingFunction;
+import io.fd.vpp.jvpp.acl.dto.AclDetailsReplyDump;
+import io.fd.vpp.jvpp.acl.dto.AclDump;
+import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDetailsReplyDump;
+import io.fd.vpp.jvpp.acl.dto.AclInterfaceListDump;
+import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.EgressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.IngressBuilder;
+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.acls.base.attributes.VppAclsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.acls.base.attributes.VppAclsKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppAcl;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class VppAclCustomizer extends FutureJVppAclCustomizer
+ implements ListReaderCustomizer<VppAcls, VppAclsKey, VppAclsBuilder>, JvppReplyConsumer, ByteDataTranslator {
+
+ private final NamingContext interfaceContext;
+ private final NamingContext standardAclContext;
+ /**
+ * true == ingress
+ * false == egress
+ */
+ private final boolean input;
+ private final DumpCacheManager<AclInterfaceListDetailsReplyDump, Integer> aclReferenceDumpManager;
+ private final DumpCacheManager<AclDetailsReplyDump, Integer> aclDumpManager;
+
+ public VppAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final NamingContext standardAclContext,
+ final boolean input) {
+ super(jVppAclFacade);
+ this.interfaceContext = interfaceContext;
+ this.standardAclContext = standardAclContext;
+ this.input = input;
+
+ aclReferenceDumpManager =
+ new DumpCacheManagerBuilder<AclInterfaceListDetailsReplyDump, Integer>()
+ .withExecutor(createAclReferenceDumpExecutor())
+ .withPostProcessingFunction(input
+ ? createInputAclFilter()
+ : createOutputAclFilter())
+ .acceptOnly(AclInterfaceListDetailsReplyDump.class)
+ .build();
+
+ aclDumpManager = new DumpCacheManagerBuilder<AclDetailsReplyDump, Integer>()
+ .withExecutor(createAclExecutor())
+ .acceptOnly(AclDetailsReplyDump.class)
+ .build();
+ }
+
+ private EntityDumpExecutor<AclDetailsReplyDump, Integer> createAclExecutor() {
+ return (identifier, params) -> {
+ AclDump request = new AclDump();
+ request.aclIndex = params;
+ return getReplyForRead(getjVppAclFacade().aclDump(request).toCompletableFuture(), identifier);
+ };
+ }
+
+ private EntityDumpPostProcessingFunction<AclInterfaceListDetailsReplyDump> createInputAclFilter() {
+ return dump -> {
+ // filters acl's to first N(those are input ones)
+ dump.aclInterfaceListDetails = dump.aclInterfaceListDetails
+ .stream()
+ .map(iface -> {
+ iface.acls = Arrays.copyOfRange(iface.acls, 0, iface.nInput - 1);
+ return iface;
+ })
+ .collect(Collectors.toList());
+ return dump;
+ };
+ }
+
+ private EntityDumpPostProcessingFunction<AclInterfaceListDetailsReplyDump> createOutputAclFilter() {
+ return dump -> {
+ // filters acl's to last N(those are output ones)
+ dump.aclInterfaceListDetails = dump.aclInterfaceListDetails
+ .stream()
+ .map(iface -> {
+ iface.acls = Arrays.copyOfRange(iface.acls, iface.nInput, iface.acls.length);
+ return iface;
+ })
+ .collect(Collectors.toList());
+ return dump;
+ };
+ }
+
+ private EntityDumpExecutor<AclInterfaceListDetailsReplyDump, Integer> createAclReferenceDumpExecutor() {
+ return (identifier, params) -> {
+ AclInterfaceListDump dumpRequest = new AclInterfaceListDump();
+ dumpRequest.swIfIndex = params;
+ return getReplyForRead(getjVppAclFacade().aclInterfaceListDump(dumpRequest).toCompletableFuture(),
+ identifier);
+ };
+ }
+
+ @Nonnull
+ @Override
+ public List<VppAclsKey> getAllIds(@Nonnull final InstanceIdentifier<VppAcls> id, @Nonnull final ReadContext context)
+ throws ReadFailedException {
+
+ final String parentInterfaceName = id.firstKeyOf(Interface.class).getName();
+ final int parentInterfaceIndex = interfaceContext.getIndex(parentInterfaceName, context.getMappingContext());
+
+ final Optional<AclInterfaceListDetailsReplyDump> dumpReply =
+ aclReferenceDumpManager.getDump(id, context.getModificationCache(), parentInterfaceIndex);
+
+ if (dumpReply.isPresent() && !dumpReply.get().aclInterfaceListDetails.isEmpty()) {
+ return Arrays.stream(dumpReply.get().aclInterfaceListDetails.get(0).acls)
+ .mapToObj(aclIndex -> standardAclContext.getName(aclIndex, context.getMappingContext()))
+ .map(aclName -> new VppAclsKey(aclName, VppAcl.class))
+ .collect(Collectors.toList());
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<VppAcls> readData) {
+ if (input) {
+ IngressBuilder.class.cast(builder).setVppAcls(readData);
+ } else {
+ EgressBuilder.class.cast(builder).setVppAcls(readData);
+ }
+ }
+
+ @Nonnull
+ @Override
+ public VppAclsBuilder getBuilder(@Nonnull final InstanceIdentifier<VppAcls> id) {
+ return new VppAclsBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<VppAcls> id,
+ @Nonnull final VppAclsBuilder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+ final VppAclsKey vppAclsKey = id.firstKeyOf(VppAcls.class);
+ final String aclName = vppAclsKey.getName();
+ final int aclIndex = standardAclContext.getIndex(aclName, ctx.getMappingContext());
+
+ final Optional<AclDetailsReplyDump> dumpReply =
+ aclDumpManager.getDump(id, ctx.getModificationCache(), aclIndex);
+
+ if (dumpReply.isPresent() && !dumpReply.get().aclDetails.isEmpty()) {
+ // FIXME (model expects hex string, but tag is written and read as ascii string)
+ // decide how tag should be handled (model change might be needed).
+ builder.setName(aclName);
+ builder.setType(vppAclsKey.getType());
+ builder.setTag(new HexString(printHexBinary(dumpReply.get().aclDetails.get(0).tag)));
+ } else {
+ throw new ReadFailedException(id,
+ new IllegalArgumentException(String.format("Acl with name %s not found", aclName)));
+ }
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/VppMacIpAclCustomizer.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/VppMacIpAclCustomizer.java
new file mode 100644
index 000000000..982d89b9a
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/VppMacIpAclCustomizer.java
@@ -0,0 +1,143 @@
+/*
+ * 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.read;
+
+import static io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor.NO_PARAMS;
+
+import com.google.common.base.Optional;
+import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
+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.ModificationCache;
+import io.fd.honeycomb.translate.read.ReadContext;
+import io.fd.honeycomb.translate.read.ReadFailedException;
+import io.fd.honeycomb.translate.spi.read.ReaderCustomizer;
+import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager;
+import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor;
+import io.fd.vpp.jvpp.acl.dto.MacipAclDetails;
+import io.fd.vpp.jvpp.acl.dto.MacipAclDetailsReplyDump;
+import io.fd.vpp.jvpp.acl.dto.MacipAclDump;
+import io.fd.vpp.jvpp.acl.dto.MacipAclInterfaceGet;
+import io.fd.vpp.jvpp.acl.dto.MacipAclInterfaceGetReply;
+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.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.HexString;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214._interface.acl.attributes.acl.IngressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.macip.acls.base.attributes.VppMacipAcl;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.vpp.macip.acls.base.attributes.VppMacipAclBuilder;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class VppMacIpAclCustomizer extends FutureJVppAclCustomizer
+ implements ReaderCustomizer<VppMacipAcl, VppMacipAclBuilder>, JvppReplyConsumer, ByteDataTranslator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(VppMacIpAclCustomizer.class);
+
+ private final DumpCacheManager<MacipAclDetailsReplyDump, Integer> macIpAclDumpManager;
+ private final DumpCacheManager<MacipAclInterfaceGetReply, Void> interfaceMacIpAclDumpManager;
+ private final NamingContext interfaceContext;
+ private final NamingContext macIpAclContext;
+
+ public VppMacIpAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final NamingContext macIpAclContext) {
+ super(jVppAclFacade);
+
+ // for dumping of Mac-ip details
+ macIpAclDumpManager = new DumpCacheManager.DumpCacheManagerBuilder<MacipAclDetailsReplyDump, Integer>()
+ .withExecutor(createMacIpDumpExecutor())
+ .acceptOnly(MacipAclDetailsReplyDump.class)
+ .build();
+
+ // for dumping of reference on interface
+ interfaceMacIpAclDumpManager = new DumpCacheManager.DumpCacheManagerBuilder<MacipAclInterfaceGetReply, Void>()
+ .withExecutor(createInterfaceMacIpDumpExecutor())
+ .acceptOnly(MacipAclInterfaceGetReply.class)
+ .build();
+ this.interfaceContext = interfaceContext;
+ this.macIpAclContext = macIpAclContext;
+ }
+
+ private EntityDumpExecutor<MacipAclDetailsReplyDump, Integer> createMacIpDumpExecutor() {
+ return (identifier, params) -> {
+ MacipAclDump request = new MacipAclDump();
+ request.aclIndex = params;
+
+ return getReplyForRead(getjVppAclFacade().macipAclDump(request).toCompletableFuture(), identifier);
+ };
+ }
+
+ private EntityDumpExecutor<MacipAclInterfaceGetReply, Void> createInterfaceMacIpDumpExecutor() {
+ return (identifier, params) -> getReplyForRead(
+ getjVppAclFacade().macipAclInterfaceGet(new MacipAclInterfaceGet()).toCompletableFuture(),
+ identifier);
+ }
+
+ @Nonnull
+ @Override
+ public VppMacipAclBuilder getBuilder(@Nonnull final InstanceIdentifier<VppMacipAcl> id) {
+ return new VppMacipAclBuilder();
+ }
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<VppMacipAcl> id,
+ @Nonnull final VppMacipAclBuilder builder,
+ @Nonnull final ReadContext ctx) throws ReadFailedException {
+ final String interfaceName = id.firstKeyOf(Interface.class).getName();
+ final MappingContext mappingContext = ctx.getMappingContext();
+ final int interfaceIndex = interfaceContext.getIndex(interfaceName, mappingContext);
+ final ModificationCache modificationCache = ctx.getModificationCache();
+ final Optional<MacipAclInterfaceGetReply> interfacesMacIpDumpReply =
+ interfaceMacIpAclDumpManager.getDump(id, modificationCache, NO_PARAMS);
+
+ if (interfacesMacIpDumpReply.isPresent() && interfaceIndex < interfacesMacIpDumpReply.get().count) {
+ final int aclIndex = interfacesMacIpDumpReply.get().acls[interfaceIndex];
+
+ final Optional<MacipAclDetailsReplyDump> macIpDumpReply =
+ macIpAclDumpManager.getDump(id, modificationCache, aclIndex);
+
+ if (macIpDumpReply.isPresent() && !macIpDumpReply.get().macipAclDetails.isEmpty()) {
+ final MacipAclDetails details = macIpDumpReply.get().macipAclDetails.get(0);
+
+ builder.setName(macIpAclContext.getName(aclIndex, mappingContext))
+ .setType(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppMacipAcl.class)
+ .setTag(new HexString(printHexBinary(details.tag)));
+ } else {
+ // this is invalid state(Interface in VPP will act as "deny-all" for security reasons), but generally
+ // it should not happen
+ throw new ReadFailedException(id,
+ new IllegalStateException(String.format("ACC with index %s not found in VPP", aclIndex)));
+ }
+ } else {
+ // this is valid state, so just logging
+ LOG.info("No Mac-ip ACL specified for Interface name={},index={}", interfaceName, interfaceIndex);
+ }
+ }
+
+ @Override
+ public void merge(@Nonnull final Builder<? extends DataObject> parentBuilder,
+ @Nonnull final VppMacipAcl readValue) {
+ IngressBuilder.class.cast(parentBuilder).setVppMacipAcl(readValue);
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/factory/InterfaceAclReaderFactory.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/factory/InterfaceAclReaderFactory.java
new file mode 100644
index 000000000..89520620d
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/read/factory/InterfaceAclReaderFactory.java
@@ -0,0 +1,85 @@
+/*
+ * 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.read.factory;
+
+import com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.hc2vpp.acl.AclModule;
+import io.fd.hc2vpp.acl.read.VppAclCustomizer;
+import io.fd.hc2vpp.acl.read.VppMacIpAclCustomizer;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.impl.read.GenericListReader;
+import io.fd.honeycomb.translate.impl.read.GenericReader;
+import io.fd.honeycomb.translate.read.ReaderFactory;
+import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder;
+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.interfaces.rev140508.InterfacesState;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.VppAclInterfaceStateAugmentation;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.VppAclInterfaceStateAugmentationBuilder;
+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.AclBuilder;
+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.EgressBuilder;
+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._interface.acl.attributes.acl.IngressBuilder;
+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 InterfaceAclReaderFactory implements ReaderFactory {
+
+ @Inject
+ private FutureJVppAclFacade futureAclFacade;
+
+ @Inject
+ @Named(AclModule.STANDARD_ACL_CONTEXT_NAME)
+ private NamingContext standardAclContext;
+
+ @Inject
+ @Named(AclModule.MAC_IP_ACL_CONTEXT_NAME)
+ private NamingContext macIpAClContext;
+
+ @Inject
+ @Named("interface-context")
+ private NamingContext interfaceContext;
+
+ private static final InstanceIdentifier<Interface>
+ IFC_ID = InstanceIdentifier.create(InterfacesState.class).child(Interface.class);
+ private static final InstanceIdentifier<VppAclInterfaceStateAugmentation> VPP_ACL_AUG_IID =
+ IFC_ID.augmentation(VppAclInterfaceStateAugmentation.class);
+ private static final InstanceIdentifier<Acl> ACL_IID = VPP_ACL_AUG_IID.child(Acl.class);
+
+ @Override
+ public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) {
+ registry.addStructuralReader(VPP_ACL_AUG_IID, VppAclInterfaceStateAugmentationBuilder.class);
+ registry.addStructuralReader(ACL_IID, AclBuilder.class);
+
+ final InstanceIdentifier<Ingress> ingressInstanceIdentifier = ACL_IID.child(Ingress.class);
+ registry.addStructuralReader(ingressInstanceIdentifier, IngressBuilder.class);
+ registry.addAfter(new GenericListReader<>(ingressInstanceIdentifier.child(VppAcls.class),
+ new VppAclCustomizer(futureAclFacade, interfaceContext, standardAclContext, true)), IFC_ID);
+ registry.addAfter(new GenericReader<>(ingressInstanceIdentifier.child(VppMacipAcl.class),
+ new VppMacIpAclCustomizer(futureAclFacade, interfaceContext, macIpAClContext)), IFC_ID);
+
+ final InstanceIdentifier<Egress> egressInstanceIdentifier = ACL_IID.child(Egress.class);
+ registry.addStructuralReader(egressInstanceIdentifier, EgressBuilder.class);
+ registry.addAfter(new GenericListReader<>(egressInstanceIdentifier.child(VppAcls.class),
+ new VppAclCustomizer(futureAclFacade, interfaceContext, standardAclContext, false)), IFC_ID);
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/FutureJVppAclCustomizer.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/FutureJVppAclCustomizer.java
new file mode 100644
index 000000000..e2d6bee58
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/FutureJVppAclCustomizer.java
@@ -0,0 +1,38 @@
+/*
+ * 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.util;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
+import javax.annotation.Nonnull;
+
+/**
+ * Holds reference to jvpp acl implementation
+ */
+public abstract class FutureJVppAclCustomizer {
+
+ private final FutureJVppAclFacade jVppAclFacade;
+
+ public FutureJVppAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade) {
+ this.jVppAclFacade = checkNotNull(jVppAclFacade, "JVpp Acl Future api is null");
+ }
+
+ public FutureJVppAclFacade getjVppAclFacade() {
+ return jVppAclFacade;
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/AceConverter.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/AceConverter.java
new file mode 100644
index 000000000..325787821
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/AceConverter.java
@@ -0,0 +1,94 @@
+/*
+ * 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.util.ace;
+
+import io.fd.hc2vpp.acl.util.ace.extractor.MacIpAceDataExtractor;
+import io.fd.hc2vpp.acl.util.ace.extractor.StandardAceDataExtractor;
+import io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer;
+import io.fd.vpp.jvpp.acl.types.AclRule;
+import io.fd.vpp.jvpp.acl.types.MacipAclRule;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+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.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.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.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppMacipAce;
+
+/**
+ * Convert Ace's to vpp rules
+ */
+public interface AceConverter extends MacIpAceDataExtractor, StandardAceDataExtractor, ProtoPreBindRuleProducer {
+
+
+ default MacipAclRule[] convertToMacIpAclRules(@Nonnull final List<Ace> aces) {
+ return aces.stream()
+ .map(ace -> {
+ final VppMacipAce macIpAce = fromMacIpAce(ace);
+
+ MacipAclRule rule = new MacipAclRule();
+
+ rule.srcMac = sourceMacAsBytes(macIpAce);
+ rule.srcMacMask = sourceMacMaskAsBytes(macIpAce);
+ rule.isPermit = macIpAction(ace);
+
+ if (macIpIsIpv6(macIpAce)) {
+ rule.isIpv6 = 1;
+ rule.srcIpAddr = ipv6Address(macIpAce);
+ rule.srcIpPrefixLen = ipv6AddressPrefix(macIpAce);
+ } else {
+ rule.isIpv6 = 0;
+ rule.srcIpAddr = ipv4Address(macIpAce);
+ rule.srcIpPrefixLen = ipv4AddressPrefix(macIpAce);
+ }
+
+ return rule;
+ })
+ .collect(Collectors.toList())
+ .toArray(new MacipAclRule[aces.size()]);
+ }
+
+ default AclRule[] convertToStandardAclRules(@Nonnull final List<Ace> aces) {
+ return aces.stream()
+ .map(ace -> {
+ final VppAce standardAce = fromStandardAce(ace);
+
+ // pre-bind rule with protocol based attributes
+ AclRule rule = createPreBindRule(standardAce);
+
+ rule.isPermit = standardAction(ace);
+
+ if (standardIsIpv6(ace)) {
+ rule.isIpv6 = 1;
+ rule.srcIpAddr = ipv6SourceAddress(standardAce);
+ rule.srcIpPrefixLen = ipv6SourceAddressPrefix(standardAce);
+ rule.dstIpAddr = ipv6DestinationAddress(standardAce);
+ rule.dstIpPrefixLen = ipv6DestinationAddressPrefix(standardAce);
+ } else {
+ rule.isIpv6 = 0;
+ rule.srcIpAddr = ipv4SourceAddress(standardAce);
+ rule.srcIpPrefixLen = ipv4SourceAddressPrefix(standardAce);
+ rule.dstIpAddr = ipv4DestinationAddress(standardAce);
+ rule.dstIpPrefixLen = ipv4DestinationAddressPrefix(standardAce);
+ }
+
+
+ return rule;
+ })
+ .collect(Collectors.toList())
+ .toArray(new AclRule[aces.size()]);
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/MacIpAceDataExtractor.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/MacIpAceDataExtractor.java
new file mode 100644
index 000000000..a0d19902a
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/MacIpAceDataExtractor.java
@@ -0,0 +1,83 @@
+/*
+ * 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.util.ace.extractor;
+
+import io.fd.hc2vpp.common.translate.util.AddressTranslator;
+import javax.annotation.Nonnull;
+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.actions.PacketHandling;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Deny;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Permit;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppMacipAceIpv4HeaderFields;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppMacipAceIpv6HeaderFields;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppMacipAce;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.ace.ip.version.AceIpv6;
+
+public interface MacIpAceDataExtractor extends AddressTranslator {
+
+ default VppMacipAce fromMacIpAce(@Nonnull final Ace ace) {
+ return VppMacipAce.class.cast(ace.getMatches().getAceType());
+ }
+
+ default boolean macIpIsIpv6(@Nonnull final VppMacipAce ace) {
+ return ace.getVppMacipAceNodes().getAceIpVersion() instanceof AceIpv6;
+ }
+
+ default byte[] sourceMacAsBytes(@Nonnull final VppMacipAce ace) {
+ return macToByteArray(ace.getVppMacipAceNodes().getSourceMacAddress().getValue());
+ }
+
+ default byte[] sourceMacMaskAsBytes(@Nonnull final VppMacipAce ace) {
+ return macToByteArray(ace.getVppMacipAceNodes().getSourceMacAddressMask().getValue());
+ }
+
+ default byte[] ipv4Address(@Nonnull final VppMacipAce ace) {
+ return ipv4AddressPrefixToArray(
+ VppMacipAceIpv4HeaderFields.class.cast(ace.getVppMacipAceNodes().getAceIpVersion()).getSourceIpv4Network());
+ }
+
+ default byte ipv4AddressPrefix(@Nonnull final VppMacipAce ace) {
+ return extractPrefix(
+ VppMacipAceIpv4HeaderFields.class.cast(ace.getVppMacipAceNodes().getAceIpVersion()).getSourceIpv4Network());
+ }
+
+ default byte[] ipv6Address(@Nonnull final VppMacipAce ace) {
+ return ipv6AddressPrefixToArray(
+ VppMacipAceIpv6HeaderFields.class.cast(ace.getVppMacipAceNodes().getAceIpVersion()).getSourceIpv6Network());
+ }
+
+ default byte ipv6AddressPrefix(@Nonnull final VppMacipAce ace) {
+ return extractPrefix(
+ VppMacipAceIpv6HeaderFields.class.cast(ace.getVppMacipAceNodes().getAceIpVersion()).getSourceIpv6Network());
+ }
+
+ /**
+ * Only 0 and 1 are allowed for mac-ip
+ */
+ default byte macIpAction(@Nonnull final Ace ace) {
+ final PacketHandling action = ace.getActions().getPacketHandling();
+ if (action instanceof Permit) {
+ return 1;
+ } else if (action instanceof Deny) {
+ return 0;
+ } else {
+ throw new IllegalArgumentException(
+ String.format("Unsupported packet-handling action %s for ACE %s", action, ace));
+ }
+ }
+
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/StandardAceDataExtractor.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/StandardAceDataExtractor.java
new file mode 100644
index 000000000..2e7ccbdc7
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/ace/extractor/StandardAceDataExtractor.java
@@ -0,0 +1,98 @@
+/*
+ * 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.util.ace.extractor;
+
+
+import com.google.common.collect.ImmutableMap;
+import io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer;
+import io.fd.hc2vpp.common.translate.util.AddressTranslator;
+import java.util.Map;
+import javax.annotation.Nonnull;
+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.actions.PacketHandling;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Deny;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.ace.actions.packet.handling.Permit;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpv4HeaderFields;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.AclIpv6HeaderFields;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.actions.packet.handling.Stateful;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.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.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.ace.ip.version.AceIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.vpp.ace.nodes.ace.ip.version.AceIpv6;
+
+
+public interface StandardAceDataExtractor extends AddressTranslator, ProtoPreBindRuleProducer {
+
+ /**
+ * Allowed packet-processing actions for Acl's
+ */
+ Map<Class<? extends PacketHandling>, Integer> ACTION_VALUE_PAIRS = ImmutableMap.of(Deny.class, 0, Permit.class, 1,
+ Stateful.class, 2);
+
+ default VppAce fromStandardAce(@Nonnull final Ace ace) {
+ return VppAce.class.cast(ace.getMatches().getAceType());
+ }
+
+ default boolean standardIsIpv6(@Nonnull final Ace ace) {
+ return VppAce.class.cast(ace.getMatches().getAceType()).getVppAceNodes().getAceIpVersion() instanceof AceIpv6;
+ }
+
+ default byte[] ipv4SourceAddress(@Nonnull final VppAce ace) {
+ return ipv4AddressPrefixToArray(
+ AclIpv4HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getSourceIpv4Network());
+ }
+
+ default byte ipv4SourceAddressPrefix(@Nonnull final VppAce ace) {
+ return extractPrefix(AclIpv4HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getSourceIpv4Network());
+ }
+
+ default byte[] ipv4DestinationAddress(@Nonnull final VppAce ace) {
+ return ipv4AddressPrefixToArray(
+ AclIpv4HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getDestinationIpv4Network());
+ }
+
+ default byte ipv4DestinationAddressPrefix(@Nonnull final VppAce ace) {
+ return extractPrefix(AceIpv4.class.cast(ace.getVppAceNodes().getAceIpVersion()).getDestinationIpv4Network());
+ }
+
+ default byte[] ipv6SourceAddress(@Nonnull final VppAce ace) {
+ return ipv6AddressPrefixToArray(
+ AclIpv6HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getSourceIpv6Network());
+ }
+
+ default byte ipv6SourceAddressPrefix(@Nonnull final VppAce ace) {
+ return extractPrefix(AclIpv6HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getSourceIpv6Network());
+ }
+
+ default byte[] ipv6DestinationAddress(@Nonnull final VppAce ace) {
+ return ipv6AddressPrefixToArray(
+ AclIpv6HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getDestinationIpv6Network());
+ }
+
+ default byte ipv6DestinationAddressPrefix(@Nonnull final VppAce ace) {
+ return extractPrefix(AclIpv6HeaderFields.class.cast(ace.getVppAceNodes().getAceIpVersion()).getDestinationIpv6Network());
+ }
+
+ default byte standardAction(@Nonnull final Ace ace) {
+ final PacketHandling action = ace.getActions().getPacketHandling();
+ return ACTION_VALUE_PAIRS.get(ACTION_VALUE_PAIRS.keySet().stream()
+ .filter(aClass -> aClass.isInstance(action))
+ .findAny()
+ .orElseThrow(() -> new IllegalArgumentException(
+ String.format("Unsupported packet-handling action %s for ACE %s", action,
+ ace.getRuleName())))).byteValue();
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclDataExtractor.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclDataExtractor.java
new file mode 100644
index 000000000..77e58fe0c
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclDataExtractor.java
@@ -0,0 +1,68 @@
+/*
+ * 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.util.acl;
+
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+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.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.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.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.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppMacipAce;
+
+/**
+ * Extracts data from Acls.
+ * Expects data validated by {@link AclValidator}
+ */
+public interface AclDataExtractor {
+
+ /**
+ * Checks if provided {@link Acl} has aces of type {@link VppAce}
+ */
+ default boolean isStandardAcl(@Nonnull final Acl acl) {
+ return acl.getAccessListEntries().getAce().stream()
+ .map(Ace::getMatches)
+ .map(Matches::getAceType)
+ .filter(aceType -> aceType instanceof VppAce)
+ .findAny()
+ .isPresent();
+ }
+
+ /**
+ * Checks if provided {@link Acl} has aces of type {@link VppMacipAce}
+ */
+ default boolean isMacIpAcl(@Nonnull final Acl acl) {
+ return acl.getAccessListEntries().getAce().stream()
+ .map(Ace::getMatches)
+ .map(Matches::getAceType)
+ .filter(aceType -> aceType instanceof VppMacipAce)
+ .findAny()
+ .isPresent();
+ }
+
+ default List<Ace> getAces(@Nonnull final Acl acl) {
+ return acl.getAccessListEntries().getAce();
+ }
+
+ /**
+ * Convert {@link Acl} name to byte array as UTF_8
+ */
+ default byte[] getAclNameAsBytes(@Nonnull final Acl acl) {
+ return acl.getAclName().getBytes(StandardCharsets.UTF_8);
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclValidator.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclValidator.java
new file mode 100644
index 000000000..3779b82bf
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclValidator.java
@@ -0,0 +1,84 @@
+/*
+ * 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.util.acl;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+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.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.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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.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.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.VppMacipAce;
+
+/**
+ * Validate Acl data if processable by vpp
+ */
+public interface AclValidator {
+
+ Set<Class<? extends AclBase>> SUPPORTED_ACL_TYPES = ImmutableSet.of(VppAcl.class, VppMacipAcl.class);
+
+ Map<Class<? extends AclBase>, Class<? extends AceType>> ACL_ACE_PAIRS = ImmutableMap.of(
+ VppAcl.class, VppAce.class,
+ VppMacipAcl.class, VppMacipAce.class);
+
+ 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);
+ }
+
+ 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()));
+ }
+
+ 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);
+ }
+
+ static void hasAceList(final Acl acl) {
+ //checks if aces are defined
+ checkArgument(!checkNotNull(checkNotNull(acl.getAccessListEntries(), "No access list entries defined")
+ .getAce(), "No aces defined")
+ .isEmpty(), "Empty ace list defined");
+ }
+
+ default void validateAcl(@Nonnull final Acl acl) {
+ hasAceList(acl);
+ isSupportedAclType(acl);
+ hasConsistentAceTypeForAclType(acl);
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclWriter.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclWriter.java
new file mode 100644
index 000000000..1fecc6c5b
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/acl/AclWriter.java
@@ -0,0 +1,125 @@
+/*
+ * 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.util.acl;
+
+import io.fd.hc2vpp.acl.util.ace.AceConverter;
+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.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 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.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Write standard and mac-ip acls
+ */
+public interface AclWriter extends AclDataExtractor, AceConverter, JvppReplyConsumer {
+
+ int ACL_INDEX_CREATE_NEW = -1;
+
+ default void addStandardAcl(@Nonnull final FutureJVppAclFacade futureFacade,
+ @Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
+ @Nonnull final NamingContext standardAclContext,
+ @Nonnull final MappingContext mappingContext) throws WriteFailedException {
+
+ final AclAddReplace request = new AclAddReplace();
+
+ request.tag = getAclNameAsBytes(acl);
+ request.aclIndex = ACL_INDEX_CREATE_NEW;
+ request.r = convertToStandardAclRules(getAces(acl));
+ request.count = request.r.length;
+
+ final AclAddReplaceReply reply =
+ getReplyForWrite(futureFacade.aclAddReplace(request).toCompletableFuture(), id);
+
+ // maps new acl to returned index
+ standardAclContext.addName(reply.aclIndex, acl.getAclName(), mappingContext);
+ }
+
+ // according to vpp team, this was tested extensively, and should work
+ default void updateStandardAcl(@Nonnull final FutureJVppAclFacade futureFacade,
+ @Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
+ @Nonnull final NamingContext standardAclContext,
+ @Nonnull final MappingContext mappingContext) throws WriteFailedException {
+
+ final AclAddReplace request = new AclAddReplace();
+
+ request.tag = getAclNameAsBytes(acl);
+ // by setting existing index, request is resolved as update
+ request.aclIndex = standardAclContext.getIndex(acl.getAclName(), mappingContext);
+ request.r = convertToStandardAclRules(getAces(acl));
+ request.count = request.r.length;
+
+ getReplyForWrite(futureFacade.aclAddReplace(request).toCompletableFuture(), id);
+
+ }
+
+
+ default void deleteStandardAcl(@Nonnull final FutureJVppAclFacade futureFacade,
+ @Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
+ @Nonnull final NamingContext standardAclContext,
+ @Nonnull final MappingContext mappingContext) throws WriteFailedException {
+
+ final AclDel request = new AclDel();
+ final String aclName = acl.getAclName();
+ request.aclIndex = standardAclContext.getIndex(aclName, mappingContext);
+
+ getReplyForDelete(futureFacade.aclDel(request).toCompletableFuture(), id);
+
+ // removes mapping after successful delete
+ standardAclContext.removeName(aclName, mappingContext);
+ }
+
+ default void addMacIpAcl(@Nonnull final FutureJVppAclFacade futureFacade,
+ @Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
+ @Nonnull final NamingContext macIpAclContext,
+ @Nonnull final MappingContext mappingContext) throws WriteFailedException {
+ final MacipAclAdd request = new MacipAclAdd();
+
+ request.tag = getAclNameAsBytes(acl);
+ request.r = convertToMacIpAclRules(getAces(acl));
+ request.count = request.r.length;
+
+ final MacipAclAddReply reply = getReplyForWrite(futureFacade.macipAclAdd(request).toCompletableFuture(), id);
+
+ // map mac-ip acl to returned index
+ macIpAclContext.addName(reply.aclIndex, acl.getAclName(), mappingContext);
+ }
+
+ default void deleteMacIpAcl(@Nonnull final FutureJVppAclFacade futureFacade,
+ @Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl acl,
+ @Nonnull final NamingContext macIpAclContext,
+ @Nonnull final MappingContext mappingContext) throws WriteFailedException {
+ final MacipAclDel request = new MacipAclDel();
+ final String aclName = acl.getAclName();
+ request.aclIndex = macIpAclContext.getIndex(aclName, mappingContext);
+
+ getReplyForDelete(futureFacade.macipAclDel(request).toCompletableFuture(), id);
+
+ macIpAclContext.removeName(aclName, mappingContext);
+ }
+
+
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/acl/AclInterfaceAssignmentRequest.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/acl/AclInterfaceAssignmentRequest.java
new file mode 100644
index 000000000..e3c5b727e
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/acl/AclInterfaceAssignmentRequest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.util.iface.acl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+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.List;
+import java.util.stream.Stream;
+import javax.annotation.Nonnull;
+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._interface.acl.attributes.Acl;
+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<Acl> identifier;
+ private List<String> inputAclNames;
+ private List<String> outputAclNames;
+ private NamingContext 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<Acl> identifier) {
+ this.identifier = identifier;
+ return this;
+ }
+
+ public AclInterfaceAssignmentRequest inputAclNames(@Nonnull final List<String> inputAclNames) {
+ this.inputAclNames = inputAclNames;
+ return this;
+ }
+
+ public AclInterfaceAssignmentRequest outputAclNames(@Nonnull final List<String> outputAclNames) {
+ this.outputAclNames = outputAclNames;
+ return this;
+ }
+
+ public AclInterfaceAssignmentRequest standardAclContext(@Nonnull final NamingContext 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(inputAclNames, "Input ACL names cannot be null");
+ checkNotNull(outputAclNames, "Output ACL names 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).getName();
+
+ // 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 Acl before, final Acl after)
+ throws WriteFailedException {
+ checkValidRequest();
+ final String interfaceName = identifier.firstKeyOf(Interface.class).getName();
+
+ // 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).getName();
+
+ // 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);
+
+ 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);
+ request.nInput = (byte) inputAclNames.size();
+ request.count = (byte) (inputAclNames.size() + outputAclNames.size());
+ request.acls = Stream.concat(inputAclNames.stream(), outputAclNames.stream())
+ .mapToInt(aclName -> standardAclContext.getIndex(aclName, mappingContext))
+ .toArray();
+ return request;
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/macip/MacIpInterfaceAssignmentRequest.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/macip/MacIpInterfaceAssignmentRequest.java
new file mode 100644
index 000000000..f8d726397
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/iface/macip/MacIpInterfaceAssignmentRequest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.util.iface.macip;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+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.interfaces.rev140508.interfaces.Interface;
+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;
+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<VppMacipAcl> identifier;
+ private String aclName;
+ private NamingContext 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<VppMacipAcl> identifier) {
+ this.identifier = identifier;
+ return this;
+ }
+
+ public MacIpInterfaceAssignmentRequest aclName(@Nonnull final String aclName) {
+ this.aclName = aclName;
+ return this;
+ }
+
+ public MacIpInterfaceAssignmentRequest macIpAclContext(@Nonnull final NamingContext 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).getName();
+
+ MacipAclInterfaceAddDel request = new MacipAclInterfaceAddDel();
+ request.isAdd = booleanToByte(isNew);
+ request.aclIndex = macIpAclContext.getIndex(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);
+ }
+ }
+}
diff --git a/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/protocol/ProtoPreBindRuleProducer.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/protocol/ProtoPreBindRuleProducer.java
new file mode 100644
index 000000000..c1f9a40ff
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/util/protocol/ProtoPreBindRuleProducer.java
@@ -0,0 +1,203 @@
+/*
+ * 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.util.protocol;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static io.fd.hc2vpp.acl.util.protocol.ProtoPreBindRuleProducer.ProtocolPair.pair;
+
+import com.google.common.collect.ImmutableSet;
+import io.fd.vpp.jvpp.acl.types.AclRule;
+import java.util.Optional;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ValueRange;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.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.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.VppAceNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.IpProtocol;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.Icmp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.IcmpV6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.Other;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.Tcp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.Udp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.IcmpNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.v6.IcmpV6Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.tcp.TcpNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.udp.UdpNodes;
+
+/**
+ * Creates ACL rules pre-bind with protocol-related fields.<br>
+ * Support TCP, UDP, ICMP and ICMPv6 protocol numbers according to
+ * <a href="http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml"> this document </a>
+ */
+public interface ProtoPreBindRuleProducer {
+
+ int ICMP_INDEX = 1;
+ int TCP_INDEX = 6;
+ int UDP_INDEX = 17;
+ int ICMPV6_INDEX = 58;
+
+ Set<ProtocolPair> PROTOCOL_PAIRS = ImmutableSet.of(pair(Icmp.class, ICMP_INDEX), pair(Tcp.class, TCP_INDEX),
+ pair(Udp.class, UDP_INDEX), pair(IcmpV6.class, ICMPV6_INDEX));
+
+ class ProtocolPair {
+ private final Class<? extends IpProtocol> protocolClass;
+ private final int index;
+
+ private ProtocolPair(final Class<? extends IpProtocol> protocolClass, final int index) {
+ this.protocolClass = protocolClass;
+ this.index = index;
+ }
+
+ static ProtocolPair pair(@Nonnull final Class<? extends IpProtocol> protocolClass, @Nonnull final int index) {
+ return new ProtocolPair(protocolClass, index);
+ }
+
+ boolean match(@Nonnull final Class<? extends IpProtocol> protocolClass) {
+ return this.protocolClass.isAssignableFrom(protocolClass);
+ }
+
+ int getIndex() {
+ return this.index;
+ }
+ }
+
+ static byte protocol(final IpProtocol ipProtocol) {
+ final Optional<ProtocolPair> optPair = PROTOCOL_PAIRS.stream()
+ .filter(protocolPair -> protocolPair.match(ipProtocol.getClass()))
+ .findAny();
+
+ if (!optPair.isPresent()) {
+ if (Other.class.isAssignableFrom(ipProtocol.getClass())) {
+ return Other.class.cast(ipProtocol).getOtherNodes().getProtocol().byteValue();
+ }
+
+ throw new IllegalArgumentException(String.format("Unsupported Protocol Type %s", ipProtocol.getClass()));
+ }
+ return (byte) optPair.get().getIndex();
+ }
+
+ static AclRule bindIcmpNodes(AclRule rule, VppAce ace) {
+ final VppAceNodes vppAceNodes = ace.getVppAceNodes();
+ checkArgument(vppAceNodes.getIpProtocol() instanceof Icmp);
+ final IcmpNodes icmp = Icmp.class.cast(vppAceNodes.getIpProtocol()).getIcmpNodes();
+ final ValueRange typesRange = icmp.getIcmpTypeRange();
+ final ValueRange codesRange = icmp.getIcmpCodeRange();
+
+ rule.srcportOrIcmptypeFirst = typesRange.getFirst();
+ rule.srcportOrIcmptypeLast = typesRange.getLast();
+ rule.dstportOrIcmpcodeFirst = codesRange.getFirst();
+ rule.dstportOrIcmpcodeLast = codesRange.getLast();
+
+ return rule;
+ }
+
+ static AclRule bindIcmpv6Nodes(AclRule rule, VppAce ace) {
+ final VppAceNodes vppAceNodes = ace.getVppAceNodes();
+ checkArgument(vppAceNodes.getIpProtocol() instanceof IcmpV6);
+ final IcmpV6Nodes icmpV6 = IcmpV6.class.cast(vppAceNodes.getIpProtocol()).getIcmpV6Nodes();
+ final ValueRange typesRange = icmpV6.getIcmpTypeRange();
+ final ValueRange codesRange = icmpV6.getIcmpCodeRange();
+
+ rule.srcportOrIcmptypeFirst = typesRange.getFirst();
+ rule.srcportOrIcmptypeLast = typesRange.getLast();
+ rule.dstportOrIcmpcodeFirst = codesRange.getFirst();
+ rule.dstportOrIcmpcodeLast = codesRange.getLast();
+
+ return rule;
+ }
+
+
+ static AclRule bindTcpNodes(AclRule rule, VppAce ace) {
+ final VppAceNodes vppAceNodes = ace.getVppAceNodes();
+ checkArgument(vppAceNodes.getIpProtocol() instanceof Tcp);
+
+ final TcpNodes tcp = Tcp.class.cast(vppAceNodes.getIpProtocol()).getTcpNodes();
+ final SourcePortRange sourcePortRange = tcp.getSourcePortRange();
+ final DestinationPortRange destinationPortRange = tcp.getDestinationPortRange();
+
+ rule.srcportOrIcmptypeFirst = portNumber(sourcePortRange.getLowerPort());
+ rule.srcportOrIcmptypeLast = portNumber(sourcePortRange.getUpperPort());
+ rule.dstportOrIcmpcodeFirst = portNumber(destinationPortRange.getLowerPort());
+ rule.dstportOrIcmpcodeLast = portNumber(destinationPortRange.getUpperPort());
+ rule.tcpFlagsMask = tcp.getTcpFlagsMask().byteValue();
+ rule.tcpFlagsValue = tcp.getTcpFlagsValue().byteValue();
+
+ return rule;
+ }
+
+ static AclRule bindUdpNodes(AclRule rule, VppAce ace) {
+ final VppAceNodes vppAceNodes = ace.getVppAceNodes();
+ checkArgument(vppAceNodes.getIpProtocol() instanceof Udp);
+
+ final UdpNodes udp = Udp.class.cast(vppAceNodes.getIpProtocol()).getUdpNodes();
+ final SourcePortRange sourcePortRange = udp.getSourcePortRange();
+ final DestinationPortRange destinationPortRange = udp.getDestinationPortRange();
+
+ rule.srcportOrIcmptypeFirst = portNumber(sourcePortRange.getLowerPort());
+ rule.srcportOrIcmptypeLast = portNumber(sourcePortRange.getUpperPort());
+ rule.dstportOrIcmpcodeFirst = portNumber(destinationPortRange.getLowerPort());
+ rule.dstportOrIcmpcodeLast = portNumber(destinationPortRange.getUpperPort());
+
+ return rule;
+ }
+
+ static AclRule bindDefaultNodes(AclRule rule) {
+ rule.srcportOrIcmptypeFirst = 0;
+ rule.srcportOrIcmptypeLast = (short) 65535;
+ rule.dstportOrIcmpcodeFirst = 0;
+ rule.dstportOrIcmpcodeLast = (short) 65535;
+ rule.tcpFlagsValue = 0;
+ rule.tcpFlagsMask = 0;
+ return rule;
+ }
+
+ static short portNumber(final PortNumber portNumber) {
+ return portNumber.getValue().shortValue();
+ }
+
+ default AclRule createPreBindRule(@Nonnull final VppAce vppAce) {
+ AclRule rule = new AclRule();
+
+ rule.proto = protocol(vppAce.getVppAceNodes().getIpProtocol());
+
+ switch (rule.proto) {
+ case ICMP_INDEX: {
+ return bindIcmpNodes(rule, vppAce);
+ }
+
+ case TCP_INDEX: {
+ return bindTcpNodes(rule, vppAce);
+ }
+
+ case UDP_INDEX: {
+ return bindUdpNodes(rule, vppAce);
+ }
+
+ case ICMPV6_INDEX: {
+ return bindIcmpv6Nodes(rule, vppAce);
+ }
+ default: {
+ return bindDefaultNodes(rule);
+ }
+ }
+
+ }
+
+}
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
new file mode 100644
index 000000000..3a4fb0cf3
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclCustomizer.java
@@ -0,0 +1,98 @@
+/*
+ * 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 java.util.stream.Collectors.toList;
+
+import io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
+import io.fd.hc2vpp.acl.util.iface.acl.AclInterfaceAssignmentRequest;
+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 java.util.Collections;
+import java.util.List;
+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.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Handles acl assignments(only standard ones, mac-ip have dedicated customizer)
+ */
+public class InterfaceAclCustomizer extends FutureJVppAclCustomizer implements WriterCustomizer<Acl> {
+
+ private final NamingContext interfaceContext;
+ private final NamingContext standardAclContext;
+
+ public InterfaceAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
+ @Nonnull final NamingContext interfaceContext,
+ @Nonnull final NamingContext standardAclContext) {
+ super(jVppAclFacade);
+ this.interfaceContext = interfaceContext;
+ this.standardAclContext = standardAclContext;
+ }
+
+ @Override
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl 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());
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataBefore,
+ @Nonnull final Acl 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()))
+ .executeAsUpdate(getjVppAclFacade(), dataBefore, dataAfter);
+ }
+
+ @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)
+ .inputAclNames(getAclNames(dataBefore.getIngress()))
+ .outputAclNames(getAclNames(dataBefore.getEgress()))
+ .executeAsDelete(getjVppAclFacade());
+ }
+
+ private static List<String> getAclNames(@Nonnull final VppAclsBaseAttributes acls) {
+ if (acls == null || acls.getVppAcls() == null) {
+ return Collections.emptyList();
+ } else {
+ return acls.getVppAcls().stream().map(VppAcls::getName).collect(toList());
+ }
+ }
+
+
+}
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
new file mode 100644
index 000000000..4b59c83f5
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/InterfaceAclMacIpCustomizer.java
@@ -0,0 +1,78 @@
+/*
+ * 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.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 NamingContext macIpAclContext;
+ private final NamingContext interfaceContext;
+
+ public InterfaceAclMacIpCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
+ @Nonnull final NamingContext 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 updateCurrentAttributes(@Nonnull final InstanceIdentifier<VppMacipAcl> id,
+ @Nonnull final VppMacipAcl dataBefore,
+ @Nonnull final VppMacipAcl dataAfter, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ throw new WriteFailedException.UpdateFailedException(id, dataBefore, dataAfter,
+ new UnsupportedOperationException("Operation not supported"));
+ }
+
+ @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/VppAclCustomizer.java b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclCustomizer.java
new file mode 100644
index 000000000..a2956784f
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/VppAclCustomizer.java
@@ -0,0 +1,110 @@
+/*
+ * 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 io.fd.hc2vpp.acl.util.FutureJVppAclCustomizer;
+import io.fd.hc2vpp.acl.util.acl.AclDataExtractor;
+import io.fd.hc2vpp.acl.util.acl.AclValidator;
+import io.fd.hc2vpp.acl.util.acl.AclWriter;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.honeycomb.translate.MappingContext;
+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.yangtools.yang.binding.InstanceIdentifier;
+
+public class VppAclCustomizer extends FutureJVppAclCustomizer
+ implements ListWriterCustomizer<Acl, AclKey>, AclValidator, AclDataExtractor, AclWriter {
+
+ private final NamingContext standardAclContext;
+ private final NamingContext macIpAclContext;
+
+ public VppAclCustomizer(@Nonnull final FutureJVppAclFacade jVppAclFacade,
+ @Nonnull final NamingContext standardAclContext,
+ @Nonnull final NamingContext macIpAclContext) {
+ super(jVppAclFacade);
+ this.standardAclContext = standardAclContext;
+ this.macIpAclContext = macIpAclContext;
+ }
+
+ @Override
+ public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataAfter,
+ @Nonnull final WriteContext writeContext) throws WriteFailedException {
+ validateAcl(dataAfter);
+
+ final MappingContext mappingContext = writeContext.getMappingContext();
+
+ if (isStandardAcl(dataAfter)) {
+ addStandardAcl(getjVppAclFacade(), id, dataAfter, standardAclContext, mappingContext);
+ } else if (isMacIpAcl(dataAfter)) {
+ addMacIpAcl(getjVppAclFacade(), id, dataAfter, macIpAclContext, mappingContext);
+ } else {
+ // double check, first one done by validation
+ throw new WriteFailedException.CreateFailedException(id, dataAfter,
+ new IllegalArgumentException("Unsupported acl option"));
+ }
+ }
+
+ @Override
+ public void updateCurrentAttributes(@Nonnull final InstanceIdentifier<Acl> id, @Nonnull final Acl dataBefore,
+ @Nonnull final Acl dataAfter, @Nonnull final WriteContext writeContext)
+ throws WriteFailedException {
+ validateAcl(dataAfter);
+
+ final MappingContext mappingContext = writeContext.getMappingContext();
+
+ if (isStandardAcl(dataAfter)) {
+ updateStandardAcl(getjVppAclFacade(), id, dataAfter, standardAclContext, mappingContext);
+ } 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);
+ }
+ } else {
+ // double check, first one done by validation
+ throw new WriteFailedException.CreateFailedException(id, dataAfter,
+ new IllegalArgumentException("Unsupported acl option"));
+ }
+ }
+
+ @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 MappingContext mappingContext = writeContext.getMappingContext();
+
+ if (isStandardAcl(dataBefore)) {
+ deleteStandardAcl(getjVppAclFacade(), id, dataBefore, standardAclContext, mappingContext);
+ } else if (isMacIpAcl(dataBefore)) {
+ deleteMacIpAcl(getjVppAclFacade(), id, dataBefore, macIpAclContext, mappingContext);
+ } else {
+ // double check, first one done by validation
+ throw new WriteFailedException.DeleteFailedException(id,
+ new IllegalArgumentException("Unsupported acl option"));
+ }
+ }
+}
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
new file mode 100644
index 000000000..fe22f2fd7
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/AbstractAclWriterFactory.java
@@ -0,0 +1,44 @@
+/*
+ * 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 com.google.inject.Inject;
+import com.google.inject.name.Named;
+import io.fd.hc2vpp.acl.AclModule;
+import io.fd.hc2vpp.common.translate.util.NamingContext;
+import io.fd.vpp.jvpp.acl.future.FutureJVppAclFacade;
+
+/**
+ * Created by jsrnicek on 12.12.2016.
+ */
+class AbstractAclWriterFactory {
+
+ @Inject
+ protected FutureJVppAclFacade futureAclFacade;
+
+ @Inject
+ @Named(AclModule.STANDARD_ACL_CONTEXT_NAME)
+ protected NamingContext standardAclContext;
+
+ @Inject
+ @Named(AclModule.MAC_IP_ACL_CONTEXT_NAME)
+ protected NamingContext macIpAClContext;
+
+ @Inject
+ @Named("interface-context")
+ protected NamingContext interfaceContext;
+}
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
new file mode 100644
index 000000000..6598aae9c
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/InterfaceAclWriterFactory.java
@@ -0,0 +1,59 @@
+/*
+ * 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 com.google.common.collect.ImmutableSet;
+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 {
+
+ private static final InstanceIdentifier<Acl> ACL_IID =
+ InstanceIdentifier.create(Interfaces.class).child(Interface.class)
+ .augmentation(VppAclInterfaceAugmentation.class).child(Acl.class);
+
+ @Override
+ public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) {
+ registry.subtreeAdd(aclHandledChildren(InstanceIdentifier.create(Acl.class)),
+ new GenericWriter<>(ACL_IID,
+ new InterfaceAclCustomizer(futureAclFacade, interfaceContext, standardAclContext)));
+
+ registry.add(new GenericWriter<>(ACL_IID.child(Ingress.class).child(VppMacipAcl.class),
+ new InterfaceAclMacIpCustomizer(futureAclFacade, macIpAClContext, interfaceContext)));
+ }
+
+ private 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));
+ }
+}
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
new file mode 100644
index 000000000..546924ee3
--- /dev/null
+++ b/acl/acl-impl/src/main/java/io/fd/hc2vpp/acl/write/factory/VppAclWriterFactory.java
@@ -0,0 +1,82 @@
+/*
+ * 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 com.google.common.collect.ImmutableSet;
+import io.fd.hc2vpp.acl.write.VppAclCustomizer;
+import io.fd.honeycomb.translate.impl.write.GenericListWriter;
+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.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.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.Actions;
+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.packet.fields.rev160708.acl.transport.header.fields.DestinationPortRange;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.packet.fields.rev160708.acl.transport.header.fields.SourcePortRange;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.ace.VppAceNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.access.lists.acl.access.list.entries.ace.matches.ace.type.vpp.macip.ace.VppMacipAceNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpCodeRange;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.icmp.header.fields.IcmpTypeRange;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.IcmpNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.icmp.v6.IcmpV6Nodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.other.OtherNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.tcp.TcpNodes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.acl.ip.protocol.header.fields.ip.protocol.udp.UdpNodes;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class VppAclWriterFactory extends AbstractAclWriterFactory implements WriterFactory {
+
+ private static Set<InstanceIdentifier<?>> vppAclCustomizerHandledChildren(final InstanceIdentifier<Acl> parentId) {
+ final InstanceIdentifier<Matches> matchesIid =
+ parentId.child(AccessListEntries.class).child(Ace.class).child(Matches.class);
+ return ImmutableSet.of(parentId.child(AccessListEntries.class),
+ parentId.child(AccessListEntries.class).child(Ace.class),
+ parentId.child(AccessListEntries.class).child(Ace.class).child(Matches.class),
+ parentId.child(AccessListEntries.class).child(Ace.class).child(Actions.class),
+ matchesIid,
+ matchesIid.child(VppMacipAceNodes.class),
+ matchesIid.child(VppAceNodes.class),
+ matchesIid.child(VppAceNodes.class).child(IcmpNodes.class),
+ matchesIid.child(VppAceNodes.class).child(IcmpNodes.class).child(IcmpCodeRange.class),
+ matchesIid.child(VppAceNodes.class).child(IcmpNodes.class).child(IcmpTypeRange.class),
+ matchesIid.child(VppAceNodes.class).child(IcmpV6Nodes.class),
+ matchesIid.child(VppAceNodes.class).child(IcmpV6Nodes.class).child(IcmpCodeRange.class),
+ matchesIid.child(VppAceNodes.class).child(IcmpV6Nodes.class).child(IcmpTypeRange.class),
+ matchesIid.child(VppAceNodes.class).child(UdpNodes.class),
+ matchesIid.child(VppAceNodes.class).child(UdpNodes.class).child(SourcePortRange.class),
+ matchesIid.child(VppAceNodes.class).child(UdpNodes.class).child(DestinationPortRange.class),
+ matchesIid.child(VppAceNodes.class).child(TcpNodes.class),
+ matchesIid.child(VppAceNodes.class).child(TcpNodes.class).child(SourcePortRange.class),
+ matchesIid.child(VppAceNodes.class).child(TcpNodes.class).child(DestinationPortRange.class),
+ matchesIid.child(VppAceNodes.class).child(OtherNodes.class)
+
+ );
+ }
+
+ @Override
+ public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) {
+ final InstanceIdentifier<AccessLists> rootNode = InstanceIdentifier.create(AccessLists.class);
+
+ registry.subtreeAdd(vppAclCustomizerHandledChildren(InstanceIdentifier.create(Acl.class)),
+ new GenericListWriter<>(rootNode.child(Acl.class),
+ new VppAclCustomizer(futureAclFacade, standardAclContext, macIpAClContext)));
+ }
+}