From 78aca8c336e69a049fd5e340b194bf7c66f61da1 Mon Sep 17 00:00:00 2001 From: Marek Gradzki Date: Wed, 9 Aug 2017 12:30:21 +0200 Subject: HC2VPP-105: add support for NAT64 BIB entries read Change-Id: Ic8e61a13cba8ae8e3e69f16985918451df239430 Signed-off-by: Marek Gradzki --- .../fd/hc2vpp/nat/read/MappingEntryCustomizer.java | 136 ++++++++++++--- .../fd/hc2vpp/nat/read/NatInstanceCustomizer.java | 37 ++-- .../io/fd/hc2vpp/nat/read/NatReaderFactory.java | 18 +- .../io/fd/hc2vpp/nat/util/MappingEntryContext.java | 84 ++++++++- .../nat/read/MappingEntryCustomizerTest.java | 188 +++++++++++++++++---- .../hc2vpp/nat/read/NatInstanceCustomizerTest.java | 55 ++++-- .../hc2vpp/nat/util/MappingEntryContextTest.java | 6 +- 7 files changed, 423 insertions(+), 101 deletions(-) diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/MappingEntryCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/MappingEntryCustomizer.java index ae4f11917..2732c5fcc 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/MappingEntryCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/MappingEntryCustomizer.java @@ -17,6 +17,7 @@ package io.fd.hc2vpp.nat.read; import io.fd.hc2vpp.common.translate.util.Ipv4Translator; +import io.fd.hc2vpp.common.translate.util.Ipv6Translator; import io.fd.hc2vpp.common.translate.util.JvppReplyConsumer; import io.fd.hc2vpp.nat.util.MappingEntryContext; import io.fd.honeycomb.translate.read.ReadContext; @@ -26,11 +27,15 @@ import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; import io.fd.honeycomb.translate.util.RWUtils; import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.vpp.jvpp.snat.dto.Nat64BibDetails; +import io.fd.vpp.jvpp.snat.dto.Nat64BibDetailsReplyDump; +import io.fd.vpp.jvpp.snat.dto.Nat64BibDump; import io.fd.vpp.jvpp.snat.dto.SnatStaticMappingDetails; import io.fd.vpp.jvpp.snat.dto.SnatStaticMappingDetailsReplyDump; import io.fd.vpp.jvpp.snat.dto.SnatStaticMappingDump; import io.fd.vpp.jvpp.snat.future.FutureJVppSnatFacade; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; @@ -50,18 +55,21 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -final class MappingEntryCustomizer implements Ipv4Translator, +final class MappingEntryCustomizer implements Ipv4Translator, Ipv6Translator, InitializingListReaderCustomizer { private static final Logger LOG = LoggerFactory.getLogger(MappingEntryCustomizer.class); - private final DumpCacheManager dumpCacheManager; + private final DumpCacheManager nat44DumpManager; + private final DumpCacheManager nat64DumpManager; private final MappingEntryContext mappingEntryContext; MappingEntryCustomizer( - final DumpCacheManager dumpCacheManager, + final DumpCacheManager nat44DumpManager, + final DumpCacheManager nat64DumpManager, final MappingEntryContext mappingEntryContext) { - this.dumpCacheManager = dumpCacheManager; + this.nat44DumpManager = nat44DumpManager; + this.nat64DumpManager = nat64DumpManager; this.mappingEntryContext = mappingEntryContext; } @@ -79,34 +87,78 @@ final class MappingEntryCustomizer implements Ipv4Translator, final int idx = id.firstKeyOf(MappingEntry.class).getIndex().intValue(); final int natInstanceId = id.firstKeyOf(NatInstance.class).getId().intValue(); - final List details = - dumpCacheManager.getDump(id, ctx.getModificationCache(), null) + final List nat44Details = + nat44DumpManager.getDump(id, ctx.getModificationCache(), null) .or(new SnatStaticMappingDetailsReplyDump()).snatStaticMappingDetails; - final SnatStaticMappingDetails snatStaticMappingDetails = - mappingEntryContext.findDetails(details, natInstanceId, idx, ctx.getMappingContext()); + final Optional snat44StaticMappingDetails = + mappingEntryContext.findDetailsNat44(nat44Details, natInstanceId, idx, ctx.getMappingContext()); - builder.setIndex((long) idx); + if (snat44StaticMappingDetails.isPresent()) { + readNat44Entry(builder, idx, snat44StaticMappingDetails.get()); + } else { + final List nat64Details = + nat64DumpManager.getDump(id, ctx.getModificationCache(), null) + .or(new Nat64BibDetailsReplyDump()).nat64BibDetails; + + final Optional snat64StaticMappingDetails = + mappingEntryContext.findDetailsNat64(nat64Details, natInstanceId, idx, ctx.getMappingContext()); + + if (snat64StaticMappingDetails.isPresent()) { + readNat64Entry(builder, idx, snat64StaticMappingDetails.get()); + } + } + + + LOG.trace("Mapping-entry read as: {}", builder); + } + + private void readNat44Entry(@Nonnull final MappingEntryBuilder builder, + final int index, final SnatStaticMappingDetails detail) { + builder.setIndex((long) index); builder.setType( org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.MappingEntry.Type.Static); - // Snat only supports ipv4 for now - builder.setExternalSrcAddress(arrayToIpv4AddressNoZone(snatStaticMappingDetails.externalIpAddress)); + builder.setExternalSrcAddress(arrayToIpv4AddressNoZone(detail.externalIpAddress)); builder.setInternalSrcAddress( - new IpAddress(arrayToIpv4AddressNoZone(snatStaticMappingDetails.localIpAddress))); + new IpAddress(arrayToIpv4AddressNoZone(detail.localIpAddress))); - if (snatStaticMappingDetails.addrOnly == 0) { + if (detail.addrOnly == 0) { builder.setExternalSrcPort(new ExternalSrcPortBuilder() .setPortType(new SinglePortNumberBuilder().setSinglePortNumber(new PortNumber( - (int) snatStaticMappingDetails.externalPort)) + (int) detail.externalPort)) .build()) .build()); builder.setInternalSrcPort(new InternalSrcPortBuilder() .setPortType(new SinglePortNumberBuilder().setSinglePortNumber(new PortNumber( - (int) snatStaticMappingDetails.localPort)) + (int) detail.localPort)) .build()) .build()); } + } - LOG.trace("Mapping-entry read as: {}", builder); + private void readNat64Entry(@Nonnull final MappingEntryBuilder builder, + final int index, final Nat64BibDetails detail) { + builder.setIndex((long) index); + if (detail.isStatic == 1) { + builder.setType( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.MappingEntry.Type.Static); + } else { + builder.setType( + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.MappingEntry.Type.Dynamic); + } + builder.setExternalSrcAddress(arrayToIpv4AddressNoZone(detail.oAddr)); + builder.setInternalSrcAddress( + new IpAddress(arrayToIpv6AddressNoZone(detail.iAddr))); + + builder.setExternalSrcPort(new ExternalSrcPortBuilder() + .setPortType(new SinglePortNumberBuilder().setSinglePortNumber(new PortNumber( + (int) detail.oPort)) + .build()) + .build()); + builder.setInternalSrcPort(new InternalSrcPortBuilder() + .setPortType(new SinglePortNumberBuilder().setSinglePortNumber(new PortNumber( + (int) detail.iPort)) + .build()) + .build()); } @Nonnull @@ -117,13 +169,24 @@ final class MappingEntryCustomizer implements Ipv4Translator, LOG.trace("Listing IDs for all mapping-entries within nat-instance(vrf):{}", natInstanceId); final List entryKeys = - dumpCacheManager.getDump(id, context.getModificationCache(), null) + nat44DumpManager.getDump(id, context.getModificationCache(), null) .or(new SnatStaticMappingDetailsReplyDump()).snatStaticMappingDetails.stream() .filter(detail -> natInstanceId == detail.vrfId) .map(detail -> mappingEntryContext .getStoredOrArtificialIndex(natInstanceId, detail, context.getMappingContext())) .map(MappingEntryKey::new) .collect(Collectors.toList()); + + + final List nat64Keys = + nat64DumpManager.getDump(id, context.getModificationCache(), null) + .or(new Nat64BibDetailsReplyDump()).nat64BibDetails.stream() + .filter(detail -> natInstanceId == detail.vrfId) + .map(detail -> mappingEntryContext + .getStoredOrArtificialIndex(natInstanceId, detail, context.getMappingContext())) + .map(MappingEntryKey::new) + .collect(Collectors.toList()); + entryKeys.addAll(nat64Keys); LOG.debug("List of mapping-entry keys within nat-instance(vrf):{} : {}", natInstanceId, entryKeys); return entryKeys; @@ -136,27 +199,31 @@ final class MappingEntryCustomizer implements Ipv4Translator, } @Override - public Initialized init(@Nonnull final InstanceIdentifier id, - @Nonnull final MappingEntry readValue, - @Nonnull final ReadContext ctx) { + public Initialized init( + @Nonnull final InstanceIdentifier id, + @Nonnull final MappingEntry readValue, + @Nonnull final ReadContext ctx) { return Initialized.create(getCfgId(id), - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntryBuilder(readValue) + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntryBuilder( + readValue) .build()); } - static InstanceIdentifier getCfgId(final @Nonnull InstanceIdentifier id) { + static InstanceIdentifier getCfgId( + final @Nonnull InstanceIdentifier id) { return NatInstanceCustomizer.getCfgId(RWUtils.cutId(id, NatInstance.class)) .child(MappingTable.class) .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntry.class, - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntryKey(id.firstKeyOf(MappingEntry.class).getIndex())); + new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntryKey( + id.firstKeyOf(MappingEntry.class).getIndex())); } - static final class MappingEntryDumpExecutor + static final class MappingEntryNat44DumpExecutor implements EntityDumpExecutor, JvppReplyConsumer { private final FutureJVppSnatFacade jvppSnat; - MappingEntryDumpExecutor(final FutureJVppSnatFacade jvppSnat) { + MappingEntryNat44DumpExecutor(final FutureJVppSnatFacade jvppSnat) { this.jvppSnat = jvppSnat; } @@ -168,4 +235,23 @@ final class MappingEntryCustomizer implements Ipv4Translator, identifier); } } + + static final class MappingEntryNat64DumpExecutor + implements EntityDumpExecutor, JvppReplyConsumer { + + private final FutureJVppSnatFacade jvppSnat; + + MappingEntryNat64DumpExecutor(final FutureJVppSnatFacade jvppSnat) { + this.jvppSnat = jvppSnat; + } + + @Nonnull + @Override + public Nat64BibDetailsReplyDump executeDump(final InstanceIdentifier identifier, final Void params) + throws ReadFailedException { + final Nat64BibDump dump = new Nat64BibDump(); + dump.proto = -1; // dump entries for all protocols + return getReplyForRead(jvppSnat.nat64BibDump(dump).toCompletableFuture(), identifier); + } + } } diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/NatInstanceCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/NatInstanceCustomizer.java index 9542587d0..18a959274 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/NatInstanceCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/NatInstanceCustomizer.java @@ -21,9 +21,11 @@ import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.spi.read.Initialized; import io.fd.honeycomb.translate.spi.read.InitializingListReaderCustomizer; import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.vpp.jvpp.snat.dto.Nat64BibDetailsReplyDump; import io.fd.vpp.jvpp.snat.dto.SnatStaticMappingDetailsReplyDump; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.NatConfig; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.NatInstancesBuilder; @@ -39,16 +41,20 @@ import org.slf4j.LoggerFactory; /** * Nat instance ID is mapped to VRF-ID in VPP. */ -final class NatInstanceCustomizer implements InitializingListReaderCustomizer { +final class NatInstanceCustomizer + implements InitializingListReaderCustomizer { private static final Logger LOG = LoggerFactory.getLogger(NatInstanceCustomizer.class); static final NatInstanceKey DEFAULT_VRF_ID = new NatInstanceKey(0L); - private final DumpCacheManager dumpCacheManager; + private final DumpCacheManager nat44DumpManager; + private final DumpCacheManager nat64DumpManager; NatInstanceCustomizer( - final DumpCacheManager dumpCacheManager) { - this.dumpCacheManager = dumpCacheManager; + final DumpCacheManager nat44DumpManager, + final DumpCacheManager nat64DumpManager) { + this.nat44DumpManager = nat44DumpManager; + this.nat64DumpManager = nat64DumpManager; } @Nonnull @@ -72,12 +78,18 @@ final class NatInstanceCustomizer implements InitializingListReaderCustomizer vrfIds = - dumpCacheManager.getDump(id, context.getModificationCache(), null) + final List vrfIds = Stream.concat( + nat44DumpManager.getDump(id, context.getModificationCache(), null) .or(new SnatStaticMappingDetailsReplyDump()).snatStaticMappingDetails.stream() - .map(detail -> detail.vrfId) - .map(vrfId -> new NatInstanceKey((long) vrfId)) - .collect(Collectors.toList()); + .map(detail -> detail.vrfId), + nat64DumpManager.getDump(id, context.getModificationCache(), null) + .or(new Nat64BibDetailsReplyDump()).nat64BibDetails.stream() + .map(detail -> detail.vrfId)) + // V4 (nat44) and V6 (nat64) VRFs in VPP can have the same id. We store them under single nat instance, + // because the ietf-nat model does not require separate instances for nat44 and nat64 features. + .distinct() + .map(vrfId -> new NatInstanceKey((long) vrfId)) + .collect(Collectors.toList()); // Add default vrf id if not present if (!vrfIds.contains(DEFAULT_VRF_ID)) { @@ -94,9 +106,10 @@ final class NatInstanceCustomizer implements InitializingListReaderCustomizer init(@Nonnull final InstanceIdentifier id, - @Nonnull final NatInstance readValue, - @Nonnull final ReadContext ctx) { + public Initialized init( + @Nonnull final InstanceIdentifier id, + @Nonnull final NatInstance readValue, + @Nonnull final ReadContext ctx) { return Initialized.create(getCfgId(id), new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.NatInstanceBuilder() .setId(readValue.getId()) diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/NatReaderFactory.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/NatReaderFactory.java index 791b7bc0b..d9c7f3380 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/NatReaderFactory.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/NatReaderFactory.java @@ -23,6 +23,7 @@ import io.fd.honeycomb.translate.impl.read.GenericInitListReader; import io.fd.honeycomb.translate.read.ReaderFactory; import io.fd.honeycomb.translate.read.registry.ModifiableReaderRegistryBuilder; import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; +import io.fd.vpp.jvpp.snat.dto.Nat64BibDetailsReplyDump; import io.fd.vpp.jvpp.snat.dto.SnatStaticMappingDetailsReplyDump; import io.fd.vpp.jvpp.snat.future.FutureJVppSnatFacade; import javax.annotation.Nonnull; @@ -53,7 +54,8 @@ public class NatReaderFactory implements ReaderFactory { private final FutureJVppSnatFacade jvppSnat; private final MappingEntryContext mappingEntryContext; - private final DumpCacheManager mapEntryDumpMgr; + private final DumpCacheManager mapEntryNat44DumpMgr; + private final DumpCacheManager mapEntryNat64DumpMgr; @Inject @@ -61,23 +63,29 @@ public class NatReaderFactory implements ReaderFactory { final MappingEntryContext mappingEntryContext) { this.jvppSnat = jvppSnat; this.mappingEntryContext = mappingEntryContext; - this.mapEntryDumpMgr = + this.mapEntryNat44DumpMgr = new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor(new MappingEntryCustomizer.MappingEntryDumpExecutor(jvppSnat)) + .withExecutor(new MappingEntryCustomizer.MappingEntryNat44DumpExecutor(jvppSnat)) .acceptOnly(SnatStaticMappingDetailsReplyDump.class) .build(); + this.mapEntryNat64DumpMgr = + new DumpCacheManager.DumpCacheManagerBuilder() + .withExecutor(new MappingEntryCustomizer.MappingEntryNat64DumpExecutor(jvppSnat)) + .acceptOnly(Nat64BibDetailsReplyDump.class) + .build(); } @Override public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { registry.addStructuralReader(NAT_OPER_ID, NatStateBuilder.class); registry.addStructuralReader(NAT_INSTANCES_ID, NatInstancesBuilder.class); - registry.add(new GenericInitListReader<>(NAT_INSTANCE_ID, new NatInstanceCustomizer(mapEntryDumpMgr))); + registry.add(new GenericInitListReader<>(NAT_INSTANCE_ID, + new NatInstanceCustomizer(mapEntryNat44DumpMgr, mapEntryNat64DumpMgr))); registry.addStructuralReader(MAP_TABLE_ID, MappingTableBuilder.class); registry.subtreeAdd(Sets.newHashSet(InstanceIdentifier.create(MappingEntry.class).child(ExternalSrcPort.class), InstanceIdentifier.create(MappingEntry.class).child(InternalSrcPort.class)), new GenericInitListReader<>(MAP_ENTRY_ID, - new MappingEntryCustomizer(mapEntryDumpMgr, mappingEntryContext))); + new MappingEntryCustomizer(mapEntryNat44DumpMgr, mapEntryNat64DumpMgr, mappingEntryContext))); registry.addStructuralReader(CURRENT_CONFIG, NatCurrentConfigBuilder.class); registry.add(new GenericInitListReader<>(CURRENT_CONFIG.child(ExternalIpAddressPool.class), diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/util/MappingEntryContext.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/util/MappingEntryContext.java index afdf8abae..292adc3aa 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/util/MappingEntryContext.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/util/MappingEntryContext.java @@ -21,7 +21,9 @@ import static com.google.common.base.Preconditions.checkArgument; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import io.fd.hc2vpp.common.translate.util.Ipv4Translator; +import io.fd.hc2vpp.common.translate.util.Ipv6Translator; import io.fd.honeycomb.translate.MappingContext; +import io.fd.vpp.jvpp.snat.dto.Nat64BibDetails; import io.fd.vpp.jvpp.snat.dto.SnatStaticMappingDetails; import java.util.Collections; import java.util.Comparator; @@ -39,6 +41,7 @@ import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.nat.context import org.opendaylight.yang.gen.v1.urn.honeycomb.params.xml.ns.yang.nat.context.rev161214.mapping.entry.context.attributes.nat.mapping.entry.context.nat.instance.mapping.table.MappingEntryKey; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,7 +50,7 @@ import org.slf4j.LoggerFactory; * Context tracker for Nat Mapping entries. */ @ThreadSafe -public class MappingEntryContext implements Ipv4Translator { +public class MappingEntryContext implements Ipv4Translator, Ipv6Translator { private static final Logger LOG = LoggerFactory.getLogger(MappingEntryContext.class); @@ -101,6 +104,12 @@ public class MappingEntryContext implements Ipv4Translator { new IpAddress(new Ipv4Address(arrayToIpv4AddressNoZone(entry.localIpAddress)))); } + private MappingEntryKey entryToKey(final Nat64BibDetails entry) { + return new MappingEntryKey( + new IpAddress(new Ipv4Address(arrayToIpv4AddressNoZone(entry.oAddr))), + new IpAddress(new Ipv6Address(arrayToIpv6AddressNoZone(entry.iAddr)))); + } + private boolean equalEntries(final SnatStaticMappingDetails detail, final MappingEntry ctxMappingEntry) { final IpAddress internalAddrFromDetails = new IpAddress(new Ipv4Address(arrayToIpv4AddressNoZone(detail.localIpAddress))); @@ -117,6 +126,22 @@ public class MappingEntryContext implements Ipv4Translator { return true; } + private boolean equalEntries(final Nat64BibDetails detail, final MappingEntry ctxMappingEntry) { + final IpAddress internalAddrFromDetails = + new IpAddress(new Ipv6Address(arrayToIpv6AddressNoZone(detail.iAddr))); + // Only IPv6 + if (!ctxMappingEntry.getInternal().equals(internalAddrFromDetails)) { + return false; + } + // Only IPv4 + final IpAddress externalAddrFromDetails = + new IpAddress(new Ipv4Address(arrayToIpv4AddressNoZone(detail.oAddr))); + if (!ctxMappingEntry.getExternal().equals(externalAddrFromDetails)) { + return false; + } + return true; + } + @VisibleForTesting static MappingEntry toCtxMapEntry( @Nonnull final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntry entry, @@ -134,6 +159,13 @@ public class MappingEntryContext implements Ipv4Translator { .build(); } + private MappingEntry toCtxMapEntry(@Nonnull final Nat64BibDetails details, final long entryId) { + return new MappingEntryBuilder() + .setKey(entryToKey(details)) + .setIndex(entryId) + .build(); + } + /** * Delete mapping of mapping entry to index from context. */ @@ -146,9 +178,9 @@ public class MappingEntryContext implements Ipv4Translator { /** * Find specific details in provided collection identified with provided index. */ - public synchronized SnatStaticMappingDetails findDetails(@Nonnull final List details, - final long natInstanceId, final long idx, - @Nonnull final MappingContext mappingContext) { + public synchronized java.util.Optional findDetailsNat44(@Nonnull final List details, + final long natInstanceId, final long idx, + @Nonnull final MappingContext mappingContext) { // Find mapping entry for Index final MappingEntry ctxMappingEntry = mappingContext.read(getTableId(natInstanceId)) .transform(MappingTable::getMappingEntry) @@ -162,9 +194,29 @@ public class MappingEntryContext implements Ipv4Translator { // Find which details matches the context stored entry under index return details.stream() .filter(detail -> equalEntries(detail, ctxMappingEntry)) + .findFirst(); + } + + /** + * Find specific details in provided collection identified with provided index. + */ + public synchronized java.util.Optional findDetailsNat64(@Nonnull final List details, + final long natInstanceId, final long idx, + @Nonnull final MappingContext mappingContext) { + // Find mapping entry for Index + final MappingEntry ctxMappingEntry = mappingContext.read(getTableId(natInstanceId)) + .transform(MappingTable::getMappingEntry) + .or(Collections.emptyList()) + .stream() + .filter(entry -> entry.getIndex() == idx) .findFirst() - .orElseThrow(() -> new IllegalStateException("Unable to match mapping for nat-instance: " - + natInstanceId + " and match: " + ctxMappingEntry + " in: " + details)); + .orElseThrow(() -> new IllegalStateException("Unable to find context mapping for nat-instance: " + + natInstanceId + " and ID: " + idx)); + + // Find which details matches the context stored entry under index + return details.stream() + .filter(detail -> equalEntries(detail, ctxMappingEntry)) + .findFirst(); } /** @@ -178,6 +230,17 @@ public class MappingEntryContext implements Ipv4Translator { .or(() -> getArtificialId(details, natInstanceId, mappingContext)); } + /** + * Get index for a mapping entry details or create an artificial one. + */ + public synchronized long getStoredOrArtificialIndex(final Long natInstanceId, + @Nonnull final Nat64BibDetails details, + @Nonnull final MappingContext mappingContext) { + return mappingContext.read(getId(natInstanceId, entryToKey(details))) + .transform(MappingEntry::getIndex) + .or(() -> getArtificialId(details, natInstanceId, mappingContext)); + } + /** * Get index for a stored mapping entry. */ @@ -197,6 +260,15 @@ public class MappingEntryContext implements Ipv4Translator { return artificialIdx; } + private long getArtificialId(final Nat64BibDetails details, final Long natInstanceId, + final MappingContext mappingContext) { + LOG.trace("Assigning artificial ID for {}", details); + final long artificialIdx = findFreeIndex(natInstanceId, mappingContext); + LOG.debug("Artificial ID for {} assigned as: {}", details, artificialIdx); + mappingContext.put(getId(natInstanceId, entryToKey(details)), toCtxMapEntry(details, artificialIdx)); + return artificialIdx; + } + private long findFreeIndex(final long natInstanceId, final MappingContext mappingContext) { return mappingContext.read(getTableId(natInstanceId)) .transform(MappingTable::getMappingEntry) diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/MappingEntryCustomizerTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/MappingEntryCustomizerTest.java index 678d67bc2..05513b6e9 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/MappingEntryCustomizerTest.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/MappingEntryCustomizerTest.java @@ -27,10 +27,13 @@ import io.fd.hc2vpp.nat.util.MappingEntryContext; 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.snat.dto.Nat64BibDetails; +import io.fd.vpp.jvpp.snat.dto.Nat64BibDetailsReplyDump; import io.fd.vpp.jvpp.snat.dto.SnatStaticMappingDetails; import io.fd.vpp.jvpp.snat.dto.SnatStaticMappingDetailsReplyDump; import java.util.Arrays; import java.util.List; +import java.util.Optional; import org.junit.Test; import org.mockito.Mock; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.NatInstances; @@ -45,18 +48,22 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev1509 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class MappingEntryCustomizerTest - extends InitializingListReaderCustomizerTest { + extends InitializingListReaderCustomizerTest { private static final long NAT_MAPPING_ID = 2L; private InstanceIdentifier mappingEntryId; private InstanceIdentifier mappingEntryWildcarded; - private DumpCacheManager dumpCacheManager; + private DumpCacheManager nat44DumpManager; + private DumpCacheManager nat64DumpManager; @Mock private MappingEntryContext mappingContext; @Mock - private EntityDumpExecutor dumpExecutor; + private EntityDumpExecutor nat44DumpExecutor; + + @Mock + private EntityDumpExecutor nat64DumpExecutor; public MappingEntryCustomizerTest() { super(MappingEntry.class, MappingTableBuilder.class); @@ -65,90 +72,199 @@ public class MappingEntryCustomizerTest @Override protected void setUp() throws Exception { mappingEntryId = InstanceIdentifier.create(NatInstances.class) - .child(NatInstance.class, new NatInstanceKey(NatInstanceCustomizer.DEFAULT_VRF_ID)) - .child(MappingTable.class) - .child(MappingEntry.class, new MappingEntryKey(NAT_MAPPING_ID)); + .child(NatInstance.class, new NatInstanceKey(NatInstanceCustomizer.DEFAULT_VRF_ID)) + .child(MappingTable.class) + .child(MappingEntry.class, new MappingEntryKey(NAT_MAPPING_ID)); mappingEntryWildcarded = InstanceIdentifier.create(NatInstances.class) - .child(NatInstance.class, new NatInstanceKey(NatInstanceCustomizer.DEFAULT_VRF_ID)) - .child(MappingTable.class) - .child(MappingEntry.class); - dumpCacheManager = new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor(dumpExecutor) - .acceptOnly(SnatStaticMappingDetailsReplyDump.class) - .build(); + .child(NatInstance.class, new NatInstanceKey(NatInstanceCustomizer.DEFAULT_VRF_ID)) + .child(MappingTable.class) + .child(MappingEntry.class); + nat44DumpManager = new DumpCacheManager.DumpCacheManagerBuilder() + .withExecutor(nat44DumpExecutor) + .acceptOnly(SnatStaticMappingDetailsReplyDump.class) + .build(); + nat64DumpManager = new DumpCacheManager.DumpCacheManagerBuilder() + .withExecutor(nat64DumpExecutor) + .acceptOnly(Nat64BibDetailsReplyDump.class) + .build(); } @Test - public void testReadAttributes() throws Exception { - final SnatStaticMappingDetailsReplyDump dump = dumpNonEmptyDefaultInstance(); - when(dumpExecutor.executeDump(mappingEntryId, null)).thenReturn(dump); + public void testReadNat44() throws Exception { + final SnatStaticMappingDetailsReplyDump dumpNat44 = dumpReplyNat44NonEmpty(); + when(nat44DumpExecutor.executeDump(mappingEntryId, null)).thenReturn(dumpNat44); final MappingEntryBuilder builder = new MappingEntryBuilder(); - when(mappingContext.findDetails(dump.snatStaticMappingDetails, NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), - NAT_MAPPING_ID, ctx.getMappingContext())).thenReturn(dump.snatStaticMappingDetails.get(2)); + when(mappingContext + .findDetailsNat44(dumpNat44.snatStaticMappingDetails, NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), + NAT_MAPPING_ID, ctx.getMappingContext())) + .thenReturn(Optional.of(dumpNat44.snatStaticMappingDetails.get(2))); getCustomizer().readCurrentAttributes(mappingEntryId, builder, ctx); assertEquals(NAT_MAPPING_ID, builder.getIndex().longValue()); assertEquals("192.168.3.8", builder.getExternalSrcAddress().getValue()); assertEquals(6874, - ((SinglePortNumber) builder.getExternalSrcPort().getPortType()).getSinglePortNumber().getValue() - .intValue()); + ((SinglePortNumber) builder.getExternalSrcPort().getPortType()).getSinglePortNumber().getValue() + .intValue()); assertArrayEquals("192.168.2.2".toCharArray(), builder.getInternalSrcAddress().getValue()); assertEquals(1274, - ((SinglePortNumber) builder.getInternalSrcPort().getPortType()).getSinglePortNumber().getValue() - .intValue()); + ((SinglePortNumber) builder.getInternalSrcPort().getPortType()).getSinglePortNumber().getValue() + .intValue()); + } + + @Test + public void testReadNat64() throws Exception { + when(nat44DumpExecutor.executeDump(mappingEntryId, null)).thenReturn(new SnatStaticMappingDetailsReplyDump()); + final Nat64BibDetailsReplyDump dumpNat64 = dumpReplyNat64NonEmpty(); + when(nat64DumpExecutor.executeDump(mappingEntryId, null)).thenReturn(dumpNat64); + final MappingEntryBuilder builder = new MappingEntryBuilder(); + when(mappingContext + .findDetailsNat64(dumpNat64.nat64BibDetails, NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), + NAT_MAPPING_ID, ctx.getMappingContext())) + .thenReturn(Optional.of(dumpNat64.nat64BibDetails.get(2))); + getCustomizer().readCurrentAttributes(mappingEntryId, builder, ctx); + + assertEquals(NAT_MAPPING_ID, builder.getIndex().longValue()); + assertEquals("192.168.64.3", builder.getExternalSrcAddress().getValue()); + assertEquals(6874, + ((SinglePortNumber) builder.getExternalSrcPort().getPortType()).getSinglePortNumber().getValue() + .intValue()); + assertArrayEquals("2001:db8:85a3::8a2e:370:7303".toCharArray(), builder.getInternalSrcAddress().getValue()); + assertEquals(1274, + ((SinglePortNumber) builder.getInternalSrcPort().getPortType()).getSinglePortNumber().getValue() + .intValue()); } @Test - public void testGetAll() throws Exception { - final SnatStaticMappingDetailsReplyDump dump = dumpNonEmptyDefaultInstance(); - when(dumpExecutor.executeDump(mappingEntryWildcarded, null)).thenReturn(dump); + public void testReadAllNat44() throws Exception { + final SnatStaticMappingDetailsReplyDump dumpNat44 = dumpReplyNat44NonEmpty(); + when(nat44DumpExecutor.executeDump(mappingEntryWildcarded, null)).thenReturn(dumpNat44); + when(nat64DumpExecutor.executeDump(mappingEntryWildcarded, null)).thenReturn(new Nat64BibDetailsReplyDump()); when(mappingContext.getStoredOrArtificialIndex(NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), - dump.snatStaticMappingDetails.get(0), ctx.getMappingContext())).thenReturn(0L); + dumpNat44.snatStaticMappingDetails.get(0), ctx.getMappingContext())).thenReturn(0L); when(mappingContext.getStoredOrArtificialIndex(NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), - dump.snatStaticMappingDetails.get(1), ctx.getMappingContext())).thenReturn(1L); + dumpNat44.snatStaticMappingDetails.get(1), ctx.getMappingContext())).thenReturn(1L); when(mappingContext.getStoredOrArtificialIndex(NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), - dump.snatStaticMappingDetails.get(2), ctx.getMappingContext())).thenReturn(2L); + dumpNat44.snatStaticMappingDetails.get(2), ctx.getMappingContext())).thenReturn(2L); final List allIds = getCustomizer().getAllIds(mappingEntryWildcarded, ctx); assertThat(allIds, hasItems(new MappingEntryKey(0L), new MappingEntryKey(2L))); } + @Test + public void testReadAllNat64() throws Exception { + final Nat64BibDetailsReplyDump dumpNat64 = dumpReplyNat64NonEmpty(); + when(nat44DumpExecutor.executeDump(mappingEntryWildcarded, null)) + .thenReturn(new SnatStaticMappingDetailsReplyDump()); + when(nat64DumpExecutor.executeDump(mappingEntryWildcarded, null)).thenReturn(dumpNat64); + when(mappingContext.getStoredOrArtificialIndex(NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), + dumpNat64.nat64BibDetails.get(0), ctx.getMappingContext())).thenReturn(0L); + when(mappingContext.getStoredOrArtificialIndex(NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), + dumpNat64.nat64BibDetails.get(1), ctx.getMappingContext())).thenReturn(1L); + when(mappingContext.getStoredOrArtificialIndex(NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), + dumpNat64.nat64BibDetails.get(2), ctx.getMappingContext())).thenReturn(2L); + + final List allIds = getCustomizer().getAllIds(mappingEntryWildcarded, ctx); + assertThat(allIds, hasItems(new MappingEntryKey(0L), new MappingEntryKey(2L))); + } + + @Test + public void testReadAll() throws Exception { + final SnatStaticMappingDetailsReplyDump dumpNat44 = dumpReplyNat44NonEmpty(); + final Nat64BibDetailsReplyDump dumpNat64 = dumpReplyNat64NonEmpty(); + when(nat44DumpExecutor.executeDump(mappingEntryWildcarded, null)) + .thenReturn(dumpNat44); + when(nat64DumpExecutor.executeDump(mappingEntryWildcarded, null)).thenReturn(dumpNat64); + when(mappingContext.getStoredOrArtificialIndex(NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), + dumpNat44.snatStaticMappingDetails.get(0), ctx.getMappingContext())).thenReturn(0L); + when(mappingContext.getStoredOrArtificialIndex(NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), + dumpNat44.snatStaticMappingDetails.get(1), ctx.getMappingContext())).thenReturn(1L); + when(mappingContext.getStoredOrArtificialIndex(NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), + dumpNat44.snatStaticMappingDetails.get(2), ctx.getMappingContext())).thenReturn(2L); + when(mappingContext.getStoredOrArtificialIndex(NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), + dumpNat64.nat64BibDetails.get(0), ctx.getMappingContext())).thenReturn(3L); + when(mappingContext.getStoredOrArtificialIndex(NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), + dumpNat64.nat64BibDetails.get(1), ctx.getMappingContext())).thenReturn(4L); + when(mappingContext.getStoredOrArtificialIndex(NatInstanceCustomizer.DEFAULT_VRF_ID.getId(), + dumpNat64.nat64BibDetails.get(2), ctx.getMappingContext())).thenReturn(5L); + + final List allIds = getCustomizer().getAllIds(mappingEntryWildcarded, ctx); + assertThat(allIds, hasItems(new MappingEntryKey(0L), new MappingEntryKey(2L), new MappingEntryKey(3L), + new MappingEntryKey(5L))); + } + @Override protected ReaderCustomizer initCustomizer() { - return new MappingEntryCustomizer(dumpCacheManager, mappingContext); + return new MappingEntryCustomizer(nat44DumpManager, nat64DumpManager, mappingContext); } - private static SnatStaticMappingDetailsReplyDump dumpNonEmptyDefaultInstance() { + private static SnatStaticMappingDetailsReplyDump dumpReplyNat44NonEmpty() { SnatStaticMappingDetailsReplyDump replyDump = new SnatStaticMappingDetailsReplyDump(); SnatStaticMappingDetails detailsOne = new SnatStaticMappingDetails(); detailsOne.isIp4 = 1; detailsOne.addrOnly = 1; - detailsOne.localIpAddress = new byte[] {-64, -88, 2, 1}; + detailsOne.localIpAddress = new byte[]{-64, -88, 2, 1}; detailsOne.localPort = 1234; - detailsOne.externalIpAddress = new byte[] {-64, -88, 2, 8}; + detailsOne.externalIpAddress = new byte[]{-64, -88, 2, 8}; detailsOne.externalPort = 5874; detailsOne.vrfId = NatInstanceCustomizer.DEFAULT_VRF_ID.getId().byteValue(); SnatStaticMappingDetails detailsTwo = new SnatStaticMappingDetails(); detailsTwo.isIp4 = 1; detailsTwo.addrOnly = 1; - detailsTwo.localIpAddress = new byte[] {-64, -88, 2, 3}; + detailsTwo.localIpAddress = new byte[]{-64, -88, 2, 3}; detailsTwo.localPort = 1235; - detailsTwo.externalIpAddress = new byte[] {-64, -88, 2, 5}; + detailsTwo.externalIpAddress = new byte[]{-64, -88, 2, 5}; detailsTwo.externalPort = 5874; detailsTwo.vrfId = 2; SnatStaticMappingDetails detailsThree = new SnatStaticMappingDetails(); detailsThree.isIp4 = 1; detailsThree.addrOnly = 0; - detailsThree.localIpAddress = new byte[] {-64, -88, 2, 2}; + detailsThree.localIpAddress = new byte[]{-64, -88, 2, 2}; detailsThree.localPort = 1274; - detailsThree.externalIpAddress = new byte[] {-64, -88, 3, 8}; + detailsThree.externalIpAddress = new byte[]{-64, -88, 3, 8}; detailsThree.externalPort = 6874; detailsThree.vrfId = NatInstanceCustomizer.DEFAULT_VRF_ID.getId().byteValue(); replyDump.snatStaticMappingDetails = Arrays.asList(detailsOne, detailsTwo, detailsThree); return replyDump; } + + private static Nat64BibDetailsReplyDump dumpReplyNat64NonEmpty() { + Nat64BibDetailsReplyDump replyDump = new Nat64BibDetailsReplyDump(); + + Nat64BibDetails detailsOne = new Nat64BibDetails(); + detailsOne.isStatic = 1; + detailsOne.iAddr = + new byte[]{0x20, 0x01, 0x0d, (byte) 0xb8, (byte) 0x85, (byte) 0xa3, 0, 0, 0, 0, (byte) 0x8a, 0x2e, 0x03, + 0x70, 0x73, 0x01}; + detailsOne.iPort = 1234; + detailsOne.oAddr = new byte[]{-64, -88, 64, 1}; + detailsOne.oPort = 5874; + detailsOne.vrfId = NatInstanceCustomizer.DEFAULT_VRF_ID.getId().byteValue(); + + Nat64BibDetails detailsTwo = new Nat64BibDetails(); + detailsTwo.isStatic = 0; + detailsTwo.iAddr = + new byte[]{0x20, 0x01, 0x0d, (byte) 0xb8, (byte) 0x85, (byte) 0xa3, 0, 0, 0, 0, (byte) 0x8a, 0x2e, 0x03, + 0x70, 0x73, 0x02}; + detailsTwo.iPort = 1235; + detailsTwo.oAddr = new byte[]{-64, -88, 64, 2}; + detailsTwo.oPort = 5874; + detailsTwo.vrfId = 2; + + Nat64BibDetails detailsThree = new Nat64BibDetails(); + detailsThree.isStatic = 1; + detailsThree.iAddr = + new byte[]{0x20, 0x01, 0x0d, (byte) 0xb8, (byte) 0x85, (byte) 0xa3, 0, 0, 0, 0, (byte) 0x8a, 0x2e, 0x03, + 0x70, 0x73, 0x03}; + detailsThree.iPort = 1274; + detailsThree.oAddr = new byte[]{-64, -88, 64, 3}; + detailsThree.oPort = 6874; + detailsThree.vrfId = NatInstanceCustomizer.DEFAULT_VRF_ID.getId().byteValue(); + + replyDump.nat64BibDetails = Arrays.asList(detailsOne, detailsTwo, detailsThree); + return replyDump; + } } \ No newline at end of file diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/NatInstanceCustomizerTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/NatInstanceCustomizerTest.java index 821a59235..0fad2abee 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/NatInstanceCustomizerTest.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/NatInstanceCustomizerTest.java @@ -17,6 +17,7 @@ package io.fd.hc2vpp.nat.read; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.core.IsCollectionContaining.hasItems; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -26,6 +27,8 @@ import io.fd.hc2vpp.common.test.read.InitializingListReaderCustomizerTest; import io.fd.honeycomb.translate.read.ReadFailedException; import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; +import io.fd.vpp.jvpp.snat.dto.Nat64BibDetails; +import io.fd.vpp.jvpp.snat.dto.Nat64BibDetailsReplyDump; import io.fd.vpp.jvpp.snat.dto.SnatStaticMappingDetails; import io.fd.vpp.jvpp.snat.dto.SnatStaticMappingDetailsReplyDump; import java.util.Arrays; @@ -41,13 +44,16 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; public class NatInstanceCustomizerTest - extends InitializingListReaderCustomizerTest { + extends InitializingListReaderCustomizerTest { @Mock - private EntityDumpExecutor dumpExecutor; + private EntityDumpExecutor nat44DumpExecutor; + @Mock + private EntityDumpExecutor nat64DumpExecutor; private KeyedInstanceIdentifier natInstanceId; private InstanceIdentifier natInstanceWildcarded; - private DumpCacheManager dumpCacheManager; + private DumpCacheManager mapEntryNat44DumpMgr; + private DumpCacheManager mapEntryNat64DumpMgr; public NatInstanceCustomizerTest() { super(NatInstance.class, NatInstancesBuilder.class); @@ -55,19 +61,23 @@ public class NatInstanceCustomizerTest @Override protected NatInstanceCustomizer initCustomizer() { - return new NatInstanceCustomizer(dumpCacheManager); + return new NatInstanceCustomizer(mapEntryNat44DumpMgr, mapEntryNat64DumpMgr); } @Override protected void setUp() throws Exception { natInstanceId = InstanceIdentifier.create(NatInstances.class) - .child(NatInstance.class, new NatInstanceKey(NatInstanceCustomizer.DEFAULT_VRF_ID)); + .child(NatInstance.class, new NatInstanceKey(NatInstanceCustomizer.DEFAULT_VRF_ID)); natInstanceWildcarded = InstanceIdentifier.create(NatInstances.class) - .child(NatInstance.class); - dumpCacheManager = new DumpCacheManager.DumpCacheManagerBuilder() - .withExecutor(dumpExecutor) - .acceptOnly(SnatStaticMappingDetailsReplyDump.class) - .build(); + .child(NatInstance.class); + mapEntryNat44DumpMgr = new DumpCacheManager.DumpCacheManagerBuilder() + .withExecutor(nat44DumpExecutor) + .acceptOnly(SnatStaticMappingDetailsReplyDump.class) + .build(); + mapEntryNat64DumpMgr = new DumpCacheManager.DumpCacheManagerBuilder() + .withExecutor(nat64DumpExecutor) + .acceptOnly(Nat64BibDetailsReplyDump.class) + .build(); } @Test @@ -79,14 +89,16 @@ public class NatInstanceCustomizerTest @Test public void testReadAll() throws ReadFailedException { - final SnatStaticMappingDetailsReplyDump dump = dumpNonEmptyDefaultInstance(); - when(dumpExecutor.executeDump(natInstanceWildcarded, null)).thenReturn(dump); + when(nat44DumpExecutor.executeDump(natInstanceWildcarded, null)).thenReturn(nat44NonEmptyDump()); + when(nat64DumpExecutor.executeDump(natInstanceWildcarded, null)).thenReturn(nat64NonEmptyDump()); final List allIds = getCustomizer().getAllIds(natInstanceWildcarded, ctx); + assertThat(allIds, hasSize(6)); assertThat(allIds, hasItems( - new NatInstanceKey(0L), new NatInstanceKey(1L), new NatInstanceKey(2L), new NatInstanceKey(3L))); + new NatInstanceKey(0L), new NatInstanceKey(1L), new NatInstanceKey(2L), new NatInstanceKey(3L), + new NatInstanceKey(5L), new NatInstanceKey(6L))); } - private static SnatStaticMappingDetailsReplyDump dumpNonEmptyDefaultInstance() { + private static SnatStaticMappingDetailsReplyDump nat44NonEmptyDump() { SnatStaticMappingDetailsReplyDump replyDump = new SnatStaticMappingDetailsReplyDump(); SnatStaticMappingDetails detailsOne = new SnatStaticMappingDetails(); detailsOne.vrfId = 1; @@ -100,4 +112,19 @@ public class NatInstanceCustomizerTest replyDump.snatStaticMappingDetails = Arrays.asList(detailsOne, detailsTwo, detailsThree); return replyDump; } + + private static Nat64BibDetailsReplyDump nat64NonEmptyDump() { + Nat64BibDetailsReplyDump replyDump = new Nat64BibDetailsReplyDump(); + Nat64BibDetails detailsOne = new Nat64BibDetails(); + detailsOne.vrfId = 2; + + Nat64BibDetails detailsTwo = new Nat64BibDetails(); + detailsTwo.vrfId = 5; + + Nat64BibDetails detailsThree = new Nat64BibDetails(); + detailsThree.vrfId = 6; + + replyDump.nat64BibDetails = Arrays.asList(detailsOne, detailsTwo, detailsThree); + return replyDump; + } } \ No newline at end of file diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/util/MappingEntryContextTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/util/MappingEntryContextTest.java index 4d8f8074d..a6643601e 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/util/MappingEntryContextTest.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/util/MappingEntryContextTest.java @@ -107,7 +107,7 @@ public class MappingEntryContextTest implements Ipv4Translator { MappingEntryContext.toCtxMapEntry(entry2, 1))) .build())); - assertSame(details, ctx.findDetails(someDetails, natId, 0, mappingCtx)); + assertSame(details, ctx.findDetailsNat44(someDetails, natId, 0, mappingCtx).get()); } @Test(expected = IllegalStateException.class) @@ -118,7 +118,7 @@ public class MappingEntryContextTest implements Ipv4Translator { final List someDetails = Lists.newArrayList(details); when(mappingCtx.read(MappingEntryContext.getTableId(natId))).thenReturn(Optional.absent()); - ctx.findDetails(someDetails, natId, entryId, mappingCtx); + ctx.findDetailsNat44(someDetails, natId, entryId, mappingCtx); } @Test(expected = IllegalStateException.class) @@ -131,7 +131,7 @@ public class MappingEntryContextTest implements Ipv4Translator { when(mappingCtx.read(MappingEntryContext.getTableId(natId))) .thenReturn(Optional.of(new MappingTableBuilder().setMappingEntry(Collections.emptyList()).build())); - ctx.findDetails(someDetails, natId, entryId, mappingCtx); + ctx.findDetailsNat44(someDetails, natId, entryId, mappingCtx); } @Test -- cgit 1.2.3-korg