diff options
author | Marek Gradzki <mgradzki@cisco.com> | 2017-08-16 17:09:37 +0200 |
---|---|---|
committer | Marek Gradzki <mgradzki@cisco.com> | 2017-08-21 09:02:10 +0200 |
commit | 70d981d7b08ba57d7789d8f33629fc33b2b0d9ff (patch) | |
tree | 1f05d75e7521ef86f63fcd9dc53444fd63e7a1ad | |
parent | 78aca8c336e69a049fd5e340b194bf7c66f61da1 (diff) |
HC2VPP-105: add support for nat64 configuration on interface
Change-Id: I071f8981b680845ea031a9e61dfca7e34ea539e5
Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
16 files changed, 248 insertions, 109 deletions
diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/AbstractInterfaceNatCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/AbstractInterfaceNatCustomizer.java index c3c81ffb8..5079f1630 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/AbstractInterfaceNatCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/AbstractInterfaceNatCustomizer.java @@ -25,6 +25,8 @@ import io.fd.honeycomb.translate.read.ReadContext; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.InitializingReaderCustomizer; import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.vpp.jvpp.snat.dto.Nat64InterfaceDetailsReplyDump; +import io.fd.vpp.jvpp.snat.dto.Nat64InterfaceDump; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceDetailsReplyDump; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceDump; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceOutputFeatureDetailsReplyDump; @@ -40,21 +42,31 @@ import org.slf4j.Logger; abstract class AbstractInterfaceNatCustomizer<C extends DataObject, B extends Builder<C>> implements InitializingReaderCustomizer<C, B>, JvppReplyConsumer { - private final FutureJVppSnatFacade jvppSnat; - private final DumpCacheManager<SnatInterfaceDetailsReplyDump, Void> preRoutingDumpMgr; - private final DumpCacheManager<SnatInterfaceOutputFeatureDetailsReplyDump, Void> postRoutingDumpMgr; + private final DumpCacheManager<SnatInterfaceDetailsReplyDump, Void> preRoutingNat44DumpMgr; + private final DumpCacheManager<Nat64InterfaceDetailsReplyDump, Void> preRoutingNat64DumpMgr; + private final DumpCacheManager<SnatInterfaceOutputFeatureDetailsReplyDump, Void> postRoutingNat44DumpMgr; private final NamingContext ifcContext; + private final VppAttributesBuilder vppAttributesBuilder; AbstractInterfaceNatCustomizer(@Nonnull final FutureJVppSnatFacade jvppSnat, - @Nonnull final NamingContext ifcContext) { - this.jvppSnat = requireNonNull(jvppSnat, "jvppSnat should not be null"); + @Nonnull final NamingContext ifcContext, + @Nonnull final VppAttributesBuilder vppAttributesBuilder) { + requireNonNull(jvppSnat, "jvppSnat should not be null"); this.ifcContext = requireNonNull(ifcContext, "ifcContext should not be null"); - this.preRoutingDumpMgr = new DumpCacheManager.DumpCacheManagerBuilder<SnatInterfaceDetailsReplyDump, Void>() - .withExecutor((id, params) -> getReplyForRead( - jvppSnat.snatInterfaceDump(new SnatInterfaceDump()).toCompletableFuture(), id)) - .acceptOnly(SnatInterfaceDetailsReplyDump.class) - .build(); - this.postRoutingDumpMgr = + this.vppAttributesBuilder = requireNonNull(vppAttributesBuilder, "ifcContext should not be null"); + this.preRoutingNat44DumpMgr = + new DumpCacheManager.DumpCacheManagerBuilder<SnatInterfaceDetailsReplyDump, Void>() + .withExecutor((id, params) -> getReplyForRead( + jvppSnat.snatInterfaceDump(new SnatInterfaceDump()).toCompletableFuture(), id)) + .acceptOnly(SnatInterfaceDetailsReplyDump.class) + .build(); + this.preRoutingNat64DumpMgr = + new DumpCacheManager.DumpCacheManagerBuilder<Nat64InterfaceDetailsReplyDump, Void>() + .withExecutor((id, params) -> getReplyForRead( + jvppSnat.nat64InterfaceDump(new Nat64InterfaceDump()).toCompletableFuture(), id)) + .acceptOnly(Nat64InterfaceDetailsReplyDump.class) + .build(); + this.postRoutingNat44DumpMgr = new DumpCacheManager.DumpCacheManagerBuilder<SnatInterfaceOutputFeatureDetailsReplyDump, Void>() .withExecutor((id, params) -> getReplyForRead( jvppSnat.snatInterfaceOutputFeatureDump(new SnatInterfaceOutputFeatureDump()) @@ -71,39 +83,51 @@ abstract class AbstractInterfaceNatCustomizer<C extends DataObject, B extends Bu getLog().debug("Reading NAT features on interface: {}", ifcName); final int index = ifcContext.getIndex(ifcName, ctx.getMappingContext()); - // There are no additional attributes for pre routing NAT, so it is enough to read post routing ifc mapping: - final Optional<SnatInterfaceOutputFeatureDetailsReplyDump> postRoutingDump = - postRoutingDumpMgr.getDump(id, ctx.getModificationCache(), null); + // Each of the following cases uses different VPP API, but we store them under single node. + // Not all combinations are possible, but we don't validate on read and rely on VPP. + readPreRoutingNat44(id, index, builder, ctx); + readPreRoutingNat64(id, index, builder, ctx); + readPostRoutingNat44(id, index, builder, ctx); + } + + private void readPreRoutingNat44(final InstanceIdentifier<C> id, final int index, final B builder, + final ReadContext ctx) throws ReadFailedException { + final Optional<SnatInterfaceDetailsReplyDump> dump = + preRoutingNat44DumpMgr.getDump(id, ctx.getModificationCache(), null); - postRoutingDump.or(new SnatInterfaceOutputFeatureDetailsReplyDump()).snatInterfaceOutputFeatureDetails.stream() + dump.or(new SnatInterfaceDetailsReplyDump()).snatInterfaceDetails.stream() .filter(snatIfcDetail -> snatIfcDetail.swIfIndex == index) .filter(snatIfcDetail -> isExpectedNatType(snatIfcDetail.isInside)) - .findFirst() - .ifPresent(snatIfcDetail -> setPostRouting(builder)); + .findAny() + .ifPresent(snatIfcDetail -> vppAttributesBuilder.enableNat44(builder)); + // do not modify builder is feature is absent (inbound/outbound are presence containers) } - @Override - public boolean isPresent(final InstanceIdentifier<C> id, final C built, final ReadContext ctx) - throws ReadFailedException { - // In the post routing case, we can reuse default implementation: - if (InitializingReaderCustomizer.super.isPresent(id, built, ctx)) { - // post routing was set - return true; - } - // In the pre routing case, we need to inspect pre routing dump: - final String ifcName = getName(id); - getLog().debug("Checking NAT presence for interface: {}", ifcName); - final int index = ifcContext.getIndex(ifcName, ctx.getMappingContext()); + private void readPreRoutingNat64(final InstanceIdentifier<C> id, final int index, final B builder, + final ReadContext ctx) throws ReadFailedException { + final Optional<Nat64InterfaceDetailsReplyDump> dump = + preRoutingNat64DumpMgr.getDump(id, ctx.getModificationCache(), null); - // Cache dump for each interface under the same key since this is all ifc dump: - final Optional<SnatInterfaceDetailsReplyDump> preRoutingDump = - preRoutingDumpMgr.getDump(id, ctx.getModificationCache(), null); + dump.or(new Nat64InterfaceDetailsReplyDump()).nat64InterfaceDetails.stream() + .filter(snatIfcDetail -> snatIfcDetail.swIfIndex == index) + .filter(snatIfcDetail -> isExpectedNatType(snatIfcDetail.isInside)) + .findAny() + .ifPresent(snatIfcDetail -> vppAttributesBuilder.enableNat64(builder)); + // do not modify builder is feature is absent (inbound/outbound are presence containers) + } - // Find entries for current ifc and if is marked as inside set the builder to return presence container: - return preRoutingDump.or(new SnatInterfaceDetailsReplyDump()).snatInterfaceDetails.stream() + private void readPostRoutingNat44(final InstanceIdentifier<C> id, final int index, final B builder, + final ReadContext ctx) throws ReadFailedException { + final Optional<SnatInterfaceOutputFeatureDetailsReplyDump> dump = + postRoutingNat44DumpMgr.getDump(id, ctx.getModificationCache(), null); + + dump.or(new SnatInterfaceOutputFeatureDetailsReplyDump()).snatInterfaceOutputFeatureDetails + .stream() .filter(snatIfcDetail -> snatIfcDetail.swIfIndex == index) - .anyMatch(snatIfcDetail -> isExpectedNatType(snatIfcDetail.isInside)); - // Not setting data, just marking the builder to propagate empty container to indicate presence. + .filter(snatIfcDetail -> isExpectedNatType(snatIfcDetail.isInside)) + .findAny() + .ifPresent(snatIfcDetail -> vppAttributesBuilder.enablePostRouting(builder)); + // do not modify builder is feature is absent (inbound/outbound are presence containers) } protected String getName(final InstanceIdentifier<C> id) { @@ -113,6 +137,4 @@ abstract class AbstractInterfaceNatCustomizer<C extends DataObject, B extends Bu abstract Logger getLog(); abstract boolean isExpectedNatType(final int isInside); - - abstract void setPostRouting(final B builder); } diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/AbstractSubInterfaceNatCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/AbstractSubInterfaceNatCustomizer.java index f3872c44e..449d57e7d 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/AbstractSubInterfaceNatCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/AbstractSubInterfaceNatCustomizer.java @@ -30,8 +30,9 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; abstract class AbstractSubInterfaceNatCustomizer<C extends DataObject, B extends Builder<C>> extends AbstractInterfaceNatCustomizer<C, B> { AbstractSubInterfaceNatCustomizer(@Nonnull final FutureJVppSnatFacade jvppSnat, - @Nonnull final NamingContext ifcContext) { - super(jvppSnat, ifcContext); + @Nonnull final NamingContext ifcContext, + @Nonnull final VppAttributesBuilder vppAttributesBuilder) { + super(jvppSnat, ifcContext, vppAttributesBuilder); } @Override diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/IfcNatReaderFactory.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/IfcNatReaderFactory.java index 51150dc1d..86dc605ce 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/IfcNatReaderFactory.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/IfcNatReaderFactory.java @@ -16,7 +16,6 @@ package io.fd.hc2vpp.nat.read.ifc; - import com.google.inject.Inject; import com.google.inject.name.Named; import io.fd.hc2vpp.common.translate.util.NamingContext; diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/InboundAttributesBuilder.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/InboundAttributesBuilder.java new file mode 100644 index 000000000..b8b9db8c7 --- /dev/null +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/InboundAttributesBuilder.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 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.nat.read.ifc; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.nat.rev170816._interface.nat.attributes.nat.InboundBuilder; + +final class InboundAttributesBuilder implements VppAttributesBuilder<InboundBuilder> { + @Override + public void enableNat44(final InboundBuilder builder) { + builder.setNat44Support(true); + } + + @Override + public void enableNat64(final InboundBuilder builder) { + builder.setNat64Support(true); + } + + @Override + public void enablePostRouting(final InboundBuilder builder) { + builder.setPostRouting(true); + } +} diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/InterfaceInboundNatCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/InterfaceInboundNatCustomizer.java index 006190610..cabdd0f8b 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/InterfaceInboundNatCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/InterfaceInboundNatCustomizer.java @@ -41,7 +41,7 @@ final class InterfaceInboundNatCustomizer extends AbstractInterfaceNatCustomizer InterfaceInboundNatCustomizer(@Nonnull final FutureJVppSnatFacade jvppSnat, @Nonnull final NamingContext ifcContext) { - super(jvppSnat, ifcContext); + super(jvppSnat, ifcContext, new InboundAttributesBuilder()); } @Override @@ -54,11 +54,6 @@ final class InterfaceInboundNatCustomizer extends AbstractInterfaceNatCustomizer return isInside == 1; } - @Override - void setPostRouting(final InboundBuilder builder) { - builder.setPostRouting(true); - } - @Nonnull @Override public InboundBuilder getBuilder(@Nonnull final InstanceIdentifier<Inbound> id) { diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/InterfaceOutboundNatCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/InterfaceOutboundNatCustomizer.java index 2fb2a9282..438e43862 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/InterfaceOutboundNatCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/InterfaceOutboundNatCustomizer.java @@ -41,7 +41,7 @@ final class InterfaceOutboundNatCustomizer extends AbstractInterfaceNatCustomize InterfaceOutboundNatCustomizer(@Nonnull final FutureJVppSnatFacade jvppSnat, @Nonnull final NamingContext ifcContext) { - super(jvppSnat, ifcContext); + super(jvppSnat, ifcContext, new OutboundAttributesReader()); } @Override @@ -54,11 +54,6 @@ final class InterfaceOutboundNatCustomizer extends AbstractInterfaceNatCustomize return isInside == 0; } - @Override - void setPostRouting(final OutboundBuilder builder) { - builder.setPostRouting(true); - } - @Nonnull @Override public OutboundBuilder getBuilder(@Nonnull final InstanceIdentifier<Outbound> id) { diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/OutboundAttributesReader.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/OutboundAttributesReader.java new file mode 100644 index 000000000..16ab317a2 --- /dev/null +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/OutboundAttributesReader.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2017 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.nat.read.ifc; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.nat.rev170816._interface.nat.attributes.nat.OutboundBuilder; + +final class OutboundAttributesReader implements VppAttributesBuilder<OutboundBuilder> { + @Override + public void enableNat44(final OutboundBuilder builder) { + builder.setNat44Support(true); + } + + @Override + public void enableNat64(final OutboundBuilder builder) { + builder.setNat64Support(true); + } + + @Override + public void enablePostRouting(final OutboundBuilder builder) { + builder.setPostRouting(true); + } +} diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/SubInterfaceInboundNatCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/SubInterfaceInboundNatCustomizer.java index f9550e1e2..39ee7c9f3 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/SubInterfaceInboundNatCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/SubInterfaceInboundNatCustomizer.java @@ -45,7 +45,7 @@ final class SubInterfaceInboundNatCustomizer extends AbstractSubInterfaceNatCust SubInterfaceInboundNatCustomizer(@Nonnull final FutureJVppSnatFacade jvppSnat, @Nonnull final NamingContext ifcContext) { - super(jvppSnat, ifcContext); + super(jvppSnat, ifcContext, new InboundAttributesBuilder()); } @Override @@ -58,11 +58,6 @@ final class SubInterfaceInboundNatCustomizer extends AbstractSubInterfaceNatCust return isInside == 1; } - @Override - void setPostRouting(final InboundBuilder builder) { - builder.setPostRouting(true); - } - @Nonnull @Override public InboundBuilder getBuilder(@Nonnull final InstanceIdentifier<Inbound> id) { diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/SubInterfaceOutboundNatCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/SubInterfaceOutboundNatCustomizer.java index 9b6dce766..330e4c4b3 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/SubInterfaceOutboundNatCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/SubInterfaceOutboundNatCustomizer.java @@ -45,7 +45,7 @@ final class SubInterfaceOutboundNatCustomizer extends AbstractSubInterfaceNatCus SubInterfaceOutboundNatCustomizer(@Nonnull final FutureJVppSnatFacade jvppSnat, @Nonnull final NamingContext ifcContext) { - super(jvppSnat, ifcContext); + super(jvppSnat, ifcContext, new OutboundAttributesReader()); } @Override @@ -58,11 +58,6 @@ final class SubInterfaceOutboundNatCustomizer extends AbstractSubInterfaceNatCus return isInside == 0; } - @Override - void setPostRouting(final OutboundBuilder builder) { - builder.setPostRouting(true); - } - @Nonnull @Override public OutboundBuilder getBuilder(@Nonnull final InstanceIdentifier<Outbound> id) { diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/VppAttributesBuilder.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/VppAttributesBuilder.java new file mode 100644 index 000000000..57c24fa4b --- /dev/null +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ifc/VppAttributesBuilder.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2017 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.nat.read.ifc; + +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.nat.rev170816.InterfaceNatVppFeatureAttributes; +import org.opendaylight.yangtools.concepts.Builder; + +interface VppAttributesBuilder<B extends Builder<? extends InterfaceNatVppFeatureAttributes>> { + void enableNat44(final B builder); + + void enableNat64(final B builder); + + void enablePostRouting(final B builder); +} diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/ifc/AbstractInterfaceNatCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/ifc/AbstractInterfaceNatCustomizer.java index dbfbb17e4..4a44fe9a6 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/ifc/AbstractInterfaceNatCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/ifc/AbstractInterfaceNatCustomizer.java @@ -16,19 +16,18 @@ package io.fd.hc2vpp.nat.write.ifc; +import static com.google.common.base.Preconditions.checkArgument; + 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.spi.write.WriterCustomizer; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; -import io.fd.vpp.jvpp.dto.JVppReply; +import io.fd.vpp.jvpp.snat.dto.Nat64AddDelInterface; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceAddDelFeature; -import io.fd.vpp.jvpp.snat.dto.SnatInterfaceAddDelFeatureReply; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceAddDelOutputFeature; -import io.fd.vpp.jvpp.snat.dto.SnatInterfaceAddDelOutputFeatureReply; import io.fd.vpp.jvpp.snat.future.FutureJVppSnatFacade; -import java.util.concurrent.CompletionStage; 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.nat.rev170816.InterfaceNatVppFeatureAttributes; @@ -56,13 +55,12 @@ abstract class AbstractInterfaceNatCustomizer<D extends InterfaceNatVppFeatureAt getLog().debug("Enabling {} NAT: {}", dataAfter, id); final int ifcIndex = ifcContext.getIndex(ifcName, writeContext.getMappingContext()); - final JVppReply reply; if (dataAfter.isPostRouting()) { - reply = postRoutingNat(id, ifcIndex, true); + postRoutingNat(id, dataAfter, ifcIndex, true); } else { - reply = preRoutingNat(id, ifcIndex, true); + preRoutingNat(id, dataAfter, ifcIndex, true); } - getLog().debug("NAT {} enabled successfully on: {}, reply: {}", dataAfter, ifcName, reply); + getLog().debug("NAT {} enabled successfully on: {}", dataAfter, ifcName); } @Override @@ -74,40 +72,61 @@ abstract class AbstractInterfaceNatCustomizer<D extends InterfaceNatVppFeatureAt getLog().debug("Disabling {} NAT: {}", dataBefore, id); final int ifcIndex = ifcContext.getIndex(ifcName, writeContext.getMappingContext()); - final JVppReply reply; if (dataBefore.isPostRouting()) { - reply = postRoutingNat(id, ifcIndex, false); + postRoutingNat(id, dataBefore, ifcIndex, false); } else { - reply = preRoutingNat(id, ifcIndex, false); + preRoutingNat(id, dataBefore, ifcIndex, false); } - getLog().debug("NAT {} disabled successfully on: {}, reply: {}", dataBefore, ifcName, reply); + getLog().debug("NAT {} disabled successfully on: {}", dataBefore, ifcName); } protected String getName(final InstanceIdentifier<D> id) { return id.firstKeyOf(Interface.class).getName(); } - private JVppReply postRoutingNat(@Nonnull final InstanceIdentifier<D> id, final int ifcIndex, final boolean enable) + private void postRoutingNat(@Nonnull final InstanceIdentifier<D> id, final D natAttributes, final int ifcIndex, + final boolean enable) throws WriteFailedException { + checkArgument(!isNat64Supported(natAttributes), "Post routing Nat64 is not supported by VPP"); final SnatInterfaceAddDelOutputFeature request = new SnatInterfaceAddDelOutputFeature(); request.isAdd = booleanToByte(enable); request.isInside = getType().isInside; request.swIfIndex = ifcIndex; + getReplyForWrite(jvppSnat.snatInterfaceAddDelOutputFeature(request).toCompletableFuture(), id); + } + + private void preRoutingNat(@Nonnull final InstanceIdentifier<D> id, final D natAttributes, final int ifcIndex, + final boolean enable) + throws WriteFailedException { + if (natAttributes.isNat44Support()) { + // default value is defined for nat44-support, so no need for null check + preRoutingNat44(id, ifcIndex, enable); + } + if (isNat64Supported(natAttributes)) { + preRoutingNat64(id, ifcIndex, enable); + } + } - final CompletionStage<SnatInterfaceAddDelOutputFeatureReply> future = - jvppSnat.snatInterfaceAddDelOutputFeature(request); - return getReplyForWrite(future.toCompletableFuture(), id); + private boolean isNat64Supported(final D natAttributes) { + return natAttributes.isNat64Support() != null && natAttributes.isNat64Support(); } - private JVppReply preRoutingNat(@Nonnull final InstanceIdentifier<D> id, final int ifcIndex, final boolean enable) + private void preRoutingNat44(@Nonnull final InstanceIdentifier<D> id, final int ifcIndex, final boolean enable) throws WriteFailedException { final SnatInterfaceAddDelFeature request = new SnatInterfaceAddDelFeature(); request.isAdd = booleanToByte(enable); request.isInside = getType().isInside; request.swIfIndex = ifcIndex; + getReplyForWrite(jvppSnat.snatInterfaceAddDelFeature(request).toCompletableFuture(), id); + } - final CompletionStage<SnatInterfaceAddDelFeatureReply> future = jvppSnat.snatInterfaceAddDelFeature(request); - return getReplyForWrite(future.toCompletableFuture(), id); + private void preRoutingNat64(@Nonnull final InstanceIdentifier<D> id, final int ifcIndex, final boolean enable) + throws WriteFailedException { + final Nat64AddDelInterface request = new Nat64AddDelInterface(); + request.isAdd = booleanToByte(enable); + request.isInside = getType().isInside; + request.swIfIndex = ifcIndex; + getReplyForWrite(jvppSnat.nat64AddDelInterface(request).toCompletableFuture(), id); } enum NatType { diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/ifc/InterfaceInboundNatCustomizerTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/ifc/InterfaceInboundNatCustomizerTest.java index 2d31e3b6a..a2d92b4d0 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/ifc/InterfaceInboundNatCustomizerTest.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/ifc/InterfaceInboundNatCustomizerTest.java @@ -16,7 +16,6 @@ package io.fd.hc2vpp.nat.read.ifc; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; @@ -29,6 +28,7 @@ import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.honeycomb.translate.impl.read.GenericReader; import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.vpp.jvpp.snat.dto.Nat64InterfaceDetailsReplyDump; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceDetails; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceDetailsReplyDump; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceOutputFeatureDetails; @@ -79,17 +79,14 @@ public class InterfaceInboundNatCustomizerTest when(jvppSnat.snatInterfaceDump(any())).thenReturn(future(new SnatInterfaceDetailsReplyDump())); when(jvppSnat.snatInterfaceOutputFeatureDump(any())) .thenReturn(future(new SnatInterfaceOutputFeatureDetailsReplyDump())); + when(jvppSnat.nat64InterfaceDump(any())) + .thenReturn(future(new Nat64InterfaceDetailsReplyDump())); } private GenericReader<Inbound, InboundBuilder> getReader() { return new GenericReader<>(RWUtils.makeIidWildcarded(id), customizer); } - @Test - public void testNoPresence() throws Exception { - assertFalse(getReader().read(id, ctx).isPresent()); - } - private void mockPostRoutingDump() { final SnatInterfaceOutputFeatureDetailsReplyDump details = new SnatInterfaceOutputFeatureDetailsReplyDump(); final SnatInterfaceOutputFeatureDetails detail = new SnatInterfaceOutputFeatureDetails(); diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/ifc/InterfaceOutboundNatCustomizerTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/ifc/InterfaceOutboundNatCustomizerTest.java index 92dfff161..4640944a5 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/ifc/InterfaceOutboundNatCustomizerTest.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/ifc/InterfaceOutboundNatCustomizerTest.java @@ -17,7 +17,6 @@ package io.fd.hc2vpp.nat.read.ifc; import static io.fd.hc2vpp.nat.read.ifc.InterfaceInboundNatCustomizerTest.getId; -import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; @@ -30,6 +29,7 @@ import io.fd.hc2vpp.common.translate.util.NamingContext; import io.fd.honeycomb.translate.impl.read.GenericReader; import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; +import io.fd.vpp.jvpp.snat.dto.Nat64InterfaceDetailsReplyDump; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceDetails; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceDetailsReplyDump; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceOutputFeatureDetails; @@ -65,17 +65,14 @@ public class InterfaceOutboundNatCustomizerTest when(jvppSnat.snatInterfaceDump(any())).thenReturn(future(new SnatInterfaceDetailsReplyDump())); when(jvppSnat.snatInterfaceOutputFeatureDump(any())) .thenReturn(future(new SnatInterfaceOutputFeatureDetailsReplyDump())); + when(jvppSnat.nat64InterfaceDump(any())) + .thenReturn(future(new Nat64InterfaceDetailsReplyDump())); } private GenericReader<Outbound, OutboundBuilder> getReader() { return new GenericReader<>(RWUtils.makeIidWildcarded(id), customizer); } - @Test - public void testNoPresence() throws Exception { - assertFalse(getReader().read(id, ctx).isPresent()); - } - private void mockPostRoutingDump() { final SnatInterfaceOutputFeatureDetailsReplyDump details = new SnatInterfaceOutputFeatureDetailsReplyDump(); final SnatInterfaceOutputFeatureDetails detail = new SnatInterfaceOutputFeatureDetails(); diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ifc/AbstractNatCustomizerTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ifc/AbstractNatCustomizerTest.java index 5e37d165d..c70999907 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ifc/AbstractNatCustomizerTest.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ifc/AbstractNatCustomizerTest.java @@ -17,12 +17,15 @@ package io.fd.hc2vpp.nat.write.ifc; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import io.fd.hc2vpp.common.test.write.WriterCustomizerTest; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; import io.fd.hc2vpp.common.translate.util.NamingContext; +import io.fd.vpp.jvpp.snat.dto.Nat64AddDelInterface; +import io.fd.vpp.jvpp.snat.dto.Nat64AddDelInterfaceReply; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceAddDelFeature; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceAddDelFeatureReply; import io.fd.vpp.jvpp.snat.dto.SnatInterfaceAddDelOutputFeature; @@ -54,13 +57,14 @@ abstract class AbstractNatCustomizerTest<D extends InterfaceNatVppFeatureAttribu when(snatApi.snatInterfaceAddDelFeature(any())).thenReturn(future(new SnatInterfaceAddDelFeatureReply())); when(snatApi.snatInterfaceAddDelOutputFeature(any())) .thenReturn(future(new SnatInterfaceAddDelOutputFeatureReply())); + when(snatApi.nat64AddDelInterface(any())).thenReturn(future(new Nat64AddDelInterfaceReply())); } @Test public void testWritePreRouting() throws Exception { final D data = getPreRoutingConfig(); customizer.writeCurrentAttributes(getIId(IFACE_NAME), data, writeContext); - verify(snatApi).snatInterfaceAddDelFeature(expectedPreRoutingRequest(data, true)); + verifyPreRouting(data, true); } @Test @@ -68,6 +72,7 @@ abstract class AbstractNatCustomizerTest<D extends InterfaceNatVppFeatureAttribu final D data = getPostRoutingConfig(); customizer.writeCurrentAttributes(getIId(IFACE_NAME), data, writeContext); verify(snatApi).snatInterfaceAddDelOutputFeature(expectedPostRoutingRequest(data, true)); + verify(snatApi, never()).nat64AddDelInterface(any()); // VPP does not support it currently } @Test(expected = UnsupportedOperationException.class) @@ -86,7 +91,7 @@ abstract class AbstractNatCustomizerTest<D extends InterfaceNatVppFeatureAttribu public void testDeletePreRouting() throws Exception { final D data = getPreRoutingConfig(); customizer.deleteCurrentAttributes(getIId(IFACE_NAME), data, writeContext); - verify(snatApi).snatInterfaceAddDelFeature(expectedPreRoutingRequest(data, false)); + verifyPreRouting(data, false); } @Test @@ -94,13 +99,34 @@ abstract class AbstractNatCustomizerTest<D extends InterfaceNatVppFeatureAttribu final D data = getPostRoutingConfig(); customizer.deleteCurrentAttributes(getIId(IFACE_NAME), data, writeContext); verify(snatApi).snatInterfaceAddDelOutputFeature(expectedPostRoutingRequest(data, false)); + verify(snatApi, never()).nat64AddDelInterface(any()); // VPP does not support it currently } - private SnatInterfaceAddDelFeature expectedPreRoutingRequest(final D data, boolean isAdd) { + private void verifyPreRouting(final D data, final boolean isAdd) { + if (data.isNat44Support()) { + verify(snatApi).snatInterfaceAddDelFeature(expectedPreRoutingNat44Request(data, isAdd)); + } else { + verify(snatApi, never()).snatInterfaceAddDelFeature(any()); + } + if (data.isNat64Support() != null && data.isNat64Support()) { + verify(snatApi).nat64AddDelInterface(expectedPreRoutingNat64Request(data, isAdd)); + } else { + verify(snatApi, never()).nat64AddDelInterface(any()); + } + + } + + private SnatInterfaceAddDelFeature expectedPreRoutingNat44Request(final D data, boolean isAdd) { SnatInterfaceAddDelFeature request = new SnatInterfaceAddDelFeature(); - request.isInside = (byte) ((data instanceof Inbound) - ? 1 - : 0); + request.isInside = booleanToByte(data instanceof Inbound); + request.swIfIndex = IFACE_ID; + request.isAdd = booleanToByte(isAdd); + return request; + } + + private Nat64AddDelInterface expectedPreRoutingNat64Request(final D data, boolean isAdd) { + Nat64AddDelInterface request = new Nat64AddDelInterface(); + request.isInside = booleanToByte(data instanceof Inbound); request.swIfIndex = IFACE_ID; request.isAdd = booleanToByte(isAdd); return request; @@ -108,9 +134,7 @@ abstract class AbstractNatCustomizerTest<D extends InterfaceNatVppFeatureAttribu private SnatInterfaceAddDelOutputFeature expectedPostRoutingRequest(final D data, boolean isAdd) { SnatInterfaceAddDelOutputFeature request = new SnatInterfaceAddDelOutputFeature(); - request.isInside = (byte) ((data instanceof Inbound) - ? 1 - : 0); + request.isInside = booleanToByte(data instanceof Inbound); request.swIfIndex = IFACE_ID; request.isAdd = booleanToByte(isAdd); return request; diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ifc/InterfaceInboundNatCustomizerTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ifc/InterfaceInboundNatCustomizerTest.java index f7d9777e3..74dd59938 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ifc/InterfaceInboundNatCustomizerTest.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ifc/InterfaceInboundNatCustomizerTest.java @@ -32,12 +32,12 @@ public class InterfaceInboundNatCustomizerTest @Override protected Inbound getPreRoutingConfig() { - return new InboundBuilder().setPostRouting(false).build(); + return new InboundBuilder().setPostRouting(false).setNat44Support(true).build(); } @Override protected Inbound getPostRoutingConfig() { - return new InboundBuilder().setPostRouting(true).build(); + return new InboundBuilder().setPostRouting(true).setNat44Support(true).build(); } @Override diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ifc/InterfaceOutboundNatCustomizerTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ifc/InterfaceOutboundNatCustomizerTest.java index ba48d914e..ddd589472 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ifc/InterfaceOutboundNatCustomizerTest.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ifc/InterfaceOutboundNatCustomizerTest.java @@ -32,12 +32,12 @@ public class InterfaceOutboundNatCustomizerTest @Override protected Outbound getPreRoutingConfig() { - return new OutboundBuilder().setPostRouting(false).build(); + return new OutboundBuilder().setPostRouting(false).setNat44Support(true).setNat64Support(true).build(); } @Override protected Outbound getPostRoutingConfig() { - return new OutboundBuilder().setPostRouting(true).build(); + return new OutboundBuilder().setPostRouting(true).setNat44Support(true).setNat64Support(false).build(); } @Override |