2.8. NAT Mapping Entries
A TCP/UDP mapping entry maintains an association between the following information: (internal-src-address, internal-src-port) (internal-dst-address, internal-dst-port) <=> (external-src-address, external-src-port) (external-dst-address, external-dst-port) An ICMP mapping entry maintains an association between the following information: (internal-src-address, internal-dst-address, internal ICMP/ICMPv6 identifier) <=> (external-src-address, external-dst-address, external ICMP/ICMPv6 identifier) As a reminder, all the ICMP Query messages contain an 'Identifier' field, which is referred to in this document as the 'ICMP Identifier'. To cover TCP, UDP, and ICMP, the NAT YANG module assumes the following structure of a mapping entry: type: Indicates how the mapping was instantiated. For example, it may indicate whether a mapping is dynamically instantiated by a packet or statically configured. transport-protocol: Indicates the transport protocol (e.g., UDP, TCP, and ICMP) of a given mapping. internal-src-address: Indicates the source IP address/prefix as used by an internal host. internal-src-port: Indicates the source port number (or ICMP identifier) as used by an internal host. external-src-address: Indicates the source IP address/prefix as assigned by the NAT. external-src-port: Indicates the source port number (or ICMP identifier) as assigned by the NAT. internal-dst-address: Indicates the destination IP address/prefix as used by an internal host when sending a packet to a remote host.
internal-dst-port: Indicates the destination port number as used by an internal host when sending a packet to a remote host. external-dst-address: Indicates the destination IP address/prefix used by a NAT when processing a packet issued by an internal host towards a remote host. external-dst-port: Indicates the destination port number used by a NAT when processing a packet issued by an internal host towards a remote host. In order to cover both NAT64 and NAT44 flavors, the NAT mapping structure allows for the inclusion of an IPv4 or an IPv6 address as an internal IP address. Remaining fields are common to both NAT schemes. For example, the mapping that will be created by a NAT64 upon receipt of a TCP SYN from source address 2001:db8:aaaa::1 and source port number 25636 to destination IP address 2001:db8:1234::198.51.100.1 and destination port number 8080 is shown in Table 2. This example assumes Endpoint-Dependent Mapping (EDM). +-----------------------+-------------------------------------------+ | Mapping Entry | Value | | Attribute | | +-----------------------+-------------------------------------------+ | type | dynamic implicit mapping | | transport-protocol | 6 (TCP) | | internal-src-address | 2001:db8:aaaa::1 | | internal-src-port | 25636 | | external-src-address | T (an IPv4 address configured on the | | | NAT64) | | external-src-port | t (a port number that is chosen by the | | | NAT64) | | internal-dst-address | 2001:db8:1234::198.51.100.1 | | internal-dst-port | 8080 | | external-dst-address | 198.51.100.1 | | external-dst-port | 8080 | +-----------------------+-------------------------------------------+ Table 2: Example of an EDM NAT64 Mapping
The mappings that will be created by a NAT44 upon receipt of an ICMP request from source address 198.51.100.1 and ICMP identifier (ID1) to destination IP address 198.51.100.11 is depicted in Table 3. This example assumes Endpoint-Independent Mapping (EIM). +----------------------+--------------------------------------------+ | Mapping-Entry | Value | | Attribute | | +----------------------+--------------------------------------------+ | type | dynamic implicit mapping | | transport-protocol | 1 (ICMP) | | internal-src-address | 198.51.100.1 | | internal-src-port | ID1 | | external-src-address | T (an IPv4 address configured on the | | | NAT44) | | external-src-port | ID2 (an ICMP identifier that is chosen by | | | the NAT44) | +----------------------+--------------------------------------------+ Table 3: Example of an EIM NAT44 Mapping Entry The mapping that will be created by a NAT64 (EIM mode) upon receipt of an ICMP request from source address 2001:db8:aaaa::1 and ICMP identifier (ID1) to destination IP address 2001:db8:1234::198.51.100.1 is shown in Table 4. +----------------------+--------------------------------------------+ | Mapping-Entry | Value | | Attribute | | +----------------------+--------------------------------------------+ | type | dynamic implicit mapping | | transport-protocol | 58 (ICMPv6) | | internal-src-address | 2001:db8:aaaa::1 | | internal-src-port | ID1 | | external-src-address | T (an IPv4 address configured on the | | | NAT64) | | external-src-port | ID2 (an ICMP identifier that is chosen by | | | the NAT64) | +----------------------+--------------------------------------------+ Table 4: Example of an EIM NAT64 Mapping Entry
Note that a mapping table is maintained only for stateful NAT functions. Particularly: o No mapping table is maintained for NPTv6 given that it is stateless and transport-agnostic. o The double translations are stateless in CLAT if a dedicated IPv6 prefix is provided for CLAT. If not, a stateful NAT44 will be required. o No per-flow mapping is maintained for EAM [RFC7757]. o No mapping table is maintained for Stateless IPv4/IPv6 translation. As a reminder, in such deployments, internal IPv6 nodes are addressed using IPv4-translatable IPv6 addresses, which enable them to be accessed by IPv4 nodes [RFC6052].2.9. Resource Limits
In order to comply with CGN deployments in particular, the NAT YANG module allows limiting the number of external ports per subscriber (port-quota) and the amount of state memory allocated per mapping and per subscriber (mapping-limits and connection-limits). According to [RFC6888], the module is designed to allow for the following: o Per-subscriber limits are configurable by the NAT administrator. o Per-subscriber limits are configurable independently per the transport protocol. o Administrator-adjustable thresholds to prevent a single subscriber from consuming excessive CPU resources from the NAT (e.g., rate- limit the subscriber's creation of new mappings) can be configured.
Table 5 lists the various limits that can be set using the NAT YANG module. Once a limit is reached, packets that would normally trigger new port mappings or be translated because they match existing mappings, are dropped by the translator. +-------------------+-----------------------------------------------+ | Limit | Description | +-------------------+-----------------------------------------------+ | port-quota | Specifies a port quota to be assigned per | | | subscriber. It corresponds to the maximum | | | number of ports to be used by a subscriber. | | | The port quota can be configured to apply to | | | all protocols or to a specific protocol. | | | Distinct port quota may be configured per | | | protocol. | +-------------------+-----------------------------------------------+ | fragments-limit | In order to prevent denial-of-service (DoS) | | | attacks that can be caused by fragments, this | | | parameter is used to limit the number of out- | | | of-order fragments that can be handled by a | | | translator. | +-------------------+-----------------------------------------------+ | mapping-limits | This parameter can be used to control the | | | maximum number of subscribers that can be | | | serviced by a NAT instance (limit-subscriber) | | | and the maximum number of address and/or port | | | mappings that can be maintained by a NAT | | | instance (limit-address-mappings and limit- | | | port-mappings). Also, limits specific to | | | protocols (e.g., TCP, UDP, ICMP) can also be | | | specified (limit-per-protocol). | +-------------------+-----------------------------------------------+ | connection-limits | In order to prevent exhausting the resources | | | of a NAT implementation and to ensure | | | fairness usage among subscribers, various | | | rate limits can be specified. Rate-limiting | | | can be enforced per subscriber (limit- | | | subscriber), per NAT instance (limit-per- | | | instance), and/or be specified for each | | | supported protocol (limit-per-protocol). | +-------------------+-----------------------------------------------+ Table 5: NAT Limits
Table 6 describes limits that, once exceeded, will trigger notifications to be generated: +--------------------------+----------------------------------------+ | Notification Threshold | Description | +--------------------------+----------------------------------------+ | high-threshold | Used to notify high address | | | utilization of a given pool. When | | | exceeded, a nat-pool-event | | | notification will be generated. | +--------------------------+----------------------------------------+ | low-threshold | Used to notify low address utilization | | | of a given pool. An administrator is | | | supposed to configure low-threshold so | | | that it can reflect an abnormal usage | | | of NAT resources. When exceeded, a | | | nat-pool-event notification will be | | | generated. | +--------------------------+----------------------------------------+ | notify-addresses-usage | Used to notify high address | | | utilization of all pools configured to | | | a NAT instance. When exceeded, a nat- | | | instance-event will be generated. | +--------------------------+----------------------------------------+ | notify-ports-usage | Used to notify high port allocation | | | taking into account all pools | | | configured to a NAT instance. When | | | exceeded, a nat-instance-event | | | notification will be generated. | +--------------------------+----------------------------------------+ | notify-subscribers-limit | Used to notify a high number of active | | | subscribers that are serviced by a NAT | | | instance. When exceeded, a nat- | | | instance-event notification will be | | | generated. | +--------------------------+----------------------------------------+ Table 6: Notification Thresholds
In order to prevent a NAT implementation from generating frequent notifications, the NAT YANG module supports the following limits (Table 7) used to control how frequent notifications can be generated. That is, notifications are subject to rate-limiting imposed by these intervals. +-------------------------------------+-----------------------------+ | Interval | Description | +-------------------------------------+-----------------------------+ | notify-pool-usage/notify-interval | Indicates the minimum | | | number of seconds between | | | successive notifications | | | for a given address pool. | +-------------------------------------+-----------------------------+ | notification-limits/notify-interval | Indicates the minimum | | | number of seconds between | | | successive notifications | | | for a NAT instance. | +-------------------------------------+-----------------------------+ Table 7: Notification Intervals2.10. Binding the NAT Function to an External Interface
The module is designed to specify an external realm on which the NAT function must be applied (external-realm). The module supports indicating an interface as an external realm [RFC8343], but the module is extensible so that other choices can be indicated in the future (e.g., Virtual Routing and Forwarding (VRF) instance). Distinct external realms can be provided as a function of the NAT policy (see, for example, Section 4 of [RFC7289]). If no external realm is provided, this assumes that the system is able to determine the external interface (VRF instance, etc.) on which the NAT will be applied. Typically, the WAN and LAN interfaces of Customer Premises Equipment (CPE) are determined by the CPE.2.11. Relationship to NATV2-MIB
Section of 5.1 of [RFC7659] indicates that the NATV2-MIB assumes that the following information is configured on the NAT by some means, which is not specified in [RFC7659]: o The set of address realms to which the device connects.
o For the CGN case, per-subscriber information including the subscriber index, address realm, assigned prefix or address, and (possibly) policies regarding address pool selection in the various possible address realms to which the subscriber may connect. o The set of NAT instances running on the device, identified by NAT instance index and name. o The port mapping, filtering, pooling, and fragment behaviors for each NAT instance. o The set of protocols supported by each NAT instance. o Address pools for each NAT instance, including for each pool the pool index, address realm, and minimum and maximum port numbers. o Static address and port mapping entries. All the above parameters can be configured by means of the NAT YANG module. Unlike the NATV2-MIB, the NAT YANG module allows the configuration of multiple policies per NAT instance.2.12. Tree Structure
The tree structure of the NAT YANG module is provided below: module: ietf-nat +--rw nat +--rw instances +--rw instance* [id] +--rw id uint32 +--rw name? string +--rw enable? boolean +--ro capabilities | +--ro nat-flavor* | | identityref | +--ro per-interface-binding* | | enumeration | +--ro transport-protocols* [protocol-id] | | +--ro protocol-id uint8 | | +--ro protocol-name? string | +--ro restricted-port-support? | | boolean | +--ro static-mapping-support? | | boolean
| +--ro port-randomization-support? | | boolean | +--ro port-range-allocation-support? | | boolean | +--ro port-preservation-suport? | | boolean | +--ro port-parity-preservation-support? | | boolean | +--ro address-roundrobin-support? | | boolean | +--ro paired-address-pooling-support? | | boolean | +--ro endpoint-independent-mapping-support? | | boolean | +--ro address-dependent-mapping-support? | | boolean | +--ro address-and-port-dependent-mapping-support? | | boolean | +--ro endpoint-independent-filtering-support? | | boolean | +--ro address-dependent-filtering? | | boolean | +--ro address-and-port-dependent-filtering? | | boolean | +--ro fragment-behavior? | enumeration +--rw type? identityref +--rw per-interface-binding? enumeration +--rw nat-pass-through* [id] | {basic-nat44 or napt44 or dst-nat}? | +--rw id uint32 | +--rw prefix inet:ip-prefix | +--rw port? inet:port-number +--rw policy* [id] | +--rw id uint32 | +--rw clat-parameters {clat}? | | +--rw clat-ipv6-prefixes* [ipv6-prefix] | | | +--rw ipv6-prefix inet:ipv6-prefix | | +--rw ipv4-prefixes* [ipv4-prefix] | | +--rw ipv4-prefix inet:ipv4-prefix | +--rw nptv6-prefixes* [internal-ipv6-prefix] {nptv6}? | | +--rw internal-ipv6-prefix inet:ipv6-prefix | | +--rw external-ipv6-prefix inet:ipv6-prefix | +--rw eam* [ipv4-prefix] {eam}? | | +--rw ipv4-prefix inet:ipv4-prefix | | +--rw ipv6-prefix inet:ipv6-prefix
| +--rw nat64-prefixes* [nat64-prefix] | | {siit or nat64 or clat}? | | +--rw nat64-prefix inet:ipv6-prefix | | +--rw destination-ipv4-prefix* [ipv4-prefix] | | | +--rw ipv4-prefix inet:ipv4-prefix | | +--rw stateless-enable? boolean | +--rw external-ip-address-pool* [pool-id] | | {basic-nat44 or napt44 or nat64}? | | +--rw pool-id uint32 | | +--rw external-ip-pool inet:ipv4-prefix | +--rw port-set-restrict {napt44 or nat64}? | | +--rw (port-type)? | | +--:(port-range) | | | +--rw start-port-number? inet:port-number | | | +--rw end-port-number? inet:port-number | | +--:(port-set-algo) | | +--rw psid-offset? uint8 | | +--rw psid-len uint8 | | +--rw psid uint16 | +--rw dst-nat-enable? boolean | | {basic-nat44 or napt44}? | +--rw dst-ip-address-pool* [pool-id] {dst-nat}? | | +--rw pool-id uint32 | | +--rw dst-in-ip-pool? inet:ip-prefix | | +--rw dst-out-ip-pool inet:ip-prefix | +--rw transport-protocols* [protocol-id] | | {napt44 or nat64 or dst-nat}? | | +--rw protocol-id uint8 | | +--rw protocol-name? string | +--rw subscriber-mask-v6? uint8 | +--rw subscriber-match* [match-id] | | {basic-nat44 or napt44 or dst-nat}? | | +--rw match-id uint32 | | +--rw subnet inet:ip-prefix | +--rw address-allocation-type? enumeration | +--rw port-allocation-type? enumeration | | {napt44 or nat64}? | +--rw mapping-type? enumeration | | {napt44 or nat64}? | +--rw filtering-type? enumeration | | {napt44 or nat64}? | +--rw fragment-behavior? enumeration | | {napt44 or nat64}? | +--rw port-quota* [quota-type] {napt44 or nat64}? | | +--rw port-limit? uint16 | | +--rw quota-type uint8
| +--rw port-set {napt44 or nat64}? | | +--rw port-set-size uint16 | | +--rw port-set-timeout? uint32 | +--rw timers {napt44 or nat64}? | | +--rw udp-timeout? uint32 | | +--rw tcp-idle-timeout? uint32 | | +--rw tcp-trans-open-timeout? uint32 | | +--rw tcp-trans-close-timeout? uint32 | | +--rw tcp-in-syn-timeout? uint32 | | +--rw fragment-min-timeout? uint32 | | +--rw icmp-timeout? uint32 | | +--rw per-port-timeout* [port-number] | | | +--rw port-number inet:port-number | | | +--rw protocol? uint32 | | | +--rw timeout uint32 | | +--rw hold-down-timeout? uint32 | | +--rw hold-down-max? uint32 | +--rw fragments-limit? uint32 | +--rw algs* [name] | | +--rw name string | | +--rw transport-protocol? uint32 | | +--rw dst-transport-port | | | +--rw start-port-number? inet:port-number | | | +--rw end-port-number? inet:port-number | | +--rw src-transport-port | | | +--rw start-port-number? inet:port-number | | | +--rw end-port-number? inet:port-number | | +--rw status? boolean | +--rw all-algs-enable? boolean | +--rw notify-pool-usage | | {basic-nat44 or napt44 or nat64}? | | +--rw pool-id? uint32 | | +--rw low-threshold? percent | | +--rw high-threshold? percent | | +--rw notify-interval? uint32 | +--rw external-realm | +--rw (realm-type)? | +--:(interface) | +--rw external-interface? if:interface-ref +--rw mapping-limits {napt44 or nat64}? | +--rw limit-subscribers? uint32 | +--rw limit-address-mappings? uint32 | +--rw limit-port-mappings? uint32 | +--rw limit-per-protocol* [protocol-id] | {napt44 or nat64 or dst-nat}? | +--rw protocol-id uint8 | +--rw limit? uint32
+--rw connection-limits | {basic-nat44 or napt44 or nat64}? | +--rw limit-per-subscriber? uint32 | +--rw limit-per-instance? uint32 | +--rw limit-per-protocol* [protocol-id] | {napt44 or nat64}? | +--rw protocol-id uint8 | +--rw limit? uint32 +--rw notification-limits | +--rw notify-interval? uint32 | | {basic-nat44 or napt44 or nat64}? | +--rw notify-addresses-usage? percent | | {basic-nat44 or napt44 or nat64}? | +--rw notify-ports-usage? percent | | {napt44 or nat64}? | +--rw notify-subscribers-limit? uint32 | {basic-nat44 or napt44 or nat64}? +--rw mapping-table | |{basic-nat44 or napt44 or nat64 or clat or dst-nat}? | +--rw mapping-entry* [index] | +--rw index uint32 | +--rw type? enumeration | +--rw transport-protocol? uint8 | +--rw internal-src-address? inet:ip-prefix | +--rw internal-src-port | | +--rw start-port-number? inet:port-number | | +--rw end-port-number? inet:port-number | +--rw external-src-address? inet:ip-prefix | +--rw external-src-port | | +--rw start-port-number? inet:port-number | | +--rw end-port-number? inet:port-number | +--rw internal-dst-address? inet:ip-prefix | +--rw internal-dst-port | | +--rw start-port-number? inet:port-number | | +--rw end-port-number? inet:port-number | +--rw external-dst-address? inet:ip-prefix | +--rw external-dst-port | | +--rw start-port-number? inet:port-number | | +--rw end-port-number? inet:port-number | +--rw lifetime? uint32 +--ro statistics +--ro discontinuity-time yang:date-and-time +--ro traffic-statistics | +--ro sent-packets? | | yang:zero-based-counter64 | +--ro sent-bytes? | | yang:zero-based-counter64
| +--ro rcvd-packets? | | yang:zero-based-counter64 | +--ro rcvd-bytes? | | yang:zero-based-counter64 | +--ro dropped-packets? | | yang:zero-based-counter64 | +--ro dropped-bytes? | | yang:zero-based-counter64 | +--ro dropped-fragments? | | yang:zero-based-counter64 | | {napt44 or nat64}? | +--ro dropped-address-limit-packets? | | yang:zero-based-counter64 | | {basic-nat44 or napt44 or nat64}? | +--ro dropped-address-limit-bytes? | | yang:zero-based-counter64 | | {basic-nat44 or napt44 or nat64}? | +--ro dropped-address-packets? | | yang:zero-based-counter64 | | {basic-nat44 or napt44 or nat64}? | +--ro dropped-address-bytes? | | yang:zero-based-counter64 | | {basic-nat44 or napt44 or nat64}? | +--ro dropped-port-limit-packets? | | yang:zero-based-counter64 | | {napt44 or nat64}? | +--ro dropped-port-limit-bytes? | | yang:zero-based-counter64 | | {napt44 or nat64}? | +--ro dropped-port-packets? | | yang:zero-based-counter64 | | {napt44 or nat64}? | +--ro dropped-port-bytes? | | yang:zero-based-counter64 | | {napt44 or nat64}? | +--ro dropped-subscriber-limit-packets? | | yang:zero-based-counter64 | | {basic-nat44 or napt44 or nat64}? | +--ro dropped-subscriber-limit-bytes? | yang:zero-based-counter64 | {basic-nat44 or napt44 or nat64}? +--ro mappings-statistics | +--ro total-active-subscribers? yang:gauge32 | | {basic-nat44 or napt44 or nat64}? | +--ro total-address-mappings? yang:gauge32 | |{basic-nat44 or napt44 or nat64 or clat or dst-nat}? | +--ro total-port-mappings? yang:gauge32 | | {napt44 or nat64}?
| +--ro total-per-protocol* [protocol-id] | {napt44 or nat64}? | +--ro protocol-id uint8 | +--ro total? yang:gauge32 +--ro pools-stats {basic-nat44 or napt44 or nat64}? +--ro addresses-allocated? yang:gauge32 +--ro addresses-free? yang:gauge32 +--ro ports-stats {napt44 or nat64}? | +--ro ports-allocated? yang:gauge32 | +--ro ports-free? yang:gauge32 +--ro per-pool-stats* [pool-id] | {basic-nat44 or napt44 or nat64}? +--ro pool-id uint32 +--ro discontinuity-time yang:date-and-time +--ro pool-stats | +--ro addresses-allocated? yang:gauge32 | +--ro addresses-free? yang:gauge32 +--ro port-stats {napt44 or nat64}? +--ro ports-allocated? yang:gauge32 +--ro ports-free? yang:gauge32 notifications: +---n nat-pool-event {basic-nat44 or napt44 or nat64}? | +--ro id -> /nat/instances/instance/id | +--ro policy-id? | | -> /nat/instances/instance/policy/id | +--ro pool-id | | -> /nat/instances/instance/policy/ | | external-ip-address-pool/pool-id | +--ro notify-pool-threshold percent +---n nat-instance-event {basic-nat44 or napt44 or nat64}? +--ro id | -> /nat/instances/instance/id +--ro notify-subscribers-threshold? uint32 +--ro notify-addresses-threshold? percent +--ro notify-ports-threshold? percent