NetCalcLab

IPv6 地址类型

全球单播、链路本地、唯一本地、组播、环回、未指定以及各种过渡范围 —— 每个前缀的用途,以及你实际会在什么时候配置它。

三个顶层类别

每个 IPv6 地址不是单播、组播,就是任播。IPv6 里不存在广播 —— 它的功能被并入组播,这是一次刻意的改动,因为组播可以有作用域、可以定向,而不必每次都去打扰同一网段上的每一台主机。

IPv6 地址的顶层类别
类别标识对象协议支持
单播单个接口任播与单播在链路层的实现方式相同
组播一组接口被强制要求支持 —— 邻居发现就靠它承载
任播一组中最近的那个接口通过把同一个单播地址配到多个节点上来实现

任播与单播的区别并不能从地址本身看出来。任播地址就是一个单播地址,只不过它被配置在了多个节点上,由路由器把流量送到最近的那个。IPv6 根域名服务器就是这么工作的。

你真正会配置的那些范围

整个空间中大部分仍未分配。下面这些才是实践中重要的范围,以及每一个的实际用途。

实际使用的 IPv6 地址范围
前缀类型可路由用途
::/128未指定否配置完成前的源地址;相当于 0.0.0.0
::1/128环回否本机;相当于 127.0.0.1
::ffff:0:0/96IPv4 映射特殊在 IPv6 中表示 IPv4 地址,双栈套接字会用到
64:ff9b::/96IPv4-IPv6 转换是NAT64 前缀,RFC 6052
100::/64仅丢弃否用于过滤的黑洞前缀,RFC 6666
2001::/32Teredo特殊在 IPv4 NAT 之上隧道传 IPv6,基本已废弃
2001:db8::/32文档用永不示例与文档,RFC 3849
2001:20::/28ORCHIDv2特殊加密标识符,RFC 7343
2002::/166to4特殊已废弃的过渡机制,RFC 7526
2600::/12 及之后全球单播是公网地址,由各 RIR 分配
fc00::/7唯一本地否私有编址;实际使用的是 fd00::/8 部分
fe80::/10链路本地否按接口自动生成;永远不会被路由
ff00::/8组播受作用域限制组地址,包含各种全节点组

全球单播地址的构成

一个全球单播地址分成三部分:来自运营商的选路前缀、由你自己掌控的子网 ID,以及 64 位的接口标识符。这意味着你能拥有 65,536 个子网、每个子网有 1.8 × 10^19 个地址,所以 IPv6 的子网规划关心的是"有多少个 /64",而不是"有多少台主机"。

2001:db8:abcd:12::1/64
|       2001:db8:abcd      |   12    |        0000:0000:0000:0001        |
|<--- 选路前缀 /48 ------->|<-子网 ID->|<---- 接口标识符 /64 ------------->|
        (运营商提供)        (你自己的)        (设备标识)

网络   /48  = 2001:db8:abcd::
子网   /64  = 2001:db8:abcd:12::
主机        = 2001:db8:abcd:12::1
一个 /64 的地址数 = 2^64 = 18,446,744,073,709,551,616

同样的结构在别的尺寸上也成立。持有一个 /32 的运营商可以给每个客户一个 /48,也就是 65,536 个客户分配;而每个客户内部又拥有 65,536 个 /64 可用。没有任何一部分是被"抠着用"的,这是有意为之 —— 这套设计把地址短缺从规划问题里彻底移除了。

示例:数一个分配里有多少子网

客户拿到 2001:db8:abcd::/48,这能提供多少个 /64 子网?两个前缀长度相差 16 位,2^16 = 65,536。所以这个 /48 含 65,536 个 /64 子网,每个子网有 2^64 个地址。

从 2001:db8:abcd:0000::/64 到 2001:db8:abcd:ffff::/64 —— 共 65,536 个子网

深入了解链路本地地址

每个 IPv6 接口都有链路本地地址,无论它有没有全球地址。它由接口的 MAC 地址或一个随机值生成,正是它让 IPv6 在还没有任何全球配置时就能工作。

  • 它是路由协议中的下一跳。OSPFv3 等协议通过链路本地地址建立邻居关系,这使得点对点链路上不再需要一段全局可路由的传输子网。
  • 它承载邻居发现。路由器通告、邻居请求与重复地址检测全都跑在链路本地地址和组播地址上。
  • 使用时必须带区域标识符。因为每个接口上都有同样的 fe80:: 前缀,你必须指明说的是哪个接口。Linux 上写作 fe80::1%eth0;Windows 上则用接口索引,例如 fe80::1%12。
  • 它永远不会被路由。路由器在接口边界就会丢弃链路本地流量,这正是"作用域"有意义的原因。

常见错误

  • 链路本地地址忘了带区域标识符。不带 %eth0 去 ping fe80::1 会报地址不明确的错误,在你想起来每个接口都有这么一个地址之前会相当令人困惑。
  • 给依赖 SLAAC 的子网用了非 /64 的前缀。无状态自动配置要求 64 位的接口标识符,所以 /72 或 /80 的子网即便在技术上合法,也无法正确自动配置。
  • 以为 fd00::/8 就是 ULA 的全部范围。整个分配范围是 fc00::/7,其中 fd00::/8 这一段才是定义用于本地分配的。想要覆盖所有 ULA 流量的规则应当匹配 fc00::/7。
  • 把 2001:db8:: 当成真实地址。它是文档用地址空间,没有任何路由器会转发它。在实际系统里看到它,说明套用了模板但没有替换。
  • 还以为广播存在。IPv6 里没有广播。试图发往子网广播地址的代码没有对应写法,需要改成使用组播组,通常是链路内全节点的 ff02::1。
  • 为了省地址而规划子网。按主机数去定子网大小是 IPv4 的习惯。在 IPv6 里每个子网都是 /64;规划精力应该花在子网 ID 上。

