RFC 4007

IPv6 Scoped Address Architecture

πŸ“… published March 2005, from ietf

RFC 4007: IPv6 Scoped Address Architecture πŸ¦‹

okay bestie, this is RFC 4007, and it's giving main character energy πŸ’… It's titled "IPv6 Scoped Address Architecture" and it came out of the Network Working Group in March 2005. It's a Standards Track document, so it's an actual protocol spec. The authors are S. Deering (Cisco Systems), B. Haberman (Johns Hopkins Univ), T. Jinmei (Toshiba), E. Nordmark (Sun Microsystems), and B. Zill (Microsoft). The header doesn't list any RFCs that it obsoletes or updates 🌸

Status of This Memo ✨

this doc specifies an Internet standards track protocol for the Internet community, and it's basically asking for discussion and suggestions for improvements 🫢 for the standardization state and status of this protocol, check the current edition of the "Internet Official Protocol Standards" (STD 1). distribution of this memo is unlimited 🌈

Copyright (C) The Internet Society (2005).

Abstract πŸ¦‹

this document describes the architectural characteristics, expected behavior, textual representation, and usage of IPv6 addresses of different scopes πŸ”₯ fun fact: according to a decision in the IPv6 working group, this document intentionally avoids the syntax and usage of unicast site-local addresses. not me skipping that drama πŸ™ˆ

Table of Contents πŸ“–

1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . .   2
2.  Definitions  . . . . . . . . . . . . . . . . . . . . . . . .   3
3.  Basic Terminology  . . . . . . . . . . . . . . . . . . . . .   3
4.  Address Scope  . . . . . . . . . . . . . . . . . . . . . . .   3
5.  Scope Zones  . . . . . . . . . . . . . . . . . . . . . . . .   4
6.  Zone Indices . . . . . . . . . . . . . . . . . . . . . . . .   6
7.  Sending Packets  . . . . . . . . . . . . . . . . . . . . . .  11
8.  Receiving Packets  . . . . . . . . . . . . . . . . . . . . .  11
9.  Forwarding . . . . . . . . . . . . . . . . . . . . . . . . .  11
10. Routing  . . . . . . . . . . . . . . . . . . . . . . . . . .  13
11. Textual Representation . . . . . . . . . . . . . . . . . . .  15
    11.1.  Non-Global Addresses  . . . . . . . . . . . . . . . .  15
    11.2.  The <zone_id> Part. . . . . . . . . . . . . . . . . .  15
    11.3.  Examples. . . . . . . . . . . . . . . . . . . . . . .  17
    11.4.  Usage Examples. . . . . . . . . . . . . . . . . . . .  17
    11.5.  Related API . . . . . . . . . . . . . . . . . . . . .  18
    11.6.  Omitting Zone Indices . . . . . . . . . . . . . . . .  18
    11.7.  Combinations of Delimiter Characters. . . . . . . . .  18
12. Security Considerations  . . . . . . . . . . . . . . . . . .  19
13. Contributors . . . . . . . . . . . . . . . . . . . . . . . .  20
14. Acknowledgements . . . . . . . . . . . . . . . . . . . . . .  20
15. References . . . . . . . . . . . . . . . . . . . . . . . . .  20
    15.1. Normative References . . . . . . . . . . . . . . . . .  20
    15.2. Informative References . . . . . . . . . . . . . . . .  21
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . .  22
Full Copyright Statement . . . . . . . . . . . . . . . . . . . .  24

1. Introduction 🌸

IPv6 supports addresses of different "scope," which means both global and non-global (e.g., link-local) addresses ✨ non-global addressing already showed up operationally in the IPv4 Internet, both through private address space ("net 10", etc.) and with administratively scoped multicast addresses. but IPv6 formally bakes the notion of address scope into its base architecture πŸ’… this document describes the architectural characteristics, expected behavior, textual representation, and usage of IPv6 addresses of different scopes.

ok so the current address architecture spec [1] defines unicast site-local addresses, but the IPv6 working group decided to deprecate the syntax and the usage [5] and is now looking into other forms of local IPv6 addressing πŸ‘€ any usage of new forms of local addresses will be documented elsewhere in the future. so this document intentionally focuses on link-local and multicast scopes only πŸ¦‹

2. Definitions πŸ’œ

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 [2] 🫢

3. Basic Terminology 🧚

the terms link, interface, node, host, and router are defined in [3]. the definitions of unicast address scopes (link-local and global) and multicast address scopes (interface-local, link-local, etc.) are in [1] πŸ“

4. Address Scope ✨

every IPv6 address other than the unspecified address has a specific scope, meaning a topological span within which the address may be used as a unique identifier for an interface or a set of interfaces πŸ”₯ the scope of an address is encoded as part of the address, as specified in [1].

