📚 第四章 IP协议
📄 一句话概括

128 位按 64 位切成两半:前半是网络前缀,后半是接口标识,划分是固定的。 地址分三类:单播、多播、任播,没有广播。

📝 本节和前面几节的关系

4.6.3 学了写法,这一节学结构。 4.3.2 讲过 IPv4 的「网络 + 主机」两段式,IPv6 把它固定成了 64 加 64。

一、固定的一刀:64 加 64

IPv4 的「网络部分多长」由掩码决定,可以随便切。 IPv6 把它固定了:前 64 位是前缀,后 64 位是接口标识。

部分 位数 谁决定
网络前缀 前 64 位 运营商或管理员
接口标识 后 64 位 主机自己生成

「固定」带来的好处是「不用协商」: 任何一台设备看到地址,就知道「前 64 位是网、后 64 位是机器」。 不用像 IPv4 那样先问「掩码是多少」。 代价是「灵活性下降」: IPv4 可以用 /30 只给两个地址,IPv6 最小也是 /64(一台机器也有 2 的 64 次方个地址)。 这种「浪费」在 IPv6 里是被允许的——因为地址本来就多。

二、三类地址

IPv6 只有三种地址类型:

类型 发给谁 前缀
单播 一台 各种前缀
多播 一组 ff00::/8
任播 一组里最近的一台 和单播同前缀

第三行「任播」是 IPv4 也有但很少用的东西: 同一个地址配在多台机器上,路由会把它送到「最近」的那台。 DNS 根服务器就用这个——全球几十个节点共用一个地址,你在哪儿就被送到最近的那个。 注意没有「广播」这一行:IPv6 把广播彻底删了,需要「通知所有人」时用多播组 ff02::1。

三、特殊地址一览

几个必须记住的前缀:

地址 含义 类比 IPv4
::/128 未指定 0.0.0.0
::1/128 回环 127.0.0.1
fe80::/10 链路本地 169.254.0.0/16
fc00::/7 唯一本地 10.0.0.0/8
2000::/3 全局单播 公网地址
ff00::/8 多播 224.0.0.0/4

第一行和第四行最容易混: :: 是「我还没有地址」(比如 DHCP 请求时用),::1 是「我自己」(回环)。 少写一个 1,含义完全变了。 第三行的 fe80 是「每块网卡都有」的地址:它只在同一链路上有效,路由器不转发。 所以「邻居发现」全靠它——不需要配置就能先通上话。

四、为什么是 64 这个数

因为「接口标识」最常用的生成方式是 EUI-64,正好 64 位。 而且 64 位足够让「同一张网里的设备永不被猜中」—— 2 的 64 次方是个天文数字,随机取值几乎不会撞。 另一个原因是「子网划分方便」: 16 位一段(十六进制的四位一组),前 64 位正好是四段,肉眼就能看出「第几段是子网」。 所以 64 这个数不是随便定的:它同时满足了「够长、好算、能自动生成」三个要求。

五、动手 Demo:一个 IPv6 地址,前后两半各管什么

拿一个 /64 的地址,把它拆成前缀和接口标识,再算「一个 /32 能切多少张网」。 注意最后一行:/64 只对应 1 个 /64,因为自己就是。

import ipaddress
for p in (32, 48, 56, 64):
    print('/%d' % p, 2 ** (64 - p), '%.2e' % (2 ** (128 - p)))

实跑输出:

--------------------------------------------------------------------
一个 IPv6 地址,前后两半各管什么
--------------------------------------------------------------------
**IPv6 地址按 64 位切成两半**:**前半是「哪张网」,后半是「网里的哪台机器」。**
**这个划分是固定的,不像 IPv4 那样靠掩码临时定。**

**拿 2001:db8:1234:5678::/64 举例**:
  部分                     这一半的值              谁决定
  ----------------------------------------------------------------
  前 64 位(网络前缀)     2001:0db8:1234:5678     由运营商分配
  后 64 位(接口标识)     0000:0000:0000:0000     由主机自己生成

**「主机自己生成」是 IPv6 的一个重要变化**:**地址可以自动配(SLAAC),不需要 DHCP 服务器。**

**再算一下「运营商给的一段能切多少张网」**:
  拿到的前缀     能切几个 /64     合计地址数
  -------------------------------------------
  /32            4294967296       7.92e+28
  /48            65536            1.21e+24
  /56            256              4.72e+21
  /64            1                1.84e+19

**第一行那个就是「一个 /32 切出 42.9 亿张网」**。
**所以运营商给每个家庭一个 /56,成本几乎为零。**
**第二行的 /48 是「企业级」的常见分配**,能切 65536 个 /64。

**「一台机器一个 /64」听起来浪费,但账不是这么算的**:**一个 /64 里有 1.84e+19 个地址**,
**全球的 /64 有 2.31e+18 个**——**地址空间大到「按网段分」都不心疼。**
**这一点和 IPv4 的「省着用」是完全不同的思路。**

「42.9 亿张网」这个数说明运营商给 /32 是「非常宽」的分配:一个 /32 能切出四十多亿个 /64, 而全球运营商只有几千家——所以「地址不够」在 IPv6 的分配体系里根本不是问题。 第二行的 /48 是「企业常见档位」:65536 个 /64,够一个有几万人的公司每个部门一个子网。 家用一般是 /56(256 个 /64),也绰绰有余。 「一台机器一个 /64」听着浪费,但这是有意的设计: 因为「按地址数省」这件事在 IPv6 里没有意义, 而「按 /64 对齐」能让自动配置、邻居发现、隐私扩展全部简化。 省地址省出复杂度,是 IPv4 的老毛病,IPv6 不想再犯。

30 秒实验

  1. 算一下:一个 /48 能切多少个 /64?
  2. 想一下:为什么 IPv6 不再需要「掩码」这个概念?
  3. 想一下:任播和「负载均衡」有什么相似之处?

常见误区

  1. 以为「IPv6 也能用 /30 这种小掩码」。 技术上可以,但破坏自动配置,规范要求 /64。
  2. 以为「IPv6 有广播地址」。 没有广播,全部改成多播。
  3. 以为「::」和「::1」是一回事。 前者是未指定,后者是回环,差一个 1,含义完全不同。
自测三问(点开对答案) 1. IPv6 地址的两半各是多少位? —— **前 64 位是网络前缀,后 64 位是接口标识。** 2. IPv6 有哪三种地址类型? —— **单播、多播、任播**,没有广播。 3. fe80::/10 是什么地址? —— **链路本地地址**,每块网卡自动生成,只在同一链路上有效。

下一节讲「全球唯一的地址」是怎么一层层分下来的。

相关笔记