IPv6 Addressing on Point-to-Point Links

One of my readers sent me this question:

In your observations on IPv6 assignments, what are common point-to-point IPv6 interfaces on routers? I know it always depends, but I’m hearing /64, /112, /126 and these opinions are causing some passionate debate.

(Checks the calendar) It’s 2023, IPv6 RFC has been published almost 25 years ago, and there are still people debating this stuff and confusing those who want to deploy IPv6? No wonder we’re not getting it deployed in enterprise networks ;)

TL;DR generated by ChatGPT GPT-4 ?
IPv6 prefix length debates persist, but key recommendations are to use /64 for consistent prefix sizes or /127 for point-to-point links. Utilize infrastructure ACLs to block external access to infrastructure IPv6 subnets for security. Be mindful of potential hardware limitations when using prefixes longer than /64.

For people who would love to get a job done (as opposed to appear smart), several organizations published “this is how you do IPv6 addressing” documents:

The above documents should answer any questions you might have on IPv6 addressing, but if you insist on discussing prefix lengths, let’s do it:

  • /64 is the way to go if you want to have consistent prefix sizes on all subnets. There you have it; you can stop reading.
  • /112 is an unusual suggestion1. I would love to hear the arguments for using it (or maybe not).
  • /126 is probably recommended by people who are not aware of /127 being the right answer2 (due to RFC 61643) if you’re worried about the neighbor discovery (ND) cache exhaustion denial-of-service attacks. Please don’t tell me you’re considering /126 prefixes to conserve the address space.
As Sean pointed out in the comments, sometimes you’re forced to use /126 because some devices still don’t support /127 prefixes more than a decade after RFC 6164 was published.
  • As recommended by RFC 7404, link-local-only IPv6 interfaces might be a perfect solution for intra-AS P2P links, and if you bought your data center gear from a vendor interested in operational simplicity you could run EBGP over those interfaces with absolutely no hassle. OSPFv3 and IS-IS work just fine with IPv6 LLA on every device I tested in netlab.

Off-Topic: ND Cache Exhaustion DoS Attack

Just in case you’re not aware what I’m talking of: an intruder could scan billions of addresses in an /64 prefix, triggering a neighbor discovery process for every one of them on the directly-attached (last hop) router. That process would burn CPU cycles and consume hardware resources and (if the attack persists) could result in severe connectivity failures once the existing ND entries time out or can’t be refreshed due to control-plane policing.

The obvious solution you OUGHT TO4 use are infrastructure ACLs that block external access to infrastructure IPv6 subnets. Obviously you’d have to deploy them on all network edge interfaces and be consistent about that (I’ve heard automation helps). However, there were rumors ages ago that some vendor’s hardware started ND process in parallel with ingress ACL check – while an ingress ACL dropped the offending packet(s), neighbor discovery proceeded to waste the resources. Lovely ;)

For more details watch the Network Security Fallacies part of How Networks Really Work webinar.

Anyway, while I understand the reasons behind recommending /127 (or /126) on P2P links, that recommendation does have its drawbacks. Data center switches5 cut down on lookup table requirements by assuming that most IPv6 prefixes are /64 (or larger) so each prefix needs just 64 bits (or two IPv4 prefix entries) in the prefix lookup table. For example, Broadcom ASICs support only a small (configurable) amount of IPv6 prefixes longer than /64. I have no idea what happens when your routing table has more of them. Software-based switching? That would be a bonanza for a would-be attacker ;)

Based on the potential problems /127 prefixes might cause, some people advocate allocating each /127 out of a distinct /64 to ensure you can quickly switch back to having /64s on every link. Similarly, I’ve heard ideas to use /120 (yet again, each /120 coming from a different /64) on server VLANs that don’t use SLAAC6 to prevent ND attacks on server VLANs.

More to Explore