for unicast addresses, this document discusses two defined scopes:

  • Link-local scope, for uniquely identifying interfaces within (i.e., attached to) a single link only.
  • Global scope, for uniquely identifying interfaces anywhere in the Internet.

the IPv6 unicast loopback address, ::1, is treated as having link-local scope within an imaginary link to which a virtual "loopback interface" is attached 🌈

the unspecified address, ::, is a special case πŸ‘‘ it doesn't have any scope, because it must never be assigned to any node according to [1]. but heads up: an implementation might use implementation dependent semantics for the unspecified address, and it may want to let the unspecified address have specific scopes πŸ™ˆ for example, implementations often use the unspecified address to represent "any" address in APIs. in that case, implementations may treat the unspecified address with a given particular scope as representing the notion of "any address in the scope". this document does not prohibit that usage, as long as it stays limited within the implementation πŸ’–

[1] defines IPv6 addresses with embedded IPv4 addresses as being part of global addresses, so those addresses have global scope with regard to the IPv6 scoped address architecture πŸ’… however, an implementation may use those addresses as if they had other scopes, for convenience. for instance, [6] assigns link-local scope to IPv4 auto-configured link-local addresses (the addresses from the prefix 169.254.0.0/16 [7]) and converts those addresses into IPv4-mapped IPv6 addresses so it can do destination address selection among IPv4 and IPv6 addresses πŸ¦‹ that would implicitly mean the IPv4-mapped IPv6 addresses equivalent to the IPv4 auto-configuration link-local addresses have link-local scope. this document doesn't preclude that usage, as long as it stays limited within the implementation 🫢

anycast addresses [1] are allocated from the unicast address space and have the same scope properties as unicast addresses. all statements in this document about unicast apply equally to anycast ✨

for multicast addresses, there are fourteen possible scopes, ranging from interface-local to global (including link-local) 🌸 the interface-local scope spans a single interface only. a multicast address of interface-local scope is only useful for loopback delivery of multicasts within a single node, for example as a form of inter-process communication within a computer. unlike the unicast loopback address, interface-local multicast addresses may be assigned to any interface 🧚

there's a size relationship among scopes:

  • For unicast scopes, link-local is a smaller scope than global.
  • For multicast scopes, scopes with lesser values in the "scop" subfield of the multicast address (Section 2.7 of [1]) are smaller than scopes with greater values, with interface-local being the smallest and global being the largest.

however, two scopes of different size may cover the exact same region of topology πŸ‘€ for example, a (multicast) site may consist of a single link, in which case both link-local and site-local scope effectively cover the same topological span πŸ’œ


part 1 is done bestie πŸŽ€ part 2 is coming next, so stay tuned πŸ’•

5. Scope Zones ✨

okay so bestie, a scope zone (or just "zone" πŸ¦‹) is a connected region of topology that has a given scope. Think of the links that routers connect inside one particular (multicast) site, plus all the interfaces attached to those links. That whole group is one zone of multicast site-local scope πŸ’–

Quick distinction, because it's easy to mix up πŸ™ˆ A zone is a particular instance of a topological region (like Alice's site or Bob's site), while a scope is the size of a topological region (like a site or a link). Zone = which one, scope = how big πŸŽ€

The zone a non-global address belongs to is NOT stored inside the address itself πŸ’… It's figured out from context, like which interface the packet was sent or received on. So addresses of a given non-global scope can be re-used in different zones of that scope. Example: two different physical links can each have a node with the link-local address fe80::1 and that is totally fine, iykyk 🌈

Here's how zones of each scope get set up:

  • Each interface on a node is its own single zone of interface-local scope (for multicast only) 🧚
  • Each link, plus the interfaces attached to that link, is a single zone of link-local scope (for both unicast and multicast) πŸ“
  • There is a single zone of global scope (for both unicast and multicast) that includes all the links and interfaces in the Internet 🌍
  • The boundaries of zones of any scope other than interface-local, link-local, and global must be defined and configured by network administrators πŸ”§

Zone boundaries are pretty stable, not changing every time the topology wiggles for a moment ✨ So when the spec says a zone's topology must be "connected," it also counts links and interfaces that are only sometimes connected 😭 For example, a residential node or network that gets internet by dialing up to an employer's (multicast) site can still be treated as part of that employer's site-local zone, even while the dial-up link is disconnected. And if a router, interface, or link fails and the zone gets split in two, it does NOT become two zones πŸ’€ The pieces are all still considered the same zone, no cap.

Zones also have some extra properties, and these are giving main character energy πŸ‘‘

  • Zone boundaries cut through nodes, not links. (Fun fact: the global zone has no boundary at all, and the boundary of an interface-local zone just wraps around a single interface 🫢)
  • Zones of the same scope cannot overlap, meaning they can't share any links or interfaces 🚫
  • A zone of a given scope (smaller than global) sits completely inside zones of larger scope. A smaller zone can't include more topology than any larger-scope zone that shares a link or interface with it πŸͺ†
  • Each zone is required to be "convex" from a routing perspective. That means packets sent from one interface to any other interface in the same zone are never routed outside that zone πŸ”’ Ngl, there's a twist: if a zone contains a tunneled link (like an IPv6-over-IPv6 tunnel link [8]), a lower layer network of that tunnel can sit outside the zone without breaking convexity ✨

