RFC8950: Announce IPv4 with an IPv6 next-hop
Understanding RFC8950: Advertising IPv4 via IPv6 Next-Hops
Originally discussed on the personal blog of Anurag Bhatia (DNS, BGP, IPv6 expert).
Recently, I have been experimenting with the implementation of RFC8950, a standard that enables the routing of IPv4 traffic across an IPv6-only infrastructure. While the conceptual logic is straightforward, the practical implications are profound: it effectively transforms IPv4 into an optional service that runs atop an IPv6 foundation without requiring tunnels.
🚀 High-Impact Use Cases
The ability to decouple the IPv4 control plane from the physical infrastructure allows for several powerful architectural shifts:
- Core Simplification: A massive network can implement an IPv6-only core, restricting IPv4 strictly to the edge devices.
- Transparent Transition: This architecture is invisible to the end-user; customers continue their operations normally while the backbone evolves.
- Transit Efficiency: IP transit providers can maintain an IPv6-only backbone while still exchanging IPv4 reachability information with peers, upstreams, and customers via IPv6 BGP sessions.
- Reduced Overhead: By eliminating the need for IPv4 interface configurations, BGP session management, and firewall rules on core routers, operational complexity is slashed.
- IXP Modernization: Internet Exchange Points can operate their LANs using unique IPv6 addresses, utilizing route servers to distribute both IPv4 and IPv6 routes over a single IPv6 session.
Analogy: Just as 464XLAT revolutionized mobile network transitions, RFC8950 has the potential to do the same for large-scale backbone networks.
🛠️ Technical Deep Dive
Traditionally, Multi-protocol BGP (MP-BGP) allowed IPv4 routes to be carried over IPv6 sessions, but they still required an IPv4 next-hop. RFC8950 evolves this by allowing the next-hop to be an IPv6 address.
The Logic
The routing decision can be represented mathematically as:
Control Plane vs. Data Plane
It is critical to understand that RFC8950 only modifies the control plane.
- Control Plane: IPv6 is used to determine where the packet should go.
- Data Plane: The actual packet remains a standard IPv4 packet. It is encapsulated in an Ethernet frame and sent to the MAC address discovered via the IPv6 Neighbor Discovery Protocol (NDP).
Key Distinction: Unlike 464XLAT or traditional tunneling, the IPv4 packet is not wrapped in an IPv6 header over the wire.
Hardware Compatibility
Most modern routing operating systems support this feature. If your OS is up-to-date, it is likely compatible:
- Juniper JunOS
- Cisco IOS XR
- Nokia SR OS
- Mikrotik
- Huawei
- BIRD
- FRR (Free Range Routing)
🧪 Lab Demonstration
I constructed a test environment using Containerlab featuring two customer routers (C1, C2) and three provider routers (R1, R2, R3).
Topology Architecture
The network flow is as follows:
C1 R1 R2 R3 C2
Node Characteristics:
| Node | Capability | Role |
|---|---|---|
| R1 & R2 | IPv6-Only | Core routers with no IPv4 interface configs. |
| R3 | Dual Stack | Connects to R2 (IPv6) and C2 (IPv4). |
| C2 | IPv4-Only | Represents a legacy enterprise user. |
Configuration & Deployment
The lab utilizes the following topology.yml for deployment:
name: rfc8950
topology:
nodes:
R1: { kind: linux, image: frr-with-bgpd, binds: ["configs/R1.conf:/etc/frr/frr.conf"] }
R2: { kind: linux, image: frr-with-bgpd, binds: ["configs/R2.conf:/etc/frr/frr.conf"] }
R3: { kind: linux, image: frr-with-bgpd, binds: ["configs/R3.conf:/etc/frr/frr.conf"] }
C1: { kind: linux, image: frr-with-bgpd, binds: ["configs/C1.conf:/etc/frr/frr.conf"] }
C2: { kind: linux, image: frr-with-bgpd, binds: ["configs/C2.conf:/etc/frr/frr.conf"] }
links:
- endpoints: ["C1:eth1", "R1:eth1"]
- endpoints: ["R1:eth2", "R2:eth1"]
- endpoints: ["R2:eth2", "R3:eth1"]
- endpoints: ["R3:eth2", "C2:eth1"]
Deployment Log Snippet:
clab deploy -t topology.yml
16:37:08 INFO Containerlab started version=0.76.1
16:37:09 INFO Creating container name=C2
16:37:09 INFO Creating container name=C1
...
16:37:09 INFO Created link: R2:eth2 ▪┄┄▪ R3:eth1
Verification
R3 originates the network 100.64.0.0/24 into the IPv4 table but points the adjacency to R2 via IPv6. C2 is assigned 100.64.0.2/30.
BGP Table Check on C1:
C1# show ip bgp 100.64.0.2
BGP routing table entry for 100.64.0.0/24, version 2
Paths: (1 available, best #1, table default)
2001:db8:0:1::1 from 2001:db8:0:1::1 (172.20.20.2) (fe80::a8c1:abff:fe60:5467) (used)
Origin IGP, valid, external, best
Connectivity Test (Traceroute):
C1# traceroute 100.64.0.2
1 clab-rfc8950-R1.clab (172.20.20.2) 0.004 ms
2 clab-rfc8950-R2.clab (172.20.20.8) 0.002 ms
3 clab-rfc8950-R3.clab (172.20.20.5) 0.002 ms
4 100.64.0.2 (100.64.0.2) 0.002 ms
Note: The IPv4 addresses seen in the traceroute are derived from the eth0 management interfaces provided by Containerlab.