From b1eece37415c11bc1eaff545b58a1eebe26e3aa5 Mon Sep 17 00:00:00 2001 From: Marek Gradzki Date: Wed, 19 Oct 2016 14:50:04 +0200 Subject: HONEYCOMB-264: cache classify table delete Change-Id: I8b43f9a6220b90aaed5d85d60c0d2095518d6226 Signed-off-by: Marek Gradzki --- .../v3po/EgressIetfAClWriterProvider.java | 4 +- .../v3po/IngressIetfAClWriterProvider.java | 4 +- .../acl/common/AbstractIetfAclWriter.java | 12 +++- .../acl/common/AclTableContextManager.java | 53 +++++++++++++++++ .../acl/common/AclTableContextManagerImpl.java | 68 +++++++++++++++++++++ .../v3po/interfaces/acl/common/IetfAclWriter.java | 11 ++-- .../interfaces/acl/egress/EgressIetfAclWriter.java | 44 ++++++++++---- .../interfaces/acl/egress/IetfAclCustomizer.java | 9 +-- .../acl/egress/SubInterfaceIetfAclCustomizer.java | 15 +++-- .../interfaces/acl/ingress/IetfAclCustomizer.java | 4 +- .../acl/ingress/IngressIetfAclWriter.java | 69 ++++++++++++---------- .../acl/ingress/SubInterfaceIetfAclCustomizer.java | 4 +- 12 files changed, 236 insertions(+), 61 deletions(-) create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManager.java create mode 100644 v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManagerImpl.java (limited to 'v3po/v3po2vpp/src/main/java/io/fd/honeycomb') diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/EgressIetfAClWriterProvider.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/EgressIetfAClWriterProvider.java index e2b60e9f4..f14900f03 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/EgressIetfAClWriterProvider.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/EgressIetfAClWriterProvider.java @@ -18,8 +18,10 @@ package io.fd.honeycomb.translate.v3po; import com.google.inject.Inject; import com.google.inject.Provider; +import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AclTableContextManagerImpl; import io.fd.honeycomb.translate.v3po.interfaces.acl.egress.EgressIetfAclWriter; import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; class EgressIetfAClWriterProvider implements Provider { @@ -32,6 +34,6 @@ class EgressIetfAClWriterProvider implements Provider { @Override public EgressIetfAclWriter get() { - return new EgressIetfAclWriter(jvpp); + return new EgressIetfAclWriter(jvpp, new AclTableContextManagerImpl(MappingTable.Direction.Egress)); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/IngressIetfAClWriterProvider.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/IngressIetfAClWriterProvider.java index c4e966460..5d97f41ae 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/IngressIetfAClWriterProvider.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/IngressIetfAClWriterProvider.java @@ -18,8 +18,10 @@ package io.fd.honeycomb.translate.v3po; import com.google.inject.Inject; import com.google.inject.Provider; +import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AclTableContextManagerImpl; import io.fd.honeycomb.translate.v3po.interfaces.acl.ingress.IngressIetfAclWriter; import io.fd.vpp.jvpp.core.future.FutureJVppCore; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; class IngressIetfAClWriterProvider implements Provider { @@ -32,6 +34,6 @@ class IngressIetfAClWriterProvider implements Provider { @Override public IngressIetfAclWriter get() { - return new IngressIetfAclWriter(jvpp); + return new IngressIetfAclWriter(jvpp, new AclTableContextManagerImpl(MappingTable.Direction.Ingress)); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AbstractIetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AbstractIetfAclWriter.java index 1a1fbd519..347397aa3 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AbstractIetfAclWriter.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AbstractIetfAclWriter.java @@ -48,6 +48,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.cont 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.ace.type.ace.ip.AceIpVersion; 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.ace.type.ace.ip.ace.ip.version.AceIpv4; 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.ace.type.ace.ip.ace.ip.version.AceIpv6; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; 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.AceIpAndEth; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; @@ -59,7 +60,7 @@ import org.slf4j.LoggerFactory; public abstract class AbstractIetfAclWriter implements IetfAclWriter, JvppReplyConsumer, AclTranslator { private static final Logger LOG = LoggerFactory.getLogger(AbstractIetfAclWriter.class); - private static final int NOT_DEFINED = -1; + protected static final int NOT_DEFINED = -1; protected final FutureJVppCore jvpp; private Map> aceWriters = new HashMap<>(); @@ -93,7 +94,14 @@ public abstract class AbstractIetfAclWriter implements IetfAclWriter, JvppReplyC return accessListEntries.getAce().stream(); } - protected void removeClassifyTable(@Nonnull final InstanceIdentifier id, final int tableIndex) + protected void removeClassifyTables(@Nonnull final InstanceIdentifier id, @Nonnull final MappingEntry entry) + throws WriteFailedException { + removeClassifyTable(id, entry.getL2TableId()); + removeClassifyTable(id, entry.getIp4TableId()); + removeClassifyTable(id, entry.getIp6TableId()); + } + + private void removeClassifyTable(@Nonnull final InstanceIdentifier id, final int tableIndex) throws WriteFailedException { if (tableIndex == -1) { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManager.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManager.java new file mode 100644 index 000000000..bddc16a23 --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManager.java @@ -0,0 +1,53 @@ +/* + * 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.honeycomb.translate.v3po.interfaces.acl.common; + +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; + +/** + * Manages interface metadata for ietf-acl model. + */ +public interface AclTableContextManager { + + /** + * Obtains mapping entry for given interface. + * + * @param index interface index + * @param mappingContext mapping context providing context data for current transaction + * @return ietf-acl metadata for given interface + */ + Optional getEntry(final int index, @Nonnull final MappingContext mappingContext); + + /** + * Adds mapping entry. + * + * @param entry to be added + * @param mappingContext mapping context providing context data for current transaction + */ + void addEntry(@Nonnull final MappingEntry entry, @Nonnull final MappingContext mappingContext); + + /** + * Removes entry for given interface (if present). + * + * @param index interface index + * @param mappingContext mapping context providing context data for current transaction + */ + void removeEntry(final int index, @Nonnull final MappingContext mappingContext); +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManagerImpl.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManagerImpl.java new file mode 100644 index 000000000..60fb0d24b --- /dev/null +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/AclTableContextManagerImpl.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.honeycomb.translate.v3po.interfaces.acl.common; + +import static com.google.common.base.Preconditions.checkNotNull; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; +import javax.annotation.Nonnull; +import javax.annotation.concurrent.ThreadSafe; +import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.naming.context.rev160513.Contexts; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.AclMappingEntryCtxAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.AclMappingEntryContext; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTable; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.MappingTableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +@ThreadSafe +public class AclTableContextManagerImpl implements AclTableContextManager { + + private MappingTable.Direction direction; + + public AclTableContextManagerImpl(@Nonnull final MappingTable.Direction direction) { + this.direction = checkNotNull(direction, "direction should not be null"); + } + + @Nonnull + @Override + public synchronized Optional getEntry(final int swIfIndex, @Nonnull final MappingContext mappingContext) { + return mappingContext.read(getId(swIfIndex)); + } + + @Override + public synchronized void addEntry(@Nonnull final MappingEntry entry, @Nonnull final MappingContext mappingContext) { + mappingContext.put(getId(entry.getIndex()), entry); + } + + @Override + public synchronized void removeEntry(final int swIfIndex, @Nonnull final MappingContext mappingContext) { + mappingContext.delete(getId(swIfIndex)); + } + + @VisibleForTesting + protected InstanceIdentifier getId(final int index) { + return InstanceIdentifier.create(Contexts.class) + .augmentation(AclMappingEntryCtxAugmentation.class) + .child(AclMappingEntryContext.class) + .child(MappingTable.class, new MappingTableKey(direction)) + .child(MappingEntry.class, new MappingEntryKey(index)); + } +} diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/IetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/IetfAclWriter.java index 1ce5a040d..2e8750cd5 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/IetfAclWriter.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/common/IetfAclWriter.java @@ -16,6 +16,7 @@ package io.fd.honeycomb.translate.v3po.interfaces.acl.common; +import io.fd.honeycomb.translate.MappingContext; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import java.util.List; @@ -30,15 +31,17 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public interface IetfAclWriter { default void write(@Nonnull final InstanceIdentifier id, final int ifIndex, @Nonnull final List acls, final AccessLists.DefaultAction defaultAction, @Nullable final InterfaceMode mode, - @Nonnull final WriteContext writeContext) + @Nonnull final WriteContext writeContext, @Nonnull final MappingContext mappingContext) throws WriteFailedException { - write(id, ifIndex, acls, defaultAction, mode, writeContext, 0); + write(id, ifIndex, acls, defaultAction, mode, writeContext, 0, mappingContext); } void write(@Nonnull final InstanceIdentifier id, int ifIndex, @Nonnull final List acls, final AccessLists.DefaultAction defaultAction, @Nullable InterfaceMode mode, - @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags) + @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, + @Nonnull final MappingContext mappingContext) throws WriteFailedException; - void deleteAcl(InstanceIdentifier id, int ifIndex) throws WriteFailedException; + void deleteAcl(@Nonnull final InstanceIdentifier id, int ifIndex, @Nonnull final MappingContext mappingContext) + throws WriteFailedException; } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/EgressIetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/EgressIetfAclWriter.java index eee8f68eb..bfd58cf4a 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/EgressIetfAclWriter.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/EgressIetfAclWriter.java @@ -17,8 +17,13 @@ package io.fd.honeycomb.translate.v3po.interfaces.acl.egress; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AbstractIetfAclWriter; +import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AclTableContextManager; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.vpp.jvpp.core.dto.ClassifySetInterfaceL2Tables; @@ -32,26 +37,31 @@ import javax.annotation.Nullable; 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.ace.type.AceEth; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public final class EgressIetfAclWriter extends AbstractIetfAclWriter { - private static final int NOT_DEFINED = -1; + private final AclTableContextManager aclCtx; - public EgressIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore) { + public EgressIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull AclTableContextManager aclCtx) { super(futureJVppCore); + this.aclCtx = checkNotNull(aclCtx, "aclCtx should not be null"); } @Override - public void deleteAcl(@Nonnull final InstanceIdentifier id, final int swIfIndex) + public void deleteAcl(@Nonnull final InstanceIdentifier id, final int swIfIndex, + @Nonnull final MappingContext mappingContext) throws WriteFailedException { - // We unassign and remove all ACL-related classify tables for given interface (we assume we are the only - // classify table manager) + Optional optional = aclCtx.getEntry(swIfIndex, mappingContext); + checkState(optional.isPresent(), "Removing ACL id=%s, but acl mapping entry is not present", id); + final MappingEntry entry = optional.get(); unassignClassifyTables(id, swIfIndex); - - // TODO(HONEYCOMB-264): remove classify tables from vpp (we need to cache interface/acl mapping) + removeClassifyTables(id, entry); + aclCtx.removeEntry(swIfIndex, mappingContext); } private void unassignClassifyTables(@Nonnull final InstanceIdentifier id, final int swIfIndex) @@ -68,8 +78,9 @@ public final class EgressIetfAclWriter extends AbstractIetfAclWriter { @Override public void write(@Nonnull final InstanceIdentifier id, int swIfIndex, @Nonnull final List acls, - final AccessLists.DefaultAction defaultAction, @Nullable InterfaceMode mode, - @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags) + @Nonnull final AccessLists.DefaultAction defaultAction, @Nullable InterfaceMode mode, + @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, + @Nonnull final MappingContext mappingContext) throws WriteFailedException { checkArgument(numberOfTags >= 0 && numberOfTags <= 2, "Number of vlan tags %s is not in [0,2] range"); checkArgument(InterfaceMode.L2.equals(mode), "Writing egress Acls is supported only in L2 mode"); @@ -86,8 +97,19 @@ public final class EgressIetfAclWriter extends AbstractIetfAclWriter { final List aces = getACEs(acls, writeContext, EgressIetfAclWriter::isNotIpRule); request.otherTableIndex = writeAces(id, aces, defaultAction, mode, numberOfTags); - final CompletionStage cs = jvpp.classifySetInterfaceL2Tables(request); - getReplyForWrite(cs.toCompletableFuture(), id); + final MappingEntry entry = new MappingEntryBuilder().setIndex(swIfIndex) + .setIp4TableId(request.ip4TableIndex) + .setIp6TableId(request.ip6TableIndex) + .setL2TableId(request.otherTableIndex) + .build(); + aclCtx.addEntry(entry, mappingContext); + + try { + getReplyForWrite(jvpp.classifySetInterfaceL2Tables(request).toCompletableFuture(), id); + } catch (WriteFailedException e) { + removeClassifyTables(id, entry); + throw e; + } } private static boolean isNotIpRule(final Ace ace) { diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/IetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/IetfAclCustomizer.java index e8f8af296..c0e4c3d14 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/IetfAclCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/IetfAclCustomizer.java @@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.honeycomb.translate.v3po.interfaces.acl.common.IetfAclWriter; import io.fd.honeycomb.translate.vpp.util.NamingContext; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; @@ -34,10 +35,10 @@ import org.slf4j.LoggerFactory; public class IetfAclCustomizer implements WriterCustomizer { private static final Logger LOG = LoggerFactory.getLogger(IetfAclCustomizer.class); - private final EgressIetfAclWriter aclWriter; + private final IetfAclWriter aclWriter; private final NamingContext interfaceContext; - public IetfAclCustomizer(final EgressIetfAclWriter aclWriter, final NamingContext interfaceContext) { + public IetfAclCustomizer(final IetfAclWriter aclWriter, final NamingContext interfaceContext) { this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); } @@ -59,7 +60,7 @@ public class IetfAclCustomizer implements WriterCustomizer { } aclWriter.write(id, ifIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext); + writeContext, writeContext.getMappingContext()); } @Override @@ -79,6 +80,6 @@ public class IetfAclCustomizer implements WriterCustomizer { final String ifName = id.firstKeyOf(Interface.class).getName(); final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); LOG.debug("Removing ACLs for interface={}(id={}): {}", ifName, ifIndex, dataBefore); - aclWriter.deleteAcl(id, ifIndex); + aclWriter.deleteAcl(id, ifIndex, writeContext.getMappingContext()); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java index cba045add..bf7c0eb46 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/egress/SubInterfaceIetfAclCustomizer.java @@ -23,6 +23,7 @@ import static io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils.getNumberOfTa import com.google.common.base.Optional; import io.fd.honeycomb.translate.spi.write.WriterCustomizer; +import io.fd.honeycomb.translate.v3po.interfaces.acl.common.IetfAclWriter; import io.fd.honeycomb.translate.vpp.util.NamingContext; import io.fd.honeycomb.translate.vpp.util.SubInterfaceUtils; import io.fd.honeycomb.translate.write.WriteContext; @@ -30,6 +31,7 @@ import io.fd.honeycomb.translate.write.WriteFailedException; 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.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterface; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.vlan.rev161214.interfaces._interface.sub.interfaces.SubInterfaceKey; @@ -40,10 +42,10 @@ import org.slf4j.LoggerFactory; public class SubInterfaceIetfAclCustomizer implements WriterCustomizer { private static final Logger LOG = LoggerFactory.getLogger(SubInterfaceIetfAclCustomizer.class); - private final EgressIetfAclWriter aclWriter; + private final IetfAclWriter aclWriter; private final NamingContext interfaceContext; - public SubInterfaceIetfAclCustomizer(final EgressIetfAclWriter aclWriter, final NamingContext interfaceContext) { + public SubInterfaceIetfAclCustomizer(final IetfAclWriter aclWriter, final NamingContext interfaceContext) { this.aclWriter = checkNotNull(aclWriter, "aclWriter should not be null"); this.interfaceContext = checkNotNull(interfaceContext, "interfaceContext should not be null"); } @@ -71,9 +73,14 @@ public class SubInterfaceIetfAclCustomizer implements WriterCustomizer { checkState(subInterfaceOptional.isPresent(), "Could not read SubInterface data object for %s", id); final SubInterface subInterface = subInterfaceOptional.get(); + if (!InterfaceMode.L2.equals(accessLists.getMode())) { + LOG.debug("Writing egress Acls is supported only in L2 mode. Ignoring config: {}", dataAfter); + return; + } + aclWriter .write(id, subInterfaceIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, getNumberOfTags(subInterface.getTags())); + writeContext, getNumberOfTags(subInterface.getTags()), writeContext.getMappingContext()); } @Override @@ -93,6 +100,6 @@ public class SubInterfaceIetfAclCustomizer implements WriterCustomizer { final String subInterfaceName = getSubInterfaceName(id); final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); LOG.debug("Removing ACLs for sub-interface={}(id={}): {}", subInterfaceName, subInterfaceIndex, dataBefore); - aclWriter.deleteAcl(id, subInterfaceIndex); + aclWriter.deleteAcl(id, subInterfaceIndex, writeContext.getMappingContext()); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IetfAclCustomizer.java index f4f3d1384..ec051e091 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IetfAclCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IetfAclCustomizer.java @@ -62,7 +62,7 @@ public class IetfAclCustomizer implements WriterCustomizer { "ietf-acl container does not define acl list"); aclWriter.write(id, ifIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext); + writeContext, writeContext.getMappingContext()); } @Override @@ -84,6 +84,6 @@ public class IetfAclCustomizer implements WriterCustomizer { final String ifName = id.firstKeyOf(Interface.class).getName(); final int ifIndex = interfaceContext.getIndex(ifName, writeContext.getMappingContext()); LOG.debug("Removing ACLs for interface={}(id={}): {}", ifName, ifIndex, dataBefore); - aclWriter.deleteAcl(id, ifIndex); + aclWriter.deleteAcl(id, ifIndex, writeContext.getMappingContext()); } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java index 969ac43f4..b7da14ecf 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/IngressIetfAclWriter.java @@ -17,12 +17,15 @@ package io.fd.honeycomb.translate.v3po.interfaces.acl.ingress; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; +import com.google.common.base.Optional; +import io.fd.honeycomb.translate.MappingContext; import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AbstractIetfAclWriter; +import io.fd.honeycomb.translate.v3po.interfaces.acl.common.AclTableContextManager; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterface; -import io.fd.vpp.jvpp.core.dto.ClassifyTableByInterfaceReply; import io.fd.vpp.jvpp.core.dto.InputAclSetInterface; import io.fd.vpp.jvpp.core.dto.InputAclSetInterfaceReply; import io.fd.vpp.jvpp.core.future.FutureJVppCore; @@ -32,47 +35,42 @@ import javax.annotation.Nonnegative; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160708.access.lists.acl.access.list.entries.Ace; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.context.rev161214.mapping.entry.context.attributes.acl.mapping.entry.context.mapping.table.MappingEntryBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.InterfaceMode; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.AccessLists; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.ietf.acl.base.attributes.access.lists.Acl; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public final class IngressIetfAclWriter extends AbstractIetfAclWriter { + private final AclTableContextManager aclCtx; - private static final int NOT_DEFINED = -1; - - public IngressIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore) { + public IngressIetfAclWriter(@Nonnull final FutureJVppCore futureJVppCore, @Nonnull AclTableContextManager aclCtx) { super(futureJVppCore); + this.aclCtx = checkNotNull(aclCtx, "aclCtx should not be null"); } @Override - public void deleteAcl(@Nonnull final InstanceIdentifier id, final int swIfIndex) + public void deleteAcl(@Nonnull final InstanceIdentifier id, final int swIfIndex, + @Nonnull final MappingContext mappingContext) throws WriteFailedException { - final ClassifyTableByInterface request = new ClassifyTableByInterface(); - request.swIfIndex = swIfIndex; - - final CompletionStage cs = jvpp.classifyTableByInterface(request); - final ClassifyTableByInterfaceReply reply = getReplyForDelete(cs.toCompletableFuture(), id); - - // We unassign and remove all ACL-related classify tables for given interface (we assume we are the only - // classify table manager) - - unassignClassifyTables(id, reply); - - removeClassifyTable(id, reply.l2TableId); - removeClassifyTable(id, reply.ip4TableId); - removeClassifyTable(id, reply.ip6TableId); + Optional optional = aclCtx.getEntry(swIfIndex, mappingContext); + checkState(optional.isPresent(), "Removing ACL id=%s, but acl mapping entry is not present", id); + final MappingEntry entry = optional.get(); + unassignClassifyTables(id, entry); + removeClassifyTables(id, entry); + aclCtx.removeEntry(swIfIndex, mappingContext); } private void unassignClassifyTables(@Nonnull final InstanceIdentifier id, - final ClassifyTableByInterfaceReply currentState) + @Nonnull final MappingEntry entry) throws WriteFailedException { final InputAclSetInterface request = new InputAclSetInterface(); request.isAdd = 0; - request.swIfIndex = currentState.swIfIndex; - request.l2TableIndex = currentState.l2TableId; - request.ip4TableIndex = currentState.ip4TableId; - request.ip6TableIndex = currentState.ip6TableId; + request.swIfIndex = entry.getIndex(); + request.l2TableIndex = entry.getL2TableId(); + request.ip4TableIndex = entry.getIp4TableId(); + request.ip6TableIndex = entry.getIp6TableId(); final CompletionStage inputAclSetInterfaceReplyCompletionStage = jvpp.inputAclSetInterface(request); getReplyForDelete(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); @@ -80,8 +78,9 @@ public final class IngressIetfAclWriter extends AbstractIetfAclWriter { @Override public void write(@Nonnull final InstanceIdentifier id, int swIfIndex, @Nonnull final List acls, - final AccessLists.DefaultAction defaultAction, @Nullable InterfaceMode mode, - @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags) + @Nonnull final AccessLists.DefaultAction defaultAction, @Nullable final InterfaceMode mode, + @Nonnull final WriteContext writeContext, @Nonnegative final int numberOfTags, + @Nonnull final MappingContext mappingContext) throws WriteFailedException { checkArgument(numberOfTags >= 0 && numberOfTags <= 2, "Number of vlan tags %s is not in [0,2] range"); @@ -102,8 +101,18 @@ public final class IngressIetfAclWriter extends AbstractIetfAclWriter { request.ip6TableIndex = writeAces(id, ip6Aces, defaultAction, mode, numberOfTags); } - final CompletionStage inputAclSetInterfaceReplyCompletionStage = - jvpp.inputAclSetInterface(request); - getReplyForWrite(inputAclSetInterfaceReplyCompletionStage.toCompletableFuture(), id); + final MappingEntry entry = new MappingEntryBuilder().setIndex(swIfIndex) + .setIp4TableId(request.ip4TableIndex) + .setIp6TableId(request.ip6TableIndex) + .setL2TableId(request.l2TableIndex) + .build(); + aclCtx.addEntry(entry, mappingContext); + + try { + getReplyForWrite(jvpp.inputAclSetInterface(request).toCompletableFuture(), id); + } catch (WriteFailedException e) { + removeClassifyTables(id, entry); + throw e; + } } } diff --git a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java index 47b8aba6f..a9fcc83a3 100644 --- a/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java +++ b/v3po/v3po2vpp/src/main/java/io/fd/honeycomb/translate/v3po/interfaces/acl/ingress/SubInterfaceIetfAclCustomizer.java @@ -82,7 +82,7 @@ public class SubInterfaceIetfAclCustomizer implements WriterCustomizer aclWriter .write(id, subInterfaceIndex, accessLists.getAcl(), accessLists.getDefaultAction(), accessLists.getMode(), - writeContext, getNumberOfTags(subInterface.getTags())); + writeContext, getNumberOfTags(subInterface.getTags()), writeContext.getMappingContext()); } @Override @@ -103,6 +103,6 @@ public class SubInterfaceIetfAclCustomizer implements WriterCustomizer final String subInterfaceName = getSubInterfaceName(id); final int subInterfaceIndex = interfaceContext.getIndex(subInterfaceName, writeContext.getMappingContext()); LOG.debug("Removing ACLs for sub-interface={}(id={}): {}", subInterfaceName, subInterfaceIndex, dataBefore); - aclWriter.deleteAcl(id, subInterfaceIndex); + aclWriter.deleteAcl(id, subInterfaceIndex, writeContext.getMappingContext()); } } -- cgit 1.2.3-korg