Last but not least, every interface belongs to exactly one zone of each possible scope πŸ’œ This is true no matter what kind of unicast address the interface has, and no matter which multicast groups the node joins on that interface. Periodt πŸ’…

Everything here is about keeping the zone picture straight, so when you're reading the next part, remember: scope is the size, zone is the specific place, and the boundaries are the rules that keep them from overlapping 🌸

  1. Zone Indices πŸ¦‹

okay so bestie, this part is lowkey my favourite bit because it's all about how a single node keeps track of which zone is which πŸ’… The same non-global address can be in use in more than one zone of the same scope (like link-local fe80::1 showing up on two separate physical links) 😭 and a node can have interfaces plugged into different zones of the same scope (a router usually has a bunch of interfaces on different links, periodt). So a node needs an internal way to tell which zone a non-global address belongs to. The fix is giving each zone of the same scope that the node is attached to its own distinct "zone index" πŸŽ€, and letting every internal use of an address be qualified by a zone index ✨

Here's the example, it's giving very organised 🌸

       ---------------------------------------------------------------
      | a node                                                        |
      |                                                               |
      |                                                               |
      |                                                               |
      |                                                               |
      |                                                               |
      |                                                               |
      |  /--link1--\ /--------link2--------\ /--link3--\ /--link4--\  |
      |                                                               |
      |  /--intf1--\ /--intf2--\ /--intf3--\ /--intf4--\ /--intf5--\  |
       ---------------------------------------------------------------
              :           |           |           |           |
              :           |           |           |           |
              :           |           |           |           |
          (imaginary    =================      a point-       a
           loopback        an Ethernet         to-point     tunnel
             link)                               link

Figure 1: Zone Indices Example

So this example node has five interfaces 🧚

  • A loopback interface to the imaginary loopback link (a phantom link that goes nowhere πŸ‘»).
  • Two interfaces to the same Ethernet link πŸ“
  • An interface to a point-to-point link πŸ’œ
  • A tunnel interface (the abstract endpoint of an IPv6-over-IPv6 tunnel [8], presumably set up over either the Ethernet or the point-to-point link) 🌈

So it's attached to five interface-local zones, identified by interface indices 1 through 5 πŸŽ€

Because the two Ethernet interfaces are on the same link, the node is only attached to four link-local zones, identified by link indices 1 through 4 ✨ Also, even if the tunnel interface runs over the Ethernet, the tunnel link still gets its own link index, which is different from the Ethernet link zone's index πŸ’…

Each zone index of a particular scope should carry enough info to show its scope, so that all indices of all scopes are unique within the node, and zone indices can be used for a dedicated purpose πŸ¦‹ Using the index to pick an entry in the Management Information Base (MIB) is one example of that dedicated purpose πŸ’– How the scope actually gets encoded is implementation dependent and is out of scope for this document πŸ™ˆ Here, we just write indices like "link index 2" so it's easy to read 🌸

The zone indices are strictly local to the node 🫢 For example, the node on the other end of that point-to-point link might use totally different interface and link index values for the same link 😭

An implementation should also support the concept of a "default" zone for each scope πŸ‘‘ And when it's supported, the index value zero at each scope SHOULD be reserved to mean "use the default zone" ✨ Unlike other zone indices, the default index doesn't contain any scope; the scope is determined by the address the default index comes with πŸ’… An implementation may also define a separate default zone for each scope πŸŽ€ Those default indices can also be used as the zone qualifier for an address when the node is attached to only one zone, e.g., with global addresses 🌈

Right now there's no way for a node to automatically figure out which of its interfaces belong to the same zones (same link, or a multicast scope zone bigger than an interface) πŸ’€ Protocols might be developed for that in the future πŸ”₯ Until then, an implementation MUST provide a means for manual assignment and/or reassignment of zone indices πŸ‘‘ To avoid manual configuration in most cases, an implementation SHOULD, by default, initially assign zone indices only as follows:

  • A unique interface index for each interface πŸ¦‹
  • A unique link index for each interface πŸ“

Manual configuration is then only needed for the less common cases: nodes with multiple interfaces to a single link, or nodes with interfaces to zones of different (multicast-only) scopes πŸ™ˆ