值得记住的组播组

常见的 IPv6 组播地址
地址组作用域使用者
ff02::1所有节点链路本地可到达链路上的每一台 IPv6 主机
ff02::2所有路由器链路本地自动配置过程中的路由器请求
ff02::5OSPFv3 所有路由器链路本地OSPFv3 hello 报文
ff02::6OSPFv3 指定路由器链路本地OSPFv3 的 DR 与 BDR
ff02::9RIPng 路由器链路本地RIPng 更新
ff02::aEIGRP 路由器链路本地EIGRP IPv6 hello
ff02::1:2所有 DHCP 服务器链路本地DHCPv6 中继代理
ff02::1:ff00:0/104请求节点组播链路本地邻居发现,每个地址对应一个组
ff05::2所有路由器站点本地可到达站点内的所有路由器
ff0e::1所有节点全局很少使用;可到达该作用域内的所有主机

请求节点组播组是其中最巧妙的一个:每个地址都有一个由它末 24 位推导出来的对应组,于是邻居发现只需检查一小部分主机,而不必打断链路上的每一台设备。IPv6 正是借此避开了大型 IPv4 子网上 ARP 那种广播行为带来的开销。

前缀尺寸及其容量

IPv6 前缀尺寸
前缀含 /64 个数地址数典型用途
/324,294,967,2967.9 × 10^28运营商分配
/4016,777,2161.2 × 10^27大型运营商或企业
/4865,5361.2 × 10^24站点分配,标准的客户地址块
/562564.7 × 10^21小型站点或家庭分配
/60162.9 × 10^20极小站点
/6411.8 × 10^19标准子网尺寸
/127—2点对点链路,相当于 IPv4 的 /31
/128—1单个主机,相当于 IPv4 的 /32

从 /64 到 /128 的跳跃值得留意:/127 与 /128 是给链路和主机用的,不是子网。/127 恰好只有两个地址,用在路由器互联链路上,这样两端都不必为一条点对点连接浪费一整个 /64。

相关:IPv6 计算器、CIDR 记法详解、子网划分指南、MTU / MSS 计算器(用于 IPv6 首部开销)。

常见问题

IPv6 地址一共有几种类型?

顶层有三种:单播,标识单个接口;组播,标识一个组;任播,标识一个组中最近的那个成员。这些顶层类别之下再细分为你实际会配置的具体范围 —— 全球单播、链路本地、唯一本地、环回、未指定以及各种过渡前缀。

链路本地地址是什么,我需要它吗?

链路本地地址属于 fe80::/10,会在每个启用了 IPv6 的接口上自动生成。它不可路由到本地链路之外,用于邻居发现、路由器通告以及路由协议中的下一跳地址。它不需要你分配 —— 系统总会自动创建它,这也是一个接口同时拥有链路本地地址和全球地址的原因。

fe80::/10 和 fe80::/64 有什么区别?

fe80::/10 是所有链路本地地址的分配范围。fe80::/64 则是链路上实际使用的子网尺寸,因为 IPv6 的子网划分标准化为 /64。实践中 /10 给出的是范围,/64 是接口配置出来的东西。在防火墙规则里写 fe80::/10 会覆盖整个范围,包括很少用到的 febf:: 部分。

唯一本地地址有什么用途?

fc00::/7 中的唯一本地地址相当于 IPv6 版的 RFC 1918 私有地址。它们在公网上不可路由,面向内部网络使用。实际使用的是 fd00::/8,其中 local 位被置为 1,后面跟 40 位的随机全局 ID,随机性足以避免组织合并或互联时发生冲突。

IPv6 还需要 NAT 吗?

设计意图是不需要。IPv6 的地址多到可以让每台设备都拥有全球可路由地址,所以不需要靠 NAT 来节省地址。大多数部署改用有状态防火墙:允许出站连接、阻止未经请求的入站流量。唯一本地地址用于纯内部的网段,而不是当作 NAT 地址池,尽管在特定场景下确实存在 NAT66。

::1 是什么,它与 :: 有什么区别?

::1 是环回地址,相当于 127.0.0.1,被分配给环回接口。全零的 :: 是未指定地址,相当于 0.0.0.0,用于接口还没有地址时的源地址。两者看起来很像,只是最后一位不同 —— 而这正是这个区别重要的原因。

/64 是什么,为什么总是用它?

/64 是标准的 IPv6 子网:前 64 位是网络,后 64 位是接口标识符。之所以固定为 /64,是因为无状态地址自动配置要求 64 位的接口位;而把尺寸标准化,意味着每个子网都能容纳 18,446,744,073,709,551,616 个地址,远超任何网络的需求。重点在于:地址节省不再是约束,所以子网尺寸可以统一。

文档用地址范围和真实范围有什么区别?

2001:db8::/32 由 RFC 3849 保留给文档与示例使用,完全等同于 IPv4 中 RFC 5737 的 192.0.2.0/24。它永远不会被路由。在配置指南里看到它,说明那只是个占位地址;在实际网络中看到它,说明有人照抄示例却没改地址。