Files
cs-note/hhs/NETWORK/03-网络层/03-IPv6地址与扩展头部.md
T
2026-05-24 11:42:38 +08:00

166 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [计算机网络, IPv6, SLAAC, 地址空间]
create time: 2026-05-18 00:20
---
# IPv6 地址与扩展头部
## 概述
IPv6 是为解决 IPv4 地址枯竭而设计的下一代互联网协议。但它的改进远不止于地址空间——简化首部、内置安全支持、无分片(by design)、自动配置等特性使其更适合现代网络架构。
## IPv6 地址表示法
### 十六进制冒号分隔格式
```
2001:0db8:0000:0000:0000:ff00:0042:8329
```
### 缩写规则
| 规则 | 说明 |
|------|------|
| 前导零省略 | `0db8` → `db8`;`0042` → `42` |
| 连续全零段压缩为 `::` | 只能出现**一次**(否则歧义) |
示例:
```
完整: 2001:0db8:0000:0000:0000:ff00:0042:8329
缩写: 2001:db8::ff00:42:8329 ← 最简形式
loopback: 0000:0000:0000:0000:0000:0000:0000:0001
::1 ← 仅一个字符
IPv4映射: 0000:0000:0000:0000:0000:ffff:c0a8:0101
::ffff:192.168.1.1 ← 兼容旧系统
```
### 常见 IPv6 地址类型
| 前缀 | 类型 | 示例 | 范围 |
|------|------|------|------|
| `2000::/3` | 全球单播 (GUA) | `2001:db8::1` | 公网路由 |
| `::1/128` | 环回 (Loopback) | `::1` | 本机 |
| `fc00::/7` | ULA (唯一本地地址) | `fd00::1` | 私有地址,等价 RFC1918 |
| `fe80::/10` | 链路本地 (Link-Local) | `fe80::1` | 仅同链路可用,自动配置 |
| `ff00::/8` | 组播 (Multicast) | `ff02::1` | 多播组 |
| — | 未指定地址 | `::` | 类似 IPv4 的 0.0.0.0 |
## IPv6 地址组成
### EUI-64(自动生成)
从 MAC 地址生成接口标识符(正在被隐私扩展取代):
```
MAC: aa:bb:cc:dd:ee:ff
插入 ff:fe → aa:bb:cc:ff:fe:dd:ee:ff
翻转第七位(UD bit) → ab:bb:cc:ff:fe:dd:ee:ff
结果: fe80::ab:bb:cc:ff:fe:dd:ee:ff (link-local)
```
### SLAAC( Stateless Address Autoconfiguration )
主机无需 DHCP 服务器,通过 Router Advertisement(RA)消息自行配置:
```mermaid
sequenceDiagram
participant Host as 主机
participant R as 路由器
R->>Host: Router Advertisement (每 200s~60min)
Note over Host: RA 中包含:
Note over Host: - 前缀 (如 2001:db8:abcd::/64)
Note over Host: - prefix length
Note over Host: - 默认网关
Note over Host: - DNS (RFC 6106 / RDNSS)
Host->>Host: 自构 IPv6 地址
Host->>R: NDP Neighbor Solicitation (查重)
R-->>Host: (无冲突 → 无回复)
Host->>Host: ✅ 分配 2001:db8:abcd::<interface-id>
```
### DUID-DHCPv6
DHCPv6 服务器分配地址时需要客户端标识:
- **DUID-LLT**: DUID + Link-Layer Time + Link-Layer Address
- **DUID-UUID**: DUID + UUID (持久不变)
## IPv6 首部 vs IPv4 首部
| 字段 | IPv4 | IPv6 |
|------|------|------|
| 版本 | 4 bit | 4 bit |
| 优先级 | DSCP+ECN (8 bit) | Traffic Class + Flow Label (20 bit) |
| 长度 | Total Length (含首部) | Payload Length (**不含**首部) |
| Next Header | Protocol (替代) | Next Header (等同) |
| Hop Limit | TTL | Hop Limit (改名但不改功能) |
| 源/目的 IP | ✅ | ✅ |
| 首部 Checksum | ✅ | ❌ **已删除!** |
| 分片 | ID/DF/MF/Offset | 移到扩展头(由源端分片) |
### IPv6 为什么去掉 Checksum?
- TCP/UDP/ICMPv6 自带端到端校验
- 链路层 Ethernet FCS 已做底层校验
- 每跳计算 Checksum 增加路由器负担 → 提升转发性能
### Flow Label(流标签)
新引入的 20-bit 字段,用于标识属于同一"流"的数据包序列。中间网络设备可据此做 QoS 或负载均衡——无需深度解析载荷。
## IPv6 扩展头部(Extension Headers)
IPv6 将可选功能移出固定首部,放在扩展头链中,由 Next Header 字段串联:
```
Fixed Header → Hop-by-Hop Options (可选) → Destination Options → Routing → Fragment → Authentication (AH) → Encapsulating Security Payload (ESP) → Upper Layer (TCP/UDP/ICMPv6)
```
| 扩展头 | 类型值 | 用途 |
|--------|-------|------|
| Hop-by-Hop Options | 0 | 逐跳选项(极少使用) |
| Routing | 43 | 路由类型 0 (SRv6 前身)、Type 2 (Mobile IPv6) |
| Fragment | 44 | 分片信息(ID/offset/MF),仅出现在原始包中 |
| Authentication (AH) | 51 | IPsec 认证(较少独立使用) |
| Encapsulating Security Payload (ESP) | 50 | IPsec 加密封装 |
| Destination Options | 60 | 终点选项(MIO 移动 IPv6、Jumbo Payload) |
| Mobility Header | 135 | Mobile IPv6 |
> [!warning] Path MTU Discovery in IPv6
> IPv6 规定**路由器不允许对 IP 包分片**。如果包超过链路 MTU,路由器直接丢弃并返回 ICMPv6 "Packet Too Big"。这就是 PMTUD 在 IPv6 中成为强制要求的原因。
## IPv4 到 IPv6 的过渡机制
| 技术 | 原理 | 适用场景 |
|------|------|---------|
| Dual Stack | 同时运行 IPv4 和 IPv6 | 最常见,逐步迁移 |
| Tunneling (6in4/6to4) | IPv6 包封装在 IPv4 中传输 | 穿越纯 IPv4 骨干网 |
| NAT64/DNS64 | 客户端仅有 IPv6,NAT 翻译到 IPv4 | 运营商级部署 |
| SIIT | 状态less 翻译,地址嵌入 (IPv4-mapped) | ISP、企业边界 |
## Go 中的 IPv6 支持
```go
import "net"
// 创建双栈监听器(同时支持 v4/v6)
ln, err := net.Listen("tcp6", ":8080")
// 设置 IPv6Only = false 可同时接受 IPv4 连接 (DualStack)
// 解析 IPv6 地址
ip := net.ParseIP("2001:db8::1") // net.IP 天然支持 v4/v6
_, cidr, _ := net.ParseCIDR("2001:db8::/32")
fmt.Println(cidr.Contains(ip)) // true
```
## 关联笔记
- [[hhs/NETWORK/IPv4首部与分段重组]] — IPv4 和 IPv6 首部的差异对比
- [[hhs/NETWORK/DNS原理与优化]] — AAAA 记录解析 IPv6 地址
- [[hhs/NETWORK/CIDR与子网划分]] — CIDR 在 IPv6 中的应用方式相同