So the default zone index assignments for the example node from Figure 1 look like Figure 2 below πŸ’– To get the same link index on the two Ethernet interfaces (like in Figure 1), you'd have to configure it manually, MUST do that 😭

       ---------------------------------------------------------------
      | a node                                                        |
      |                                                               |
      |                                                               |
      |                                                               |
      |                                                               |
      |                                                               |
      |  /--link1--\ /--link2--\ /--link3--\ /--link4--\ /--link5--\  |
      |                                                               |
      |  /--intf1--\ /--intf2--\ /--intf3--\ /--intf4--\ /--intf5--\  |
       ---------------------------------------------------------------
              :           |           |           |           |
              :           |           |           |           |
              :           |           |           |           |
          (imaginary    =================      a point-       a
           loopback        an Ethernet         to-point     tunnel
             link)                               link

Figure 2: Example of Default Zone Indices

On top of assigning zone indices like that, an implementation SHOULD automatically pick a default zone for each scope where there's more than one choice πŸŽ€ That default gets used whenever an address shows up without a zone index (or with a zone index of zero) ✨ For example, in Figure 2, the implementation might automatically pick intf2 and link2 as the default zones for those two scopes 🌸 (One possible picking method is to choose the first zone that includes an interface other than the loopback interface as the default for each scope 🧚) A means MUST also be provided to assign the default zone for a scope manually, overriding any automatic choice πŸ‘‘