I’m pretty sure I mentioned these details in some IPv6 webinar, and we might have covered them in the October 2021 Design Clinic.

  1. I’m trying to be diplomatic and politically correct these days. I would use a slightly different wording in private conversations. ↩︎

  2. On a more serious note, using /126 prefixes is as valid as using /127 prefixes, it’s just not cool enough ;) ↩︎

  3. Here’s a funny story: There was an RFC published in 2003 saying “/127 prefix considered harmful” until another RFC came along saying “/127 is the way to go”, so they needed a third RFC saying “the first one is obsoleted by the second one.” Dotting the I-s and crossing the T-s is important ;) ↩︎

  4. See RFC 6919 for details ↩︎

  5. And other forwarding great that cannot afford to be reassuringly expensive. ↩︎

  6. That probably won’t play well with merchant silicon, but it definitely looks great in blog posts and PowerPoints. ↩︎


  1. History can give some insight...

    IPv6 was actually seen by some people as IPXv2, with some influence from DECnet. You can get rid of explicit interface addressing and move to node addressing. You could get rid of ARP/ND all together. This is why we have /64 even for point-to-point links, getting rid of ARP/ND. You can easily map IPv6 addresses with MAC addresses. Just embed it. The other functions should be done by some successor of ES-IS.

    Then came some other people and destroyed the original clean design. Pity for this...

    1. Thank you! Have to make a blog post out of that one of these days ;)

  2. There might be another issue with prefixes like /127: DHCP-based auto provisioning mechanisms I'm not sure if it's possible make it work with in IPv6 somehow (never tried that...), but at least with IPv4 /31 it's impossible to setup such a scope on Windows or ISC DHCP server, to my knowledge.

    1. You should use /127 only for numbered router-to-router links, so you don't need DHCPv6 in that case.

      Although DHCPv6 SHOULD work on prefix sizes other than /64, I wouldn't push my luck unless absolutely necessary.

    2. >> You should use /127 only for numbered router-to-router links, so you don't need DHCPv6 in that case. I fully agree, but that's the exactly the point: If I have a design like that (f.e. routed access layer) and I want to use ZTP such as Cisco PnP, all of that usually relies on DHCP(v6). If I'm unable to create a /127 scope, I'm doomed with a ZTP approach unless I move to /126 (at least) or even /64.

      So basically the same issue with IPv4 /31 - with ZTP, you're somewhat forced to use /30 because of DHCP.

      I'm pretty confident not everybody is aware of that and / or takes that "issue" into consideration for their IP addressing design. So that might turn into a bad surprise later on as the importance for ZTP is raising more than ever with the higher demand for automation.

    3. (A) A lot of data center deployments use an out-of-band management network with a flat subnet.

      (B) Haven't checked DHCPv6 details, but DHCP uses IP address (not prefix) in giaddr field, which means that the DHCP server scope does not have to match the real subnets. Obviously you have to be careful and use static assignments or you'll get out-of-subnet addresses assigned to DHCP clients.

  3. My personal preference is to reserve a /64 per point-to-point link, and configure a /127. Because xxx::/127 and xxx::1/127 looks ugly, I usually use xxx::a/127 and xxx::b/127 for aesthetics. It also makes it easier in discussions to refer to the A side or the B side.

    And for the /112, talk to Iljitsch 😉

    1. The main reason I use /126 rather than /127 in places is that there are some devices that do not understand how to /127 properly (and for that matter, how to /31 in IPvLegacy space,) so the 126 provides maximum compatibility while keeping the attack surface small. I have used /124's before for small transit networks, but never a /112.

    2. @Sean: Thank you, will add.

    3. I also allocate each /127 out of a distinct /64. (and make sure null / summary routes are properly defined!)

      I really like the idea about using 'a' and 'b' for the host IPs. I stupidly used 0 and 1. IPv6 notation drops the silent 0, leaving me with 2607:fee0:2002:10:: and 2607:fee0:2002:10::1 -- ugly!

  4. The /112 prefix length makes the last quibble the host part. This might seem more pleasing to people not using a proper IPAM ;-)

    1. As you'd be dealing with static or DHCPv6 address assignment anyway, it doesn't matter what the prefix size is -- just zero out all the other quibbles if that's what you'd like to have.

  5. Not actually point-to-point case but very close to it, and I know here are skillful people to shoot me down, so here we go, my thoughts:

    Routers-to-firewalls link networks that need space for HSRP/VRRP/clustering addresses are configured as /116:

    • Our-side devices are addressed: ::a = virtual IP ::a1 = first device in the group/cluster ::a2 = second device in the group/cluster
    • The other side devices are addressed: ::b = virtual IP ::b1 = first device in the group/cluster ::b2 = second device in the group/cluster
    • Reasoning for using /116 instead of /64: It limits the possibility of NCE (Neighbor cache exhaustion) in the routers-to-firewalls link networks. It is unclear if NCE is still practical in 2023 but a smaller subnet was nevertheless selected as a precaution. SLAAC is never used in these subnets so there is no technical reason to stick with /64.
    • Reasoning for using /116 instead of /120: RFC 2526 (Reserved IPv6 Subnet Anycast Addresses): "Within each subnet, the highest 128 interface identifier values are reserved for assignment as subnet anycast addresses." If using /120 for routers-to-firewalls subnets it is not possible to use the ::a1, ::a2, ::b1 and ::b2 addresses that are illustrative when using ::a and ::b for the VIPs. Using /116 enables using them for "a-side and b-side" consistency with point-to-point subnets. /116 is the next-shorter netmask from /120 when sticking with nibble-boundaries.
  6. I like IS-IS. I like the original CLNS addressing-scheme. One address per box. All interfaces are unnumbered. Routing is done based on L1 host-routes. Even for directly connected routers. If I ran an IPv6-network, I'd want to do the same thing. Link-local IPv6 addresses work fine for this.

    So why would people want to manually assign a non-link-local address to their interfaces? The only thing I can think of is so they will be able to ping for troubleshooting. Correct? Are there more reasons?

    Pinging a link-local address is a pain, I'd guess. Because you have to look up the remote router's link-local address first. Not fun. So how can we improve this?

    I would guess we need a new flavor of "ping".
    A ping that only works on p2p interfaces.
    A ping that takes only an outgoing interface-name as argument.
    The new ping will send out a packet over the p2p interface.
    The destination-address in the ping-address doesn't matter.
    The router on the other end replies anyway.

    Ideally the new ping-reply holds a bit more information about the remote router. Like maybe its interface-address, its interface-name, and maybe the hostname of the router. I would assume such a tool would be rather handy, if you often use unnumbered interfaces or link-local addresses.

    Can we do this with existing protocols?
    For IPv4 we could send a ping to the IPv4-broadcast address, or directed-broadcast address. Long time ago, routers would respond to that. Maybe today you can't ping anymore. And directed-broadcasts are probably not accepted. IPv6 doesn't have broadcast-addresses. So we'd have to define a new well-known IPv6 multicast-address.

    Ping packets can be padded to any size. Can we use the padding to carry TLVs? If so, we could put the if-address, if-name and hostname in a TLV in the ping reply. That should be backwards compatible.

    Or else we could use another existing protocol? E.g. extend LLDP to have some sort of ping? One that replies with the if-name, if-address and hostname? Unfortunately LLDP seems to be under the control of IEEE, not IETF. I have no experience working with the IEEE, so I have no idea if this is feasible.

    Just an idea.
    Operators, do you think such a new ping would be useful?

    1. At least on Linux, one can ping the All Nodes multicast address on a given interface:

      $ ping ff02::1%enp0s31f6
      PING ff02::1%enp0s31f6(ff02::1%enp0s31f6) 56 data bytes
      $ ping -I enp0s31f6 ff02::1
      ping: Warning: source address might be selected on device other than: enp0s31f6
      PING ff02::1(ff02::1) from :: enp0s31f6: 56 data bytes

      With a point-to-point link between two routers, the All Routers multicast address ff02::2 could be used instead (or as a check if the neighbor considers itself a router).

    2. @Henk: You're looking for RFC 5837. There's also RFC 8335.

      In 2021, Ron Bonica promised Junos implementation of RFC 5837 (see https://pretalx.com/denog13/talk/BCNAHM/). No idea whether it shipped in the meantime.

    3. Thanks Ivan. I was not aware of that RFC. I'll check out the details.
      It seems we have all the building blocks required to build such an extension to ping.
      I'll see if there is a way to implement this in the OS I work on.

      Having a customer ask for this functionality would speed up the process a lot. Without a customer demand, this would probably take ages. :(

    4. I can't raise a big-enough P/O to make it happen. I can only moan and complain on my blog 🥴

  7. We did a handful of podcasts on point to point addressing on MODEM, but we specifically focused on v6. Could be relevant, links to each one at the bottom of their respective pages: https://www.modem.show/post/s02e07/ https://www.modem.show/post/s03e01/

Add comment