diff options
author | Marek Gradzki <mgradzki@cisco.com> | 2018-05-10 08:41:03 +0200 |
---|---|---|
committer | Marek Gradzki <mgradzki@cisco.com> | 2018-05-17 05:20:09 +0000 |
commit | 58bb277ee19627abbf5d8c7e77aeacfe8b63995f (patch) | |
tree | 274497583238d25fbcdc3b827d18adecf2597144 | |
parent | 03f6001049d60c59c81408c472996cba4e703a75 (diff) |
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 <mgradzki@cisco.com>
29 files changed, 2838 insertions, 1525 deletions
diff --git a/nat/nat-api/src/main/yang/ietf-nat@2015-09-08.yang b/nat/nat-api/src/main/yang/ietf-nat@2015-09-08.yang deleted file mode 100644 index 54707708c..000000000 --- a/nat/nat-api/src/main/yang/ietf-nat@2015-09-08.yang +++ /dev/null @@ -1,1074 +0,0 @@ -module ietf-nat { - - namespace "urn:ietf:params:xml:ns:yang:ietf-nat"; - //namespace to be assigned by IANA - prefix "nat"; - import ietf-inet-types { - prefix "inet"; - } - - organization "IETF NetMod Working Group"; - contact - "Senthil Sivakumar <ssenthil@cisco.com> - Mohamed Boucadair <mohamed.boucadair@orange.com> - Suresh Vinapamula <sureshk@juniper.net>"; - - description - "This module is a YANG module for NAT implementations - (including both NAT44 and NAT64 flavors. - - Copyright (c) 2015 IETF Trust and the persons identified as - authors of the code. All rights reserved. - - Redistribution and use in source and binary forms, with or - without modification, is permitted pursuant to, and subject - to the license terms contained in, the Simplified BSD License - set forth in Section 4.c of the IETF Trust's Legal Provisions - Relating to IETF Documents - (http://trustee.ietf.org/license-info). - - This version of this YANG module is part of RFC XXXX; see - the RFC itself for full legal notices."; - - revision 2015-09-08 { - description "Fixes few YANG errors."; - reference "-02"; - } - - revision 2015-09-07 { - description "Completes the NAT64 model."; - reference "01"; - } - - revision 2015-08-29 { - description "Initial version."; - reference "00"; - } - - typedef percent { - type uint8 { - range "0 .. 100"; - } - description - "Percentage"; - } - - /* - * Grouping - */ - - grouping timeouts { - description - "Configure values of various timeouts."; - - leaf udp-timeouts { - type uint32; - default 300; - description - "UDP inactivity timeout."; - } - - leaf tcp-idle-timeout { - type uint32; - default 7440; - description - "TCP Idle timeout, as per RFC 5382 should be no - 2 hours and 4 minutes."; - } - - leaf tcp-trans-open-timeout { - type uint32; - default 240; - description - "The value of the transitory open connection - idle-timeout."; - } - - leaf tcp-trans-close-timeout { - type uint32; - default 240; - description - "The value of the transitory close connection - idle-timeout."; - } - - leaf tcp-in-syn-timeout { - type uint32; - default 6; - description - "6 seconds, as defined in [RFC5382]."; - } - - leaf fragment-min-timeout { - type uint32; - default 2; - description - "As long as the NAT has available resources, - the NAT allows the fragments to arrive - over fragment-min-timeout interval. - The default value is inspired from RFC6146."; - } - - leaf icmp-timeout { - type uint32; - default 60; - description - "60 seconds, as defined in [RFC5508]."; - } - } - - // port numbers: single or port range - - grouping port-number { - description - "Individual port or a range of ports."; - - choice port-type { - default single-port-number; - description - "Port type: single or port-range."; - - case single-port-number { - leaf single-port-number { - type inet:port-number; - description - "Used for single port numbers."; - } - } - - case port-range { - leaf start-port-number { - type inet:port-number; - description - "Begining of the port range."; - } - - leaf end-port-number { - type inet:port-number; - description - "End of the port range."; - } - } - } - } - - grouping mapping-entry { - description - "NAT mapping entry."; - - leaf index { - type uint32; - description - "A unique identifier of a mapping entry."; - } - - leaf type { - type enumeration { - enum "static" { - description - "The mapping entry is manually configured."; - } - - enum "dynamic" { - description - "This mapping is created by an outgoing - packet."; - } - } - description - "Indicates the type of a mapping entry. E.g., - a mapping can be: static or dynamic"; - } - - leaf internal-src-address { - type inet:ip-address; - mandatory true; - description - "Corresponds to the source IPv4/IPv6 address - of the IPv4 packet"; - } - - container internal-src-port { - description - "Corresponds to the source port of the - IPv4 packet."; - uses port-number; - } - - leaf external-src-address { - type inet:ipv4-address; - mandatory true; - description - "External IPv4 address assigned by NAT"; - } - - container external-src-port { - description - "External source port number assigned by NAT."; - uses port-number; - } - - leaf transport-protocol { - type uint8; - // mandatory true; - description - "Upper-layer protocol associated with this mapping. - Values are taken from the IANA protocol registry. - For example, this field contains 6 (TCP) for a TCP - mapping or 17 (UDP) for a UDP mapping."; - } - - leaf internal-dst-address { - type inet:ipv4-prefix; - description - "Corresponds to the destination IPv4 address - of the IPv4 packet, for example, some NAT - implementation support translating both source - and destination address and ports referred to as - Twice NAT"; - } - - container internal-dst-port { - description - "Corresponds to the destination port of the - IPv4 packet."; - uses port-number; - } - - leaf external-dst-address { - type inet:ipv4-address; - description - "External destination IPv4 address"; - } - - container external-dst-port { - description - "External source port number."; - uses port-number; - } - - leaf lifetime { - type uint32; - // mandatory true; - description - "Lifetime of the mapping."; - } - } - - grouping nat-parameters { - description - "NAT parameters for a given instance"; - - list external-ip-address-pool { - key pool-id; - - - description - "Pool of external IP addresses used to service - internal hosts. - Both contiguous and non-contiguous pools - can be configured for NAT."; - - leaf pool-id { - type uint32; - description - "An identifier of the address pool."; - } - - leaf external-ip-pool { - type inet:ipv4-prefix; - description - "An IPv4 prefix used for NAT purposes."; - } - } - - - leaf subscriber-mask-v6 { - type uint8 { - range "0 .. 128"; - } - description - "The subscriber-mask is an integer that indicates - the length of significant bits to be applied on - the source IP address (internal side) to - unambiguously identify a CPE. - - Subscriber-mask is a system-wide configuration - parameter that is used to enforce generic - per-subscriberpolicies (e.g., port-quota). - - The enforcement of these generic policies does not - require the configuration of every subscriber's - prefix. - - Example: suppose the 2001:db8:100:100::/56 prefix - is assigned to a NAT64 serviced CPE. Suppose also - that 2001:db8:100:100::1 is the IPv6 address used - by the client that resides in that CPE. When the - NAT64 receives a packet from this client, - it applies the subscriber-mask (e.g., 56) on - the source IPv6 address to compute the associated - prefix for this client (2001:db8:100:100::/56). - Then, the NAT64 enforces policies based on that - prefix (2001:db8:100:100::/56), not on the exact - source IPv6 address."; - } - - - list subscriber-mask-v4 { - - key sub-mask-id; - - description - "IPv4 subscriber mask."; - - leaf sub-mask-id { - type uint32; - description - "An identifier of the subscriber masks."; - } - leaf sub-mask { - type inet:ipv4-prefix; - // mandatory true; - description - "The IP address subnets that matches - should be translated. E.g., If the - private realms that are to be translated - by NAT would be 192.0.2.0/24"; - } - } - - leaf paired-address-pooling { - type boolean; - default true; - description - "Paired address pooling is indicating to NAT - that all the flows from an internal IP - address must be assigned the same external - address. This is defined in RFC 4007."; - } - - leaf nat-mapping-type { - type enumeration { - enum "eim" { - description - "endpoint-independent-mapping. - Refer section 4 of RFC 4787."; - } - - enum "adm" { - description - "address-dependent-mapping. - Refer section 4 of RFC 4787."; - } - - enum "edm" { - description - "address-and-port-dependent-mapping. - Refer section 4 of RFC 4787."; - } - } - description - "Indicates the type of a NAT mapping."; - } - leaf nat-filtering-type { - type enumeration { - enum "eif" { - description - "endpoint-independent- filtering. - Refer section 5 of RFC 4787."; - } - - enum "adf" { - description - "address-dependent- filtering. - Refer section 5 of RFC 4787."; - } - - enum "edf" { - description - "address-and-port-dependent- filtering. - Refer section 5 of RFC 4787."; - } - } - description - "Indicates the type of a NAT filtering."; - } - - leaf port-quota { - type uint16; - description - "Configures a port quota to be assigned per - subscriber."; - } - - container port-set { - description - "Manages port-set assignments."; - - leaf port-set-enable { - type boolean; - description - "Enable/Disable port set assignment."; - } - - leaf port-set-size { - type uint16; - description - "Indicates the size of assigned port - sets."; - } - - leaf port-set-timeout { - type uint32; - description - "Inactivty timeout for port sets."; - } - } - - leaf port-randomization-enable { - type boolean; - description - "Enable/disable port randomization - feature."; - } - - leaf port-preservation-enable { - type boolean; - description - "Indicates whether the PCP server should - preserve the internal port number."; - } - - leaf port-range-preservation-enable { - type boolean; - description - "Indicates whether the NAT device should - preserve the internal port range."; - } - - leaf port-parity-preservation-enable { - type boolean; - description - "Indicates whether the PCP server should - preserve the port parity of the - internal port number."; - } - leaf address-roundrobin-enable { - type boolean; - description - "Enable/disable address allocation - round robin."; - } - - uses timeouts; - container logging-info { - description - "Information about Logging NAT events"; - - leaf destination-address { - type inet:ipv4-prefix; - // mandatory true; - description - "Address of the collector that receives - the logs"; - } - leaf destination-port { - type inet:port-number; - // mandatory true; - description - "Destination port of the collector."; - } - - } - container connection-limit { - description - "Information on the config parameters that - rate limit the translations based on various - criteria"; - - leaf limit-per-subscriber { - type uint32; - description - "Maximum number of NAT mappings per - subscriber."; - } - leaf limit-per-vrf { - type uint32; - description - "Maximum number of NAT mappings per - VLAN/VRF."; - } - leaf limit-per-subnet { - type inet:ipv4-prefix; - description - "Maximum number of NAT mappings per - subnet."; - } - leaf limit-per-instance { - type uint32; - // mandatory true; - description - "Maximum number of NAT mappings per - instance."; - } - } - container mapping-limit { - description - "Information on the config parameters that - rate limit the mappings based on various - criteria"; - - leaf limit-per-subscriber { - type uint32; - description - "Maximum number of NAT mappings per - subscriber."; - } - leaf limit-per-vrf { - type uint32; - description - "Maximum number of NAT mappings per - VLAN/VRF."; - } - leaf limit-per-subnet { - type inet:ipv4-prefix; - description - "Maximum number of NAT mappings per - subnet."; - } - leaf limit-per-instance { - type uint32; - // mandatory true; - description - "Maximum number of NAT mappings per - instance."; - } - } - leaf ftp-alg-enable { - type boolean; - description - "Enable/Disable FTP ALG"; - } - - leaf dns-alg-enable { - type boolean; - description - "Enable/Disable DNSALG"; - } - - leaf tftp-alg-enable { - type boolean; - description - "Enable/Disable TFTP ALG"; - } - - leaf msrpc-alg-enable { - type boolean; - description - "Enable/Disable MS-RPC ALG"; - } - - leaf netbios-alg-enable { - type boolean; - description - "Enable/Disable NetBIOS ALG"; - } - - leaf rcmd-alg-enable { - type boolean; - description - "Enable/Disable rcmd ALG"; - } - - leaf ldap-alg-enable { - type boolean; - description - "Enable/Disable LDAP ALG"; - } - - leaf sip-alg-enable { - type boolean; - description - "Enable/Disable SIP ALG"; - } - - leaf rtsp-alg-enable { - type boolean; - description - "Enable/Disable RTSP ALG"; - } - - leaf h323-alg-enable { - type boolean; - description - "Enable/Disable H323 ALG"; - } - - leaf all-algs-enable { - type boolean; - description - "Enable/Disable all the ALGs"; - } - - container notify-pool-usage { - description - "Notification of Pool usage when certain criteria - is met"; - - leaf pool-id { - type uint32; - description - "Pool-ID for which the notification - criteria is defined"; - } - - leaf notify-pool-hi-threshold { - type percent; - // mandatory true; - description - "Notification must be generated when the - defined high threshold is reached. - For example, if a notification is - required when the pool utilization reaches - 90%, this configuration parameter must - be set to 90%"; - } - - leaf notify-pool-low-threshold { - type percent; - description - "Notification must be generated when the defined - low threshold is reached. - For example, if a notification is required when - the pool utilization reaches below 10%, - this configuration parameter must be set to - 10%"; - } - } - list nat64-prefixes { - key nat64-prefix-id; - - description - "Provides one or a list of NAT64 prefixes - With or without a list of destination IPv4 prefixes. - - Destination-based Pref64::/n is discussed in - Section 5.1 of [RFC7050]). For example: - 192.0.2.0/24 is mapped to 2001:db8:122:300::/56. - 198.51.100.0/24 is mapped to 2001:db8:122::/48."; - - leaf nat64-prefix-id { - type uint32; - description - "An identifier of the NAT64 prefix."; - } - - leaf nat64-prefix { - type inet:ipv6-prefix; - default "64:ff9b::/96"; - description - "A NAT64 prefix. Can be NSP or WKP [RFC6052]."; - } - - list destination-ipv4-prefix { - - key ipv4-prefix-id; - - description - "An IPv4 prefix/address."; - - leaf ipv4-prefix-id { - type uint32; - description - "An identifier of the IPv4 prefix/address."; - } - - leaf ipv4-prefix { - type inet:ipv4-prefix; - description - "An IPv4 address/prefix. "; - } - } - } - } //nat-parameters group - - container nat-config { - description - "NAT"; - - container nat-instances { - description - "nat instances"; - - list nat-instance { - - key "id"; - - description - "A NAT instance."; - - leaf id { - type uint32; - description - "NAT instance identifier."; - } - - leaf enable { - type boolean; - description - "Status of the the NAT instance."; - } - - uses nat-parameters; - - container mapping-table { - description - "NAT dynamic mapping table used to track - sessions"; - - list mapping-entry { - key "index"; - description - "NAT mapping entry."; - uses mapping-entry; - } - } - } - } - } - - /* - * NAT State - */ - - container nat-state { - - config false; - - description - "nat-state"; - - container nat-instances { - description - "nat instances"; - - list nat-instance { - key "id"; - - description - "nat instance"; - - leaf id { - // FIXME changed int32 to uint32 to align with nat-config (authors of draft notified) - type uint32; - description - "The identifier of the nat instance."; - } - - container nat-capabilities { - description - "NAT Capabilities"; - - leaf nat44-support { - type boolean; - description - "Indicates NAT44 support"; - } - - leaf nat64-support { - type boolean; - description - "Indicates NAT64 support"; - } - - leaf static-mapping-support { - type boolean; - description - "Indicates whether static mappings are - supported."; - } - - leaf port-set-support { - type boolean; - description - "Indicates port set assignment - support "; - } - - leaf port-randomization-support { - type boolean; - description - "Indicates whether port randomization is - supported."; - } - - leaf port-range-preservation-support { - type boolean; - description - "Indicates whether port range - preservation is supported."; - } - - leaf port-preservation-suport { - type boolean; - description - "Indicates whether port preservation - is supported."; - } - - leaf port-parity-preservation-support { - type boolean; - description - "Indicates whether port parity - preservation is supported."; - } - - leaf address-roundrobin-support { - type boolean; - description - "Indicates whether address allocation - round robin is supported."; - } - - leaf ftp-alg-support { - type boolean; - description - "Indicates whether FTP ALG is supported"; - } - - leaf dns-alg-support { - type boolean; - description - "Indicates whether DNSALG is supported"; - } - - leaf tftp-support { - type boolean; - description - "Indicates whether TFTP ALG is supported"; - } - - leaf msrpc-alg-support { - type boolean; - description - "Indicates whether MS-RPC ALG is supported"; - } - - leaf netbios-alg-support { - type boolean; - description - "Indicates whether NetBIOS ALG is supported"; - } - - leaf rcmd-alg-support { - type boolean; - description - "Indicates whether rcmd ALG is supported"; - } - - leaf ldap-alg-support { - type boolean; - description - "Indicates whether LDAP ALG is supported"; - } - - leaf sip-alg-support { - type boolean; - description - "Indicates whether SIP ALG is supported"; - } - - leaf rtsp-alg-support { - type boolean; - description - "Indicates whether RTSP ALG is supported"; - } - - leaf h323-alg-support { - type boolean; - description - "Indicates whether H323 ALG is supported"; - } - - leaf paired-address-pooling-support { - type boolean; - description - "Indicates whether paired-address-pooling is - supported"; - } - - leaf endpoint-independent-mapping-support { - type boolean; - description - "Indicates whether endpoint-independent-mapping - in Section 4 of RFC 4787 is supported."; - } - - leaf address-dependent-mapping-support { - type boolean; - description - "Indicates whether endpoint-independent-mapping - in Section 4 of RFC 4787 is supported."; - } - - leaf address-and-port-dependent-mapping-support { - type boolean; - description - "Indicates whether endpoint-independent-mapping in - section 4 of RFC 4787 is supported."; - } - - leaf endpoint-independent-filtering-support { - type boolean; - description - "Indicates whether endpoint-independent-mapping in - section 5 of RFC 4787 is supported."; - } - - leaf address-dependent-filtering { - type boolean; - description - "Indicates whether endpoint-independent-mapping in - section 5 of RFC 4787 is supported."; - } - - leaf address-and-port-dependent-filtering { - type boolean; - description - "Indicates whether endpoint-independent-mapping in - section 5 of RFC 4787 is supported."; - } - - leaf stealth-mode-support { - type boolean; - description - "Indicates whether to respond for unsolicited - traffic."; - } - - } - - container nat-current-config { - description - "current config"; - - uses nat-parameters; - } - - container mapping-table { - description - "Mapping table"; - list mapping-entry { - key "index"; - description - "mapping entry"; - uses mapping-entry; - } - } - - container statistics { - description - "Statistics related to the NAT instance"; - - leaf total-mappings { - type uint32; - description - "Total number of NAT Mappings present - at the time. This includes all the - static and dynamic mappings"; - } - leaf total-tcp-mappings { - type uint32; - description - "Total number of TCP Mappings present - at the time."; - } - leaf total-udp-mappings { - type uint32; - description - "Total number of UDP Mappings present - at the time."; - } - leaf total-icmp-mappings { - type uint32; - description - "Total number of ICMP Mappings present - at the time."; - } - container pool-stats { - description - "Statistics related to Pool usage"; - leaf pool-id { - type uint32; - description - "Unique Identifier that represents - a pool"; - } - leaf address-allocated { - type uint32; - description - "Number of allocated addresses in - the pool"; - } - leaf address-free { - type uint32; - description - "Number of free addresses in - the pool.The sum of free - addresses and allocated - addresses are the total - addresses in the pool"; - } - container port-stats { - description - "Statistics related to port - usage."; - - leaf ports-allocated { - type uint32; - description - "Number of allocated ports - in the pool"; - } - - leaf ports-free { - type uint32; - description - "Number of free addresses - in the pool"; - } - } - } - } //statistics - } //nat-instance - } //nat-instances - } //nat-state - /* - * Notifications - */ - notification nat-event { - description - "Notifications must be generated when the defined - high/low threshold is reached. Related configuration - parameters must be provided to trigger - the notifications."; - - leaf id { - type leafref { - path - "/nat-state/nat-instances/" - + "nat-instance/id"; - } - description - "NAT instance ID."; - } - - leaf notify-pool-threshold { - type percent; - // mandatory true; - description - "A treshhold has been fired."; - } - } -} //module nat
\ No newline at end of file diff --git a/nat/nat-api/src/main/yang/ietf-nat@2018-02-23.yang b/nat/nat-api/src/main/yang/ietf-nat@2018-02-23.yang new file mode 100644 index 000000000..77e2d7be7 --- /dev/null +++ b/nat/nat-api/src/main/yang/ietf-nat@2018-02-23.yang @@ -0,0 +1,2392 @@ +module ietf-nat { + yang-version 1.1; + namespace "urn:ietf:params:xml:ns:yang:ietf-nat"; + prefix "nat"; + + import ietf-inet-types { + prefix inet; + reference + "Section 4 of RFC 6991"; + } + + import ietf-yang-types { + prefix yang; + reference + "Section 3 of RFC 6991"; + } + + import ietf-interfaces { + prefix if; + reference + "RFC 8343: A YANG Data Model for Interface Management"; + } + + organization + "IETF OPSAWG (Operations and Management Area Working Group)"; + + contact + + "WG Web: <https://datatracker.ietf.org/wg/opsawg/> + WG List: <mailto:opsawg@ietf.org> + + Editor: Mohamed Boucadair + <mailto:mohamed.boucadair@orange.com> + + Editor: Senthil Sivakumar + <mailto:ssenthil@cisco.com> + + Editor: Christian Jacquenet + <mailto:christian.jacquenet@orange.com> + + Editor: Suresh Vinapamula + <mailto:sureshk@juniper.net> + + Editor: Qin Wu + <mailto:bill.wu@huawei.com>"; + + description + "This module is a YANG module for NAT implementations. + + NAT44, Network Address and Protocol Translation from IPv6 + Clients to IPv4 Servers (NAT64), Customer-side transLATor (CLAT), + Stateless IP/ICMP Translation (SIIT), Explicit Address Mappings + for Stateless IP/ICMP Translation (SIIT EAM), IPv6 Network + Prefix Translation (NPTv6), and Destination NAT are covered. + + Copyright (c) 2018 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, is permitted pursuant to, and subject + to the license terms contained in, the Simplified BSD License + set forth in Section 4.c of the IETF Trust's Legal Provisions + Relating to IETF Documents + (http://trustee.ietf.org/license-info). + + This version of this YANG module is part of RFC XXXX; see + the RFC itself for full legal notices."; + + revision 2018-02-23 { + description + "Initial revision."; + reference + "RFC XXXX: A YANG Module for Network Address Translation + (NAT) and Network Prefix Translation (NPT)"; + } + + /* + * Definitions + */ + + typedef percent { + type uint8 { + range "0 .. 100"; + } + description + "Percentage"; + } + + /* + * Features + */ + + feature basic-nat44{ + description + "Basic NAT44 translation is limited to IP addresses alone."; + reference + "RFC 3022: Traditional IP Network Address Translator + (Traditional NAT)"; + } + + feature napt44 { + description + "Network Address/Port Translator (NAPT): translation is + extended to include IP addresses and transport identifiers + (such as a TCP/UDP port or ICMP query ID). + + If the internal IP address is not sufficient to uniquely + disambiguate NAPT44 mappings, an additional attribute is + required. For example, that additional attribute may + be an IPv6 address (a.k.a., DS-Lite) or + a Layer 2 identifier (a.k.a., Per-Interface NAT)"; + reference + "RFC 3022: Traditional IP Network Address Translator + (Traditional NAT)"; + } + + feature dst-nat { + description + "Destination NAT is a translation that acts on the destination + IP address and/or destination port number. This flavor is + usually deployed in load balancers or at devices + in front of public servers."; + } + + feature nat64 { + description + "NAT64 translation allows IPv6-only clients to contact IPv4 + servers using unicast UDP, TCP, or ICMP. One or more + public IPv4 addresses assigned to a NAT64 translator are + shared among several IPv6-only clients."; + reference + "RFC 6146: Stateful NAT64: Network Address and Protocol + Translation from IPv6 Clients to IPv4 Servers"; + } + + feature siit { + description + "The Stateless IP/ICMP Translation Algorithm (SIIT), which + translates between IPv4 and IPv6 packet headers (including + ICMP headers). + + In the stateless mode, an IP/ICMP translator converts IPv4 + addresses to IPv6 and vice versa solely based on the + configuration of the stateless IP/ICMP translator and + information contained within the packet being translated. + + The translator must support the stateless address mapping + algorithm defined in RFC6052, which is the default behavior."; + reference + "RFC 7915: IP/ICMP Translation Algorithm"; + } + + feature clat { + description + "CLAT is customer-side translator that algorithmically + translates 1:1 private IPv4 addresses to global IPv6 addresses, + and vice versa. + + When a dedicated /64 prefix is not available for translation + from DHCPv6-PD, the CLAT may perform NAT44 for all IPv4 LAN + packets so that all the LAN-originated IPv4 packets appear + from a single IPv4 address and are then statelessly translated + to one interface IPv6 address that is claimed by the CLAT via + the Neighbor Discovery Protocol (NDP) and defended with + Duplicate Address Detection."; + reference + "RFC 6877: 464XLAT: Combination of Stateful and Stateless + Translation"; + } + + feature eam { + description + "Explicit Address Mapping (EAM) is a bidirectional coupling + between an IPv4 Prefix and an IPv6 Prefix."; + reference + "RFC 7757: Explicit Address Mappings for Stateless IP/ICMP + Translation"; + } + + feature nptv6 { + description + "NPTv6 is a stateless transport-agnostic IPv6-to-IPv6 + prefix translation."; + reference + "RFC 6296: IPv6-to-IPv6 Network Prefix Translation"; + } + + /* + * Identities + */ + + identity nat-type { + description + "Base identity for nat type."; + } + + identity basic-nat44 { + base nat:nat-type; + description + "Identity for Basic NAT support."; + reference + "RFC 3022: Traditional IP Network Address Translator + (Traditional NAT)"; + } + + identity napt44 { + base nat:nat-type; + description + "Identity for NAPT support."; + reference + "RFC 3022: Traditional IP Network Address Translator + (Traditional NAT)"; + } + + identity dst-nat { + base nat:nat-type; + description + "Identity for Destination NAT support."; + } + + identity nat64 { + base nat:nat-type; + description + "Identity for NAT64 support."; + reference + "RFC 6146: Stateful NAT64: Network Address and Protocol + Translation from IPv6 Clients to IPv4 Servers"; + } + + identity siit { + base nat:nat-type; + description + "Identity for SIIT support."; + reference + "RFC 7915: IP/ICMP Translation Algorithm"; + } + + identity clat { + base nat:nat-type; + description + "Identity for CLAT support."; + reference + "RFC 6877: 464XLAT: Combination of Stateful and Stateless + Translation"; + } + + identity eam { + base nat:nat-type; + description + "Identity for EAM support."; + reference + "RFC 7757: Explicit Address Mappings for Stateless IP/ICMP + Translation"; + } + + identity nptv6 { + base nat:nat-type; + description + "Identity for NPTv6 support."; + reference + "RFC 6296: IPv6-to-IPv6 Network Prefix Translation"; + } + + /* + * Grouping + */ + + grouping port-number { + description + "Individual port or a range of ports. + When only start-port-number is present, + it represents a single port number."; + + leaf start-port-number { + type inet:port-number; + description + "Beginning of the port range."; + reference + "Section 3.2.9 of RFC 8045."; + } + + leaf end-port-number { + type inet:port-number; + + must ". >= ../start-port-number" + { + error-message + "The end-port-number must be greater than or + equal to start-port-number."; + } + description + "End of the port range."; + reference + "Section 3.2.10 of RFC 8045."; + } + } + + grouping port-set { + description + "Indicates a set of ports. + + It may be a simple port range, or use the Port Set ID (PSID) + algorithm to represent a range of transport layer + ports which will be used by a NAPT."; + + choice port-type { + default port-range; + description + "Port type: port-range or port-set-algo."; + case port-range { + uses port-number; + } + + case port-set-algo { + leaf psid-offset { + type uint8 { + range 0..15; + } + + description + "The number of offset bits (a.k.a., 'a' bits). + + Specifies the numeric value for the excluded port + range/offset bits. + + Allowed values are between 0 and 15 "; + + reference + "Section 5.1 of RFC 7597"; + } + + leaf psid-len { + type uint8 { + range 0..15; + } + mandatory true; + + description + "The length of PSID, representing the sharing + ratio for an IPv4 address. + + (also known as 'k'). + + The address-sharing ratio would be 2^k."; + reference + "Section 5.1 of RFC 7597"; + } + + leaf psid { + type uint16; + mandatory true; + description + "Port Set Identifier (PSID) value, which + identifies a set of ports algorithmically."; + reference + "Section 5.1 of RFC 7597"; + } + } + reference + "Section 7597: Mapping of Address and Port with + Encapsulation (MAP-E)"; + } + } + + grouping mapping-entry { + description + "NAT mapping entry. + + If an attribute is not stored in the mapping/session table, + this means the corresponding fields of a packet that + matches this entry is not rewritten by the NAT or this + information is not required for NAT filtering purposes."; + + leaf index { + type uint32; + description + "A unique identifier of a mapping entry. This identifier can be + automatically assigned by the NAT instance or be explicitly + configured."; + } + + leaf type { + type enumeration { + enum "static" { + description + "The mapping entry is explicitly configured + (e.g., via command-line interface)."; + } + + enum "dynamic-implicit" { + description + "This mapping is created implicitly as a side effect + of processing a packet that requires a new mapping."; + + } + + enum "dynamic-explicit" { + description + "This mapping is created as a result of an explicit + request, e.g., a PCP message."; + + } + } + description + "Indicates the type of a mapping entry. E.g., + a mapping can be: static, implicit dynamic + or explicit dynamic."; + } + + leaf transport-protocol { + type uint8; + description + "Upper-layer protocol associated with this mapping. + Values are taken from the IANA protocol registry. + For example, this field contains 6 (TCP) for a TCP + mapping or 17 (UDP) for a UDP mapping. + + If this leaf is not instantiated, then the mapping + applies to any protocol."; + } + + leaf internal-src-address { + // TODO(HC2VPP-325): original model uses inet:ip-prefix; + type inet:ip-address; + description + "Corresponds to the source IPv4/IPv6 address/prefix + of the packet received on an internal + interface."; + } + + container internal-src-port { + description + "Corresponds to the source port of the packet received + on an internal interface. + + It is used also to indicate the internal source ICMP + identifier. + + As a reminder, all the ICMP Query messages contain + an 'Identifier' field, which is referred to in this + document as the 'ICMP Identifier'."; + + uses port-number; + } + + leaf external-src-address { + // TODO(HC2VPP-325): original model uses inet:ip-prefix; + type inet:ipv4-address; + description + "Source IP address/prefix of the packet sent on an + external interface of the NAT."; + } + + container external-src-port { + description + "Source port of the packet sent on an external + interface of the NAT. + It is used also to indicate the external source ICMP + identifier."; + + uses port-number; + } + + leaf internal-dst-address { + // TODO(HC2VPP-325): original model uses inet:ip-prefix; + type inet:ipv4-prefix; + description + "Corresponds to the destination IP address/prefix + of the packet received on an internal interface + of the NAT. + + For example, some NAT implementations support + the translation of both source and destination + addresses and ports, sometimes referred to + as 'Twice NAT'."; + } + + container internal-dst-port { + description + "Corresponds to the destination port of the + IP packet received on the internal interface. + + It is used also to include the internal + destination ICMP identifier."; + + uses port-number; + } + + leaf external-dst-address { + // TODO(HC2VPP-325): original model uses inet:ip-prefix; + type inet:ipv4-address; + description + "Corresponds to the destination IP address/prefix + of the packet sent on an external interface + of the NAT."; + } + + container external-dst-port { + description + "Corresponds to the destination port number of + the packet sent on the external interface + of the NAT. + + It is used also to include the external + destination ICMP identifier."; + + uses port-number; + } + + leaf lifetime { + type uint32; + units "seconds"; + description + "When specified, it is used to track the connection that is + fully-formed (e.g., once the three-way handshake + TCP is completed) or the duration for maintaining + an explicit mapping alive. The mapping entry will be + removed by the NAT instance once this lifetime is expired. + + When reported in a get operation, the lifetime indicates + the remaining validity lifetime. + + Static mappings may not be associated with a + lifetime. If no lifetime is associated with a + static mapping, an explicit action is required to + remove that mapping."; + } + } + + /* + * NAT Module + */ + + container nat { + description + "NAT module"; + + container instances { + description + "NAT instances"; + + list instance { + key "id"; + + description + "A NAT instance. This identifier can be automatically assigned + or explicitly configured."; + + leaf id { + type uint32; + must ". >= 1"; + description + "NAT instance identifier. + + The identifier must be greater than zero."; + reference + "RFC 7659: Definitions of Managed Objects for Network + Address Translators (NATs)"; + } + + leaf name { + type string; + description + "A name associated with the NAT instance."; + reference + "RFC 7659: Definitions of Managed Objects for Network + Address Translators (NATs)"; + } + + leaf enable { + type boolean; + description + "Status of the NAT instance."; + } + + container capabilities { + config false; + + description + "NAT capabilities"; + + leaf-list nat-flavor { + type identityref { + base nat-type; + } + description + "Supported translation type(s)."; + } + + leaf-list per-interface-binding { + type enumeration { + enum "unsupported" { + description + "No capability to associate a NAT binding with + an extra identifier."; + } + + enum "layer-2" { + description + "The NAT instance is able to associate a mapping with + a layer-2 identifier."; + } + + enum "dslite" { + description + "The NAT instance is able to associate a mapping with + an IPv6 address (a.k.a., DS-Lite)."; + } + } + description + "Indicates the capability of a NAT to associate a particular + NAT session not only with the five tuples used for the + transport connection on both sides of the NAT but also with + the internal interface on which the user device is + connected to the NAT."; + reference + "Section 4 of RFC 6619"; + } + + list transport-protocols { + key protocol-id; + + description + "List of supported protocols."; + + leaf protocol-id { + type uint8; + mandatory true; + description + "Upper-layer protocol associated with this mapping. + + Values are taken from the IANA protocol registry: + https://www.iana.org/assignments/protocol-numbers/ + protocol-numbers.xhtml + + For example, this field contains 6 (TCP) for a TCP + mapping or 17 (UDP) for a UDP mapping."; + } + + leaf protocol-name { + type string; + description + "The name of the Upper-layer protocol associated + with this mapping. + + Values are taken from the IANA protocol registry: + https://www.iana.org/assignments/protocol-numbers/ + protocol-numbers.xhtml + + For example, TCP, UDP, DCCP, and SCTP."; + } + } + + leaf restricted-port-support { + type boolean; + description + "Indicates source port NAT restriction support."; + reference + "RFC 7596: Lightweight 4over6: An Extension to + the Dual-Stack Lite Architecture."; + } + + leaf static-mapping-support { + type boolean; + description + "Indicates whether static mappings are supported."; + } + + leaf port-randomization-support { + type boolean; + description + "Indicates whether port randomization is supported."; + reference + "Section 4.2.1 of RFC 4787."; + } + + leaf port-range-allocation-support { + type boolean; + description + "Indicates whether port range allocation is supported."; + reference + "Section 1.1 of RFC 7753."; + } + + leaf port-preservation-suport { + type boolean; + description + "Indicates whether port preservation is supported."; + reference + "Section 4.2.1 of RFC 4787."; + } + + leaf port-parity-preservation-support { + type boolean; + description + "Indicates whether port parity preservation is + supported."; + reference + "Section 8 of RFC 7857."; + } + + leaf address-roundrobin-support { + type boolean; + description + "Indicates whether address allocation round robin is + supported."; + } + + leaf paired-address-pooling-support { + type boolean; + description + "Indicates whether paired-address-pooling is + supported"; + reference + "REQ-2 of RFC 4787."; + } + + leaf endpoint-independent-mapping-support { + type boolean; + description + "Indicates whether endpoint-independent- + mapping is supported."; + reference + "Section 4 of RFC 4787."; + } + + leaf address-dependent-mapping-support { + type boolean; + description + "Indicates whether address-dependent-mapping is + supported."; + reference + "Section 4 of RFC 4787."; + } + + leaf address-and-port-dependent-mapping-support { + type boolean; + description + "Indicates whether address-and-port-dependent-mapping is + supported."; + reference + "Section 4 of RFC 4787."; + } + + leaf endpoint-independent-filtering-support { + type boolean; + description + "Indicates whether endpoint-independent-filtering is + supported."; + reference + "Section 5 of RFC 4787."; + } + + leaf address-dependent-filtering { + type boolean; + description + "Indicates whether address-dependent-filtering is + supported."; + reference + "Section 5 of RFC 4787."; + } + + leaf address-and-port-dependent-filtering { + type boolean; + description + "Indicates whether address-and-port-dependent is + supported."; + reference + "Section 5 of RFC 4787."; + } + + leaf fragment-behavior { + type enumeration { + enum "unsupported" { + description + "No capability to translate incoming fragments. + All received fragments are dropped."; + } + + enum "in-order" { + description + "The NAT instance is able to translate fragments only if + they are received in order. That is, in particular the + header is in the first packet. Fragments received + out of order are dropped. "; + } + + enum "out-of-order" { + description + "The NAT instance is able to translate a fragment even + if it is received out of order. + + This behavior is recommended."; + reference + "REQ-14 of RFC 4787"; + } + } + description + "The fragment behavior is the NAT instance's capability to + translate fragments received on the external interface of + the NAT."; + } + } + + leaf type { + type identityref { + base nat-type; + } + description + "Specify the translation type. Particularly useful when + multiple translation flavors are supported. + + If one type is supported by a NAT, this parameter is by + default set to that type."; + } + + leaf per-interface-binding { + type enumeration { + enum "disabled" { + description + "Disable the capability to associate an extra identifier + with NAT mappings."; + } + + enum "layer-2" { + description + "The NAT instance is able to associate a mapping with + a layer-2 identifier."; + } + + enum "dslite" { + description + "The NAT instance is able to associate a mapping with + an IPv6 address (a.k.a., DS-Lite)."; + } + } + description + "A NAT that associates a particular NAT session not only with + the five tuples used for the transport connection on both + sides of the NAT but also with the internal interface on + which the user device is connected to the NAT. + + If supported, this mode of operation should be configurable, + and it should be disabled by default in general-purpose NAT + devices. + + If one single per-interface binding behavior is supported by + a NAT, this parameter is by default set to that behavior."; + reference + "Section 4 of RFC 6619"; + } + + list nat-pass-through { + if-feature "basic-nat44 or napt44 or dst-nat"; + key id; + + description + "IP prefix NAT pass through."; + + leaf id { + type uint32; + description + "An identifier of the IP prefix pass through."; + } + + leaf prefix { + type inet:ip-prefix; + mandatory true; + description + "The IP addresses that match should not be translated. + + It must be possible to administratively turn + off translation for specific destination addresses + and/or ports."; + reference + "REQ#6 of RFC 6888."; + } + + leaf port { + type inet:port-number; + description + "It must be possible to administratively turn off + translation for specific destination addresses + and/or ports. + + If no prefix is defined, the NAT pass through bound + to a given port applies for any destination address."; + reference + "REQ#6 of RFC 6888."; + } + } + + list policy { + key id; + description + "NAT parameters for a given instance"; + + leaf id { + type uint32; + description + "An identifier of the NAT policy. It must be unique + within the NAT instance."; + } + + container clat-parameters { + if-feature clat; + description + "CLAT parameters."; + + list clat-ipv6-prefixes { + key ipv6-prefix; + description + "464XLAT double translation treatment is stateless when a + dedicated /64 is available for translation on the CLAT. + Otherwise, the CLAT will have both stateful and stateless + since it requires NAT44 from the LAN to a single IPv4 + address and then stateless translation to a single + IPv6 address."; + reference + "RFC 6877: 464XLAT: Combination of Stateful and Stateless + Translation"; + + leaf ipv6-prefix { + type inet:ipv6-prefix; + description + "An IPv6 prefix used for CLAT."; + } + } + + list ipv4-prefixes { + key ipv4-prefix; + description + "Pool of IPv4 addresses used for CLAT. + 192.0.0.0/29 is the IPv4 service continuity prefix."; + reference + "RFC 7335: IPv4 Service Continuity Prefix"; + + leaf ipv4-prefix { + type inet:ipv4-prefix; + description + "464XLAT double translation treatment is + stateless when a dedicated /64 is available + for translation on the CLAT. Otherwise, the + CLAT will have both stateful and stateless + since it requires NAT44 from the LAN to + a single IPv4 address and then stateless + translation to a single IPv6 address. + The CLAT performs NAT44 for all IPv4 LAN + packets so that all the LAN-originated IPv4 + packets appear from a single IPv4 address + and are then statelessly translated to one + interface IPv6 address that is claimed by + the CLAT. + + An IPv4 address from this pool is also + provided to an application that makes + use of literals."; + + reference + "RFC 6877: 464XLAT: Combination of Stateful and Stateless + Translation"; + } + } + } + + list nptv6-prefixes { + if-feature nptv6; + key internal-ipv6-prefix ; + description + "Provides one or a list of (internal IPv6 prefix, + external IPv6 prefix) required for NPTv6. + + In its simplest form, NPTv6 interconnects two network + links, one of which is an 'internal' network link + attached to a leaf network within a single + administrative domain and the other of which is an + 'external' network with connectivity to the global + Internet."; + reference + "RFC 6296: IPv6-to-IPv6 Network Prefix Translation"; + + leaf internal-ipv6-prefix { + type inet:ipv6-prefix; + mandatory true; + description + "An IPv6 prefix used by an internal interface of NPTv6."; + reference + "RFC 6296: IPv6-to-IPv6 Network Prefix Translation"; + } + + leaf external-ipv6-prefix { + type inet:ipv6-prefix; + mandatory true; + description + "An IPv6 prefix used by the external interface of NPTv6."; + reference + "RFC 6296: IPv6-to-IPv6 Network Prefix Translation"; + } + } + + list eam { + if-feature eam; + key ipv4-prefix; + description + "The Explicit Address Mapping Table, a conceptual + table in which each row represents an EAM. + + Each EAM describes a mapping between IPv4 and IPv6 + prefixes/addresses."; + reference + "Section 3.1 of RFC 7757."; + + leaf ipv4-prefix { + type inet:ipv4-prefix; + mandatory true; + description + "The IPv4 prefix of an EAM."; + reference + "Section 3.2 of RFC 7757."; + } + + leaf ipv6-prefix { + type inet:ipv6-prefix; + mandatory true; + description + "The IPv6 prefix of an EAM."; + reference + "Section 3.2 of RFC 7757."; + } + } + + list nat64-prefixes { + if-feature "siit or nat64 or clat"; + key nat64-prefix; + description + "Provides one or a list of NAT64 prefixes + with or without a list of destination IPv4 prefixes. + It allows mapping IPv4 address ranges to IPv6 prefixes. + + For example: + 192.0.2.0/24 is mapped to 2001:db8:122:300::/56. + 198.51.100.0/24 is mapped to 2001:db8:122::/48."; + reference + "Section 5.1 of RFC 7050."; + + leaf nat64-prefix { + type inet:ipv6-prefix; + mandatory true; + description + "A NAT64 prefix. Can be Network-Specific Prefix (NSP) or + Well-Known Prefix (WKP). + + Organizations deploying stateless IPv4/IPv6 translation + should assign a Network-Specific Prefix to their + IPv4/IPv6 translation service. + + For stateless NAT64, IPv4-translatable IPv6 addresses + must use the selected Network-Specific Prefix. + + Both IPv4-translatable IPv6 addresses and IPv4-converted + IPv6 addresses should use the same prefix."; + reference + "Sections 3.3 and 3.4 of RFC 6052."; + } + + list destination-ipv4-prefix { + key ipv4-prefix; + description + "An IPv4 prefix/address."; + + leaf ipv4-prefix { + type inet:ipv4-prefix; + description + "An IPv4 address/prefix."; + } + } + + leaf stateless-enable { + type boolean; + default false; + description + "Enable explicitly stateless NAT64."; + } + } + + list external-ip-address-pool { + if-feature "basic-nat44 or napt44 or nat64"; + key pool-id; + + description + "Pool of external IP addresses used to service internal + hosts. + + A pool is a set of IP prefixes."; + + leaf pool-id { + type uint32; + must ". >= 1"; + description + "An identifier that uniquely identifies the address pool + within a NAT instance. + + The identifier must be greater than zero."; + reference + "RFC 7659: Definitions of Managed Objects for + Network Address Translators (NATs)"; + } + + leaf external-ip-pool { + type inet:ipv4-prefix; + mandatory true; + description + "An IPv4 prefix used for NAT purposes."; + } + } + + container port-set-restrict { + if-feature "napt44 or nat64"; + description + "Configures contiguous and non-contiguous port ranges. + + The port set is used to restrict the external source + port numbers used by the translator."; + + uses port-set; + } + + leaf dst-nat-enable { + if-feature "basic-nat44 or napt44"; + type boolean; + default false; + description + "Enable/Disable destination NAT. + A NAT44 may be configured to enable Destination + NAT, too."; + } + + list dst-ip-address-pool { + if-feature dst-nat; + key pool-id; + description + "Pool of IP addresses used for destination NAT."; + + leaf pool-id { + type uint32; + description + "An identifier of the address pool."; + } + + leaf dst-in-ip-pool { + type inet:ip-prefix; + description + "Is used to identify an internal destination + IP prefix/address to be translated."; + } + + leaf dst-out-ip-pool { + type inet:ip-prefix; + mandatory true; + description + "IP address/prefix used for destination NAT."; + } + } + + list transport-protocols { + if-feature "napt44 or nat64 or dst-nat"; + key protocol-id; + + description + "Configure the transport protocols to be handled by + the translator. + + TCP and UDP are supported by default."; + + leaf protocol-id { + type uint8; + mandatory true; + description + "Upper-layer protocol associated with this mapping. + + Values are taken from the IANA protocol registry: + https://www.iana.org/assignments/protocol-numbers/ + protocol-numbers.xhtml + + For example, this field contains 6 (TCP) for a TCP + mapping or 17 (UDP) for a UDP mapping."; + } + + leaf protocol-name { + type string; + description + "The name of the Upper-layer protocol associated + with this mapping. + + Values are taken from the IANA protocol registry: + https://www.iana.org/assignments/protocol-numbers/ + protocol-numbers.xhtml + + For example, TCP, UDP, DCCP, and SCTP."; + } + } + + leaf subscriber-mask-v6 { + type uint8 { + range "0 .. 128"; + } + + description + "The subscriber mask is an integer that indicates + the length of significant bits to be applied on + the source IPv6 address (internal side) to + unambiguously identify a user device (e.g., CPE). + + Subscriber mask is a system-wide configuration + parameter that is used to enforce generic + per-subscriber policies (e.g., port-quota). + + The enforcement of these generic policies does not + require the configuration of every subscriber's + prefix. + + Example: suppose the 2001:db8:100:100::/56 prefix + is assigned to a NAT64 serviced CPE. Suppose also + that 2001:db8:100:100::1 is the IPv6 address used + by the client that resides in that CPE. When the + NAT64 receives a packet from this client, + it applies the subscriber-mask-v6 (e.g., 56) on + the source IPv6 address to compute the associated + prefix for this client (2001:db8:100:100::/56). + Then, the NAT64 enforces policies based on that + prefix (2001:db8:100:100::/56), not on the exact + source IPv6 address."; + } + + list subscriber-match { + if-feature "basic-nat44 or napt44 or dst-nat"; + key match-id; + + description + "IP prefix match. + A subscriber is identified by a subnet."; + + leaf match-id { + type uint32; + description + "An identifier of the subscriber match."; + } + + leaf subnet { + type inet:ip-prefix; + mandatory true; + description + "The IP address subnets that match + should be translated. E.g., all addresses + that belong to the 192.0.2.0/24 prefix must + be processed by the NAT."; + } + } + + leaf address-allocation-type { + type enumeration { + enum "arbitrary" { + if-feature "basic-nat44 or napt44 or nat64"; + description + "Arbitrary pooling behavior means that the NAT + instance may create the new port mapping using any + address in the pool that has a free port for the + protocol concerned."; + } + + enum "roundrobin" { + if-feature "basic-nat44 or napt44 or nat64"; + description + "Round robin allocation."; + } + + enum "paired" { + if-feature "napt44 or nat64"; + description + "Paired address pooling informs the NAT + that all the flows from an internal IP + address must be assigned the same external + address. This is the recommended behavior for + NAPT/NAT64."; + reference + "RFC 4787: Network Address Translation (NAT) + Behavioral Requirements for Unicast UDP"; + } + } + description + "Specifies how external IP addresses are allocated."; + } + + leaf port-allocation-type { + if-feature "napt44 or nat64"; + type enumeration { + enum "random" { + description + "Port randomization is enabled. A NAT port allocation + scheme should make it hard for attackers to guess + port numbers"; + reference + "REQ-15 of RFC 6888"; + } + + enum "port-preservation" { + description + "Indicates whether the NAT should preserve the internal + port number."; + } + + enum "port-parity-preservation" { + description + "Indicates whether the NAT should preserve the port + parity of the internal port number."; + } + + enum "port-range-allocation" { + description + "Indicates whether the NAT assigns a range of ports + for an internal host. This scheme allows to minimize + log volume."; + reference + "REQ-14 of RFC 6888"; + } + } + description + "Indicates the type of port allocation."; + } + + leaf mapping-type { + if-feature "napt44 or nat64"; + type enumeration { + enum "eim" { + description + "endpoint-independent-mapping."; + reference + "Section 4 of RFC 4787."; + } + + enum "adm" { + description + "address-dependent-mapping."; + reference + "Section 4 of RFC 4787."; + } + + enum "edm" { + description + "address-and-port-dependent-mapping."; + reference + "Section 4 of RFC 4787."; + } + } + description + "Indicates the type of a NAT mapping."; + } + + leaf filtering-type { + if-feature "napt44 or nat64"; + type enumeration { + enum "eif" { + description + "endpoint-independent-filtering."; + reference + "Section 5 of RFC 4787."; + } + + enum "adf" { + description + "address-dependent-filtering."; + reference + "Section 5 of RFC 4787."; + } + + enum "edf" { + description + "address-and-port-dependent-filtering"; + reference + "Section 5 of RFC 4787."; + } + } + description + "Indicates the type of a NAT filtering."; + } + + leaf fragment-behavior { + if-feature "napt44 or nat64"; + type enumeration { + enum "drop-all" { + description + "All received fragments are dropped."; + } + + enum "in-order" { + description + "Translate fragments only if they are received + in order."; + } + + enum "out-of-order" { + description + "Translate a fragment even if it is received out + of order. + + This behavior is recommended."; + reference + "REQ-14 of RFC 4787"; + } + } + description + "The fragment behavior instructs the NAT about the + behavior to follow to translate fragments received + on the external interface of the NAT."; + } + + list port-quota { + if-feature "napt44 or nat64"; + key quota-type; + description + "Configures a port quota to be assigned per subscriber. + It corresponds to the maximum number of ports to be + used by a subscriber."; + + leaf port-limit { + type uint16; + description + "Configures a port quota to be assigned per subscriber. + It corresponds to the maximum number of ports to be + used by a subscriber."; + reference + "REQ-4 of RFC 6888."; + } + + leaf quota-type { + type uint8; + description + "Indicates whether the port quota applies to + all protocols (0) or to a specific protocol."; + } + } + + container port-set { + + when "../port-allocation-type = 'port-range-allocation'"; + + if-feature "napt44 or nat64"; + description + "Manages port-set assignments."; + + leaf port-set-size { + type uint16; + // TODO(HC2VPP-328) + // mandatory true; + description + "Indicates the size of assigned port sets."; + } + + leaf port-set-timeout { + type uint32; + units "seconds"; + description + "inactivity timeout for port sets."; + } + } + + container timers { + if-feature "napt44 or nat64"; + description + "Configure values of various timeouts."; + + leaf udp-timeout { + type uint32; + units "seconds"; + default 300; + description + "UDP inactivity timeout. That is the time a mapping + will stay active without packets traversing the NAT."; + reference + "RFC 4787: Network Address Translation (NAT) + Behavioral Requirements for Unicast UDP"; + } + + leaf tcp-idle-timeout { + type uint32; + units "seconds"; + default 7440; + description + "TCP Idle timeout should be 2 hours and 4 minutes."; + reference + "RFC 5382: NAT Behavioral Requirements for TCP"; + } + + leaf tcp-trans-open-timeout { + type uint32; + units "seconds"; + default 240; + description + "The value of the transitory open connection + idle-timeout. + + A NAT should provide different configurable + parameters for configuring the open and + closing idle timeouts. + + To accommodate deployments that consider + a partially open timeout of 4 minutes as being + excessive from a security standpoint, a NAT may + allow the configured timeout to be less than + 4 minutes. + + However, a minimum default transitory connection + idle-timeout of 4 minutes is recommended."; + reference + "Section 2.1 of RFC 7857."; + } + + leaf tcp-trans-close-timeout { + type uint32; + units "seconds"; + default 240; + description + "The value of the transitory close connection + idle-timeout. + + A NAT should provide different configurable + parameters for configuring the open and + closing idle timeouts."; + reference + "Section 2.1 of RFC 7857."; + } + + leaf tcp-in-syn-timeout { + type uint32; + units "seconds"; + default 6; + description + "A NAT must not respond to an unsolicited + inbound SYN packet for at least 6 seconds + after the packet is received. If during + this interval the NAT receives and translates + an outbound SYN for the connection the NAT + must silently drop the original unsolicited + inbound SYN packet."; + reference + "RFC 5382 NAT Behavioral Requirements for TCP"; + } + + leaf fragment-min-timeout { + when "../../fragment-behavior='out-of-order'"; + type uint32; + units "seconds"; + default 2; + description + "As long as the NAT has available resources, + the NAT allows the fragments to arrive + over fragment-min-timeout interval. + The default value is inspired from RFC6146."; + } + + leaf icmp-timeout { + type uint32; + units "seconds"; + default 60; + description + "An ICMP Query session timer must not expire + in less than 60 seconds. It is recommended + that the ICMP Query session timer be made + configurable"; + reference + "RFC 5508: NAT Behavioral Requirements for ICMP"; + } + + list per-port-timeout { + key port-number; + description + "Some NATs are configurable with short timeouts + for some ports, e.g., as 10 seconds on + port 53 (DNS) and 123 (NTP) and longer timeouts + on other ports."; + + leaf port-number { + type inet:port-number; + description + "A port number."; + } + + leaf timeout { + type uint32; + units "seconds"; + mandatory true; + description + "Timeout for this port number"; + } + } + + leaf hold-down-timeout { + type uint32; + units "seconds"; + default 120; + description + "Hold down timer. + + Ports in the hold down pool are not reassigned until + hold-down-timeout expires. + + The length of time and the maximum number of ports in + this state must be configurable by the administrator. + + This is necessary in order to prevent collisions + between old and new mappings and sessions. It ensures + that all established sessions are broken instead of + redirected to a different peer."; + reference + "REQ#8 of RFC 6888."; + } + + leaf hold-down-max { + type uint32; + description + "Maximum ports in the Hold down timer pool. + + Ports in the hold down pool are not reassigned + until hold-down-timeout expires. + + The length of time and the maximum + number of ports in this state must be + configurable by the administrator. + This is necessary in order + to prevent collisions between old + and new mappings and sessions. It ensures + that all established sessions are broken + instead of redirected to a different peer."; + reference + "REQ#8 of RFC 6888."; + } + } + + leaf fragments-limit{ + when "../fragment-behavior='out-of-order'"; + type uint32; + description + "Limits the number of out of order fragments that can + be handled."; + reference + "Section 11 of RFC 4787."; + } + + list algs { + key name; + description + "ALG-related features."; + + leaf name { + type string; + description + "The name of the ALG."; + } + + leaf transport-protocol { + type uint32; + description + "The transport protocol used by the ALG + (e.g., TCP, UDP)."; + } + + container dst-transport-port { + uses port-number; + description + "The destination port number(s) used by the ALG. + For example, + - 21 for the FTP ALG + - 53 for the DNS ALG."; + } + + container src-transport-port { + uses port-number; + description + "The source port number(s) used by the ALG."; + } + + leaf status { + type boolean; + description + "Enable/disable the ALG."; + } + } + + leaf all-algs-enable { + type boolean; + description + "Enable/disable all ALGs. + + When specified, this parameter overrides the one + that may be indicated, eventually, by the 'status' + of an individual ALG."; + } + + container notify-pool-usage { + if-feature "basic-nat44 or napt44 or nat64"; + description + "Notification of pool usage when certain criteria + are met."; + + leaf pool-id { + type uint32; + description + "Pool-ID for which the notification criteria + is defined"; + } + + leaf high-threshold { + type percent; + description + "Notification must be generated when the defined high + threshold is reached. + + For example, if a notification is required when the + pool utilization reaches 90%, this configuration + parameter must be set to 90. + + 0% indicates that no high threshold is enabled."; + } + + leaf low-threshold { + type percent; + must ". >= ../high-threshold" { + error-message + "The upper port number must be greater than or + equal to lower port number."; + } + description + "Notification must be generated when the defined low + threshold is reached. + + For example, if a notification is required when the + pool utilization reaches below 10%, this + configuration parameter must be set to 10"; + } + + leaf notify-interval { + type uint32 { + range "1 .. 3600"; + } + units "seconds"; + default '20'; + description + "Minimum number of seconds between successive + notifications for this pool."; + + reference + "RFC 7659: Definitions of Managed Objects for + Network Address Translators (NATs)"; + } + } + + container external-realm { + description + "Identifies the external realm of the NAT instance."; + + choice realm-type { + description + "Can be an interface, VRF instance, etc."; + + case interface { + description + "External interface."; + + leaf external-interface { + type if:interface-ref; + description + "Name of the external interface."; + } + } + } + } + } + + container mapping-limits { + if-feature "napt44 or nat64"; + description + "Information about the configuration parameters that + limits the mappings based upon various criteria."; + + leaf limit-subscribers { + type uint32; + description + "Maximum number of subscribers that can be serviced + by a NAT instance. + + A subscriber is identified by a given prefix."; + reference + "RFC 7659: Definitions of Managed Objects for + Network Address Translators (NATs)"; + } + + leaf limit-address-mappings { + type uint32; + description + "Maximum number of address mappings that can be + handled by a NAT instance. + + When this limit is reached, packets that would + normally trigger translation, will be dropped."; + reference + "RFC 7659: Definitions of Managed Objects + for Network Address Translators + (NATs)"; + } + + leaf limit-port-mappings { + type uint32; + description + "Maximum number of port mappings that can be handled + by a NAT instance. + + When this limit is reached, packets that would + normally trigger translation, will be dropped."; + reference + "RFC 7659: Definitions of Managed Objects for + Network Address Translators (NATs)"; + } + + list limit-per-protocol { + if-feature "napt44 or nat64 or dst-nat"; + key protocol-id; + + description + "Configure limits per transport protocol"; + + leaf protocol-id { + type uint8; + mandatory true; + description + "Upper-layer protocol associated with this mapping. + + Values are taken from the IANA protocol registry: + https://www.iana.org/assignments/protocol-numbers/ + protocol-numbers.xhtml + + For example, this field contains 6 (TCP) for a TCP + mapping or 17 (UDP) for a UDP mapping."; + } + + leaf limit { + type uint32; + description + "Maximum number of protocol-specific NAT mappings + per instance."; + } + } + } + + container connection-limits { + if-feature "basic-nat44 or napt44 or nat64"; + description + "Information about the configuration parameters that + rate limit the translation based upon various criteria."; + + leaf limit-per-subscriber { + type uint32; + units "bits/second"; + description + "Rate-limit the number of new mappings and sessions + per subscriber."; + } + + leaf limit-per-instance { + type uint32; + units "bits/second"; + // TODO(HC2VPP-328) + // mandatory true; + description + "Rate-limit the number of new mappings and sessions + per instance."; + } + + list limit-per-protocol { + if-feature "napt44 or nat64"; + key protocol-id; + description + "Configure limits per transport protocol"; + + leaf protocol-id { + type uint8; + mandatory true; + description + "Upper-layer protocol associated with this mapping. + + Values are taken from the IANA protocol registry: + https://www.iana.org/assignments/protocol-numbers/ + protocol-numbers.xhtml + + For example, this field contains 6 (TCP) for a TCP + mapping or 17 (UDP) for a UDP mapping."; + } + + leaf limit { + type uint32; + description + "Rate-limit the number of protocol-specific mappings + and sessions per instance."; + } + } + } + + container notification-limits { + description "Sets notification limits."; + + leaf notify-interval { + if-feature "basic-nat44 or napt44 or nat64"; + type uint32 { + range "1 .. 3600"; + } + units "seconds"; + default '10'; + description + "Minimum number of seconds between successive + notifications for this NAT instance."; + reference + "RFC 7659: Definitions of Managed Objects + for Network Address Translators (NATs)"; + } + + leaf notify-addresses-usage { + if-feature "basic-nat44 or napt44 or nat64"; + type percent; + description + "Notification of address mappings usage over + the whole NAT instance. + + Notification must be generated when the defined + threshold is reached. + + For example, if a notification is required when + the address mappings utilization reaches 90%, + this configuration parameter must be set + to 90."; + } + + leaf notify-ports-usage { + if-feature "napt44 or nat64"; + type percent; + description + "Notification of port mappings usage over the + whole NAT instance. + + Notification must be generated when the defined + threshold is reached. + + For example, if a notification is required when + the port mappings utilization reaches 90%, this + configuration parameter must be set to 90."; + } + + leaf notify-subscribers-limit { + if-feature "basic-nat44 or napt44 or nat64"; + type uint32; + description + "Notification of active subscribers per NAT + instance. + + Notification must be generated when the defined + threshold is reached."; + } + } + + leaf logging-enable { + if-feature "basic-nat44 or napt44 or nat64"; + type boolean; + description + "Enable logging features."; + reference + "Section 2.3 of RFC 6908 and REQ-12 of RFC 6888."; + } + + container mapping-table { + if-feature "basic-nat44 or napt44 " + + "or nat64 or clat or dst-nat"; + description + "NAT mapping table. Applicable for functions which maintain + static and/or dynamic mappings, such as NAT44, Destination + NAT, NAT64, or CLAT."; + + list mapping-entry { + key "index"; + description "NAT mapping entry."; + uses mapping-entry; + } + } + + container statistics { + config false; + + description + "Statistics related to the NAT instance."; + + leaf discontinuity-time { + type yang:date-and-time; + mandatory true; + description + "The time on the most recent occasion at which the NAT + instance suffered a discontinuity. This must be + initialized when the NAT instance is configured + or rebooted."; + } + + container traffic-statistics { + description + "Generic traffic statistics."; + + leaf sent-packets { + type yang:zero-based-counter64; + description + "Number of packets sent."; + } + + leaf sent-bytes { + type yang:zero-based-counter64; + units 'bytes'; + description + "Counter for sent traffic in bytes."; + } + + leaf rcvd-packets { + type yang:zero-based-counter64; + description + "Number of received packets."; + } + + leaf rcvd-bytes { + type yang:zero-based-counter64; + units 'bytes'; + description + "Counter for received traffic in bytes."; + } + + leaf dropped-packets { + type yang:zero-based-counter64; + description + "Number of dropped packets."; + } + + leaf dropped-bytes { + type yang:zero-based-counter64; + units 'bytes'; + description + "Counter for dropped traffic in bytes."; + } + + leaf dropped-fragments { + if-feature "napt44 or nat64"; + type yang:zero-based-counter64; + description + "Number of dropped fragments on the external realm."; + } + + leaf dropped-address-limit-packets { + if-feature "basic-nat44 or napt44 or nat64"; + type yang:zero-based-counter64; + description + "Number of dropped packets because an address limit + is reached."; + } + + leaf dropped-address-limit-bytes { + if-feature "basic-nat44 or napt44 or nat64"; + type yang:zero-based-counter64; + units 'bytes'; + description + "Counter of dropped packets because an address limit + is reached, in bytes."; + } + + leaf dropped-address-packets { + if-feature "basic-nat44 or napt44 or nat64"; + type yang:zero-based-counter64; + description + "Number of dropped packets because no address is + available for allocation."; + } + + leaf dropped-address-bytes { + if-feature "basic-nat44 or napt44 or nat64"; + type yang:zero-based-counter64; + units 'bytes'; + description + "Counter of dropped packets because no address is + available for allocation, in bytes."; + } + + leaf dropped-port-limit-packets { + if-feature "napt44 or nat64"; + type yang:zero-based-counter64; + description + "Number of dropped packets because a port limit + is reached."; + } + + leaf dropped-port-limit-bytes { + if-feature "napt44 or nat64"; + type yang:zero-based-counter64; + units 'bytes'; + description + "Counter of dropped packets because a port limit + is reached, in bytes."; + } + + leaf dropped-port-packets { + if-feature "napt44 or nat64"; + type yang:zero-based-counter64; + description + "Number of dropped packets because no port is + available for allocation."; + } + + leaf dropped-port-bytes { + if-feature "napt44 or nat64"; + type yang:zero-based-counter64; + units 'bytes'; + description + "Counter of dropped packets because no port is + available for allocation, in bytes."; + } + + leaf dropped-subscriber-limit-packets { + if-feature "basic-nat44 or napt44 or nat64"; + type yang:zero-based-counter64; + description + "Number of dropped packets because the subscriber + limit per instance is reached."; + } + + leaf dropped-subscriber-limit-bytes { + if-feature "basic-nat44 or napt44 or nat64"; + type yang:zero-based-counter64; + units 'bytes'; + description + "Counter of dropped packets because the subscriber + limit per instance is reached, in bytes."; + } + } + + container mappings-statistics { + description + "Mappings statistics."; + + leaf total-active-subscribers { + if-feature "basic-nat44 or napt44 or nat64"; + type yang:gauge32; + description + "Total number of active subscribers (that is, + subscribers for which the NAT maintains active + mappings. + + A subscriber is identified by a subnet, + subscriber-mask, etc."; + } + + leaf total-address-mappings { + if-feature "basic-nat44 or napt44 " + + "or nat64 or clat or dst-nat"; + type yang:gauge32; + description + "Total number of address mappings present at a given + time. It includes both static and dynamic mappings."; + reference + "Section 3.3.8 of RFC 7659"; + } + + leaf total-port-mappings { + if-feature "napt44 or nat64"; + type yang:gauge32; + description + "Total number of NAT port mappings present at + a given time. It includes both static and dynamic + mappings."; + reference + "Section 3.3.9 of RFC 7659"; + } + + list total-per-protocol { + if-feature "napt44 or nat64"; + key protocol-id; + description + "Total mappings for each enabled/supported protocol."; + + leaf protocol-id { + type uint8; + mandatory true; + description + "Upper-layer protocol associated with this mapping. + For example, this field contains 6 (TCP) for a TCP + mapping or 17 (UDP) for a UDP mapping."; + } + + leaf total { + type yang:gauge32; + description + "Total number of a protocol-specific mappings present + at a given time. The protocol is identified by + protocol-id."; + } + } + } + + container pools-stats { + if-feature "basic-nat44 or napt44 or nat64"; + description + "Statistics related to address/prefix pools + usage"; + + leaf addresses-allocated { + type yang:gauge32; + description + "Number of all allocated addresses."; + } + + leaf addresses-free { + type yang:gauge32; + description + "Number of unallocated addresses of all pools at + a given time. The sum of unallocated and allocated + addresses is the total number of addresses of + the pools."; + } + + container ports-stats { + if-feature "napt44 or nat64"; + + description + "Statistics related to port numbers usage."; + + leaf ports-allocated { + type yang:gauge32; + description + "Number of allocated ports from all pools."; + } + + leaf ports-free { + type yang:gauge32; + description + "Number of unallocated addresses from all pools."; + } + } + + list per-pool-stats { + if-feature "basic-nat44 or napt44 or nat64"; + key "pool-id"; + description + "Statistics related to address/prefix pool usage"; + + leaf pool-id { + type uint32; + description + "Unique Identifier that represents a pool of + addresses/prefixes."; + } + + leaf discontinuity-time { + type yang:date-and-time; + mandatory true; + description + "The time on the most recent occasion at which this + pool counters suffered a discontinuity. This must + be initialized when the address pool is + configured."; + } + + container pool-stats { + description + "Statistics related to address/prefix pool usage"; + + leaf addresses-allocated { + type yang:gauge32; + description + "Number of allocated addresses from this pool."; + } + + leaf addresses-free { + type yang:gauge32; + description + "Number of unallocated addresses in this pool."; + } + } + + container port-stats { + if-feature "napt44 or nat64"; + description + "Statistics related to port numbers usage."; + + leaf ports-allocated { + type yang:gauge32; + description + "Number of allocated ports from this pool."; + } + + leaf ports-free { + type yang:gauge32; + description + "Number of unallocated addresses from this pool."; + } + } + } + } + } + } + } + } + + /* + * Notifications + */ + + notification nat-pool-event { + if-feature "basic-nat44 or napt44 or nat64"; + description + "Notifications must be generated when the defined high/low + threshold is reached. Related configuration parameters + must be provided to trigger the notifications."; + + leaf id { + type leafref { + path "/nat/instances/instance/id"; + } + mandatory true; + description + "NAT instance Identifier."; + } + + leaf policy-id { + type leafref { + path "/nat/instances/instance/policy/id"; + } + + description + "Policy Identifier."; + } + + leaf pool-id { + type leafref { + path "/nat/instances/instance/policy/" + + "external-ip-address-pool/pool-id"; + } + mandatory true; + description + "Pool Identifier."; + } + + leaf notify-pool-threshold { + type percent; + mandatory true; + description + "A threshold (high-threshold or low-threshold) has + been fired."; + } + } + + notification nat-instance-event { + if-feature "basic-nat44 or napt44 or nat64"; + description + "Notifications must be generated when notify-addresses-usage + and/or notify-ports-usage threshold are reached."; + + leaf id { + type leafref { + path "/nat/instances/instance/id"; + } + mandatory true; + description + "NAT instance Identifier."; + } + + leaf notify-subscribers-threshold { + type uint32; + description + "The notify-subscribers-limit threshold has been fired."; + } + + leaf notify-addresses-threshold { + type percent; + description + "The notify-addresses-usage threshold has been fired."; + } + + leaf notify-ports-threshold { + type percent; + description + "The notify-ports-usage threshold has been fired."; + } + } +} diff --git a/nat/nat-api/src/main/yang/vpp-nat@2017-08-04.yang b/nat/nat-api/src/main/yang/vpp-nat@2018-05-10.yang index 6f4215a21..375d89936 100644 --- a/nat/nat-api/src/main/yang/vpp-nat@2017-08-04.yang +++ b/nat/nat-api/src/main/yang/vpp-nat@2018-05-10.yang @@ -21,7 +21,7 @@ module vpp-nat { "This module contains a collection of YANG definitions that extend ietf-nat module with VPP specific features provided by the VPP NAT plugin. - Copyright (c) 2017 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. @@ -35,6 +35,10 @@ module vpp-nat { See the License for the specific language governing permissions and limitations under the License."; + revision "2018-05-10" { + description "Adapt to ietf-nat@2018-02-23."; + } + revision "2017-08-04" { description "Initial revision of vpp-nat model."; } @@ -56,14 +60,8 @@ module vpp-nat { } } - augment /nat:nat-config/nat:nat-instances/nat:nat-instance/nat:external-ip-address-pool { - ext:augment-identifier "external-ip-address-pool-config-augmentation"; - - uses external-ip-address-pool-vpp-attributes; - } - - augment /nat:nat-state/nat:nat-instances/nat:nat-instance/nat:nat-current-config/nat:external-ip-address-pool { - ext:augment-identifier "external-ip-address-pool-state-augmentation"; + augment /nat:nat/nat:instances/nat:instance/nat:policy/nat:external-ip-address-pool { + ext:augment-identifier "external-ip-address-pool-augmentation"; uses external-ip-address-pool-vpp-attributes; } 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> NAT_ID = InstanceIdentifier.create(Nat.class); + InstanceIdentifier<Instances> NAT_INSTANCES_ID = NAT_ID.child(Instances.class); + InstanceIdentifier<Instance> NAT_INSTANCE_ID = NAT_INSTANCES_ID.child(Instance.class); + InstanceIdentifier<MappingTable> MAPPING_TABLE_ID = NAT_INSTANCE_ID.child(MappingTable.class); + InstanceIdentifier<MappingEntry> MAPPING_ENTRY_ID = MAPPING_TABLE_ID.child(MappingEntry.class); + InstanceIdentifier<Policy> POLICY_ID = NAT_INSTANCE_ID.child(Policy.class); + InstanceIdentifier<ExternalIpAddressPool> ADDRESS_POOL_ID = POLICY_ID.child(ExternalIpAddressPool.class); + InstanceIdentifier<Nat64Prefixes> 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<ExternalIpAddressPool> getCfgId(final @Nonnull InstanceIdentifier<ExternalIpAddressPool> 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<ExternalIpAddressPoolKey> getAllIds(@Nonnull final InstanceIdentifier<ExternalIpAddressPool> 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<? extends DataObject> builder, @Nonnull final List<ExternalIpAddressPool> readData) { - ((NatCurrentConfigBuilder) builder).setExternalIpAddressPool(readData); + ((PolicyBuilder) builder).setExternalIpAddressPool(readData); } @Override @@ -182,6 +176,6 @@ final class ExternalIpPoolCustomizer implements @Nonnull final InstanceIdentifier<ExternalIpAddressPool> 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<MappingEntry, MappingEntryKey, MappingEntryBuilder> { + InitializingListReaderCustomizer<MappingEntry, MappingEntryKey, MappingEntryBuilder> { 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<Nat44StaticMappingDetails> 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<MappingEntryKey> getAllIds(@Nonnull final InstanceIdentifier<MappingEntry> 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<MappingEntryKey> entryKeys = @@ -199,23 +184,11 @@ final class MappingEntryCustomizer implements Ipv4Translator, Ipv6Translator, } @Override - public Initialized<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntry> init( + public Initialized<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.nat.instances.instance.mapping.table.MappingEntry> init( @Nonnull final InstanceIdentifier<MappingEntry> 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<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntry> getCfgId( - final @Nonnull InstanceIdentifier<MappingEntry> 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<Nat64PrefixesKey> getAllIds(@Nonnull final InstanceIdentifier<Nat64Prefixes> 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<Long, Nat64PrefixDetails> 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<? extends DataObject> builder, @Nonnull final List<Nat64Prefixes> 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<Long, Nat64PrefixDetails> 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<Map<Long, Nat64PrefixDetails>, 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<NatInstance, NatInstanceKey, NatInstanceBuilder> { + implements InitializingListReaderCustomizer<Instance, InstanceKey, InstanceBuilder> { 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<Nat44StaticMappingDetailsReplyDump, Void> nat44DumpManager; private final DumpCacheManager<Nat64BibDetailsReplyDump, Void> nat64DumpManager; @@ -59,26 +58,26 @@ final class NatInstanceCustomizer @Nonnull @Override - public NatInstanceBuilder getBuilder(@Nonnull final InstanceIdentifier<NatInstance> id) { - return new NatInstanceBuilder(); + public InstanceBuilder getBuilder(@Nonnull final InstanceIdentifier<Instance> id) { + return new InstanceBuilder(); } @Override - public void readCurrentAttributes(@Nonnull final InstanceIdentifier<NatInstance> id, - @Nonnull final NatInstanceBuilder builder, @Nonnull final ReadContext ctx) + public void readCurrentAttributes(@Nonnull final InstanceIdentifier<Instance> 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<NatInstanceKey> getAllIds(@Nonnull final InstanceIdentifier<NatInstance> id, + public List<InstanceKey> getAllIds(@Nonnull final InstanceIdentifier<Instance> 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<NatInstanceKey> vrfIds = Stream.concat( + final List<InstanceKey> 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<? extends DataObject> builder, @Nonnull final List<NatInstance> readData) { - ((NatInstancesBuilder) builder).setNatInstance(readData); + public void merge(@Nonnull final Builder<? extends DataObject> builder, @Nonnull final List<Instance> readData) { + ((InstancesBuilder) builder).setInstance(readData); } @Override - public Initialized<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.NatInstance> init( - @Nonnull final InstanceIdentifier<NatInstance> id, - @Nonnull final NatInstance readValue, + public Initialized<Instance> init( + @Nonnull final InstanceIdentifier<Instance> 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<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.NatInstance> getCfgId( - @Nonnull final InstanceIdentifier<NatInstance> 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<NatState> NAT_OPER_ID = InstanceIdentifier.create(NatState.class); - private static final InstanceIdentifier<NatInstances> NAT_INSTANCES_ID = NAT_OPER_ID.child(NatInstances.class); - private static final InstanceIdentifier<NatInstance> NAT_INSTANCE_ID = NAT_INSTANCES_ID.child(NatInstance.class); - private static final InstanceIdentifier<NatCurrentConfig> CURRENT_CONFIG = - NAT_INSTANCE_ID.child(NatCurrentConfig.class); - private static final InstanceIdentifier<MappingTable> MAP_TABLE_ID = NAT_INSTANCE_ID.child(MappingTable.class); - private static final InstanceIdentifier<MappingEntry> MAP_ENTRY_ID = MAP_TABLE_ID.child(MappingEntry.class); - private final FutureJVppNatFacade jvppNat; private final MappingEntryContext mappingEntryContext; private final DumpCacheManager<Nat44StaticMappingDetailsReplyDump, Void> mapEntryNat44DumpMgr; private final DumpCacheManager<Nat64BibDetailsReplyDump, Void> 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<MappingEntry> 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<MappingEntry> 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<Long> 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<ExternalIpA public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<ExternalIpAddressPool> 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<ExternalIpA @Nonnull final ExternalIpAddressPool addressPool, final boolean isAdd) throws WriteFailedException { boolean isNat64 = false; - final ExternalIpAddressPoolConfigAugmentation augmentation = - addressPool.getAugmentation(ExternalIpAddressPoolConfigAugmentation.class); + final ExternalIpAddressPoolAugmentation augmentation = + addressPool.getAugmentation(ExternalIpAddressPoolAugmentation.class); if (augmentation != null) { isNat64 = Nat64.equals(augmentation.getPoolType()); } diff --git a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizer.java b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizer.java index 97a41c0ca..6aca1af9e 100644 --- a/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizer.java +++ b/nat/nat2vpp/src/main/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizer.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. @@ -35,12 +35,10 @@ 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.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Address; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.PortNumber; -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.mapping.table.MappingEntry; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntryKey; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.port.number.PortType; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.port.number.port.type.SinglePortNumber; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.PortNumber; +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.mapping.table.MappingEntry; +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.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -65,9 +63,9 @@ final class MappingEntryCustomizer implements ListWriterCustomizer<MappingEntry, throws WriteFailedException { // Only static mapping supported by SNAT for now checkArgument(dataAfter.getType() == - 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, "Only static NAT entries are supported currently. Trying to write: %s entry", dataAfter.getType()); - final Long natInstanceId = id.firstKeyOf(NatInstance.class).getId(); + final Long natInstanceId = id.firstKeyOf(Instance.class).getId(); final Long mappingEntryId = id.firstKeyOf(MappingEntry.class).getIndex(); LOG.debug("Writing mapping entry: {} for nat-instance(vrf): {}", natInstanceId, mappingEntryId); @@ -130,7 +128,7 @@ final class MappingEntryCustomizer implements ListWriterCustomizer<MappingEntry, public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<MappingEntry> 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<MappingEntry, request.protocol = protocol.byteValue(); } - Optional<Short> internalPortNumber = getPortNumber(id, mappingEntry, - (entry) -> Optional.fromNullable(entry.getInternalSrcPort()).transform(PortNumber::getPortType)); - Optional<Short> 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<MappingEntry, request.proto = protocol.byteValue(); } - Optional<Short> internalPortNumber = getPortNumber(id, mappingEntry, - (entry) -> Optional.fromNullable(entry.getInternalSrcPort()).transform(PortNumber::getPortType)); - Optional<Short> 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<Short> getPortNumber(final InstanceIdentifier<MappingEntry> 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<MappingEntry> 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<PortType> 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<Nat64Prefixes> 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<DestinationIpv4Prefix> 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<NatInstance, NatInstanceKey> { +final class NatInstaceCustomizer implements ListWriterCustomizer<Instance, InstanceKey> { private static final Logger LOG = LoggerFactory.getLogger(NatInstaceCustomizer.class); @Override - public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<NatInstance> id, - @Nonnull final NatInstance dataAfter, @Nonnull final WriteContext writeContext) + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Instance> 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<NatInstance> id, - @Nonnull final NatInstance dataBefore, @Nonnull final WriteContext writeContext) + public void deleteCurrentAttributes(@Nonnull final InstanceIdentifier<Instance> 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<NatConfig> NAT_CFG_ID = InstanceIdentifier.create(NatConfig.class); - private static final InstanceIdentifier<NatInstance> NAT_INSTANCE_ID = - NAT_CFG_ID.child(NatInstances.class).child(NatInstance.class); - private static final InstanceIdentifier<MappingEntry> 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<Policy, PolicyKey> { + + private static final Logger LOG = LoggerFactory.getLogger(PolicyCustomizer.class); + + @Override + public void writeCurrentAttributes(@Nonnull final InstanceIdentifier<Policy> 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<Policy> id, + @Nonnull final Policy dataBefore, @Nonnull final WriteContext writeContext) + throws WriteFailedException { + LOG.trace("Deleting NAT policy: {}", id); + } +} diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/NatTestSchemaContext.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/NatTestSchemaContext.java index 054bc8cee..01e66e525 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/NatTestSchemaContext.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/NatTestSchemaContext.java @@ -32,9 +32,9 @@ public interface NatTestSchemaContext { .getInstance(), org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.$YangModuleInfoImpl .getInstance(), - org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.$YangModuleInfoImpl + org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.$YangModuleInfoImpl .getInstance(), - org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev170804.$YangModuleInfoImpl + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev180510.$YangModuleInfoImpl .getInstance(), org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.nat.rev170816.$YangModuleInfoImpl .getInstance())); diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/ExternalIpPoolCustomizerTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/ExternalIpPoolCustomizerTest.java index 521320591..f9e27e520 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/ExternalIpPoolCustomizerTest.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/ExternalIpPoolCustomizerTest.java @@ -16,14 +16,15 @@ package io.fd.hc2vpp.nat.read; +import static io.fd.hc2vpp.nat.NatIds.NAT_INSTANCES_ID; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsEmptyCollection.empty; import static org.hamcrest.core.IsCollectionContaining.hasItems; import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.when; -import static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev170804.NatPoolType.Nat44; -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.Nat44; +import static org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.nat.rev180510.NatPoolType.Nat64; import io.fd.hc2vpp.common.test.read.ListReaderCustomizerTest; import io.fd.honeycomb.translate.spi.read.ReaderCustomizer; @@ -37,37 +38,36 @@ import java.util.List; import java.util.stream.LongStream; import org.junit.Test; import org.mockito.Mock; -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.NatInstances; -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.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.opendaylight.params.xml.ns.yang.vpp.nat.rev170804.ExternalIpAddressPoolStateAugmentation; +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.Policy; +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.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.yangtools.yang.binding.InstanceIdentifier; public class ExternalIpPoolCustomizerTest extends ListReaderCustomizerTest<ExternalIpAddressPool, ExternalIpAddressPoolKey, ExternalIpAddressPoolBuilder> { - private static final InstanceIdentifier<NatCurrentConfig> NAT_CONFIG_ID = - InstanceIdentifier.create(NatInstances.class) - .child(NatInstance.class, new NatInstanceKey(NatInstanceCustomizer.DEFAULT_VRF_ID)) - .child(NatCurrentConfig.class); + private static final InstanceIdentifier<Policy> POLICY_ID = + NAT_INSTANCES_ID.child(Instance.class, new InstanceKey(NatInstanceCustomizer.DEFAULT_VRF_ID)) + .child(Policy.class, new PolicyKey(0L)); private static final InstanceIdentifier<ExternalIpAddressPool> NAT_DEFAULT_POOL_WILDCARDED_ID = - NAT_CONFIG_ID.child(ExternalIpAddressPool.class); + POLICY_ID.child(ExternalIpAddressPool.class); private static final InstanceIdentifier<ExternalIpAddressPool> NAT_NON_DEFAULT_POOL_WILDCARDED_ID = - InstanceIdentifier.create(NatInstances.class).child(NatInstance.class, new NatInstanceKey(7L)) - .child(NatCurrentConfig.class).child(ExternalIpAddressPool.class); + NAT_INSTANCES_ID.child(Instance.class, new InstanceKey(7L)) + .child(Policy.class).child(ExternalIpAddressPool.class); @Mock private FutureJVppNatFacade jvppNat; public ExternalIpPoolCustomizerTest() { - super(ExternalIpAddressPool.class, NatCurrentConfigBuilder.class); + super(ExternalIpAddressPool.class, PolicyBuilder.class); } @Override @@ -84,7 +84,7 @@ public class ExternalIpPoolCustomizerTest assertEquals("192.168.44.3/32", builder.getExternalIpPool().getValue()); assertEquals(poolId, builder.getPoolId().longValue()); - assertEquals(Nat44, builder.getAugmentation(ExternalIpAddressPoolStateAugmentation.class).getPoolType()); + assertEquals(Nat44, builder.getAugmentation(ExternalIpAddressPoolAugmentation.class).getPoolType()); } @Test @@ -98,7 +98,7 @@ public class ExternalIpPoolCustomizerTest assertEquals("192.168.64.3/32", builder.getExternalIpPool().getValue()); assertEquals(poolId, builder.getPoolId().longValue()); - assertEquals(Nat64, builder.getAugmentation(ExternalIpAddressPoolStateAugmentation.class).getPoolType()); + assertEquals(Nat64, builder.getAugmentation(ExternalIpAddressPoolAugmentation.class).getPoolType()); } @Test @@ -112,7 +112,7 @@ public class ExternalIpPoolCustomizerTest assertEquals("192.168.64.3/32", builder.getExternalIpPool().getValue()); assertEquals(poolId, builder.getPoolId().longValue()); - assertEquals(Nat64, builder.getAugmentation(ExternalIpAddressPoolStateAugmentation.class).getPoolType()); + assertEquals(Nat64, builder.getAugmentation(ExternalIpAddressPoolAugmentation.class).getPoolType()); } @Test @@ -161,7 +161,7 @@ public class ExternalIpPoolCustomizerTest } private static InstanceIdentifier<ExternalIpAddressPool> getId(final long id) { - return NAT_CONFIG_ID.child(ExternalIpAddressPool.class, new ExternalIpAddressPoolKey(id)); + return POLICY_ID.child(ExternalIpAddressPool.class, new ExternalIpAddressPoolKey(id)); } private static Nat44AddressDetailsReplyDump dumpReplyNat44Empty() { 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 576324757..7f38dc9b9 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 @@ -36,15 +36,14 @@ 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; -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.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.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.SinglePortNumber; +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.InstanceKey; +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.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.yang.binding.InstanceIdentifier; public class MappingEntryCustomizerTest @@ -71,12 +70,12 @@ public class MappingEntryCustomizerTest @Override protected void setUp() throws Exception { - mappingEntryId = InstanceIdentifier.create(NatInstances.class) - .child(NatInstance.class, new NatInstanceKey(NatInstanceCustomizer.DEFAULT_VRF_ID)) + mappingEntryId = InstanceIdentifier.create(Instances.class) + .child(Instance.class, new InstanceKey(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)) + mappingEntryWildcarded = InstanceIdentifier.create(Instances.class) + .child(Instance.class, new InstanceKey(NatInstanceCustomizer.DEFAULT_VRF_ID)) .child(MappingTable.class) .child(MappingEntry.class); nat44DumpManager = new DumpCacheManager.DumpCacheManagerBuilder<Nat44StaticMappingDetailsReplyDump, Void>() @@ -100,13 +99,9 @@ public class MappingEntryCustomizerTest assertEquals(NAT_MAPPING_ID, builder.getIndex().longValue()); assertEquals("192.168.3.8", builder.getExternalSrcAddress().getValue()); - assertEquals(6874, - ((SinglePortNumber) builder.getExternalSrcPort().getPortType()).getSinglePortNumber().getValue() - .intValue()); + assertEquals(6874, builder.getExternalSrcPort().getStartPortNumber().getValue().intValue()); assertArrayEquals("192.168.2.2".toCharArray(), builder.getInternalSrcAddress().getValue()); - assertEquals(1274, - ((SinglePortNumber) builder.getInternalSrcPort().getPortType()).getSinglePortNumber().getValue() - .intValue()); + assertEquals(1274, builder.getInternalSrcPort().getStartPortNumber().getValue().intValue()); } @Test @@ -118,12 +113,8 @@ public class MappingEntryCustomizerTest final MappingEntryBuilder builder = new MappingEntryBuilder(); getCustomizer().readCurrentAttributes(mappingEntryId, builder, ctx); - assertEquals(65535, - ((SinglePortNumber) builder.getExternalSrcPort().getPortType()).getSinglePortNumber().getValue() - .intValue()); - assertEquals(60000, - ((SinglePortNumber) builder.getInternalSrcPort().getPortType()).getSinglePortNumber().getValue() - .intValue()); + assertEquals(65535, builder.getExternalSrcPort().getStartPortNumber().getValue().intValue()); + assertEquals(60000, builder.getInternalSrcPort().getStartPortNumber().getValue().intValue()); } @Test @@ -138,13 +129,9 @@ public class MappingEntryCustomizerTest assertEquals(NAT_MAPPING_ID, builder.getIndex().longValue()); assertEquals("192.168.64.3", builder.getExternalSrcAddress().getValue()); - assertEquals(6874, - ((SinglePortNumber) builder.getExternalSrcPort().getPortType()).getSinglePortNumber().getValue() - .intValue()); + assertEquals(6874, builder.getExternalSrcPort().getStartPortNumber().getValue().intValue()); assertArrayEquals("2001:db8:85a3::8a2e:370:7303".toCharArray(), builder.getInternalSrcAddress().getValue()); - assertEquals(1274, - ((SinglePortNumber) builder.getInternalSrcPort().getPortType()).getSinglePortNumber().getValue() - .intValue()); + assertEquals(1274, builder.getInternalSrcPort().getStartPortNumber().getValue().intValue()); } @Test @@ -157,12 +144,8 @@ public class MappingEntryCustomizerTest final MappingEntryBuilder builder = new MappingEntryBuilder(); getCustomizer().readCurrentAttributes(mappingEntryId, builder, ctx); - assertEquals(65535, - ((SinglePortNumber) builder.getExternalSrcPort().getPortType()).getSinglePortNumber().getValue() - .intValue()); - assertEquals(60000, - ((SinglePortNumber) builder.getInternalSrcPort().getPortType()).getSinglePortNumber().getValue() - .intValue()); + assertEquals(65535, builder.getExternalSrcPort().getStartPortNumber().getValue().intValue()); + assertEquals(60000, builder.getInternalSrcPort().getStartPortNumber().getValue().intValue()); } @Test diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/Nat64PrefixesCustomizerTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/Nat64PrefixesCustomizerTest.java index bdb1793ff..2aae28a9e 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/Nat64PrefixesCustomizerTest.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/read/Nat64PrefixesCustomizerTest.java @@ -33,14 +33,15 @@ import java.util.List; import org.junit.Test; import org.mockito.Mock; 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.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.NatInstances; -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.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.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.InstanceKey; +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.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.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.yang.binding.InstanceIdentifier; public class Nat64PrefixesCustomizerTest extends ListReaderCustomizerTest<Nat64Prefixes, Nat64PrefixesKey, Nat64PrefixesBuilder> { @@ -49,7 +50,7 @@ public class Nat64PrefixesCustomizerTest extends ListReaderCustomizerTest<Nat64P private FutureJVppNatFacade jvppNat; public Nat64PrefixesCustomizerTest() { - super(Nat64Prefixes.class, NatCurrentConfigBuilder.class); + super(Nat64Prefixes.class, PolicyBuilder.class); } @Override @@ -70,14 +71,7 @@ public class Nat64PrefixesCustomizerTest extends ListReaderCustomizerTest<Nat64P final long vrfId = 0; final List<Nat64PrefixesKey> allIds = getCustomizer().getAllIds(getWildcardedId(vrfId), ctx); assertEquals(1, allIds.size()); - assertEquals(new Nat64PrefixesKey(0L), allIds.get(0)); - } - - @Test - public void testReadNonZeroId() throws ReadFailedException { - final Nat64PrefixesBuilder builder = mock(Nat64PrefixesBuilder.class); - getCustomizer().readCurrentAttributes(getId(0L, 42L), builder, ctx); - verifyZeroInteractions(builder); + assertEquals(new Nat64PrefixesKey(new Ipv6Prefix("64:ff9b::1/96")), allIds.get(0)); } @Test @@ -85,7 +79,7 @@ public class Nat64PrefixesCustomizerTest extends ListReaderCustomizerTest<Nat64P final long vrfId = 123; when(jvppNat.nat64PrefixDump(any())).thenReturn(future(dump())); final Nat64PrefixesBuilder builder = mock(Nat64PrefixesBuilder.class); - getCustomizer().readCurrentAttributes(getId(vrfId, 0L), builder, ctx); + getCustomizer().readCurrentAttributes(getId(vrfId, "::1/128"), builder, ctx); verifyZeroInteractions(builder); } @@ -94,23 +88,22 @@ public class Nat64PrefixesCustomizerTest extends ListReaderCustomizerTest<Nat64P final long vrfId = 1; when(jvppNat.nat64PrefixDump(any())).thenReturn(future(dump())); final Nat64PrefixesBuilder builder = mock(Nat64PrefixesBuilder.class); - getCustomizer().readCurrentAttributes(getId(vrfId, 0L), builder, ctx); - verify(builder).setNat64PrefixId(0L); + getCustomizer().readCurrentAttributes(getId(vrfId, "::1/128"), builder, ctx); verify(builder).setNat64Prefix(new Ipv6Prefix("::1/128")); } private static InstanceIdentifier<Nat64Prefixes> getWildcardedId(final long vrfId) { - return InstanceIdentifier.create(NatInstances.class) - .child(NatInstance.class, new NatInstanceKey(vrfId)) - .child(NatCurrentConfig.class) + return InstanceIdentifier.create(Instances.class) + .child(Instance.class, new InstanceKey(vrfId)) + .child(Policy.class, new PolicyKey(0L)) .child(Nat64Prefixes.class); } - private static InstanceIdentifier<Nat64Prefixes> getId(final long vrfId, final long prefixId) { - return InstanceIdentifier.create(NatInstances.class) - .child(NatInstance.class, new NatInstanceKey(vrfId)) - .child(NatCurrentConfig.class) - .child(Nat64Prefixes.class, new Nat64PrefixesKey(prefixId)); + private static InstanceIdentifier<Nat64Prefixes> getId(final long vrfId, final String prefix) { + return InstanceIdentifier.create(Instances.class) + .child(Instance.class, new InstanceKey(vrfId)) + .child(Policy.class, new PolicyKey(0L)) + .child(Nat64Prefixes.class, new Nat64PrefixesKey(new Ipv6Prefix(prefix))); } private Nat64PrefixDetailsReplyDump dump() { 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 8978fe5ba..5974f4a45 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 @@ -35,28 +35,28 @@ import java.util.Arrays; import java.util.List; 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; -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.Instances; +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.yang.binding.InstanceIdentifier; import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; public class NatInstanceCustomizerTest - extends InitializingListReaderCustomizerTest<NatInstance, NatInstanceKey, NatInstanceBuilder> { + extends InitializingListReaderCustomizerTest<Instance, InstanceKey, InstanceBuilder> { @Mock private EntityDumpExecutor<Nat44StaticMappingDetailsReplyDump, Void> nat44DumpExecutor; @Mock private EntityDumpExecutor<Nat64BibDetailsReplyDump, Void> nat64DumpExecutor; - private KeyedInstanceIdentifier<NatInstance, NatInstanceKey> natInstanceId; - private InstanceIdentifier<NatInstance> natInstanceWildcarded; + private KeyedInstanceIdentifier<Instance, InstanceKey> natInstanceId; + private InstanceIdentifier<Instance> natInstanceWildcarded; private DumpCacheManager<Nat44StaticMappingDetailsReplyDump, Void> mapEntryNat44DumpMgr; private DumpCacheManager<Nat64BibDetailsReplyDump, Void> mapEntryNat64DumpMgr; public NatInstanceCustomizerTest() { - super(NatInstance.class, NatInstancesBuilder.class); + super(Instance.class, InstancesBuilder.class); } @Override @@ -66,10 +66,10 @@ public class NatInstanceCustomizerTest @Override protected void setUp() throws Exception { - natInstanceId = InstanceIdentifier.create(NatInstances.class) - .child(NatInstance.class, new NatInstanceKey(NatInstanceCustomizer.DEFAULT_VRF_ID)); - natInstanceWildcarded = InstanceIdentifier.create(NatInstances.class) - .child(NatInstance.class); + natInstanceId = InstanceIdentifier.create(Instances.class) + .child(Instance.class, new InstanceKey(NatInstanceCustomizer.DEFAULT_VRF_ID)); + natInstanceWildcarded = InstanceIdentifier.create(Instances.class) + .child(Instance.class); mapEntryNat44DumpMgr = new DumpCacheManager.DumpCacheManagerBuilder<Nat44StaticMappingDetailsReplyDump, Void>() .withExecutor(nat44DumpExecutor) .acceptOnly(Nat44StaticMappingDetailsReplyDump.class) @@ -82,7 +82,7 @@ public class NatInstanceCustomizerTest @Test public void testRead() throws ReadFailedException { - final NatInstanceBuilder builder = mock(NatInstanceBuilder.class); + final InstanceBuilder builder = mock(InstanceBuilder.class); getCustomizer().readCurrentAttributes(natInstanceId, builder, ctx); verify(builder).setId(natInstanceId.getKey().getId()); } @@ -91,11 +91,11 @@ public class NatInstanceCustomizerTest public void testReadAll() throws ReadFailedException { when(nat44DumpExecutor.executeDump(natInstanceWildcarded, null)).thenReturn(nat44NonEmptyDump()); when(nat64DumpExecutor.executeDump(natInstanceWildcarded, null)).thenReturn(nat64NonEmptyDump()); - final List<NatInstanceKey> allIds = getCustomizer().getAllIds(natInstanceWildcarded, ctx); + final List<InstanceKey> 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(5L), new NatInstanceKey(6L))); + new InstanceKey(0L), new InstanceKey(1L), new InstanceKey(2L), new InstanceKey(3L), + new InstanceKey(5L), new InstanceKey(6L))); } private static Nat44StaticMappingDetailsReplyDump nat44NonEmptyDump() { 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 cd173fddc..df5912bce 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 @@ -37,9 +37,9 @@ import org.mockito.Mock; 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.MappingTableBuilder; 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.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.config.nat.instances.nat.instance.mapping.table.MappingEntryBuilder; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.nat.config.nat.instances.nat.instance.mapping.table.MappingEntryKey; +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.yang.binding.InstanceIdentifier; @SuppressWarnings("unchecked") @@ -189,7 +189,7 @@ public class MappingEntryContextTest implements Ipv4Translator { private static MappingEntry getEntry(final long id, final String longernalIpv4, final String externalIpv4) { return new MappingEntryBuilder() .setKey(new MappingEntryKey(id)) - .setType(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev150908.MappingEntry.Type.Static) + .setType(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.nat.rev180223.MappingEntry.Type.Static) .setInternalSrcAddress(new IpAddress(new Ipv4Address(longernalIpv4))) .setExternalSrcAddress(new Ipv4Address(externalIpv4)) .build(); diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ExternalIpPoolCustomizerTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ExternalIpPoolCustomizerTest.java index db68ecf6a..294473937 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ExternalIpPoolCustomizerTest.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/ExternalIpPoolCustomizerTest.java @@ -16,6 +16,7 @@ package io.fd.hc2vpp.nat.write; +import static io.fd.hc2vpp.nat.NatIds.NAT_INSTANCES_ID; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -35,12 +36,13 @@ import io.fd.vpp.jvpp.nat.future.FutureJVppNatFacade; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -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.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.NatInstanceKey; -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.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.InstanceKey; +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.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.yangtools.yang.binding.InstanceIdentifier; @RunWith(HoneycombTestRunner.class) @@ -49,11 +51,11 @@ public class ExternalIpPoolCustomizerTest extends WriterCustomizerTest implement private static final long NAT_INSTANCE_ID = 0; private static final long POOL_ID = 22; - private static final InstanceIdentifier<ExternalIpAddressPool> IID = InstanceIdentifier.create(NatConfig.class) - .child(NatInstances.class).child(NatInstance.class, new NatInstanceKey(NAT_INSTANCE_ID)) + private static final InstanceIdentifier<ExternalIpAddressPool> IID = NAT_INSTANCES_ID + .child(Instance.class, new InstanceKey(NAT_INSTANCE_ID)).child(Policy.class, new PolicyKey(0L)) .child(ExternalIpAddressPool.class, new ExternalIpAddressPoolKey(POOL_ID)); - private static final String NAT_INSTANCES_PATH = "/ietf-nat:nat-config/ietf-nat:nat-instances"; + private static final String NAT_INSTANCES_PATH = "/ietf-nat:nat/ietf-nat:instances"; @Mock private FutureJVppNatFacade jvppNat; @@ -68,7 +70,7 @@ public class ExternalIpPoolCustomizerTest extends WriterCustomizerTest implement @Test public void testWriteNat44( - @InjectTestData(resourcePath = "/nat44/external-ip-pool.json", id = NAT_INSTANCES_PATH) NatInstances data) + @InjectTestData(resourcePath = "/nat44/external-ip-pool.json", id = NAT_INSTANCES_PATH) Instances data) throws WriteFailedException { customizer.writeCurrentAttributes(IID, extractIpPool(data), writeContext); final Nat44AddDelAddressRange expectedRequest = getExpectedRequestNat44(true); @@ -77,7 +79,7 @@ public class ExternalIpPoolCustomizerTest extends WriterCustomizerTest implement @Test public void testWriteNat64( - @InjectTestData(resourcePath = "/nat64/external-ip-pool.json", id = NAT_INSTANCES_PATH) NatInstances data) + @InjectTestData(resourcePath = "/nat64/external-ip-pool.json", id = NAT_INSTANCES_PATH) Instances data) throws WriteFailedException { customizer.writeCurrentAttributes(IID, extractIpPool(data), writeContext); final Nat64AddDelPoolAddrRange expectedRequest = getExpectedRequestNat64(true); @@ -92,7 +94,7 @@ public class ExternalIpPoolCustomizerTest extends WriterCustomizerTest implement @Test public void testDeleteNat44( - @InjectTestData(resourcePath = "/nat44/external-ip-pool.json", id = NAT_INSTANCES_PATH) NatInstances data) + @InjectTestData(resourcePath = "/nat44/external-ip-pool.json", id = NAT_INSTANCES_PATH) Instances data) throws WriteFailedException { customizer.deleteCurrentAttributes(IID, extractIpPool(data), writeContext); final Nat44AddDelAddressRange expectedRequest = getExpectedRequestNat44(false); @@ -101,16 +103,16 @@ public class ExternalIpPoolCustomizerTest extends WriterCustomizerTest implement @Test public void testDeleteNat64( - @InjectTestData(resourcePath = "/nat64/external-ip-pool.json", id = NAT_INSTANCES_PATH) NatInstances data) + @InjectTestData(resourcePath = "/nat64/external-ip-pool.json", id = NAT_INSTANCES_PATH) Instances data) throws WriteFailedException { customizer.deleteCurrentAttributes(IID, extractIpPool(data), writeContext); final Nat64AddDelPoolAddrRange expectedRequest = getExpectedRequestNat64(false); verify(jvppNat).nat64AddDelPoolAddrRange(expectedRequest); } - private static ExternalIpAddressPool extractIpPool(NatInstances data) { + private static ExternalIpAddressPool extractIpPool(Instances data) { // assumes single nat instance and single ip pool - return data.getNatInstance().get(0).getExternalIpAddressPool().get(0); + return data.getInstance().get(0).getPolicy().get(0).getExternalIpAddressPool().get(0); } private Nat44AddDelAddressRange getExpectedRequestNat44(final boolean isAdd) { diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizerTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizerTest.java index 29869381a..95bce699a 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizerTest.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/MappingEntryCustomizerTest.java @@ -16,6 +16,7 @@ package io.fd.hc2vpp.nat.write; +import static io.fd.hc2vpp.nat.NatIds.NAT_INSTANCES_ID; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -34,13 +35,11 @@ import io.fd.vpp.jvpp.nat.future.FutureJVppNatFacade; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -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.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.NatInstanceKey; -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.config.nat.instances.nat.instance.mapping.table.MappingEntryKey; +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.MappingTable; +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.MappingEntryKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @RunWith(HoneycombTestRunner.class) @@ -48,12 +47,12 @@ public class MappingEntryCustomizerTest extends WriterCustomizerTest implements private static final long NAT_INSTANCE_ID = 1; private static final long MAPPING_ID = 22; - private static final InstanceIdentifier<MappingEntry> IID = InstanceIdentifier.create(NatConfig.class) - .child(NatInstances.class).child(NatInstance.class, new NatInstanceKey(NAT_INSTANCE_ID)) + private static final InstanceIdentifier<MappingEntry> IID = NAT_INSTANCES_ID + .child(Instance.class, new InstanceKey(NAT_INSTANCE_ID)) .child(MappingTable.class).child(MappingEntry.class, new MappingEntryKey(MAPPING_ID)); - private static final String MAPPING_TABLE_PATH = "/ietf-nat:nat-config/ietf-nat:nat-instances/" - + "ietf-nat:nat-instance[ietf-nat:id='" + NAT_INSTANCE_ID + "']/ietf-nat:mapping-table"; + private static final String MAPPING_TABLE_PATH = "/ietf-nat:nat/ietf-nat:instances/" + + "ietf-nat:instance[ietf-nat:id='" + NAT_INSTANCE_ID + "']/ietf-nat:mapping-table"; @Mock private FutureJVppNatFacade jvppNat; @@ -145,7 +144,9 @@ public class MappingEntryCustomizerTest extends WriterCustomizerTest implements expectedRequest.proto = 58; // icmp v6 expectedRequest.vrfId = (int) NAT_INSTANCE_ID; expectedRequest.iAddr = new byte[] {0x20, 0x01, 0x0d, (byte) 0xb8, (byte) 0x85, (byte) 0xa3, 0, 0, 0, 0, (byte) 0x8a, 0x2e, 0x03, 0x70, 0x73, 0x33}; + expectedRequest.iPort = 123; expectedRequest.oAddr = new byte[] {10, 1, 1, 3}; + expectedRequest.oPort = 456; return expectedRequest; } diff --git a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/Nat64PrefixesCustomizerTest.java b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/Nat64PrefixesCustomizerTest.java index 63a3b4673..2d3290e7c 100644 --- a/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/Nat64PrefixesCustomizerTest.java +++ b/nat/nat2vpp/src/test/java/io/fd/hc2vpp/nat/write/Nat64PrefixesCustomizerTest.java @@ -16,8 +16,8 @@ package io.fd.hc2vpp.nat.write; +import static io.fd.hc2vpp.nat.NatIds.NAT_INSTANCES_ID; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -26,28 +26,27 @@ import io.fd.hc2vpp.common.translate.util.ByteDataTranslator; import io.fd.vpp.jvpp.nat.dto.Nat64AddDelPrefix; import io.fd.vpp.jvpp.nat.dto.Nat64AddDelPrefixReply; import io.fd.vpp.jvpp.nat.future.FutureJVppNatFacade; -import java.util.Collections; import org.junit.Test; import org.mockito.Mock; 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.NatConfig; -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.NatInstanceKey; -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.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.InstanceKey; +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.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.yang.binding.InstanceIdentifier; public class Nat64PrefixesCustomizerTest extends WriterCustomizerTest implements ByteDataTranslator { private static final long VRF_ID = 123; - private static final InstanceIdentifier<NatInstance> NAT_INSTANCE_ID = - InstanceIdentifier.create(NatConfig.class).child(NatInstances.class).child(NatInstance.class, new NatInstanceKey(VRF_ID)); + private static final InstanceIdentifier<Policy> POLICY_ID = + NAT_INSTANCES_ID.child(Instance.class, new InstanceKey(VRF_ID)).child(Policy.class, new PolicyKey(0L)); - private static final Nat64Prefixes VALID_DATA = new Nat64PrefixesBuilder().setNat64Prefix(new Ipv6Prefix("2001:db8::/32")).build(); + private static final Nat64Prefixes + VALID_DATA = new Nat64PrefixesBuilder().setNat64Prefix(new Ipv6Prefix("2001:db8::/32")).build(); @Mock private FutureJVppNatFacade jvppNat; @@ -60,32 +59,20 @@ public class Nat64PrefixesCustomizerTest extends WriterCustomizerTest implements when(jvppNat.nat64AddDelPrefix(any())).thenReturn(future(new Nat64AddDelPrefixReply())); } - @Test(expected = IllegalArgumentException.class) - public void testWriteNonZeroPrefixIdFails() throws Exception { - customizer.writeCurrentAttributes(getID(1), mock(Nat64Prefixes.class), writeContext); - } - - @Test(expected = IllegalArgumentException.class) - public void testWriteDestinationPrefixFails() throws Exception { - final Nat64Prefixes data = mock(Nat64Prefixes.class); - when(data.getDestinationIpv4Prefix()).thenReturn(Collections.singletonList(mock(DestinationIpv4Prefix.class))); - customizer.writeCurrentAttributes(getID(1), data, writeContext); - } - @Test public void testWrite() throws Exception { - customizer.writeCurrentAttributes(getID(0), VALID_DATA, writeContext); + customizer.writeCurrentAttributes(getID("::1/128"), VALID_DATA, writeContext); verify(jvppNat).nat64AddDelPrefix(expectedRequest(true)); } @Test public void testDelete() throws Exception { - customizer.deleteCurrentAttributes(getID(0), VALID_DATA, writeContext); + customizer.deleteCurrentAttributes(getID("::1/128"), VALID_DATA, writeContext); verify(jvppNat).nat64AddDelPrefix(expectedRequest(false)); } - private static InstanceIdentifier<Nat64Prefixes> getID(final long prefixId) { - return NAT_INSTANCE_ID.child(Nat64Prefixes.class, new Nat64PrefixesKey(prefixId)); + private static InstanceIdentifier<Nat64Prefixes> getID(final String prefix) { + return POLICY_ID.child(Nat64Prefixes.class, new Nat64PrefixesKey(new Ipv6Prefix(prefix))); } private Nat64AddDelPrefix expectedRequest(final boolean isAdd) { diff --git a/nat/nat2vpp/src/test/resources/nat44/external-ip-pool.json b/nat/nat2vpp/src/test/resources/nat44/external-ip-pool.json index 37e8e907f..8e309ef2f 100644 --- a/nat/nat2vpp/src/test/resources/nat44/external-ip-pool.json +++ b/nat/nat2vpp/src/test/resources/nat44/external-ip-pool.json @@ -1,12 +1,14 @@ { - "nat-instances" : { - "nat-instance" : { - "id" : 0, - "external-ip-address-pool": { - "pool-id": 22, - "external-ip-pool": "192.168.1.1/24" + "instances": { + "instance": { + "id": 0, + "policy": { + "id": 0, + "external-ip-address-pool": { + "pool-id": 22, + "external-ip-pool": "192.168.1.1/24" + } } } } } - diff --git a/nat/nat2vpp/src/test/resources/nat64/external-ip-pool.json b/nat/nat2vpp/src/test/resources/nat64/external-ip-pool.json index 3be25d299..724407b29 100644 --- a/nat/nat2vpp/src/test/resources/nat64/external-ip-pool.json +++ b/nat/nat2vpp/src/test/resources/nat64/external-ip-pool.json @@ -1,13 +1,15 @@ { - "nat-instances" : { - "nat-instance" : { - "id" : 0, - "external-ip-address-pool": { - "pool-id": 22, - "external-ip-pool": "192.168.1.1/24", - "vpp-nat:pool-type": "nat64" + "instances": { + "instance": { + "id": 0, + "policy": { + "id": 0, + "external-ip-address-pool": { + "pool-id": 22, + "external-ip-pool": "192.168.1.1/24", + "vpp-nat:pool-type": "nat64" + } } } } } - diff --git a/nat/nat2vpp/src/test/resources/nat64/static-mapping-address-update.json b/nat/nat2vpp/src/test/resources/nat64/static-mapping-address-update.json index 73f2c0e55..2e836ce91 100644 --- a/nat/nat2vpp/src/test/resources/nat64/static-mapping-address-update.json +++ b/nat/nat2vpp/src/test/resources/nat64/static-mapping-address-update.json @@ -7,10 +7,10 @@ "internal-src-address": "2001:db8:85a3::8a2e:370:7334", "external-src-address": "10.1.1.4", "internal-src-port" : { - "single-port-number" : 1234 + "start-port-number" : 1234 }, "external-src-port" : { - "single-port-number" : 5678 + "start-port-number" : 5678 } } } diff --git a/nat/nat2vpp/src/test/resources/nat64/static-mapping.json b/nat/nat2vpp/src/test/resources/nat64/static-mapping.json index d3a1c40c4..9fff452a2 100644 --- a/nat/nat2vpp/src/test/resources/nat64/static-mapping.json +++ b/nat/nat2vpp/src/test/resources/nat64/static-mapping.json @@ -5,7 +5,13 @@ "type": "static", "transport-protocol": 58, "internal-src-address": "2001:db8:85a3::8a2e:370:7333", - "external-src-address": "10.1.1.3" + "internal-src-port": { + "start-port-number": 123 + }, + "external-src-address": "10.1.1.3", + "external-src-port": { + "start-port-number": 456 + } } } } |