RFC8950: 使用 IPv6 下一跳通告 IPv4
RFC8950: Announce IPv4 with an IPv6 next-hop

原始链接: https://anuragbhatia.com/post/2026/06/rfc8950-announce-ipv4-with-ipv6-next-hop/

RFC 8950 使 IPv4 路由能够通过 IPv6 BGP 会话、使用 IPv6 下一跳进行传输,因此 IPv4 可以在无隧道的情况下原生运行于仅 IPv6 的核心网络之上。这使得大型网络、传输提供商和 IXP 能够将 IPv4 保留为边缘/客户功能,同时在骨干网中运行仅 IPv6,从而降低 IPv4 的配置开销。在控制平面,MP-BGP 通告带有 IPv6 下一跳的 IPv4 前缀;IPv4 数据平面流量在 NDP 解析下一跳 MAC 之后,仍然通过以太网使用 IPv4。演示使用 FRR 路由器 C1–C2 和 R1–R3:C1 在 WAN 侧为仅 IPv6,并发起 10.0.0.0/24;R1/R2 为仅 IPv6 但承载 IPv4 路由;R3 连接仅 IPv4 的 C2,使用 100.64.0.0/24。C1 成功通过 IPv4 访问 C2,确认了 IPv4 在仅 IPv6 骨干网中的连通性。

RFC8950 允许网络使用 IPv6 下一跳通告 IPv4 路由,使纯 IPv6 骨干网可以在不为每个接口分配 IPv4 的情况下承载旧版 IPv4。Hacker News 讨论涵盖了其目的:运营商可以减少核心网中的 IPv4,同时保留边缘 IPv4 可达性,使用链路本地下一跳,并简化骨干网管理,不过 ICMP/traceroute 仍可能需要 IPv4 地址。评论者广泛争论 IPv6 迁移:支持者引用 CLAT、NAT64、MAP-T、464XLAT 和单栈优势;批评者认为 IPv6 过度工程化,存在扩展头部等运维问题、ULA 与 GUA 之间的地址选择问题以及多宿主挑战,而 IPv4 NAT 往往掩盖类似问题。帖子还提到这基于更早的 RFC5549,并且过渡机制持续演进。总体上,RFC8950 被视为朝向 IPv6 主导网络、IPv4 仍留在边缘的又一个渐进兼容步骤。
相关文章

原文

For the last few days I have been playing with RFC8950 setup, which allows routing of IPv4 on top of IPv6. While logically it’s quite simple, it has a very powerful application towards making “IPv4 an optional” feature riding on top of an IPv6 network (but without any tunnels!)

Some of the interesting use cases:

  1. A large network can run IPv6 only everywhere on its core and leave IPv4 only on edge devices. This can work without customers doing any tweaking at their end. They still do things the old way but Backbone can run IPv6 only at its core.
  2. An IP transit backbone can run IPv6 only while exchanging IPv4 routes with its customers/peers/upstream over IPv6 sessions. So IPv4 as a “feature” stays but the network in itself is IPv6 only without the overhead of IPv4 interface config, BGP session config, firewall config, etc.
  3. An IXP can offer services without IPv4 essentually by using a (unique) IPv6 at the IX LAN & running route server to exchange both IPv4 & IPv6 routes over the IPv6 only session.

Thus what 464XLAT did to the mobile networks - this has the potential to do that for the backbone networks.

How does it work?

Multi-protocol BGP (MP-BGP) supports announcement of IPv4 routes over IPv6 sessions with IPv4 next-hops and IPv6 routes over IPv4 sessions with IPv6 next-hops. RFC8950 extends this feature for IPv4 to have IPv6 next-hops. So for IPv4 address, next hop is IPv6, IPv6 reach works via usual NDP and IPv4 rides on ethernet frames to the same MAC as discovered by the NDP. Technically RFC8950 only impacts control plane decisions by using IPv6 as the control plane but keeps the data plane as it is. IPv4 stays IPv4 & goes as IPv4 over the wire unlike say some tunnel or 464xLAT etc.

Hardware support

As of now it’s quite widely supported by a lot of routing platforms like Juniper JunOS, Cisco IOS XR, Nokia SR OS, Mikrotik, Huawei, BIRD, FRR etc. So, it is very likely supported if you are running a recent version of the OS.

Demo lab

Here’s a fun lab with two customer routers: C1 & C2 connected via provider routers R1-R2-R3 in Container Lab. All routers here are running open source FRR.

  • C1 is IPv6 only on the WAN side facing R1. It originates 10.0.0.0/24 to R1 over an IPv6 session.
  • R1 & R2 are IPv6 only with no IPv4 anywhere on their interfaces (but carry IPv4 routes in their table)
  • R3 has IPv6 with R2 but just IPv4 only with C2. So C2 is like a typical enterprise user who lacks IPv6 deployment and still wants IPv4 only to work.
  • R3 has 100.64.0.0/24 and originates it in the IPv4 table (to IPv6 adjacency - R2)
  • C2 sits on 100.64.0.2/30 given by R3 and communicate in IPv4 only.
  • C1 and C2 can reach each other over this network with parts being IPv6 only without any tunnel.

