One document matched: draft-mrw-nat66-12.xml


<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?rfc strict="yes" ?>
<?rfc comments="no" ?>
<?rfc inline="no" ?>
<?rfc editing="no" ?>
<?rfc toc="yes"?>
<?rfc tocompact="yes"?>
<?rfc tocdepth="3"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes" ?>
<?rfc compact="yes" ?>
<?rfc subcompact="no" ?>
<rfc category="exp" docName="draft-mrw-nat66-12" ipr="trust200902">
  <front>
    <title abbrev="NPTv6">IPv6-to-IPv6 Network Prefix Translation</title>

    <author fullname="Margaret Wasserman" initials="M." surname="Wasserman">
      <organization>Painless Security</organization>

      <address>
        <postal>
          <street></street>

          <city>North Andover</city>

          <region>MA</region>

          <code>01845</code>

          <country>USA</country>
        </postal>

        <phone>+1 781 405 7464</phone>

        <email>mrw@painless-security.com</email>

        <uri>http://www.painless-security.com</uri>
      </address>
    </author>

    <author fullname="Fred Baker" initials="F.J." surname="Baker">
      <organization>Cisco Systems</organization>

      <address>
        <postal>
          <street></street>

          <city>Santa Barbara</city>

          <code>93117</code>

          <region>California</region>

          <country>USA</country>
        </postal>

        <phone>+1-408-526-4257</phone>

        <email>fred@cisco.com</email>
      </address>
    </author>

    <date year="2011" />

    <area>Transport</area>

    <workgroup></workgroup>

    <abstract>
      <t>This document describes a stateless, transport-agnostic IPv6-to-IPv6
      Network Prefix Translation (NPTv6) function that provides the address
      independence benefit associated with IPv4-to-IPv4 NAT (NAPT44), and in
      addition provides a 1:1 relationship between addresses in the "inside"
      and "outside" prefixes, preserving end to end reachability at the
      network layer.</t>
    </abstract>

    <note title="Requirements Terminology">
      <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
      "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
      document are to be interpreted as described in <xref
      target="RFC2119">RFC 2119</xref>.</t>
    </note>
  </front>

  <middle>
    <section title="Introduction">
      <t>This document describes a stateless IPv6-to-IPv6 Network Prefix
      Translation (NPTv6) function, designed to provide address independence
      to the edge network. It is transport-agnostic with respect to transports
      that don't checksum the IP header, such as SCTP, and to transports that
      use the TCP/UDP/DCCP pseudo-header and <xref
      target="RFC1071">checksum</xref>.</t>

      <t>This has several ramifications: <list style="symbols">
          <t>Any security benefit that NAPT44 might offer is not present in
          NPTv6, necessitating the use of a firewall to obtain those benefits
          if desired. An example of such a firewall is described in <xref
          target="RFC6092"></xref>.</t>

          <t>End to end reachability is preserved, although the address used
          "inside" the edge network differs from the address used "outside"
          the edge network. This has implications for application referrals
          and other uses of Internet layer addresses.</t>

          <t>If there are multiple identically-configured prefix translators
          between two networks, there is no need for them to exchange dynamic
          state, as there is no dynamic state - the algorithmic translation
          will be identical across each of them. The network can therefore
          asymmetrically route, load-share, and fail-over among them without
          issue.</t>

          <t>Since translation is 1:1 at the network layer, there is no need
          to modify port numbers or other transport parameters.</t>

          <t>TCP sessions that authenticate peers using the <xref
          target="RFC5925">TCP Authentication Option</xref> cannot have their
          addresses translated, as the addresses are used in the calculation
          of the Message Authentication Code. This consideration applies in
          general to any <xref target="RFC3424">UNilateral Self-Address Fixing
          (UNSAF)</xref> Protocol, which the IAB recommends against the
          deployment of in an environment that changes Internet addresses.</t>

          <t>Applications using the <xref target="RFC5996">Internet Key
          Exchange Protocol Version 2 (IKEv2)</xref> should, at least in
          theory, detect the presence of the translator; while no NAT
          traversal solution is required, <xref target="RFC5996"></xref> would
          require such sessions to use UDP.</t>
        </list></t>

      <section title="What is Address Independence?">
        <t>For the purposes of this document, IPv6 Address Independence
        consists of the following set of properties: <list style="hanging">
            <t hangText="From the perspective of the edge network:"><list
                style="symbols">
                <t>The IPv6 addresses used inside the local network (for
                interfaces, access lists, and logs) do not need to be
                renumbered if the global prefix(es) assigned for use by the
                edge network are changed.</t>

                <t>The IPv6 addresses used inside the edge network (for
                interfaces, access lists, and logs) or within other upstream
                networks (such as when multihoming) do not need to be
                renumbered when a site adds, drops, or changes upstream
                networks.</t>

                <t>It is not necessary for an administration to convince an
                upstream network to route its internal IPv6 prefixes, or for
                it to advertise prefixes derived from other upstream networks
                into it.</t>

                <t>Unless it wants to optimize routing between multiple
                upstream networks in the process of multihoming, there is
                therefore no need for a BGP exchange with the upstream
                network.</t>
              </list></t>

            <t hangText="From the perspective of the upstream network:"><list
                style="symbols">
                <t>IPv6 addresses used by the edge network are guaranteed to
                have a provider-allocated prefix, eliminating the need and
                concern for <xref target="RFC2827">BCP 38</xref> ingress
                filtering and the advertisement of customer-specific
                prefixes.</t>
              </list></t>
          </list></t>

        <t>Thus, address independence has ramifications for the edge network,
        networks it directly connects with (especially its upstream networks),
        and for the Internet as a whole. The desire for address independence
        has been a primary driver for IPv4 NAT deployment in medium to
        large-sized enterprise networks, including NAT deployments in
        enterprises that have plenty of IPv4 provider independent address
        space (from IPv4 "swamp space"). It has also been a driver for edge
        networks to become members of Regional Internet Registry (RIR)
        communities, seeking to obtain BGP Autonomous System Numbers and
        provider independent prefixes, and as a result has been one of the
        drivers of the explosion of the IPv4 route table. Service providers
        have stated that the lack of address independence from their customers
        has been a negative incentive to deployment, due to the impact of
        customer routing expected in their networks.</t>

        <t>The <xref target="RFC4864">Local Network Protection</xref> document
        discusses a related concept called "Address Autonomy" as a benefit of
        NAPT44. <xref target="RFC4864"></xref> indicates that address autonomy
        can be achieved by the simultaneous use of global addresses on all
        nodes within a site that need external connectivity, and Unique Local
        Addresses (ULAs) <xref target="RFC4193"></xref> for all internal
        communication. However, this solution fails to meet the requirement
        for address independence, because if an ISP renumbering event occurs,
        all of the hosts, routers, DHCP servers, ACLs, firewalls and other
        internal systems that are configured with global addresses from the
        ISP will need to be renumbered before global connectivity is fully
        restored.</t>

        <t>The use of IPv6 Provider Independent (PI) addresses has also been
        suggested as a means to fulfill the address independence requirement.
        However, this solution requires that an enterprise qualify to receive
        a PI assignment and persuade their ISP to install specific routes for
        the enterprise's PI addresses. There are a number of practical issues
        with this approach, especially if there is a desire to route to a
        number of geographically and topologically diverse set of sites, which
        can sometimes involve coordinating with several ISPs to route portions
        of a single PI prefix. These problems have caused numerous enterprises
        with plenty of IPv4 swamp space to choose to use IPv4 NAT for part, or
        substantially all, of their internal network instead of using their
        provider independent address space.</t>
      </section>

      <section title="NPTv6 Applicability">
        <t>NPTv6 provides a simple and compelling solution to meet the Address
        Independence requirement in IPv6. The address independence benefit
        stems directly from the translation function of the network prefix
        translator. To avoid as many of the issues associated with NAPT44 as
        possible, NPTv6 is defined to include a two-way, checksum-neutral,
        algorithmic translation function, and nothing else.</t>

        <t>The fact that NPTv6 does not map ports and is checksum-neutral
        avoids the need for an NPTv6 Translator to re-write transport layer
        headers. This makes it feasible to deploy new or improved transport
        layer protocols without upgrading NPTv6 Translators. Similarly, since
        NPTv6 does not re-write transport layer headers, NPTv6 will not
        interfere with encryption of the full IP payload in many cases.</t>

        <t>The default NPTv6 address mapping mechanism is purely algorithmic,
        so NPTv6 translators do not need to maintain per-node or
        per-connection state, allowing deployment of more robust and adaptive
        networks than can be deployed using NAPT44. Since the default NPTv6
        mapping can be performed in either direction, it does not interfere
        with inbound connection establishment, thus allowing internal nodes to
        participate in direct Peer-to-Peer applications without the
        application layer overhead one finds in many IPv4 Peer-to-Peer
        applications.</t>

        <t>Although NPTv6 compares favorably to NAPT44 in several ways, it
        does not eliminate all of the architectural problems associated with
        IPv4 NAT, as described in <xref target="RFC2993"></xref>. NPTv6
        involves modifying IP headers in transit, so it is not compatible with
        security mechanisms, such as the IPsec Authentication Header, that
        provide integrity protection for the IP header. NPTv6 may interfere
        with the use of application protocols that transmit IP addresses in
        the application-specific portion of the IP packet. These applications
        currently require application layer gateways (ALGs) to work correctly
        through NAPT44 devices, and similar ALGs may be required for these
        applications to work through NPTv6 Translators. The use of separate
        internal and external prefixes creates complexity for DNS deployment,
        due to the desire for internal nodes to communicate with other
        internal nodes using internal addresses, while external nodes need to
        obtain external addresses to communicate with the same nodes. This
        frequently results in the deployment of "split DNS", which may add
        complexity to network configuration.</t>

        <t>The choice of address within the edge network bears consideration.
        One could use a ULA, which maximizes address independence. That could
        also be considered a misuse of the ULA; if the expectation is that a
        ULA prevents access to a system from outside the range of the ULA,
        NPTv6 overrides that. On the other hand, the administration is aware
        that it has made that choice, and could if it desired deploy a second
        ULA for the purpose of privacy; the only prefix that will be
        translated is one that has an NPTv6 Translator configured to translate
        to or from it. Also, using any other global scope address format makes
        one either obtain a PI prefix or be at the mercy of the agency from
        which it was allocated.</t>

        <t>There are significant technical impacts associated with the
        deployment of any prefix translation mechanism, including NPTv6, and
        we strongly encourage anyone who is considering the implementation or
        deployment of NPTv6 to read <xref target="RFC4864"></xref> and <xref
        target="RFC5902"></xref>, and to carefully consider the alternatives
        described in that document, some of which may cause fewer problems
        than NPTv6.</t>
      </section>
    </section>

    <section title="NPTv6 Overview">
      <t>NPTv6 may be implemented in an IPv6 router to map one IPv6 address
      prefix to another IPv6 prefix as each IPv6 packet transits the router. A
      router that implements an NPTv6 prefix translation function is referred
      to as an NPTv6 Translator.</t>

      <section title="NPTv6: the simplest case">
        <t>In its simplest form, an NPTv6 Translator 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. All
        of the hosts on the internal network will use addresses from a single,
        locally-routed prefix, and those addresses will be translated to/from
        addresses in a globally-routable prefix as IP packets transit the
        NPTv6 Translator. The lengths of these two prefixes will be
        functionally the same; if they differ, the longer of the two will
        limit the ability to use subnets in the shorter.</t>

        <figure anchor="simpleNPTv6" title="A simple translator">
          <artwork align="center"><![CDATA[ 
External Network:  Prefix = 2001:0DB8:0001:/48 
    --------------------------------------
                      |
                      |
               +-------------+
               |     NPTv6   |
               |  Translator |
               +-------------+
                      |
                      |
    --------------------------------------
Internal Network:  Prefix = FD01:0203:0405:/48
]]></artwork>
        </figure>

        <t><xref target="simpleNPTv6"></xref> shows an NPTv6 Translator
        attached to two networks. In this example, the internal network uses
        <xref target="RFC4193">IPv6 Unique Local Addresses (ULAs)</xref> to
        represent the internal IPv6 nodes, and the external network uses
        globally routable IPv6 addresses to represent the same nodes.</t>

        <t>When an NPTv6 Translator forwards packets in the "outbound"
        direction, from the internal network to the external network, NPTv6
        overwrites the IPv6 source prefix (in the IPv6 header) with a
        corresponding external prefix. When packets are forwarded in the
        "inbound" direction, from the external network to the internal
        network, the IPv6 destination prefix is overwritten with a
        corresponding internal prefix. Using the prefixes shown in the diagram
        above, as an IP packet passes through the NPTv6 Translator in the
        outbound direction, the source prefix (FD01:0203:0405:/48) will be
        overwritten with the external prefix (2001:0DB8:0001:/48). In an
        inbound packet, the destination prefix (2001:0DB8:0001:/48) will be
        overwritten with the internal prefix (FD01:0203:0405:/48). In both
        cases, it is the local IPv6 prefix that is overwritten; the remote
        IPv6 prefix remains unchanged. Nodes on the internal network are said
        to be "behind" the NPTv6 Translator.</t>
      </section>

      <section title="NPTv6 between peer networks">
        <t>NPTv6 can also be used between two private networks. In these
        cases, both networks may use ULA prefixes, with each subnet in one
        network mapped into a corresponding subnet in the other network, and
        vice versa. Or, each network may use ULA prefixes for internal
        addressing, and global unicast addresses on the other network.</t>

        <figure anchor="flow" title="Flow of Information in Translation">
          <artwork align="center"><![CDATA[ 
    Internal Prefix = FD01:4444:5555:/48
    --------------------------------------
         V            |      External Prefix
         V            |      2001:0DB8:6666:/48
         V        +---------+      ^
         V        |  NPTv6  |      ^
         V        |  Device |      ^
         V        +---------+      ^
External Prefix       |            ^
2001:0DB8:0001:/48    |            ^
    --------------------------------------
    Internal Prefix = FD01:0203:0405:/48
]]></artwork>
        </figure>
      </section>

      <section title="NPTv6 redundancy and load-sharing">
        <t>In some cases, more than one NPTv6 Translator may be attached to a
        network, as shown in <xref target="parallel"></xref>. In such cases,
        NPTv6 Translators are configured with the same internal and external
        prefixes. Since there is only one translation, even though there are
        multiple translators, they map only one external address (prefix and
        IID) to the internal address.</t>

        <figure anchor="parallel" title="Parallel Translators">
          <artwork align="center"><![CDATA[ 
External Network:  Prefix = 2001:0DB8:0001:/48 
    --------------------------------------
           |                      |
           |                      |
    +-------------+        +-------------+
    |  NPTv6      |        |  NPTv6      |
    |  Translator |        |  Translator |
    |   #1        |        |   #2        |
    +-------------+        +-------------+
           |                      |
           |                      |
    --------------------------------------
Internal Network:  Prefix = FD01:0203:0405:/48
]]></artwork>
        </figure>
      </section>

      <section title="NPTv6 multihoming">
        <figure anchor="distinct"
                title="Parallel Translators with different upstream networks">
          <artwork align="center"><![CDATA[ 
   External Network #1:          External Network #2:
Prefix = 2001:0DB8:0001:/48    Prefix = 2001:0DB8:5555:/48
---------------------------    --------------------------
                |                      |
                |                      |
         +-------------+        +-------------+
         |  NPTv6      |        |  NPTv6      |
         |  Translator |        |  Translator |
         |   #1        |        |   #2        |
         +-------------+        +-------------+
                |                      |
                |                      |
         --------------------------------------
     Internal Network:  Prefix = FD01:0203:0405:/48
]]></artwork>
        </figure>

        <t>When multihoming, NPTv6 Translators are attached to an internal
        network, as shown in <xref target="distinct"></xref>, but connected to
        different external networks. In such cases, NPTv6 Translators are
        configured with the same internal prefix, but different external
        prefixes. Since there are multiple translations, they map multiple
        external addresses (prefix and IID) to the common internal address. A
        system within the edge network is unable to determine which external
        address it is using apart from services such as STUN.</t>

        <t>Multihoming in this sense has one negative feature as compared with
        multihoming with a provider independent address; when routes change
        between NPTv6 Translators, since the upstream network changes, the
        translated prefix can change. This would cause sessions and referrals
        dependent on it to fail as well. This is not expected to be a major
        issue, however, in networks where routing is generally stable.</t>
      </section>

      <section title="Mapping with No Per-Flow State">
        <t>When NPTv6 is used as described in this document, no per-node or
        per-flow state is maintained in the NPTv6 Translator. Both inbound and
        outbound packets are translated algorithmically, using only
        information found in the IPv6 header. Due to this property, NPTv6's
        two-way, algorithmic address mapping can support both outbound and
        inbound connection establishment without the need for state-priming or
        rendezvous mechanisms, or the maintenance of mapping state. This is a
        significant improvement over NAPT44 devices, but it also has
        significant security implications which are described in <xref
        target="security"></xref>.</t>
      </section>

      <section title="Checksum-Neutral Mapping">
        <t>When a change is made to one of the IP header fields in the IPv6
        pseudo-header checksum (such as one of the IP addresses), the checksum
        field in the transport layer header may become invalid. Fortunately,
        an incremental change in the area covered by the Internet standard
        checksum <xref target="RFC1071"></xref> will result in a well-defined
        change to the checksum value <xref target="RFC1624"></xref>. So, a
        checksum change caused by modifying part of the area covered by the
        checksum can be corrected by making a complementary change to a
        different 16-bit field covered by the same checksum.</t>

        <t>The NPTv6 mapping mechanisms described in this document are
        checksum-neutral, which means that they result in IP headers that will
        generate the same IPv6 pseudo-header checksum when the checksum is
        calculated using the standard Internet checksum algorithm <xref
        target="RFC1071"></xref>. Any changes that are made during translation
        of the IPv6 prefix are offset by changes to other parts of the IPv6
        address. This results in transport layers that use the Internet
        checksum (such as TCP and UDP) calculating the same IPv6 pseudo header
        checksum for both the internal and external forms of the same packet,
        which avoids the need for the NPTv6 Translator to modify those
        transport layer headers to correct the checksum value.</t>

        <t>As noted in <xref target="FFFF"></xref>, this mapping results in an
        edge network using a /48 external prefix to be unable to use subnet
        0xFFFF.</t>
      </section>
    </section>

    <section title="NPTv6 Algorithmic Specification">
      <t>The <xref target="RFC4291"></xref> IPv6 Address is reproduced for
      clarity in <xref target="address"></xref>.</t>

      <figure anchor="address"
              title="Enumeration of the IPv6 Address [RFC4291]">
        <artwork align="center"><![CDATA[ 
 0    15 16   31 32   47 48   63 64   79 80   95 96  111 112  127
+-------+-------+-------+-------+-------+-------+-------+-------+
|     Routing Prefix    | Subnet|   Interface Identifier (IID)  |
+-------+-------+-------+-------+-------+-------+-------+-------+
]]></artwork>
      </figure>

      <section anchor="configuration" title="NPTv6 configuration calculations">
        <t>When an NPTv6 Translation function is configured, it is configured
        with <list style="symbols">
            <t>one or more "internal" interfaces with their "internal" routing
            domain prefixes, and</t>

            <t>one or more "external" interfaces with their "external" routing
            domain prefixes.</t>
          </list></t>

        <t>In the simple case, there is one of each. If a single router
        provides NPTv6 translation services between a multiplicity of domains
        (as might be true when multihoming), each internal/external pair must
        be thought of as a separate NPTv6 Translator from the perspective of
        this specification.</t>

        <t>When an NPTv6 Translator is configured, the translation function
        first ensures that the internal and external prefixes are the same
        length, if necessary by extending the shorter of the two with zeroes.
        These two prefixes will be used in the prefix translation function
        described in <xref target="leaving"></xref> and <xref
        target="returning"></xref>.</t>

        <t>They are then zero-extended to /64, for the purposes of a
        calculation. The translation function calculates the ones-complement
        sum of the 16 bit words of the /64 external prefix and the /64
        internal prefix. It then calculates the difference between these
        values: internal minus external. This value, called the "adjustment",
        is effectively constant for the lifetime of the NPTv6 Translator
        configuration, and used in per-packet processing.</t>
      </section>

      <section anchor="leaving"
               title="NPTv6 translation, internal network to external network">
        <t>When a datagram passes through the NPTv6 Translator from an
        internal to an external network, its IPv6 Source Address is changed in
        two ways: <list style="symbols">
            <t>If the internal subnet number has no mapping, such as being
            0xFFFF or simply not mapped, discard the datagram. This SHOULD
            result in an ICMP Destination Unreachable.</t>

            <t>The internal prefix is overwritten with the external prefix, in
            effect subtracting the difference between the two checksums (the
            adjustment) from the pseudo-header's checksum, and</t>

            <t>A 16-bit word of the address has the adjustment added to it
            using one's complement arithmetic. If the result is 0xFFFF, it is
            overwritten as zero. The choice of word is as specified in <xref
            target="slash48"></xref> or <xref target="slash56"></xref> as
            appropriate.</t>
          </list></t>
      </section>

      <section anchor="returning"
               title="NPTv6 translation, external network to internal network">
        <t>When a datagram passes through the NPTv6 Translator from an
        external to an internal network, its IPv6 Destination Address is
        changed in two ways: <list style="symbols">
            <t>The external prefix is overwritten with the internal prefix, in
            effect adding the difference between the two checksums (the
            adjustment) to the pseudoheader's checksum, and</t>

            <t>A 16-bit word of the address has the adjustment subtracted from
            it (bitwise inverted and added to it) it using one's complement
            arithmetic. If the result is 0xFFFF, it is overwritten as zero.
            The choice of word is as specified in <xref
            target="slash48"></xref> or <xref target="slash56"></xref> as
            appropriate.</t>
          </list></t>
      </section>

      <section anchor="slash48" title="NPTv6 with a /48 or shorter prefix">
        <t>When an NPTv6 Translator is configured with internal and external
        prefixes that are 48 bits in length (a /48) or shorter, the adjustment
        MUST be added to or subtracted from bits 48..63 of the address.</t>

        <t>This mapping results in no modification of the Interface Identifier
        (IID), which is held in the lower half of the IPv6 address, so it will
        not interfere with future protocols that may use unique IIDs for node
        identification.</t>

        <t>NPTv6 Translator implementations MUST implement the /48
        mapping.</t>
      </section>

      <section anchor="slash56" title="NPTv6 with a /49 or longer prefix">
        <t>When an NPTv6 Translator is configured with internal and external
        prefixes that are longer than 48 bits in length (such as a /52, /56,
        or /60), the adjustment must be added to or subtracted from one of the
        words in bits 64..79, 80..95, 96..111, or 112..127 of the address.
        While the choice of word is immaterial as long as it is consistent,
        for consistency's sake, these words MUST be inspected in that
        sequence, and the first that is not initially 0xFFFF chosen.</t>

        <t>NPTv6 Translator implementations SHOULD implement the mapping for
        longer prefixes.</t>
      </section>

      <section anchor="example48" title="/48 Prefix Mapping Example">
        <t>For the network shown in <xref target="simpleNPTv6"></xref>, the
        Internal Prefix is FD01:0203:0405:/48, and the External Prefix is
        2001:0DB8:0001:/48.</t>

        <t>If a node with internal address FD01:0203:0405:0001::1234 sends an
        outbound packet through the NPTv6 Translator, the resulting external
        address will be 2001:0DB8:0001:D550::1234. The resulting address is
        obtained by calculating the checksum of both the internal and external
        48-bit prefixes, subtracting the internal prefix from the external
        prefix using one's complement arithmetic to calculate the
        "adjustment", and adding the adjustment to the 16-bit subnet field (in
        this case 0x0001).</t>

        <t>To show the work:</t>

        <t>The one's complement checksum of FD01:0203:0405 is 0xFCF5. The
        one's complement checksum of 2001:0DB8:0001 is 0xD245. Using one's
        complement arithmetic, 0xD245 - 0xFCF5 = 0xD54F. The subnet in the
        original packet is 0x0001. Using one's complement arithmetic, 0x0001 +
        0xD54F = 0xD550. Since 0xD550 != 0xFFFF, it is not changed to
        0x0000.</t>

        <t>So, the value 0xD550 is written in the 16-bit subnet area,
        resulting in a mapped external address of
        2001:0DB8:0001:D550::1234.</t>

        <t>When a response packet is received, it will contain the destination
        address 2001:0DB8:0001:D550::0001, which will be mapped using the
        inverse mapping algorithm, back to FD01:0203:0405:0001::1234.</t>

        <t>In this case, the difference between the two prefixes will be
        calculated as follows:</t>

        <t>Using one's complement arithmetic, 0xFCF5 - 0xD245 = 0x2AB0. The
        subnet in the original packet = 0xD550. Using one's complement
        arithmetic, 0xD550 + 0x2AB0 = 0x0001. Since 0x0001 != 0xFFFF, it is
        not changed to 0x0000.</t>

        <t>So the value 0x0001 is written into the subnet field, and the
        internal value of the subnet field is properly restored.</t>
      </section>

      <section title="Address Mapping for Longer Prefixes">
        <t>If the prefix being mapped is longer than 48 bits, the algorithm is
        slightly more complex. A common case will be that the internal and
        external prefixes are of different length. In such a case, the shorter
        prefix is zero-extended to the length of the longer as described in
        <xref target="configuration"></xref> for the purposes of overwriting
        the prefix. Then, they are both zero-extended to 64 bits to facilitate
        one's complement arithmetic. The "adjustment" is calculated using
        those 64 bit prefixes.</t>

        <t>For example if the internal prefix is a /48 ULA and the external
        prefix is a /56 provider-allocated prefix, the ULA becomes a /56 with
        zeros in bits 48..55. For purposes of one's complement arithmetic,
        they are then both zero-extended to 64 bits. A side-effect of this is
        that a subset of the subnets possible in the shorter prefix are
        untranslatable. While the security value of this is debatable, the
        administration may choose to use them for subnets that it knows need
        no external accessibility.</t>

        <t>We then find the first word in the IID that does not have the value
        0xFFFF, trying bits 64..79, and then 80..95, 96..111, and finally
        112..127. We perform the same calculation (with the same proof of
        correctness) as in <xref target="example48"></xref>, but applying it
        to that word.</t>

        <t>Although any 16-bit portion of an IPv6 IID could contain 0xFFFF, an
        IID of all-ones is a reserved anycast identifier that should not be
        used on the network <xref target="RFC2526"></xref>. If an NPTv6
        Translator discovers a packet with an IID of all-zeros while
        performing address mapping, that packet MUST be dropped, and an ICMPv6
        Parameter Problem error SHOULD be generated <xref
        target="RFC4443"></xref>.</t>

        <t>Note: this mechanism does involve modification of the IID; it may
        not be compatible with future mechanisms that use unique IIDs for node
        identification.</t>
      </section>
    </section>

    <section title="Implications of Network Address Translator Behavioral Requirements">
      <section title="Prefix configuration and generation">
        <t>NPTv6 Translators MUST support manual configuration of internal and
        external prefixes, and MUST NOT place any restrictions on those
        prefixes except that they be valid IPv6 unicast prefixes as described
        in <xref target="RFC4291"></xref>. They MAY also support random
        generation of ULA addresses on command. Since the most common place
        anticipated for the implementation of an NPTv6 Translator is a CPE
        router, the reader is urged to consider the requirements of <xref
        target="I-D.ietf-v6ops-ipv6-cpe-router"></xref>.</t>
      </section>

      <section anchor="FFFF" title="Subnet numbering">
        <t>For reasons detailed in <xref target="math"></xref>, a network
        using NPTv6 Translation and a /48 external prefix MUST NOT use the
        value 0xFFFF to designate a subnet that it expects to be
        translated.</t>
      </section>

      <section anchor="requirements" title="NAT Behavioral Requirements">
        <t>NPTv6 Translators MUST support hairpinning behavior, as defined in
        the NAT Behavioral Requirements for UDP document <xref
        target="RFC4787"></xref>. This means that when an NPTv6 Translator
        receives a packet on the internal interface that has a destination
        address that matches the site's external prefix, it will translate the
        packet and forward it internally. This allows internal nodes to reach
        other internal nodes using their external, global addresses when
        necessary.</t>

        <t>Conceptually, the datagram leaves the domain (is translated as
        described in <xref target="leaving"></xref>), and returns (is again
        translated as described in <xref target="returning"></xref>). As a
        result, the datagram exchange will be through the NPTv6 Translator in
        both directions for the lifetime of the session. The alternative would
        be to require the NPTv6 Translator to drop the datagram, forcing the
        sender to use the correct internal prefix for its peer. Performing
        only the external-to-internal translation results in the datagram
        being sent from the untranslated internal address of the source to the
        translated and therefore internal address of its peer, which would
        enable the session to bypass the NPTv6 Translator for future
        datagrams. It would also mean that the original sender would be
        unlikely to recognize the response when it arrived.</t>

        <t>Because NPTv6 does not perform port mapping and uses a one-to-one,
        reversible mapping algorithm, none of the other NAT behavioral
        requirements apply to NPTv6.</t>
      </section>
    </section>

    <section title="Implications for Applications">
      <t>NPTv6 Translation does not create several of the problems known to
      exist with other kinds of NATs and discussed in <xref
      target="RFC2993"></xref>. In particular: NPTv6 Translation is stateless,
      so a "reset" or brief outage of an NPTv6 Translator does not break
      connections that traverse the translation function, and if multiple
      NPTv6 Translators exist between the same two networks, load can shift or
      be dynamically load-shared among them. Also, an NPTv6 Translator does
      not aggregate traffic for several hosts/interfaces behind a lesser
      number of external addresses, so there is no inherent expectation for an
      NPTv6 Translator to block new inbound flows from external hosts, and no
      issue with a filter or blacklist associated with one prefix within the
      domain affecting another. A firewall can of course be used in
      conjunction with NPTv6 Translator; this would allow the network
      administrator more flexibility to specify security policy than would be
      possible with a traditional NAT.</t>

      <t>However, NPTv6 Translation does create difficulties for some kinds of
      applications. Some examples include: <list style="symbols">
          <t>An application instance "behind" an NPTv6 Translator will see a
          different address for its connections than its peers "outside" the
          NPTv6 Translator.</t>

          <t>An application instance "outside" an NPTv6 Translator will see a
          different address for its connections than any peer "inside" an
          NPTv6 Translator.</t>

          <t>An application instance wishing to establish communication with a
          peer "behind" an NPTv6 Translator may need to use a different
          address to reach that peer depending on whether the instance is
          behind the same NPTv6 Translator or external to it. Since an NPTv6
          Translator implements <xref
          target="requirements">hairpinning</xref>, it suffices for
          applications to always use their external addresses. However, this
          creates inefficiencies in the local network and may also complicate
          implementation of the NPTv6 Translator. <xref
          target="RFC3484"></xref> also would prefer the private address in
          such a case in order to reduce those inefficiencies.</t>

          <t>An application instance which moves from a realm "behind" an
          NPTv6 Translator to a realm that is "outside" the network, or vice
          versa, may find that it is no longer able to reach its peers at the
          same addresses it was previously able to use.</t>

          <t>An application instance which is intermittently communicating
          with a peer that moves from behind an NPTv6 Translator to "outside"
          of it, or vice versa, may find that it is no longer able to reach
          that peer at the same address that it had previously used.</t>
        </list></t>

      <t>Many, but not all, of the applications which are adversely affected
      by NPTv6 Translation are those that do "referrals" - where an
      application instance passes its own addresses, and/or addresses of its
      peers, to other peers. (Some believe referrals are inherently
      undesirable; others believe that they are necessary in some
      circumstances. A discussion of the merits of referrals, or lack thereof,
      is beyond the scope of this document.)</t>

      <t>To some extent, the incidence of these difficulties can be reduced by
      DNS hacks that attempt to expose addresses "behind" an NPTv6 Translator
      only to hosts which are also behind the same NPTv6 Translator; and
      perhaps also, to expose only the "internal" addresses of hosts behind
      the NPTv6 Translator to other hosts behind the same NPTv6 Translator.
      However, this cannot be a complete solution. A full discussion of these
      issues is out of scope for this document, but briefly: (a) reliance on
      DNS to solve this problem depends on hosts always making queries from
      DNS servers in the same realm as they are (or on DNS interception
      proxies, which create their own problems), and on mobile
      hosts/applications not caching those results; (b) reliance on DNS to
      solve this problem depends on network administrators on all networks
      using such applications to reliably and accurately maintain current DNS
      entries for every host using those applications; and (c) reliance on DNS
      to solve this problem depends on applications always using DNS names,
      even though they often must run in environments where DNS names are not
      reliably maintained for every host. Other issues are that there is often
      no single distinguished name for a host, no reliable way for a host to
      determine what DNS names are associated with it, and which names are
      appropriate to use in which contexts.</t>

      <section title="Recommendation for network planners considering use of NPTv6 Translation">
        <t>In light of the above, network planners considering the use of
        NPTv6 translation should carefully consider the kinds of applications
        that they will need to run in the future, and determine whether the
        address stability and provider independence benefits are consistent
        with their application requirements.</t>
      </section>

      <section title="Recommendations for application writers">
        <t>Several mechanisms (e.g. STUN, TURN, ICE) have been used with
        traditional IPv4 NAT to circumvent some of the limitations of such
        devices. Similar mechanisms could also be applied to circumvent some
        of the issues with NPTv6 Translator. However, all of these require the
        assistance of an external server or a function co-located with the
        translator that can tell an "internal" host what its "external"
        addresses are.</t>
      </section>

      <section title="Recommendation for future work">
        <t>It might be desirable to define a general mechanism which would
        allow hosts within a translation domain to determine their external
        addresses and/or request that inbound traffic be permitted. If such a
        mechanism were to be defined, it would ideally be general enough to
        also accommodate other types of NAT likely to be encountered by IPV6
        applications - in particular, <xref
        target="I-D.ietf-behave-v6v4-framework">IPv4/IPv6 Translation</xref>
        <xref target="I-D.ietf-behave-dns64"></xref> <xref
        target="I-D.ietf-behave-v6v4-xlate"></xref> <xref
        target="I-D.ietf-behave-v6v4-xlate-stateful"></xref> <xref
        target="RFC6052"></xref>. For this and other reasons, such a mechanism
        is beyond the scope of this document.</t>
      </section>
    </section>

    <section title="A Note on Port Mapping">
      <t>In addition to overwriting IP addresses when packets are forwarded,
      NAPT44 devices overwrite the source port number in outbound traffic, and
      the destination port number in inbound traffic. This mechanism is called
      "port mapping".</t>

      <t>The major benefit of port mapping is that it allows multiple
      computers to share a single IPv4 address. A large number of internal
      IPv4 addresses (typically from one of the <xref target="RFC1918"></xref>
      private address spaces) can be mapped into a single external, globally
      routable IPv4 address, with the local port number used to identify which
      internal node should receive each inbound packet. This address
      amplification feature is not generally foreseen as a necessity at this
      time.</t>

      <t>Since port mapping requires re-writing a portion of the transport
      layer header, it requires NAPT44 devices to be aware of all of the
      transport protocols that they forward, thus stifling the development of
      new and improved transport protocols and preventing the use of IPsec
      encryption. Modifying the transport layer header is incompatible with
      security mechanisms that encrypt the full IP payload, and restricts the
      NAPT44 to forwarding transport layers that use weak checksum algorithms
      that are easily recalculated in routers.</t>

      <t>Since there is significant detriment caused by modifying transport
      layer headers and very little, if any, benefit to the use of port
      mapping in IPv6, NPTv6 Translators that comply with this specification
      MUST NOT perform port mapping.</t>
    </section>

    <section anchor="security" title="Security Considerations">
      <t>When NPTv6 is deployed using either of the two-way, algorithmic
      mappings defined in the document, it allows direct inbound connections
      to internal nodes. While this can be viewed as a benefit of NPTv6 vs.
      NAPT44, it does open internal nodes to attacks that would be more
      difficult in a NAPT44 network. Although this situation is not
      substantially worse, from a security standpoint, than running IPv6 with
      no NAT, some enterprises may assume that an NPTv6 Translator will offer
      similar protection to a NAPT44 device.</t>

      <t>The port mapping mechanism in NAPT44 implementations requires that
      state be created in both directions. This has lead to an industry-wide
      perception that NAT functionality is the same as a stateful firewall. It
      is not. The translation function of the NAT only creates dynamic state
      in one direction and has no policy. For this reason, it is RECOMMENDED
      that NPTv6 Translators also implement firewall functionality such as
      described in <xref target="RFC6092"></xref>, with appropriate
      configuration options including turning it on or off.</t>

      <t>When <xref target="RFC4864"></xref> talks about randomizing the
      subnet identifier, the idea is to make it harder for worms to guess a
      valid subnet identifier at an advertised network prefix. This should not
      be interpreted as endorsing concealing the subnet identifier behind the
      obfuscating function of a translator such as NPTv6. <xref
      target="RFC4864"></xref> specifically talks about how to obtain the
      desired properties of concealment without using a translator. Topology
      hiding when using NAT is often ineffective in environments where the
      topology is visible in application layer messaging protocols such as
      DNS, SIP, SMTP, etc. If the information were not available through the
      application layer, <xref target="RFC2993"></xref> would not be
      valid.</t>

      <t>Due to the potential interactions with IKEv2/IPsec NAT traversal, it
      would be valuable to test interactions of NPTv6 with various aspects of
      current-day IKEv2/IPsec NAT traversal.</t>
    </section>

    <section title="IANA Considerations">
      <t>This document has no IANA considerations.</t>
    </section>

    <section title="Acknowledgements">
      <t>The checksum-neutral algorithmic address mapping described in this
      document is based on e-mail written by Iljtsch van Beijnum.</t>

      <t>The following people provided advice or review comments that
      substantially improved this document: Allison Mankin, Christian Huitema,
      Dave Thaler, Ed Jankiewicz, Eric Kline, Iljtsch van Beijnum, Jari Arkko,
      Keith Moore, Mark Townsley, Merike Kaeo, Ralph Droms, Remi Depres, Steve
      Blake, and Tony Hain.</t>

      <t>This document was written using the xml2rfc tool described in RFC
      2629 <xref target="RFC2629"></xref>.</t>
    </section>

    <section title="Change Log">
      <t>This section should be removed by the RFC Editor.</t>

      <section title="Changes Between draft-mrw-behave-nat66-00 and -01">
        <t>There were several minor changes made between the *behave-nat66-00
        and -01 versions of this draft: <list style="symbols">
            <t>Added Fred Baker as a co-author.</t>

            <t>Minor arithmetic corrections.</t>

            <t>Added AH to paragraph on NAT security issues.</t>

            <t>Added additional NAT topologies to overview (diagrams TBD).</t>
          </list></t>
      </section>

      <section title="Changes between *behave-nat66-01 and -02">
        <t>There were further changes made between *behave-nat66-01 and -02:
        <list style="symbols">
            <t>Removed topology hiding mechanism.</t>

            <t>Added diagrams.</t>

            <t>Made minor updates based on mailing list feedback.</t>

            <t>Added discussion of IPv6 SAF document.</t>

            <t>Added applicability section.</t>

            <t>Added discussion of Address Independence requirement.</t>

            <t>Added hairpinning requirement and discussion of applicability
            of other NAT behavioral requirements.</t>
          </list></t>
      </section>

      <section title="Changes between *nat66-00 and *nat66-01">
        <t>There were further changes made between nat66-01 and nat66-02:
        <list style="symbols">
            <t>Added mapping for prefixes longer than /48.</t>

            <t>Change draft name to remove reference to the behave WG.</t>

            <t>Resolved various open issues and fixed typos.</t>
          </list></t>
      </section>

      <section title="Changes between *nat66-01 and *nat66-02">
        <t><list style="symbols">
            <t>Change the acronym "NAT66" to "NPTv6", so people don't read
            "NAT" and MEGO.</t>

            <t>Change the term used to refer to the function from "NAT66
            device" to "NPTv6 Translator". It's not a "device" function, it's
            a function that is applied between two interfaces. Consider a
            router with two upstreams and two legs in the local network; it
            will not translate between the local legs, but will translate to
            and from each upstream, and be configured differently for each of
            the two ISPs.</t>

            <t>Comment specifically on the security aspects.</t>

            <t>Comment specifically on the application issues raised on this
            list.</t>

            <t>Comment specifically on multihoming, load-sharing, and
            asymmetric routing.</t>

            <t>Spell out the hairpinning requirement and its implications.</t>

            <t>Spell out the service provider side of Address
            Independence.</t>

            <t>00 focuses on the edge's view</t>

            <t>Detail the algorithm in a manner clearer to the implementor (I
            think)</t>

            <t>Spell out the case for GSE-style DMZs between the edge and the
            transit network, which is about the implications for the global
            routing table.</t>

            <t>Refer to <xref target="RFC6092"></xref> as a CPE firewall
            description.</t>
          </list></t>
      </section>

      <section title="Changes between *nat66-02 and *nat66-03">
        <t><list style="symbols">
            <t>Added an appendix on Verification code</t>

            <t>Various minor markups in response to Ralph Droms</t>
          </list></t>
      </section>

      <section title="Changes between *nat66-03 and *nat66-04">
        <t><list style="symbols">
            <t>Markups in response to Christian Huitema, mostly surrounding
            the issue of subnet 0xFFFF.</t>

            <t>Refer to <xref target="I-D.ietf-v6ops-ipv6-cpe-router"></xref>
            for CPE router requirements.</t>
          </list></t>
      </section>

      <section title="Changes between *nat66-04 and *nat66-05">
        <t><list style="symbols">
            <t>Update statistics in appendix A per BGP report of 17 December
            2010</t>

            <t>Update security considerations using text supplied by Merike
            Kaeo.</t>
          </list></t>
      </section>

      <section title="Changes between *nat66-05 and *nat66-06">
        <t><list style="symbols">
            <t>restore a code snippet inadvertently removed in version -05</t>
          </list></t>
      </section>

      <section title="Changes between *nat66-06 and *nat66-07">
        <t><list style="symbols">
            <t>Changed requested status to experimental</t>

            <t>Incorporated comments from Eric Kline</t>
          </list></t>
      </section>

      <section title="Changes between *nat66-07 and *nat66-08">
        <t>The section on Application Considerations was expanded after
        discussion with Keith Moore.</t>
      </section>

      <section title="Changes up to *nat66-10">
        <t>Address review comments during IETF Last Call and the Transport
        Directorate Review.</t>
      </section>

      <section title="Changes up to *nat66-11 and -12">
        <t>Address Dave Thaler's comments, mostly editorial, bit also
        addressing UNSAF protocols like the TCP Authentication Option.</t>
      </section>
    </section>
  </middle>

  <back>
    <references title="Normative References">
      <?rfc include="reference.RFC.2119" ?>

      <?rfc include="reference.RFC.2526" ?>

      <?rfc include="reference.RFC.4193" ?>

      <?rfc include="reference.RFC.4291" ?>

      <?rfc include="reference.RFC.4443" ?>

      <?rfc include="reference.RFC.4787" ?>
    </references>

    <references title="Informative References">
      <?rfc include="reference.I-D.ietf-v6ops-ipv6-cpe-router"?>

      <?rfc include="reference.RFC.1071" ?>

      <?rfc include="reference.RFC.1624" ?>

      <?rfc include="reference.RFC.1918" ?>

      <?rfc include="reference.RFC.2629" ?>

      <?rfc include="reference.RFC.2827" ?>

      <?rfc include="reference.RFC.2993" ?>

      <?rfc include="reference.RFC.3424" ?>

      <?rfc include="reference.RFC.3484" ?>

      <?rfc include="reference.RFC.4864" ?>

      <?rfc include="reference.RFC.5902" ?>

      <?rfc include="reference.RFC.5925" ?>

      <?rfc include="reference.RFC.5996" ?>

      <?rfc include="reference.RFC.6092" ?>

      <?rfc include="reference.I-D.ietf-behave-dns64" ?>

      <?rfc include="reference.I-D.ietf-behave-v6v4-framework" ?>

      <?rfc include="reference.I-D.ietf-behave-v6v4-xlate" ?>

      <?rfc include="reference.I-D.ietf-behave-v6v4-xlate-stateful" ?>

      <?rfc include="reference.RFC.6052" ?>

      <reference anchor="NIST">
        <front>
          <title>Draft NIST Framework and Roadmap for Smart Grid
          Interoperability, Release 1.0</title>

          <author fullname="NIST" initials="" surname="NIST">
            <organization>NIST</organization>
          </author>

          <date month="September" year="2009" />
        </front>

        <format target="http://www.nist.gov/public_affairs/releases/upload/smartgrid_interoperability.pdf"
                type="PDF" />
      </reference>

      <reference anchor="GSE"
                 target="http://tools.ietf.org/id/draft-ietf-ipngwg-gseaddr">
        <front>
          <title>GSE - An Alternate Addressing Architecture for IPv6</title>

          <author fullname=" Mike O'Dell" initials="M." surname="O'Dell">
            <organization>UUNET Technologies</organization>
          </author>

          <date month="February" year="1997" />
        </front>

        <format target="http://tools.ietf.org/id/draft-ietf-ipngwg-gseaddr"
                type="TXT" />
      </reference>
    </references>

    <section anchor="appendix1" title="Why GSE?">
      <t>For the purpose of this discussion, let us over-simplify the
      Internet's structure by distinguishing between two broad classes of
      networks: transit and edge. A "transit network", in this context, is a
      network that provides connectivity services to other networks. Its AS
      number may show up in a non-final position in BGP AS paths, or in the
      case of mobile and residential broadband networks, it may offer network
      services to smaller networks that can't justify RIR membership. An "edge
      network", in contrast, is any network that is not a transit network; it
      is the ultimate customer, and while it provides internal connectivity
      for its own use, it is in other respects a consumer of transit services.
      In terms of routing, a network in the transit domain generally needs
      some way to make choices about how it routes to other networks; an edge
      network is generally quite satisfied with a simple default route.</t>

      <t>The <xref target="GSE"></xref> proposal, and as a result this
      proposal (which is similar to GSE in most respects and inspired by it),
      responds directly to current concerns in the RIR communities. Edge
      networks are used to an environment in IPv4 in which their addressing is
      disjoint from that of their upstream transit networks; it is either
      provider independent, or a network prefix translator makes their
      external address distinct from their internal address, and they like the
      distinction. In IPv6, there is a mantra that edge network addresses
      should be derived from their upstream, and if they have multiple
      upstreams, edge networks are expected to design their networks to use
      all of those prefixes equivalently. They see this as unnecessary and
      unwanted operational complexity, and are as a result pushing very hard
      in the RIR communities for provider independent addressing.</t>

      <t>Widespread use of provider independent addressing has a natural and
      perhaps unavoidable side-effect that is likely to be very expensive in
      the long term. It means that the routing table will enumerate the
      networks at the edge of the transit domain, the edge networks, rather
      than enumerating the transit domain. Per the BGP Update Report of 17
      December 2010, there are currently over 36,000 Autonomous Systems being
      advertised in BGP, of which over 15,000 advertise only one prefix. There
      are in the neighborhood of 5000 AS's that show up in a non-final
      position in AS paths, and perhaps another 5000 networks whose AS numbers
      are terminal in more than one AS path. In other words, we have prefixes
      for some 36,000 transit and edge networks in the route table now, many
      of which arguably need an Autonomous System number only for multihoming.
      Current estimates suggest that we could easily see that be on the order
      of 10,000,000 within fifteen years. However, the vast majority of
      networks (2/3) having the tools necessary to multihome are not visibly
      doing so, and would be well served by any solution that gives them
      address independence without the overhead of RIR membership and BGP
      routing.</t>

      <t>Current growth estimates suggest that we could easily see that be on
      the order of 10,000,000 within fifteen years. Tens of thousands of
      entries in the route table is very survivable; while our protocols and
      computers will likely do quite well with tens of millions of routes, the
      heat produced and power consumed by those routers, and the inevitable
      impact on the cost of those routers, is not a good outcome. To avoid
      having a massive and unscalable route table, we need to find a way that
      is politically acceptable and returns us to enumerating the transit
      domain, not the edge.</t>

      <t>There have been a number of proposals. As described, shim6 moves the
      complexity to the edge, and the edge is rebelling. Geographic addressing
      in essence forces ISPs to "own" geographic territory from a routing
      perspective, as otherwise there is no clue in the address as to what
      network a datagram should be delivered to in order to reach it.
      Metropolitan Addressing can imply regulatory authority, and even if it
      is implemented using internet exchange consortia, visits a great deal of
      complexity on the transit networks that directly serve the edge. The one
      that is likely to be most acceptable is any proposal that enables an
      edge network to be operationally independent of its upstreams, with no
      obligation to renumber when it adds, drops, or changes ISPs, and with no
      additional burden placed either on the ISP or the edge network as a
      result. From an application perspective, an additional operational
      requirement in the words of <xref target="NIST"> Roadmap for the Smart
      Grid</xref>, is that <list style="empty">
          <t>"...the Network should enable an application in a particular
          domain to communicate with an application in any other domain in the
          information network, with proper management control over who and
          where applications can be interconnected."</t>
        </list></t>

      <t>In other words, the structure of the network should allow for and
      enable appropriate access control, but the structure of the network
      should not inherently limit access.</t>

      <t>The GSE model, by statelessly translating the prefix between an edge
      network and its upstream transit network, accomplishes that with a
      minimum of fuss and bother. Stated in the simplest terms, it enables the
      edge network to behave as if it has a provider independent prefix from a
      multihoming and renumbering perspective without the overhead of RIR
      membership or maintaining BGP connectivity, and it enables the transit
      networks to aggressively aggregate what are from their perspective
      provider-allocated customer prefixes, to maintain a rational-sized
      routing table.</t>
    </section>

    <section anchor="math" title="Verification code">
      <t>This non-normative appendix is presented as a proof of concept. It is
      in no sense optimized; for example, one's complement arithmetic is
      implemented in portable subroutines, where operational implementations
      might use one's complement arithmetic instructions through a pragma;
      such implementations probably need to explicitly force 0xFFFF to 0x0000,
      as the instruction will not. The original purpose of the code was to
      verify whether or not it was necessary to suppress 0xFFFF by overwriting
      with zero, and whether predicted issues with subnet numbering were
      real.</t>

      <t>The point is to<list style="symbols">
          <t>demonstrate that if one or the other representation of zero is
          not used in the word the checksum is updated in, the program maps
          inner and outer addresses in a manner that is, mathematically, 1:1
          and onto (each inner address maps to a unique outer address, and
          that outer address maps back to exactly the same inner address),
          and</t>

          <t>give guidance on the suppression of 0xFFFF checksums.</t>
        </list></t>

      <t>In short, in one's complement arithmetic, x-x=0, but will take the
      negative representation of zero. If 0xFFFF results are forced to the
      value 0x0000, as is recommended in <xref target="RFC1071"></xref>, the
      word the checksum is adjusted in cannot be initially 0xFFFF, as on the
      return it will be forced to 0. If 0xFFFF results are not forced to the
      value 0x0000 as is recommended in <xref target="RFC1071"></xref>, the
      word the checksum is adjusted in cannot be initially 0, as on the return
      it will be calculated as 0+(~0) = 0xFFFF. We chose to follow <xref
      target="RFC1071"></xref>'s recommendations, which implies a requirement
      to not use 0xFFFF as a subnet number in networks with a /48 external
      prefix.</t>

      <figure>
        <artwork><![CDATA[
/*
 * Copyright (c) 2010 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, are permitted provided that the following
 * conditions are met:
 *
 * o  Redistributions of source code must retain the above
 *    copyright notice, this list of conditions and the
 *    following disclaimer.
 *
 * o  Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the
 *    following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * o  Neither the name of Internet Society, IETF or IETF Trust,
 *    nor the names of specific contributors, may be used to
 *    endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include "stdio.h"
#include "assert.h"
/*
 * program to verify the NPTv6 algorithm
 *
 * argument:
 *     perform negative zero suppression: boolean
 *
 * method:
 *    We specify an internal and an external prefix. The prefix
 *    length is presumed to be the common length of both, and for
 *    this is a /48. We perform the three algorithms specified.
 *    the "packet" address is in effect the source address
 *    internal->external and the destination address
 *    external->internal.
 */
unsigned short  inner_init[] = {
    0xFD01, 0x0203, 0x0405, 1, 2, 3, 4, 5};
unsigned short  outer_init[] = {
    0x2001, 0x0db8, 0x0001, 1, 2, 3, 4, 5};
unsigned short  inner[8];
unsigned short  packet[8];
unsigned char   checksum[65536] = {0};
unsigned short  outer[8];
unsigned short  adjustment;
unsigned short  suppress;
/*
 * One's complement sum.
 * return number1 + number2
 */
unsigned short
add1(number1, number2)
    unsigned short  number1;
    unsigned short  number2;
{
    unsigned int    result;

    result = number1;
    result += number2;
    if (suppress) {
        while (0xFFFF <= result) {
            result = result + 1 - 0x10000;
        }
    } else {
        while (0xFFFF < result) {
            result = result + 1 - 0x10000;
        }
    }
    return result;
}

/*
 * One's complement difference
 * return number1 - number2
 */
unsigned short
sub1(number1, number2)
    unsigned short  number1;
    unsigned short  number2;
{
    return add1(number1, ~number2);
}

/*
 * return one's complement sum of an array of numbers
 */
unsigned short
sum1(numbers, count)
    unsigned short *numbers;
    int             count;
{
    unsigned int    result;

    result = *numbers++;
    while (--count > 0) {
        result += *numbers++;
    }

    if (suppress) {
        while (0xFFFF <= result) {
            result = result + 1 - 0x10000;
        }
    } else {
        while (0xFFFF < result) {
            result = result + 1 - 0x10000;
        }
    }
    return result;
}

/*
 * NPTv6 initialization: section 3.1 assuming section 3.4
 *
 * create the /48, a source address in internal format, and a
 * source address in external format. calculate the adjustment
 * if one /48 is overwritten with the other.
 */
void
nptv6_initialization(subnet)
    unsigned short  subnet;
{
    int             i;
    unsigned short  inner48;
    unsigned short  outer48;

    /* initialize the internal and external prefixes. */
    for (i = 0; i < 8; i++) {
        inner[i] = inner_init[i];
        outer[i] = outer_init[i];
    }
    inner[3] = subnet;
    outer[3] = subnet;
    /* calculate the checksum adjustment */
    inner48 = sum1(inner, 3);
    outer48 = sum1(outer, 3);
    adjustment = sub1(inner48, outer48);
}

/*
 * NPTv6 packet from edge to transit: section 3.2 assuming
 * section 3.4
 *
 * overwrite the prefix in the source address with the outer
 * prefix, and adjust the checksum
 */
void
nptv6_inner_to_outer()
{
    int             i;

    /* let's get the source address into the packet */
    for (i = 0; i < 8; i++) {
        packet[i] = inner[i];
    }

    /* overwrite the prefix with the outer prefix */
    for (i = 0; i < 3; i++) {
        packet[i] = outer[i];
    }

    /* adjust the checksum */
    packet[3] = add1(packet[3], adjustment);
}

/*
 * NPTv6 packet from transit to edge:: section 3.3 assuming
 * section 3.4
 *
 * overwrite the prefix in the destination address with the
 * inner prefix, and adjust the checksum
 */
void
nptv6_outer_to_inner()
{
    int             i;

    /* overwrite the prefix with the outer prefix */
    for (i = 0; i < 3; i++) {
        packet[i] = inner[i];
    }

    /* adjust the checksum */
    packet[3] = sub1(packet[3], adjustment);
}

/*
 * main program
 */
main(argc, argv)
    int             argc;
    char          **argv;
{
    unsigned        subnet;
    int             i;

    if (argc < 2) {
           fprintf(stderr, "usage: nptv6 supression\n");	 		
           assert(0);	 		
       }	 		
       suppress = atoi(argv[1]);	 		
       assert(suppress <= 1);	 		
 		
       for (subnet = 0; subnet < 0x10000; subnet++) {	 		
           /* section 3.1: initialize the system */	 		
           nptv6_initialization(subnet);	 		
 		
           /* section 3.2: take a packet from inside to outside */	 		
           nptv6_inner_to_outer();	 		

           /* the resulting checksum value should be unique */	 		
           if (checksum[subnet]) {
                printf("inner->outer duplicated checksum: "
                       "inner: %x:%x:%x:%x:%x:%x:%x:%x(%x) "
                       "calculated: %x:%x:%x:%x:%x:%x:%x:%x(%x)\n",
                       inner[0], inner[1], inner[2], inner[3],
                       inner[4], inner[5], inner[6], inner[7],
                       sum1(inner, 8),
                       packet[0], packet[1], packet[2], packet[3],
                       packet[4], packet[5], packet[6], packet[7],
                       sum1(packet, 8));
        }

        checksum[subnet] = 1;

        /*
         * the resulting checksum should be the same as the inner
         * address's checksum
         */
        if (sum1(packet, 8) != sum1(inner, 8)) {
            printf("inner->outer incorrect: "
                   "inner: %x:%x:%x:%x:%x:%x:%x:%x(%x) "
                   "calculated: %x:%x:%x:%x:%x:%x:%x:%x(%x)\n",
                   inner[0], inner[1], inner[2], inner[3],
                   inner[4], inner[5], inner[6], inner[7],
                   sum1(inner, 8),
                   packet[0], packet[1], packet[2], packet[3],
                   packet[4], packet[5], packet[6], packet[7],
                   sum1(packet, 8));
        }

        /* section 3.3: take a packet from outside to inside */
        nptv6_outer_to_inner();

        /*
         * the returning packet should have the same checksum it
         * left with
         */
        if (sum1(packet, 8) != sum1(inner, 8)) {
            printf("outer->inner checksum incorrect: "
                   "calculated: %x:%x:%x:%x:%x:%x:%x:%x(%x) "
                   "inner: %x:%x:%x:%x:%x:%x:%x:%x(%x)\n",
                   packet[0], packet[1], packet[2], packet[3],
                   packet[4], packet[5], packet[6], packet[7],
                sum1(packet, 8), inner[0], inner[1], inner[2],
                   inner[3], inner[4], inner[5], inner[6],
                   inner[7], sum1(inner, 8));
        }

        /*
         * and every octet should calculate back to the same inner
         * value
         */
        for (i = 0; i < 8; i++) {
            if (inner[i] != packet[i]) {
                printf("outer->inner different: "
                       "calculated: %x:%x:%x:%x:%x:%x:%x:%x "
                       "inner: %x:%x:%x:%x:%x:%x:%x:%x\n",
                   packet[0], packet[1], packet[2], packet[3],
                   packet[4], packet[5], packet[6], packet[7],
                       inner[0], inner[1], inner[2], inner[3],
                       inner[4], inner[5], inner[6], inner[7]);
                break;
            }
        }
    }
}
]]></artwork>
      </figure>
    </section>
  </back>
</rfc>

PAFTECH AB 2003-20262026-04-23 14:42:58