CIDR /31 and /32 in production: RFC 3021, point-to-point links, and host routes

4 min read

CIDR introductions tend to write off /31 (“nothing usable left after network/broadcast”) and /32 (“a single host”), but production routing tables are full of both. This article works from RFC 3021 outward to the cases where these prefixes are routine — point-to-point links, router loopbacks, container CNIs — and the L2/L3 traps that come with them.

The “/31 is useless” myth

Classical IP subnet theory reserves the first address (network) and last (broadcast) per subnet:

  • A /30 (4 addresses) leaves 2 usable hosts
  • A /31 (2 addresses) leaves zero usable hosts under the classical rules

RFC 3021 (2000) explicitly amended this for a specific case.

RFC 3021: /31 for point-to-point links

RFC 3021 observes that on point-to-point links (links connecting exactly two routers) the concepts of “network” and “broadcast” don’t make sense — there’s nowhere to broadcast to. So both addresses can be used as host addresses:

192.0.2.0/31   ← address 0 to router A, address 1 to router B
AddressClassicalRFC 3021
192.0.2.0networkhost (router A)
192.0.2.1broadcasthost (router B)

Why /31 matters

ISPs and large data centers have huge numbers of inter-router links. Spending 4 addresses per link (/30) versus 2 (/31) halves IPv4 consumption on point-to-point fabric. Standard for BGP peering, MPLS backbones, and switch fabrics.

Both ends must support RFC 3021. Cisco IOS 12.2+, Juniper, Linux, and modern switches all do; some legacy gear rejects /31 configurations.

/32: a single-host route

A /32 has all-ones mask (255.255.255.255) — it specifies exactly one address.

Use 1: loopback addresses

Router loopback (virtual) interfaces are conventionally /32:

ip address 192.0.2.1/32 → loopback0

Provides a “stable IP for the router itself” decoupled from physical interface state. Used as OSPF/BGP router-id, SNMP management IP, syslog source address, etc.

Use 2: host routes

Routing table entries that send a single IP via a specific next hop:

ip route 198.51.100.5/32 via 10.0.0.1
  • Send traffic to a specific server via a dedicated LB
  • BGP-advertise a single address (anycast, DDoS hole-punching, etc.)

Use 3: containers and CNIs

Kubernetes Pod IPs and Docker bridges very commonly use per-pod /32 host routes:

ip route add 10.244.1.5/32 dev veth-podX

This decouples container IP routing from any underlying physical subnet. Calico and Cilium take this approach.

The /32 trap: longest prefix match and ARP

Host routes win longest prefix match against larger covering prefixes:

10.0.0.0/24   via 10.0.0.1   ← default gateway for the subnet
10.0.0.5/32   via 10.0.0.99  ← exception: 10.0.0.5 goes elsewhere

Traffic to 10.0.0.5 takes the /32 route. Meanwhile, ARP operates at L2 — independent of routing — and resolves the address via broadcast.

Linux ARP behavior for /32 host routes

Advertising container or pod IPs (where the host doesn’t own the IP itself) requires the host to answer ARP for foreign IPs:

sysctl net.ipv4.conf.all.arp_filter=0
sysctl net.ipv4.conf.all.arp_announce=0

If misconfigured: “ping works to the pod IP but ARP times out,” “pod-to-pod traffic on the same subnet drops” — classic L3/L2 mismatch symptoms.

IPv6: /127 and /128

IPv6 has analogous rules:

  • /127 (RFC 6164): the /31 of IPv6, for point-to-point links.
  • /128: the /32 of IPv6, single-host routes.

IPv6’s address space is effectively infinite, so address conservation isn’t the motivation. Instead, /127 reduces Neighbor Discovery overhead on inter-router links (RFC 6164 §5.1).

Design checklist

  • Saving IPv4 on inter-router links → /31 (verify RFC 3021 support both ends).
  • Router loopback / management address → /32.
  • Per-host routing exception → /32 host route (longest prefix match wins).
  • Container / Pod IP → /32 (CNI installs it).
  • IPv6 point-to-point → /127, plus /128 host routes as needed.
  • L3 route works but L2 doesn’t resolve → check proxy ARP and arp_filter.

Summary

/31 was redefined by RFC 3021 — it’s the standard ISP/DC choice for point-to-point links today. /32 is fundamental for loopbacks, host routes, and container networks, and you have to think about both routing-table longest prefix match and ARP/NDP when using it. The CIDR-calculator showing “0 usable hosts” for /31 is correct under classical rules but misleading for modern routing — under RFC 3021 a /31 carries exactly two routable hosts.

To inspect prefix sizes, masks, and host counts concretely, the CIDR calculator tool covers the standard cases.