The unicast loopback address, ::1, MUST NOT be assigned to any interface other than the loopback interface πŸ™ˆ So it's RECOMMENDED that whenever ::1 is specified without a zone index or with the default zone index, it gets read as belonging to the loopback link-local zone, no matter which link-local zone was picked as the default πŸ¦‹ If you do this, then for nodes with only one non-loopback interface (like a single Ethernet interface, the common case πŸ’…), link-local addresses don't need a zone index at all πŸ’– The unqualified ::1 always refers to the link-local zone with the loopback interface, and all other unqualified link-local addresses refer to the link-local zone with the non-loopback interface (as long as that's the zone set as the default link-local zone) 🫢

Because a zone of a given scope has to fall completely within zones of larger scope (see Section 5, above), two interfaces in different zones of scope S also MUST be in different zones of every scope smaller than S 😭 So manually assigning distinct zone indices for one scope can force automatic assignment of distinct zone indices for smaller scopes too 🌈 For example, say distinct multicast site-local indices 1 and 2 are manually assigned in Figure 1, and site 1 contains links 1, 2, and 3, while site 2 only contains link 4 πŸ’€ That setup would automatically create matching admin-local indices 1 and 2 (multicast "scop" value 4), since admin-local scope is smaller than site-local scope πŸ”₯

With all of the above, the complete set of zone indices for our example node from Figure 1, plus those extra configurations, looks like Figure 3 below πŸ‘‘

       ---------------------------------------------------------------
      | a node                                                        |
      |                                                               |
      |                                                               |
      |                                                               |
      |                                                               |
      |                                                               |
      |  /--------------------site1--------------------\ /--site2--\  |
      |                                                               |
      |  /-------------------admin1--------------------\ /-admin2--\  |
      |                                                               |
      |  /--link1--\ /--------link2--------\ /--link3--\ /--link4--\  |
      |                                                               |
      |  /--intf1--\ /--intf2--\ /--intf3--\ /--intf4--\ /--intf5--\  |
       ---------------------------------------------------------------
              :           |           |           |           |
              :           |           |           |           |
              :           |           |           |           |
          (imaginary    =================      a point-       a
           loopback        an Ethernet         to-point     tunnel
             link)                               link

Figure 3: Complete Zone Indices Example

Even though the examples above number zones in order for each scope, starting at one, the zone index values are actually arbitrary πŸ¦‹ An implementation can label a zone with any value it likes, as long as the index value of each zone of all scopes is unique within the node πŸ’– Zero SHOULD be reserved to represent the default zone ✨ If an implementation follows the recommended basic API [10], it will probably want to keep its index values within what the sin6_scope_id field of the sockaddr_in6 structure can represent πŸŽ€


7. Sending Packets ✨

okay so when an upper-layer protocol sends a packet to a non-global destination address, it must have a way to tell the IPv6 layer which zone it means πŸŽ€. This matters when the node is attached to more than one zone of the destination address's scope, because otherwise IPv6 has no idea which one you're going for πŸ™ˆ.

Identifying the outgoing interface is enough to pin down a zone, since each interface is attached to no more than one zone of each scope πŸ¦‹. But ngl that's often more specific than you actually want πŸ’€. Say you're sending to a link-local unicast address from a node with more than one interface to that link (a pretty unusual setup). The upper-layer protocol might not care which of those interfaces gets used. It would rather leave that call to the routing function in the IP layer 🧚. So the upper layer needs to be able to specify a zone index when it sends to a non-global, non-loopback destination address πŸ’œ.

8. Receiving Packets 🌸

when an upper-layer protocol gets a packet with a non-global source or destination address, the zone that address belongs to can be figured out from the arrival interface 🫢. That's because the arrival interface can only be attached to one zone of the same scope as the address you're looking at πŸ’….

still, it is recommended that the IP layer pass the correct zone indices for the arriving source and destination addresses up to the upper layer, along with the arrival interface identifier ✨. Being extra about it is iconic πŸ‘‘.

9. Forwarding πŸ¦‹

when a router gets a packet addressed to some other node, it must take the zone of the destination and source addresses into account, like this πŸ’–:

  • the zone of the destination address is determined by the scope of the address and the arrival interface of the packet. the next-hop interface is picked by looking up the destination address in a (conceptual) routing table specific to that zone (see Section 10) πŸ—ΊοΈ. That routing table is restricted to only refer to interfaces that belong to that zone πŸ”’.
  • once the next-hop interface is chosen, the zone of the source address gets checked πŸ‘€. Same as before, the zone of the source address is determined by the scope of the address and the arrival interface of the packet. If sending the packet out the chosen next-hop interface would make it leave the zone of the source address (aka cross a zone boundary of the source address's scope), the packet gets discarded πŸ—‘οΈ. On top of that, if the packet's destination address is a unicast address, an ICMP Destination Unreachable message [4] with Code 2 ("beyond scope of source address") is sent back to the source of the original packet πŸ“¨. Quick tea: Code 2 is currently left as unassigned in [4], but the IANA will re-assign the value for the new purpose, and [4] will be revised with this change πŸ“.

Note that even if unicast site-local addresses are deprecated, the procedure above still applies to link-local addresses 🌈. So if a router gets a packet with a link-local destination address that isn't one of the router's own link-local addresses on the arrival link, the router is expected to try forwarding the packet to the destination on that link (as long as the destination's link-layer address gets successfully determined through the Neighbor Discovery protocol [9]) 🧭. The forwarded packet may go back out the arrival interface, or out any other interface attached to the same link πŸ”.

A node that receives a packet addressed to itself, which contains a Routing Header with more than zero Segments Left (Section 4.4 of [3]), first checks the scope of the next address in the Routing Header πŸ”. If the scope of the next address is smaller than the scope of the original destination address, the node MUST discard the packet 🚫. Otherwise, it swaps the original destination address with the next address in the Routing Header πŸ”„. Then the forwarding rules above apply like this:

  • the zone of the new destination address is determined by the scope of the next address and the arrival interface of the packet. The next-hop interface is chosen as per the first bullet of the rules above 🎯.
  • once the next-hop interface is chosen, the zone of the source address is considered as per the second bullet of the rules above πŸ’….

This check on the scope of the next address is what makes sure that when a packet arrives at its final destination, and that destination is link-local, the receiving node can know the packet originated on-link 🧠. That helps the receiving node send a "response" packet, with the final destination of the received packet as the source address, without breaking its source zone 🫢.

Note that it's possible, though generally inadvisable, to use a Routing Header to carry a non-global address across its associated zone boundary in the previously used next address field πŸ™…β€β™€οΈ. For example, picture a link-border node (e.g., a router) that receives a packet with a link-local destination address and a global source address. If the packet has a Routing Header where the next address is a global address, the next-hop interface to that global address may belong to a different link than the original destination's 🌍. That's allowed because the scope of the next address is not smaller than the scope of the original destination βœ….

10. Routing πŸ›£οΈ

Note that since unicast site-local addresses are deprecated, and link-local addresses don't need routing, the discussion in this section only applies to multicast scoped routing πŸ’œ.

When a routing protocol determines that it is operating on a zone boundary, it MUST protect inter-zone integrity and maintain intra-zone connectivity πŸ›‘οΈ.

To maintain connectivity, the routing protocol must be able to create forwarding information for the global groups and for all the scoped groups for each of its attached zones 🌷. The most straightforward way to do that is to create (conceptual) forwarding tables for each specific zone πŸ“š.

To protect inter-zone integrity, routers must be selective about the group information they share with neighboring routers 🀐. Routers routinely exchange routing information with their neighbors. When a router is transmitting this routing information, it must not include any information about zones other than the zones assigned to the interface used to transmit it 🚧.

Here's the picture πŸ“Έ:

                         *                                 *
                         *                                 *
                         *   ===========    Organization X *
                         *    |       |                    *
                         *    |       |                    *
                       +-*----|-------|------+             *
                       | *  intf1   intf2    |             *
                       | *                   |             *
                       | *             intf3 ---           *
                       | *                   |             *
                       | ***********************************
                       |                     |
                       |        Router       |
                       |                     |
         **********************       **********************
                       |       *     *       |
            Org. Y   --- intf4  *   *  intf5 ---   Org. Z
                       |       *     *       |
         **********************       **********************
                       +---------------------+

             Figure 4: Multi-Organization Multicast Router

As an example, the router in Figure 4 has to exchange routing information on five interfaces πŸ”₯. The info exchanged goes like this (for simplicity, multicast scopes smaller or larger than the organization scope, except global, aren't considered here) πŸ“:

  • Interface 1
    • All global groups
    • All organization groups learned from Interfaces 1, 2, and 3
  • Interface 2
    • All global groups
    • All organization groups learned from Interfaces 1, 2, and 3
  • Interface 3
    • All global groups
    • All organization groups learned from Interfaces 1, 2, and 3
  • Interface 4
    • All global groups
    • All organization groups learned from Interface 4
  • Interface 5
    • All global groups
    • All organization groups learned from Interface 5

By putting these route exchange rules in place, zone integrity is maintained by keeping all zone-specific routing information contained within the zone πŸŽ€βœ¨.

11. Textual Representation πŸ’¬

As already mentioned, to specify an IPv6 non-global address without ambiguity, an intended scope zone should be specified as well 🌸. For the common notation to specify the scope zone, an implementation SHOULD support the following format πŸ’–:

         <address>%<zone_id>

where

<address> is a literal IPv6 address,

<zone_id> is a string identifying the zone of the address, and

% is a delimiter character to distinguish between <address> and <zone_id>.

The following subsections describe detailed definitions, concrete examples, and additional notes of the format πŸ“–πŸ¦‹.

11.1. Non-Global Addresses 🌍

The format applies to all kinds of unicast and multicast addresses of non-global scope, except the unspecified address, which doesn't have a scope πŸ’…. The format is meaningless and should not be used for global addresses πŸ™…β€β™€οΈ. The loopback address belongs to the trivial link, i.e., the link attached to the loopback interface πŸ”. So the format should not be used for the loopback address either πŸ’€. This document doesn't specify usage of the format when <address> is the unspecified address, since that address doesn't have a scope πŸ€·β€β™€οΈ. However, this document does not prohibit an implementation from using the format for those special addresses for implementation-dependent purposes 🧚.

11.2. The <zone_id> Part πŸŽ€

Okay so in the textual representation, the <zone_id> part should be able to point at one particular zone of the address's scope πŸ¦‹. A zone index is supposed to carry enough info to figure out its own scope and be unique across all scopes (see Section 6), but the <zone_id> part doesn't have to include the scope at all. The <address> part already tells you which scope you're in, so <zone_id> doesn't need to be unique across every scope πŸ’…βœ¨

With that looser rule, an implementation can pick a super convenient <zone_id> πŸ“ For example, to represent link index 2, it can just write "2" as the <zone_id>. That's way more readable than any version that spells out the "link" scope 🌸

When an implementation reads the format, it should build the "full" zone index, the one that includes the scope, from the <zone_id> part plus the scope named by the <address> part. (Remember that a zone index itself should contain the scope, as Section 6 says 🧚)

An implementation SHOULD support, at the very least, numerical indices that are non-negative decimal integers as <zone_id> πŸ”₯ The default zone index, which should typically be 0 (see Section 6), counts as one of those integers. When <zone_id> is the default, you can drop both the "%" delimiter and the <zone_id> itself πŸ™ˆ Same idea if an IPv6 address shows up without a zone index: it should be read as <address>%<default ID>, where <default ID> is the default zone index for the scope that <address> lives in πŸ’œ

An implementation MAY support other kinds of non-null strings as <zone_id>. But those strings must not conflict with the delimiter character, and the exact format and meaning of any extra strings is up to the implementation 🌈

One possible candidate for those strings is interface names πŸ‘‘ Interfaces uniquely disambiguate any scopes, so interface names can work as "default identifiers" for interfaces and links. By default there's a one-to-one mapping between interfaces and each of those scopes (see Section 6), so it's pretty clean 🫢

An implementation could also use interface names as <zone_id> for scopes bigger than links, but it gets messy ngl 😭 For example, when more than one interface belongs to the same (multicast) site, a user would be totally confused about which interface to use. Also, a mapping function that goes from an address back to a name would hit the same problem when it prints an address with an interface name as its zone index. This document doesn't say how these cases should be handled and leaves them up to the implementation ✨

It cannot be assumed that indices are common across all nodes in a zone (see Section 6) πŸ’€ So the format MUST be used only within a node, and it MUST NOT be sent on the wire unless every node that interprets the format agrees on the semantics. Not me sending zone indices across the network πŸ™…β€β™€οΈ

11.3. Examples 🧚

Let's look at these addresses:

fe80::1234 (on the 1st link of the node)
ff02::5678 (on the 5th link of the node)
ff08::9abc (on the 10th organization of the node)

They'd be written like this:

fe80::1234%1
ff02::5678%5
ff08::9abc%10

(Here we assume a natural translation from a zone index to the <zone_id> part, where the Nth zone of any scope is translated into "N" 🌷)

If we use interface names as <zone_id>, those same addresses could also look like this:

fe80::1234%ne0
ff02::5678%pvc1.3
ff08::9abc%interface10

Here the interface "ne0" belongs to the 1st link, "pvc1.3" belongs to the 5th link, and "interface10" belongs to the 10th organization πŸ¦‹

11.4. Usage Examples πŸ’–

Apps meant for end hosts, like telnet, ftp, and ssh, may not explicitly support the idea of address scope, especially for link-local addresses πŸ™ˆ But an expert user (think a network administrator) sometimes still has to hand even link-local addresses to those apps. Iconic behavior from the admin, honestly πŸ‘‘

Here's a concrete example. Picture a multi-linked router called "R1" with at least two point-to-point interfaces (links) πŸ”₯ Each interface connects to another router: one to "R2" and the other to "R3". Also assume those point-to-point interfaces only have link-local addresses ✨

Now suppose the routing system on R2 hangs up and has to be reinvoked 😭 We might not be able to use a global address of R2, because this is a routing problem, and we can't count on having enough routes for global reachability to R2.

So we have to log in to R1 first, and then try to log in to R2 using its link-local address 🫢 In this case we have to give R2's link-local address to, for example, telnet. Here we assume that address is fe80::2.

Quick warning, though: we can't just type

% telnet fe80::2

because R1 has more than one link, so the telnet command can't tell which link it should use to connect πŸ’€ Instead, we should type the link-local address with the link index, like this:

% telnet fe80::2%3

Here the "3" after the delimiter character % matches the link index of the point-to-point link πŸ’…

An extension to the recommended basic API defines how the format for non-global addresses should be treated in library functions that translate a nodename to an address, or the other way around [11] πŸ“

11.6. Omitting Zone Indices πŸ¦‹

This format doesn't mean to invalidate the original format for non-global addresses, which is the one without the zone index portion πŸŽ€ As Section 6 explains, in some common cases that use the default zone index, there can be no ambiguity about scope zones. In that kind of environment, the implementation can omit the "%<zone_id>" part, and then it can act as though it never supported the extended format at all ✨

11.7. Combinations of Delimiter Characters 🌈

There are other kinds of delimiter characters defined for IPv6 addresses, so in this subsection we look at how they should be combined with the format for non-global addresses 🧚

The IPv6 addressing architecture [1] also defines the syntax of IPv6 prefixes. If the address portion of a prefix is non-global and its scope zone needs to be disambiguated, the address portion SHOULD be in the format πŸ’– For example, a link-local prefix fe80::/64 on the second link can be written like this:

fe80::%2/64

In this combo, the zone index portion has to go before the prefix length when a name-to-address library function [11] parses it. That way we can first split the address with the zone index from the prefix length, and pass only the former to the library function 🫢

The preferred format for literal IPv6 addresses in URLs is also defined [12]. When a user types the preferred format for an IPv6 non-global address whose zone should be explicitly specified, they could combine the non-global address format with the preferred format πŸ¦‹

However, a typed URL often gets sent on the wire, and it would cause confusion if an application didn't strip the <zone_id> portion before sending 😭 Note that applications shouldn't need to care which kind of address they're using, let alone parse or strip out the <zone_id> portion of it πŸ’…

Also, the format for non-global addresses might conflict with the URI syntax [13], since that syntax defines the delimiter character (%) as the escape character. Because of this conflict, the <zone_id> part for zone 1 with the delimiter would have to be written as '%251' πŸ’€ It also means we can't just copy a non-escaped format from other sources and feed it to the URI parser. And if the URI parser doesn't convert the escaped format before passing it to a name-to-address library, the conversion will fail. All of these issues would reduce the benefit of the textual representation described in this section πŸ™ˆ

So this document doesn't specify how the format for non-global addresses should be combined with the preferred format for literal IPv6 addresses. Either way, it is recommended to use an FQDN instead of a literal IPv6 address in a URL whenever an FQDN is available πŸ‘‘βœ¨

12. Security Considerations πŸ”₯

A limited-scope address without a zone index has security implications, and it cannot be used for some security contexts 😭 For example, a link-local address cannot be used in a traffic selector of a security association established by Internet Key Exchange (IKE) when the IKE messages are carried over global addresses. Also, a link-local address without a zone index cannot be used in access control lists.

The routing section of this document sets out a set of guidelines that routers can use to stop zone-specific information from leaking out of each zone. If, for example, multicast site boundary routers allow site routing information to be forwarded outside of the site, the integrity of the site could be compromised πŸ’€ This is a serious one, bestie.

Since the textual representation of non-global addresses is restricted to use within a single node, it doesn't create a security vulnerability from outside the node. However, a malicious node might send a packet that contains a textual IPv6 non-global address with a zone index, intending to deceive the receiving node about the zone of that non-global address. So an implementation should be careful when it receives packets that contain textual non-global addresses as data 🚨

13. Contributors 🫢

This document is a combination of several separate efforts. Atsushi Onoe took a significant role in one of them and deeply contributed to the content of Section 11 as a co-author of a separate proposal 🌟

14. Acknowledgements πŸ’œ

Many members of the IPv6 working group gave useful comments and feedback on this document πŸŽ€ In particular, Margaret Wasserman and Bob Hinden led the working group to a consensus on IPv6 local addressing. Richard Draves proposed an additional rule for processing Routing headers that contain scoped addresses. Dave Thaler and Francis Dupont gave valuable suggestions for defining the semantics of zone indices in terms of the related API. Pekka Savola reviewed a version of the document very carefully and made detailed comments about serious problems πŸ” Steve Bellovin, Ted Hardie, Bert Wijnen, and Timothy Gleeson reviewed and helped improve the document during preparation for publication. Literally a whole squad 🧚✨

15. References 🌈

15.1. Normative References πŸ“š

  • [1] Hinden, R. and S. Deering, "Internet Protocol Version 6 (IPv6) Addressing Architecture", RFC 3513, April 2003.
  • [2] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
  • [3] Deering, S. and R. Hinden, "Internet Protocol, Version 6 (IPv6) Specification", RFC 2460, December 1998.
  • [4] Conta, A. and S. Deering, "Internet Control Message Protocol (ICMPv6) for the Internet Protocol Version 6 (IPv6) Specification", RFC 2463, December 1998.

15.2. Informative References πŸ“š

[5] Huitema, C. and B. Carpenter, "Deprecating Site Local Addresses", RFC 3879, September 2004.

[6] Draves, R., "Default Address Selection for Internet Protocol version 6 (IPv6)", RFC 3484, February 2003.

[7] Cheshire, S., Aboba, B., and E. Guttman, "Dynamic Configuration of Link-Local IPv4 Addresses", Work in Progress.

[8] Conta, A. and S. Deering, "Generic Packet Tunneling in IPv6 Specification", RFC 2473, December 1998.

[9] Narten, T., Nordmark, E., and W. Simpson, "Neighbor Discovery for IP Version 6 (IPv6)", RFC 2461, December 1998.

[10] Gilligan, R., Thomson, S., Bound, J., McCann, J., and W. Stevens, "Basic Socket Interface Extensions for IPv6", RFC 3493, February 2003.

[11] Gilligan, R., "Scoped Address Extensions to the IPv6 Basic Socket API", Work in Progress, July 2002.

[12] Hinden, R., Carpenter, B., and L. Masinter, "Format for Literal IPv6 Addresses in URL's", RFC 2732, December 1999.

[13] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifiers (URI): Generic Syntax", RFC 3986, January 2005.


Authors' Addresses πŸŽ€

Meet the crew who made this happen, bestie! Here's where you can find them πŸ’–

Stephen E. Deering
Cisco Systems, Inc.
170 West Tasman Drive
San Jose, CA  95134-1706
USA


Brian Haberman
Johns Hopkins University Applied Physics Laboratory
11100 Johns Hopkins Road
Laurel, MD  20723-6099
USA

Phone: +1-443-778-1319
EMail: brian@innovationslab.net


Tatuya Jinmei
Corporate Research & Development Center, Toshiba Corporation
1 Komukai Toshiba-cho, Saiwai-ku
Kawasaki-shi, Kanagawa  212-8582
Japan

Phone: +81-44-549-2230
Fax:   +81-44-520-1841
EMail: jinmei@isl.rdc.toshiba.co.jp


Erik Nordmark
17 Network Circle
Menlo Park, CA 94025
USA

Phone: +1 650 786 2921
Fax:   +1 650 786 5896
EMail: Erik.Nordmark@sun.com
Brian D. Zill
Microsoft Research
One Microsoft Way
Redmond, WA  98052-6399
USA

Phone: +1-425-703-3568
Fax:   +1-425-936-7329
EMail: bzill@microsoft.com

Copyright (C) The Internet Society (2005). 🌈

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Intellectual Property πŸ¦‹

Okay so the IETF is being super neutral here πŸ™ˆ It doesn't take a side on whether any Intellectual Property Rights (or other rights) might cover the tech in this document, or whether you could get a license for them. It also hasn't gone hunting for those rights itself.

If you want the details on how RFC documents handle rights, check out BCP 78 and BCP 79. Copies of IPR disclosures sent to the IETF Secretariat, plus any promised licenses, or the results of trying to get a general license for implementers or users, can be found in the IETF's online IPR repository at http://www.ietf.org/ipr.

And if you know about any copyrights, patents, patent applications or other proprietary rights that might cover technology needed to implement this standard, the IETF wants to hear from you. Send it to ietf-ipr@ietf.org ✨

Acknowledgement 🫢

Big thanks to the Internet Society, which currently funds the RFC Editor function 🌸

πŸ“¦ where this page comes from