From 58bb277ee19627abbf5d8c7e77aeacfe8b63995f Mon Sep 17 00:00:00 2001 From: Marek Gradzki Date: Thu, 10 May 2018 08:41:03 +0200 Subject: HC2VPP-321: bump nat model to ietf-nat@2018-02-23.yang Uses ietf-nat module as defined in https://tools.ietf.org/html/draft-ietf-opsawg-nat-yang-14 Modifications to original model: - ip-address is used instead of ip-prefix (draft is not clear, see HC2VPP-325). API changes relevant to HC/VPP: - nat-config and nat-state merged into nat container - nat-instances and nat-instace renamed to instances and instance respectively - external-ip-address-pool has new parent - policy list - port-type choice was removed, port is now defined using start-port-number and end-port-number leaves. Missing end is equivalent to single-port-number case from the older version. TODOs: - HC2VPP-322: single nat64Prefix per NAT instance - HC2VPP-323: update postman collection - HC2VPP-324: update CSIT tests. Out of the scope of NAT model update: - HC2VPP-326: support for nat-type handling (vpp-nat model might become obsolete) - HC2VPP-327: support external-realm container (requires adding augmentations that are alredy present in the interface-nat model). Change-Id: Ie229a55b0a3f6ee3f8c97f4fd13c54a797a62438 Signed-off-by: Marek Gradzki --- .../src/main/java/io/fd/hc2vpp/nat/NatIds.java | 38 +++++++++++++ .../hc2vpp/nat/read/ExternalIpPoolCustomizer.java | 34 +++++------ .../fd/hc2vpp/nat/read/MappingEntryCustomizer.java | 65 +++++++--------------- .../hc2vpp/nat/read/Nat64PrefixesCustomizer.java | 43 +++++++------- .../fd/hc2vpp/nat/read/NatInstanceCustomizer.java | 53 +++++++----------- .../io/fd/hc2vpp/nat/read/NatReaderFactory.java | 61 ++++++++++---------- .../io/fd/hc2vpp/nat/util/MappingEntryContext.java | 12 ++-- .../hc2vpp/nat/write/ExternalIpPoolCustomizer.java | 18 +++--- .../hc2vpp/nat/write/MappingEntryCustomizer.java | 62 +++++++++------------ .../hc2vpp/nat/write/Nat64PrefixesCustomizer.java | 18 +++--- .../fd/hc2vpp/nat/write/NatInstaceCustomizer.java | 20 +++---- .../io/fd/hc2vpp/nat/write/NatWriterFactory.java | 58 ++++++++++--------- .../io/fd/hc2vpp/nat/write/PolicyCustomizer.java | 55 ++++++++++++++++++ 13 files changed, 279 insertions(+), 258 deletions(-) create mode 100644 nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/NatIds.java create mode 100644 nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/PolicyCustomizer.java (limited to 'nat/nat2vpp/src/main') diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/NatIds.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/NatIds.java new file mode 100644 index 000000000..c0aa538d5 --- /dev/null +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/NatIds.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.nat; + +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.Nat; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.Instances; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.Instance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.MappingTable; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.Policy; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.ExternalIpAddressPool; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.Nat64Prefixes; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +public interface NatIds { + InstanceIdentifier NAT_ID = InstanceIdentifier.create(Nat.class); + InstanceIdentifier NAT_INSTANCES_ID = NAT_ID.child(Instances.class); + InstanceIdentifier NAT_INSTANCE_ID = NAT_INSTANCES_ID.child(Instance.class); + InstanceIdentifier MAPPING_TABLE_ID = NAT_INSTANCE_ID.child(MappingTable.class); + InstanceIdentifier MAPPING_ENTRY_ID = MAPPING_TABLE_ID.child(MappingEntry.class); + InstanceIdentifier POLICY_ID = NAT_INSTANCE_ID.child(Policy.class); + InstanceIdentifier ADDRESS_POOL_ID = POLICY_ID.child(ExternalIpAddressPool.class); + InstanceIdentifier NAT64_PREFIXES_ID = POLICY_ID.child(Nat64Prefixes.class); +} diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ExternalIpPoolCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ExternalIpPoolCustomizer.java index 77b5b2cf6..cfc9be4ce 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ExternalIpPoolCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/ExternalIpPoolCustomizer.java @@ -24,7 +24,6 @@ import io.fd.honeycomb.translate.read.ReadContext; 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.RWUtils; import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; import io.fd.vpp.jvpp.nat.dto.Nat44AddressDetails; import io.fd.vpp.jvpp.nat.dto.Nat44AddressDetailsReplyDump; @@ -39,15 +38,15 @@ import java.util.stream.Collectors; import java.util.stream.LongStream; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.ExternalIpAddressPool; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.ExternalIpAddressPoolBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.ExternalIpAddressPoolKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.NatInstance; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.NatInstanceKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.nat.instance.NatCurrentConfigBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev170804.ExternalIpAddressPoolStateAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev170804.ExternalIpAddressPoolStateAugmentationBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev170804.NatPoolType; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.Instance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.InstanceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.PolicyBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.ExternalIpAddressPool; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.ExternalIpAddressPoolBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.ExternalIpAddressPoolKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev180510.ExternalIpAddressPoolAugmentation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev180510.ExternalIpAddressPoolAugmentationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev180510.NatPoolType; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -76,13 +75,8 @@ final class ExternalIpPoolCustomizer implements } private static void setPoolType(@Nonnull final ExternalIpAddressPoolBuilder builder, final NatPoolType poolType) { - builder.addAugmentation(ExternalIpAddressPoolStateAugmentation.class, - new ExternalIpAddressPoolStateAugmentationBuilder().setPoolType(poolType).build()); - } - - static InstanceIdentifier getCfgId(final @Nonnull InstanceIdentifier id) { - return NatInstanceCustomizer.getCfgId(RWUtils.cutId(id, NatInstance.class)) - .child(ExternalIpAddressPool.class, id.firstKeyOf(ExternalIpAddressPool.class)); + builder.addAugmentation(ExternalIpAddressPoolAugmentation.class, + new ExternalIpAddressPoolAugmentationBuilder().setPoolType(poolType).build()); } @Nonnull @@ -138,7 +132,7 @@ final class ExternalIpPoolCustomizer implements @Override public List getAllIds(@Nonnull final InstanceIdentifier id, @Nonnull final ReadContext ctx) throws ReadFailedException { - final NatInstanceKey natKey = id.firstKeyOf(NatInstance.class); + final InstanceKey natKey = id.firstKeyOf(Instance.class); if (!natKey.equals(NatInstanceCustomizer.DEFAULT_VRF_ID)) { // IP Pools are not vrf aware ... so they are only visible under default vrf (nat-instance) return Collections.emptyList(); @@ -174,7 +168,7 @@ final class ExternalIpPoolCustomizer implements @Override public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { - ((NatCurrentConfigBuilder) builder).setExternalIpAddressPool(readData); + ((PolicyBuilder) builder).setExternalIpAddressPool(readData); } @Override @@ -182,6 +176,6 @@ final class ExternalIpPoolCustomizer implements @Nonnull final InstanceIdentifier id, @Nonnull final ExternalIpAddressPool readValue, @Nonnull final ReadContext ctx) { - return Initialized.create(getCfgId(id), readValue); + return Initialized.create(id, readValue); } } 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 9075f4d0c..43dba092a 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 @@ -24,7 +24,6 @@ import io.fd.honeycomb.translate.read.ReadContext; 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.RWUtils; import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; import io.fd.honeycomb.translate.util.read.cache.EntityDumpExecutor; import io.fd.vpp.jvpp.nat.dto.Nat44StaticMappingDetails; @@ -40,15 +39,13 @@ 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; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.mapping.entry.ExternalSrcPortBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.mapping.entry.InternalSrcPortBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.MappingTable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.NatInstance; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.nat.instance.MappingTableBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.nat.instance.mapping.table.MappingEntry; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.nat.instance.mapping.table.MappingEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.nat.instance.mapping.table.MappingEntryKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.port.number.port.type.SinglePortNumberBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.mapping.entry.ExternalSrcPortBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.mapping.entry.InternalSrcPortBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.Instance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.MappingTableBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.mapping.table.MappingEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.mapping.table.MappingEntryKey; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -56,7 +53,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; final class MappingEntryCustomizer implements Ipv4Translator, Ipv6Translator, - InitializingListReaderCustomizer { + InitializingListReaderCustomizer { private static final Logger LOG = LoggerFactory.getLogger(MappingEntryCustomizer.class); @@ -86,7 +83,7 @@ final class MappingEntryCustomizer implements Ipv4Translator, Ipv6Translator, LOG.trace("Reading current attributes for mapping-entry: {}", id); final int idx = id.firstKeyOf(MappingEntry.class).getIndex().intValue(); - final int natInstanceId = id.firstKeyOf(NatInstance.class).getId().intValue(); + final int natInstanceId = id.firstKeyOf(Instance.class).getId().intValue(); final List nat44Details = nat44DumpManager.getDump(id, ctx.getModificationCache()) .or(new Nat44StaticMappingDetailsReplyDump()).nat44StaticMappingDetails; @@ -116,22 +113,16 @@ final class MappingEntryCustomizer implements Ipv4Translator, Ipv6Translator, final int index, final Nat44StaticMappingDetails detail) { builder.setIndex((long) index); builder.setType( - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.MappingEntry.Type.Static); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.MappingEntry.Type.Static); builder.setExternalSrcAddress(arrayToIpv4AddressNoZone(detail.externalIpAddress)); builder.setInternalSrcAddress( new IpAddress(arrayToIpv4AddressNoZone(detail.localIpAddress))); if (detail.addrOnly == 0) { builder.setExternalSrcPort(new ExternalSrcPortBuilder() - .setPortType(new SinglePortNumberBuilder().setSinglePortNumber(new PortNumber( - Short.toUnsignedInt(detail.externalPort))) - .build()) - .build()); + .setStartPortNumber(new PortNumber(Short.toUnsignedInt(detail.externalPort))).build()); builder.setInternalSrcPort(new InternalSrcPortBuilder() - .setPortType(new SinglePortNumberBuilder().setSinglePortNumber(new PortNumber( - Short.toUnsignedInt(detail.localPort))) - .build()) - .build()); + .setStartPortNumber(new PortNumber(Short.toUnsignedInt(detail.localPort))).build()); } } @@ -140,32 +131,26 @@ final class MappingEntryCustomizer implements Ipv4Translator, Ipv6Translator, 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); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.MappingEntry.Type.Static); } else { builder.setType( - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.MappingEntry.Type.Dynamic); + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.MappingEntry.Type.DynamicImplicit); } builder.setExternalSrcAddress(arrayToIpv4AddressNoZone(detail.oAddr)); builder.setInternalSrcAddress( new IpAddress(arrayToIpv6AddressNoZone(detail.iAddr))); builder.setExternalSrcPort(new ExternalSrcPortBuilder() - .setPortType(new SinglePortNumberBuilder().setSinglePortNumber(new PortNumber( - Short.toUnsignedInt(detail.oPort))) - .build()) - .build()); + .setStartPortNumber(new PortNumber(Short.toUnsignedInt(detail.oPort))).build()); builder.setInternalSrcPort(new InternalSrcPortBuilder() - .setPortType(new SinglePortNumberBuilder().setSinglePortNumber(new PortNumber( - Short.toUnsignedInt(detail.iPort))) - .build()) - .build()); + .setStartPortNumber(new PortNumber(Short.toUnsignedInt(detail.iPort))).build()); } @Nonnull @Override public List getAllIds(@Nonnull final InstanceIdentifier id, @Nonnull final ReadContext context) throws ReadFailedException { - final Long natInstanceId = id.firstKeyOf(NatInstance.class).getId(); + final Long natInstanceId = id.firstKeyOf(Instance.class).getId(); LOG.trace("Listing IDs for all mapping-entries within nat-instance(vrf):{}", natInstanceId); final List entryKeys = @@ -199,23 +184,11 @@ final class MappingEntryCustomizer implements Ipv4Translator, Ipv6Translator, } @Override - public Initialized init( + 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) - .build()); - } - - 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())); + return Initialized.create(id, readValue); } static final class MappingEntryNat44DumpExecutor diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/Nat64PrefixesCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/Nat64PrefixesCustomizer.java index 5026a0127..c32bbd5a7 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/Nat64PrefixesCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/read/Nat64PrefixesCustomizer.java @@ -37,12 +37,13 @@ import java.util.Collections; import java.util.List; import java.util.Map; import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.Nat64Prefixes; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.Nat64PrefixesBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.Nat64PrefixesKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.NatInstance; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.NatInstanceKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.nat.instance.NatCurrentConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.Instance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.InstanceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.PolicyBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.Nat64Prefixes; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.Nat64PrefixesBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.Nat64PrefixesKey; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -70,16 +71,15 @@ final class Nat64PrefixesCustomizer public List getAllIds(@Nonnull final InstanceIdentifier id, @Nonnull final ReadContext context) throws ReadFailedException { - final NatInstanceKey natKey = id.firstKeyOf(NatInstance.class); + final InstanceKey natKey = id.firstKeyOf(Instance.class); LOG.trace("Listing IDs for all nat64 prefixes within nat-instance(vrf): {}", natKey); + // VPP supports only single nat64-prefix per VRF/nat-instance (we map nat-instances to VRFs) final Map prefixesByVrfId = dumpManager.getDump(id, context.getModificationCache()).get(); - final Nat64PrefixDetails nat64PrefixDetails = prefixesByVrfId.get(natKey.getId()); - if (nat64PrefixDetails != null) { - // VPP supports only single nat64-prefix per VRF/nat-instance (we map nat-instances to VRFs) - // To ensure that (and for simplicity), we set nat64-prefix-id to 0. - return Collections.singletonList(new Nat64PrefixesKey(0L)); + final Nat64PrefixDetails details = prefixesByVrfId.get(natKey.getId()); + if (details != null) { + return Collections.singletonList(new Nat64PrefixesKey(readPrefix(details))); } else { return Collections.emptyList(); } @@ -88,7 +88,7 @@ final class Nat64PrefixesCustomizer @Override public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { - ((NatCurrentConfigBuilder) builder).setNat64Prefixes(readData); + ((PolicyBuilder) builder).setNat64Prefixes(readData); } @Nonnull @@ -102,21 +102,18 @@ final class Nat64PrefixesCustomizer @Nonnull final Nat64PrefixesBuilder builder, @Nonnull final ReadContext context) throws ReadFailedException { LOG.trace("Reading nat64-prefixes: {}", id); - final long prefixId = id.firstKeyOf(Nat64Prefixes.class).getNat64PrefixId().longValue(); - if (prefixId != 0L) { - // Ignore non zero IDs (VPP supports single nat64 prefix per VRF) - return; - } final Map prefixesByVrfId = dumpManager.getDump(id, context.getModificationCache()).get(); - final Nat64PrefixDetails prefixDetails = prefixesByVrfId.get(id.firstKeyOf(NatInstance.class).getId()); - if (prefixDetails != null) { - builder.setNat64PrefixId(prefixId); - builder.setNat64Prefix( - toIpv6Prefix(prefixDetails.prefix, UnsignedBytes.toInt(prefixDetails.prefixLen))); + final Nat64PrefixDetails details = prefixesByVrfId.get(id.firstKeyOf(Instance.class).getId()); + if (details != null) { + builder.setNat64Prefix(readPrefix(details)); } } + private Ipv6Prefix readPrefix(final Nat64PrefixDetails details) { + return toIpv6Prefix(details.prefix, UnsignedBytes.toInt(details.prefixLen)); + } + private final class Nat64PrefixesExecutor implements EntityDumpExecutor, Void> { private final FutureJVppNatFacade jvppNat; 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 926c6e95f..1bbd5f19e 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 @@ -27,11 +27,10 @@ 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; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.NatInstance; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.NatInstanceBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.NatInstanceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.InstancesBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.Instance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.InstanceBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.InstanceKey; import org.opendaylight.yangtools.concepts.Builder; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -42,10 +41,10 @@ import org.slf4j.LoggerFactory; * Nat instance ID is mapped to VRF-ID in VPP. */ final class NatInstanceCustomizer - implements InitializingListReaderCustomizer { + implements InitializingListReaderCustomizer { private static final Logger LOG = LoggerFactory.getLogger(NatInstanceCustomizer.class); - static final NatInstanceKey DEFAULT_VRF_ID = new NatInstanceKey(0L); + static final InstanceKey DEFAULT_VRF_ID = new InstanceKey(0L); private final DumpCacheManager nat44DumpManager; private final DumpCacheManager nat64DumpManager; @@ -59,26 +58,26 @@ final class NatInstanceCustomizer @Nonnull @Override - public NatInstanceBuilder getBuilder(@Nonnull final InstanceIdentifier id) { - return new NatInstanceBuilder(); + public InstanceBuilder getBuilder(@Nonnull final InstanceIdentifier id) { + return new InstanceBuilder(); } @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final NatInstanceBuilder builder, @Nonnull final ReadContext ctx) + public void readCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final InstanceBuilder builder, @Nonnull final ReadContext ctx) throws ReadFailedException { LOG.trace("Reading current attributes for nat-instance: {}", id); - builder.setId(id.firstKeyOf(NatInstance.class).getId()); + builder.setId(id.firstKeyOf(Instance.class).getId()); } @Nonnull @Override - public List getAllIds(@Nonnull final InstanceIdentifier id, + public List getAllIds(@Nonnull final InstanceIdentifier id, @Nonnull final ReadContext context) throws ReadFailedException { LOG.trace("Listing IDs for all nat-instances"); // Find the nat instance IDs (vrf-ids) by listing all static mappings and their VRF assignment - final List vrfIds = Stream.concat( + final List vrfIds = Stream.concat( nat44DumpManager.getDump(id, context.getModificationCache()) .or(new Nat44StaticMappingDetailsReplyDump()).nat44StaticMappingDetails.stream() .map(detail -> detail.vrfId), @@ -88,7 +87,7 @@ final class NatInstanceCustomizer // 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)) + .map(vrfId -> new InstanceKey((long) vrfId)) .collect(Collectors.toList()); // Add default vrf id if not present @@ -101,27 +100,15 @@ final class NatInstanceCustomizer } @Override - public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { - ((NatInstancesBuilder) builder).setNatInstance(readData); + public void merge(@Nonnull final Builder builder, @Nonnull final List readData) { + ((InstancesBuilder) builder).setInstance(readData); } @Override - public Initialized init( - @Nonnull final InstanceIdentifier id, - @Nonnull final NatInstance readValue, + public Initialized init( + @Nonnull final InstanceIdentifier id, + @Nonnull final Instance 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()) - .build()); - } - - static InstanceIdentifier getCfgId( - @Nonnull final InstanceIdentifier id) { - return InstanceIdentifier.create(NatConfig.class) - .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.NatInstances.class) - .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.NatInstance.class, - new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.NatInstanceKey( - id.firstKeyOf(NatInstance.class).getId())); + return Initialized.create(id, readValue); } } 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 a97d47a1a..c89b3030f 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 @@ -16,6 +16,15 @@ package io.fd.hc2vpp.nat.read; +import static io.fd.hc2vpp.nat.NatIds.ADDRESS_POOL_ID; +import static io.fd.hc2vpp.nat.NatIds.MAPPING_ENTRY_ID; +import static io.fd.hc2vpp.nat.NatIds.MAPPING_TABLE_ID; +import static io.fd.hc2vpp.nat.NatIds.NAT64_PREFIXES_ID; +import static io.fd.hc2vpp.nat.NatIds.NAT_ID; +import static io.fd.hc2vpp.nat.NatIds.NAT_INSTANCES_ID; +import static io.fd.hc2vpp.nat.NatIds.NAT_INSTANCE_ID; +import static io.fd.hc2vpp.nat.NatIds.POLICY_ID; + import com.google.common.collect.Sets; import com.google.inject.Inject; import io.fd.hc2vpp.nat.util.MappingEntryContext; @@ -27,40 +36,27 @@ import io.fd.honeycomb.translate.util.read.cache.DumpCacheManager; import io.fd.vpp.jvpp.nat.dto.Nat44StaticMappingDetailsReplyDump; import io.fd.vpp.jvpp.nat.dto.Nat64BibDetailsReplyDump; import io.fd.vpp.jvpp.nat.future.FutureJVppNatFacade; +import java.util.Collections; import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.NatState; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.NatStateBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.mapping.entry.ExternalSrcPort; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.mapping.entry.InternalSrcPort; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.ExternalIpAddressPool; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.Nat64Prefixes; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.nat64.prefixes.DestinationIpv4Prefix; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.NatInstances; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.NatInstancesBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.NatInstance; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.nat.instance.MappingTable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.nat.instance.MappingTableBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.nat.instance.NatCurrentConfig; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.nat.instance.NatCurrentConfigBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.state.nat.instances.nat.instance.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.NatBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.mapping.entry.ExternalSrcPort; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.mapping.entry.InternalSrcPort; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.InstancesBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.MappingTableBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.PolicyBuilder; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.PolicyKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.Nat64Prefixes; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.nat64.prefixes.DestinationIpv4Prefix; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; public class NatReaderFactory implements ReaderFactory { - private static final InstanceIdentifier NAT_OPER_ID = InstanceIdentifier.create(NatState.class); - private static final InstanceIdentifier NAT_INSTANCES_ID = NAT_OPER_ID.child(NatInstances.class); - private static final InstanceIdentifier NAT_INSTANCE_ID = NAT_INSTANCES_ID.child(NatInstance.class); - private static final InstanceIdentifier CURRENT_CONFIG = - NAT_INSTANCE_ID.child(NatCurrentConfig.class); - private static final InstanceIdentifier MAP_TABLE_ID = NAT_INSTANCE_ID.child(MappingTable.class); - private static final InstanceIdentifier MAP_ENTRY_ID = MAP_TABLE_ID.child(MappingEntry.class); - private final FutureJVppNatFacade jvppNat; private final MappingEntryContext mappingEntryContext; private final DumpCacheManager mapEntryNat44DumpMgr; private final DumpCacheManager mapEntryNat64DumpMgr; - @Inject public NatReaderFactory(final FutureJVppNatFacade jvppNat, final MappingEntryContext mappingEntryContext) { @@ -80,24 +76,23 @@ public class NatReaderFactory implements ReaderFactory { @Override public void init(@Nonnull final ModifiableReaderRegistryBuilder registry) { - registry.addStructuralReader(NAT_OPER_ID, NatStateBuilder.class); - registry.addStructuralReader(NAT_INSTANCES_ID, NatInstancesBuilder.class); + registry.addStructuralReader(NAT_ID, NatBuilder.class); + registry.addStructuralReader(NAT_INSTANCES_ID, InstancesBuilder.class); registry.add(new GenericInitListReader<>(NAT_INSTANCE_ID, new NatInstanceCustomizer(mapEntryNat44DumpMgr, mapEntryNat64DumpMgr))); - registry.addStructuralReader(MAP_TABLE_ID, MappingTableBuilder.class); + registry.addStructuralReader(MAPPING_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 GenericInitListReader<>(MAPPING_ENTRY_ID, new MappingEntryCustomizer(mapEntryNat44DumpMgr, mapEntryNat64DumpMgr, mappingEntryContext))); - registry.addStructuralReader(CURRENT_CONFIG, NatCurrentConfigBuilder.class); - registry.add(new GenericInitListReader<>(CURRENT_CONFIG.child(ExternalIpAddressPool.class), - new ExternalIpPoolCustomizer(jvppNat))); + // Ony single policy is supported + registry.addStructuralListReader(POLICY_ID, PolicyBuilder.class, Collections.singletonList(new PolicyKey(0L))); + registry.add(new GenericInitListReader<>(ADDRESS_POOL_ID, new ExternalIpPoolCustomizer(jvppNat))); // nat64-prefixes registry.subtreeAdd( Sets.newHashSet(InstanceIdentifier.create(Nat64Prefixes.class).child(DestinationIpv4Prefix.class)), - new GenericListReader<>(CURRENT_CONFIG.child(Nat64Prefixes.class), - new Nat64PrefixesCustomizer(jvppNat))); + new GenericListReader<>(NAT64_PREFIXES_ID, new Nat64PrefixesCustomizer(jvppNat))); } } 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 0f3924ec6..0f7220988 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 @@ -59,7 +59,7 @@ public class MappingEntryContext implements Ipv4Translator, Ipv6Translator { */ public synchronized void addEntry(final long natInstanceId, final long entryId, - @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, + @Nonnull final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.mapping.table.MappingEntry entry, @Nonnull final MappingContext mappingContext) { final InstanceIdentifier id = getId(natInstanceId, entryToKey(entry)); checkArgument(!containsEntry(natInstanceId, entry, mappingContext), "Mapping for %s already present", id); @@ -70,7 +70,7 @@ public class MappingEntryContext implements Ipv4Translator, Ipv6Translator { * Check whether mapping entry to index mapping already exists in context. */ public synchronized boolean containsEntry(final long natInstanceId, - @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, + @Nonnull final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.mapping.table.MappingEntry entry, @Nonnull final MappingContext mappingContext) { final InstanceIdentifier id = getId(natInstanceId, entryToKey(entry)); return mappingContext.read(id).isPresent(); @@ -92,7 +92,7 @@ public class MappingEntryContext implements Ipv4Translator, Ipv6Translator { @VisibleForTesting static MappingEntryKey entryToKey( - 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) { + final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.mapping.table.MappingEntry entry) { // Only IPv4 return new MappingEntryKey(new IpAddress(entry.getExternalSrcAddress()), entry.getInternalSrcAddress()); } @@ -144,7 +144,7 @@ public class MappingEntryContext implements Ipv4Translator, Ipv6Translator { @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, + @Nonnull final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.mapping.table.MappingEntry entry, final long entryId) { return new MappingEntryBuilder() .setKey(entryToKey(entry)) @@ -170,7 +170,7 @@ public class MappingEntryContext implements Ipv4Translator, Ipv6Translator { * Delete mapping of mapping entry to index from context. */ public synchronized void removeEntry(final long natInstanceId, - @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, + @Nonnull final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.mapping.table.MappingEntry entry, @Nonnull final MappingContext mappingContext) { mappingContext.delete(getId(natInstanceId, entryToKey(entry))); } @@ -245,7 +245,7 @@ public class MappingEntryContext implements Ipv4Translator, Ipv6Translator { * Get index for a stored mapping entry. */ public synchronized Optional getStoredIndex(final long natInstanceId, - @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, + @Nonnull final org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.mapping.table.MappingEntry entry, @Nonnull final MappingContext mappingContext) { return mappingContext.read(getId(natInstanceId, entryToKey(entry))) .transform(MappingEntry::getIndex); diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/ExternalIpPoolCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/ExternalIpPoolCustomizer.java index 775c9a6dd..36440b013 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/ExternalIpPoolCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/ExternalIpPoolCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Cisco and/or its affiliates. + * Copyright (c) 2018 Cisco and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ package io.fd.hc2vpp.nat.write; import static com.google.common.base.Preconditions.checkArgument; -import static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev170804.NatPoolType.Nat64; +import static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev180510.NatPoolType.Nat64; import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; import io.fd.hc2vpp.common.translate.util.Ipv4AddressRange; @@ -31,10 +31,10 @@ import io.fd.vpp.jvpp.nat.dto.Nat64AddDelPoolAddrRange; import io.fd.vpp.jvpp.nat.future.FutureJVppNatFacade; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.NatInstance; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.ExternalIpAddressPool; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.ExternalIpAddressPoolKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev170804.ExternalIpAddressPoolConfigAugmentation; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.Instance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.ExternalIpAddressPool; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.ExternalIpAddressPoolKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev180510.ExternalIpAddressPoolAugmentation; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,7 +54,7 @@ final class ExternalIpPoolCustomizer implements ListWriterCustomizer id, @Nonnull final ExternalIpAddressPool dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException { - checkArgument(id.firstKeyOf(NatInstance.class).getId() == 0, + checkArgument(id.firstKeyOf(Instance.class).getId() == 0, "External IP pools are only assignable for nat instance(vrf-id) with ID 0"); LOG.trace("Adding address range:{}, as: {}", id, dataAfter); // TODO check overlaps ? VPP-478 maybe no necessary, depending on how VPP handles them @@ -75,8 +75,8 @@ final class ExternalIpPoolCustomizer implements ListWriterCustomizer id, @Nonnull final MappingEntry dataBefore, @Nonnull final WriteContext writeContext) throws WriteFailedException { - final long natInstanceId = id.firstKeyOf(NatInstance.class).getId(); + final long natInstanceId = id.firstKeyOf(Instance.class).getId(); final MappingEntryKey mappingEntryKey = id.firstKeyOf(MappingEntry.class); LOG.debug("Deleting mapping entry: {} for nat-instance(vrf): {}", natInstanceId, mappingEntryKey); @@ -167,14 +165,12 @@ final class MappingEntryCustomizer implements ListWriterCustomizer internalPortNumber = getPortNumber(id, mappingEntry, - (entry) -> Optional.fromNullable(entry.getInternalSrcPort()).transform(PortNumber::getPortType)); - Optional externalPortNumber = getPortNumber(id, mappingEntry, - (entry) -> Optional.fromNullable(entry.getExternalSrcPort()).transform(PortNumber::getPortType)); - if (internalPortNumber.isPresent() && externalPortNumber.isPresent()) { + final Short internalPortNumber = getPortNumber(id, mappingEntry.getInternalSrcPort()); + final Short externalPortNumber = getPortNumber(id, mappingEntry.getExternalSrcPort()); + if (internalPortNumber != null && externalPortNumber != null) { request.addrOnly = 0; - request.localPort = internalPortNumber.get(); - request.externalPort = externalPortNumber.get(); + request.localPort = internalPortNumber; + request.externalPort = externalPortNumber; } return request; } @@ -205,32 +201,24 @@ final class MappingEntryCustomizer implements ListWriterCustomizer internalPortNumber = getPortNumber(id, mappingEntry, - (entry) -> Optional.fromNullable(entry.getInternalSrcPort()).transform(PortNumber::getPortType)); - Optional externalPortNumber = getPortNumber(id, mappingEntry, - (entry) -> Optional.fromNullable(entry.getExternalSrcPort()).transform(PortNumber::getPortType)); - if (internalPortNumber.isPresent() && externalPortNumber.isPresent()) { - request.iPort = internalPortNumber.get(); - request.oPort = externalPortNumber.get(); + final Short internalPortNumber = getPortNumber(id, mappingEntry.getInternalSrcPort()); + final Short externalPortNumber = getPortNumber(id, mappingEntry.getExternalSrcPort()); + if (internalPortNumber != null && externalPortNumber != null) { + request.iPort = internalPortNumber; + request.oPort = externalPortNumber; } return request; } - - private Optional getPortNumber(final InstanceIdentifier id, final MappingEntry dataAfter, - final PortGetter portGetter) { - return portGetter.getPortType(dataAfter).transform(port -> { - if (port instanceof SinglePortNumber) { - return ((SinglePortNumber) port).getSinglePortNumber().getValue().shortValue(); + private Short getPortNumber(final InstanceIdentifier id, final PortNumber portNumber) { + if (portNumber != null) { + if (portNumber.getStartPortNumber() != null && portNumber.getEndPortNumber() == null) { + return portNumber.getStartPortNumber().getValue().shortValue(); } else { throw new IllegalArgumentException( - String.format("Only single port number supported. Submitted: %s for entry: %s", - dataAfter.getInternalSrcPort(), id)); + String.format("Only single port number supported. Submitted: %s for entry: %s", portNumber, id)); } - }); - } - - interface PortGetter { - Optional getPortType(MappingEntry entry); + } + return null; } } diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/Nat64PrefixesCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/Nat64PrefixesCustomizer.java index b62733e75..33dad0d1b 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/Nat64PrefixesCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/Nat64PrefixesCustomizer.java @@ -30,10 +30,10 @@ import io.fd.vpp.jvpp.nat.future.FutureJVppNatFacade; import java.util.List; import javax.annotation.Nonnull; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.NatInstance; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.Nat64Prefixes; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.Nat64PrefixesKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.nat64.prefixes.DestinationIpv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.Instance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.Nat64Prefixes; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.Nat64PrefixesKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.nat64.prefixes.DestinationIpv4Prefix; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -54,14 +54,10 @@ final class Nat64PrefixesCustomizer public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, @Nonnull final Nat64Prefixes dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException { - final int natInstanceId = id.firstKeyOf(NatInstance.class).getId().intValue(); + final int natInstanceId = id.firstKeyOf(Instance.class).getId().intValue(); LOG.debug("Configuring nat64 prefix: {} for nat-instance(vrf): {}", dataAfter, natInstanceId); - // VPP supports only single nat64-prefix per VRF/nat-instance (we map nat-instances to VRFs) - // To ensure that (and for simplicity), we require nat64-prefix-id = 0. - final Long nat64PrefixId = id.firstKeyOf(Nat64Prefixes.class).getNat64PrefixId(); - checkArgument(nat64PrefixId == 0, "Only single nat64 prefix is supported (expected id=0, but %s given)", - nat64PrefixId); + // TODO(HC2VPP-320): ensure at most one prefix is configured per NAT instance // VPP does not support configuring different nat64-prefixes depending on ipv4 destination prefix: final List destinationIpv4PrefixList = dataAfter.getDestinationIpv4Prefix(); @@ -77,7 +73,7 @@ final class Nat64PrefixesCustomizer @Nonnull final Nat64Prefixes dataBefore, @Nonnull final WriteContext writeContext) throws WriteFailedException { - final int natInstanceId = id.firstKeyOf(NatInstance.class).getId().intValue(); + final int natInstanceId = id.firstKeyOf(Instance.class).getId().intValue(); LOG.debug("Removing nat64 prefix configuration: {} for nat-instance(vrf): {}", dataBefore, natInstanceId); // No need for validation here (it was done on write) addDelPrefix(id, dataBefore, natInstanceId, false); diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/NatInstaceCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/NatInstaceCustomizer.java index 8e5673003..22641437f 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/NatInstaceCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/NatInstaceCustomizer.java @@ -20,31 +20,31 @@ import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; import io.fd.honeycomb.translate.write.WriteContext; import io.fd.honeycomb.translate.write.WriteFailedException; import javax.annotation.Nonnull; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.NatInstance; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.NatInstanceKey; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.Instance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.InstanceKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -final class NatInstaceCustomizer implements ListWriterCustomizer { +final class NatInstaceCustomizer implements ListWriterCustomizer { private static final Logger LOG = LoggerFactory.getLogger(NatInstaceCustomizer.class); @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final NatInstance dataAfter, @Nonnull final WriteContext writeContext) + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Instance dataAfter, @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.trace("Writing nat-instance: {}", id); + LOG.trace("Writing NAT instance: {}", id); } @Override - public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, - @Nonnull final NatInstance dataBefore, @Nonnull final WriteContext writeContext) + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Instance dataBefore, @Nonnull final WriteContext writeContext) throws WriteFailedException { - LOG.trace("Deleting nat-instance: {}", id); + LOG.trace("Deleting NAT instance: {}", id); // For consistency with reader, forbid removing default NAT instance: - final Long vrfId = id.firstKeyOf(NatInstance.class).getId(); + final Long vrfId = id.firstKeyOf(Instance.class).getId(); if (vrfId == 0) { throw new WriteFailedException.DeleteFailedException(id, new UnsupportedOperationException("Removing default NAT instance (vrf=0) is not supported.")); diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/NatWriterFactory.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/NatWriterFactory.java index 802d6875b..ae9e0efca 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/NatWriterFactory.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/NatWriterFactory.java @@ -16,6 +16,12 @@ package io.fd.hc2vpp.nat.write; +import static io.fd.hc2vpp.nat.NatIds.ADDRESS_POOL_ID; +import static io.fd.hc2vpp.nat.NatIds.MAPPING_ENTRY_ID; +import static io.fd.hc2vpp.nat.NatIds.NAT64_PREFIXES_ID; +import static io.fd.hc2vpp.nat.NatIds.NAT_INSTANCE_ID; +import static io.fd.hc2vpp.nat.NatIds.POLICY_ID; + import com.google.common.collect.Sets; import com.google.inject.Inject; import io.fd.hc2vpp.nat.util.MappingEntryContext; @@ -24,17 +30,13 @@ import io.fd.honeycomb.translate.write.WriterFactory; import io.fd.honeycomb.translate.write.registry.ModifiableWriterRegistryBuilder; import io.fd.vpp.jvpp.nat.future.FutureJVppNatFacade; 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.mapping.entry.ExternalSrcPort; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.mapping.entry.InternalSrcPort; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.NatInstances; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.NatInstance; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.MappingTable; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntry; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.ExternalIpAddressPool; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.Nat64Prefixes; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.parameters.nat64.prefixes.DestinationIpv4Prefix; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev170804.ExternalIpAddressPoolConfigAugmentation; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.mapping.entry.ExternalSrcPort; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.mapping.entry.InternalSrcPort; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.mapping.table.MappingEntry; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.ExternalIpAddressPool; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.Nat64Prefixes; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.policy.nat64.prefixes.DestinationIpv4Prefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev180510.ExternalIpAddressPoolAugmentation; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; /** @@ -42,12 +44,6 @@ import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; */ public final class NatWriterFactory implements WriterFactory { - private static final InstanceIdentifier NAT_CFG_ID = InstanceIdentifier.create(NatConfig.class); - private static final InstanceIdentifier NAT_INSTANCE_ID = - NAT_CFG_ID.child(NatInstances.class).child(NatInstance.class); - private static final InstanceIdentifier MAP_ENTRY_ID = - NAT_INSTANCE_ID.child(MappingTable.class).child(MappingEntry.class); - private final FutureJVppNatFacade jvppNat; private final MappingEntryContext mappingEntryContext; @@ -60,26 +56,28 @@ public final class NatWriterFactory implements WriterFactory { @Override public void init(@Nonnull final ModifiableWriterRegistryBuilder registry) { - // Nat-instance + // +-- nat + // +-- instances/instance registry.add(new GenericListWriter<>(NAT_INSTANCE_ID, new NatInstaceCustomizer())); - // Mapping-entry + // +-- mapping-table/mapping-entry registry.subtreeAdd(Sets.newHashSet(InstanceIdentifier.create(MappingEntry.class).child(ExternalSrcPort.class), InstanceIdentifier.create(MappingEntry.class).child(InternalSrcPort.class)), - new GenericListWriter<>(MAP_ENTRY_ID, new MappingEntryCustomizer(jvppNat, mappingEntryContext))); + new GenericListWriter<>(MAPPING_ENTRY_ID, new MappingEntryCustomizer(jvppNat, mappingEntryContext))); + + // +-- policy + registry.add(new GenericListWriter<>(POLICY_ID, new PolicyCustomizer())); - // External address pool has to be executed before mapping entry. Because adding mapping entries requires to - // already have an IP range predefined ... in some cases + // +-- external-ip-address-pool registry.subtreeAddBefore( - Sets.newHashSet(InstanceIdentifier.create(ExternalIpAddressPool.class) - .augmentation(ExternalIpAddressPoolConfigAugmentation.class)), - new GenericListWriter<>(NAT_INSTANCE_ID.child(ExternalIpAddressPool.class), - new ExternalIpPoolCustomizer(jvppNat)), - MAP_ENTRY_ID); + // External address pool has to be executed before mapping entry. Because adding mapping entries + // requires to already have an IP range predefined ... in some cases + Sets.newHashSet(InstanceIdentifier.create(ExternalIpAddressPool.class) + .augmentation(ExternalIpAddressPoolAugmentation.class)), + new GenericListWriter<>(ADDRESS_POOL_ID, new ExternalIpPoolCustomizer(jvppNat)), MAPPING_ENTRY_ID); - // nat64-prefixes + // +-- nat64-prefixes registry.subtreeAdd( Sets.newHashSet(InstanceIdentifier.create(Nat64Prefixes.class).child(DestinationIpv4Prefix.class)), - new GenericListWriter<>(NAT_INSTANCE_ID.child(Nat64Prefixes.class), - new Nat64PrefixesCustomizer(jvppNat))); + new GenericListWriter<>(NAT64_PREFIXES_ID, new Nat64PrefixesCustomizer(jvppNat))); } } diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/PolicyCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/PolicyCustomizer.java new file mode 100644 index 000000000..ecc340f38 --- /dev/null +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/PolicyCustomizer.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.hc2vpp.nat.write; + +import static com.google.common.base.Preconditions.checkArgument; + +import io.fd.honeycomb.translate.spi.write.ListWriterCustomizer; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; +import javax.annotation.Nonnull; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.Instance; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.Policy; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.PolicyKey; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +final class PolicyCustomizer implements ListWriterCustomizer { + + private static final Logger LOG = LoggerFactory.getLogger(PolicyCustomizer.class); + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Policy dataAfter, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.trace("Writing NAT policy: {}", id); + + // HC supports only single NAT policy per NAT instance (VRF) + // To ensure that (and for simplicity), we require policy id = 0. + final Long policyId = id.firstKeyOf(Policy.class).getId(); + checkArgument(policyId == 0, + "Only single policy per NAT instance (VRF) is supported (expected id=0, but %s given)", policyId); + } + + @Override + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier id, + @Nonnull final Policy dataBefore, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.trace("Deleting NAT policy: {}", id); + } +} -- cgit 1.2.3-korg