topology.yml

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"]      
> clab deploy -t topology.yml
16:37:08 INFO Containerlab started version=0.76.1
16:37:08 INFO Parsing & checking topology file=topology.yml
16:37:09 INFO Creating lab directory path=~/ipv4-over-ipv6/clab-rfc8950
16:37:09 INFO Creating container name=C2
16:37:09 INFO Creating container name=C1
16:37:09 INFO Creating container name=R1
16:37:09 INFO Creating container name=R2
16:37:09 INFO Creating container name=R3
16:37:09 INFO Created link: R3:eth2 ▪┄┄▪ C2:eth1
16:37:09 INFO Created link: C1:eth1 ▪┄┄▪ R1:eth1
16:37:09 INFO Created link: R1:eth2 ▪┄┄▪ R2:eth1
16:37:09 INFO Created link: R2:eth2 ▪┄┄▪ R3:eth1
16:37:09 INFO Adding host entries path=/etc/hosts
16:37:09 INFO Adding SSH config for nodes path=/etc/ssh/ssh_config.d/clab-rfc8950.conf
╭─────────────────┬───────────────┬─────────┬───────────────────╮
│       Name      │   Kind/Image  │  State  │   IPv4/6 Address  │
├─────────────────┼───────────────┼─────────┼───────────────────┤
│ clab-rfc8950-C1 │ linux         │ running │ 172.20.20.6       │
│                 │ frr-with-bgpd │         │ 3fff:172:20:20::6 │
├─────────────────┼───────────────┼─────────┼───────────────────┤
│ clab-rfc8950-C2 │ linux         │ running │ 172.20.20.4       │
│                 │ frr-with-bgpd │         │ 3fff:172:20:20::4 │
├─────────────────┼───────────────┼─────────┼───────────────────┤
│ clab-rfc8950-R1 │ linux         │ running │ 172.20.20.2       │
│                 │ frr-with-bgpd │         │ 3fff:172:20:20::2 │
├─────────────────┼───────────────┼─────────┼───────────────────┤
│ clab-rfc8950-R2 │ linux         │ running │ 172.20.20.8       │
│                 │ frr-with-bgpd │         │ 3fff:172:20:20::8 │
├─────────────────┼───────────────┼─────────┼───────────────────┤
│ clab-rfc8950-R3 │ linux         │ running │ 172.20.20.5       │
│                 │ frr-with-bgpd │         │ 3fff:172:20:20::5 │
╰─────────────────┴───────────────┴─────────┴───────────────────╯

Checking C1 for route to C2

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)
 Advertised to non peer-group peers:
 2001:db8:0:1::1
 65501 65502 65503
 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 (First path received)
 Last update: Mon Jun 22 18:57:38 2026
C1# 

C1 -> C2 trace

C1# traceroute 100.64.0.2
traceroute to 100.64.0.2 (100.64.0.2), 30 hops max, 46 byte packets
 1  clab-rfc8950-R1.clab (172.20.20.2)  0.004 ms  0.004 ms  0.002 ms
 2  clab-rfc8950-R2.clab (172.20.20.8)  0.002 ms  0.003 ms  0.003 ms
 3  clab-rfc8950-R3.clab (172.20.20.5)  0.002 ms  0.003 ms  0.003 ms
 4  100.64.0.2 (100.64.0.2)  0.002 ms  0.006 ms  0.003 ms
C1# 

Note: It took IPv4 from the eth0 management interfaces as deployed by Container Lab for TTL exceeded used in the trace.

If I check R1, it has only IPv6 sessions but no IPv6 prefixes

R1# sh bgp ipv6 summary 

IPv6 Unicast Summary (VRF default):
BGP router identifier 172.20.20.2, local AS number 65501 vrf-id 0
BGP table version 0
RIB entries 0, using 0 bytes of memory
Peers 2, using 1434 KiB of memory

Neighbor        V         AS   MsgRcvd   MsgSent   TblVer  InQ OutQ  Up/Down State/PfxRcd   PfxSnt Desc
2001:db8:0:1::2 4      64512       151       141        0    0    0 00:39:19            0        0 N/A
2001:db8:0:2::2 4      65502        65        64        0    0    0 00:36:46            0        0 N/A

Total number of neighbors 2
R1# 

Checking for IPv4 routes on R1

R1# sh bgp ipv4 
BGP table version is 4, local router ID is 172.20.20.2, vrf id 0
Default local pref 100, local AS 65501
Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
 i internal, r RIB-failure, S Stale, R Removed
Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
Origin codes:  i - IGP, e - EGP, ? - incomplete
RPKI validation codes: V valid, I invalid, N Not found

 Network          Next Hop            Metric LocPrf Weight Path
*> 10.0.0.0/24      fe80::a8c1:abff:fe44:afb8
 0             0 64512 i
*> 100.64.0.0/24    fe80::a8c1:abff:fed8:5eb5
 0 65502 65503 i

Displayed  2 routes and 2 total paths
R1# 

Router Configs

联系我们 contact @ memedata.com