路由基础与转发流水线
路由表:网络层的"导航地图"
路由器收到 IP 包后,需要决定"往哪送"。这个决策依据就是路由表(Routing Information Base, RIB)。
查看路由表
# Linux
$ ip route
default via 192.168.1.1 dev eth0 proto dhcp metric 100
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10
10.0.0.0/8 via 172.16.0.1 dev eth1
# Windows
C:\> route print
IPv4 路由表
===========================================================================
活动路由:
网络目标 网络掩码 网关 接口 跃点数
0.0.0.0 0.0.0.0 192.168.1.1 192.168.1.10 35
192.168.1.0 255.255.255.0 在链路上 192.168.1.10 291
路由表核心字段
| 字段 | 含义 | 类比 |
|---|---|---|
| Destination / 网络目标 | 目的网络前缀 | 城市名 |
| Genmask / 网络掩码 | 前缀长度 | 城市范围 |
| Gateway / 网关 | 下一跳地址 | 下一站火车站 |
| Iface / 接口 | 出网卡 | 出站口 |
| Metric / 跃点数 | 到达成本 | 票价/时间 |
最长前缀匹配(Longest Prefix Match)
路由表可能有多条记录匹配同一个目的 IP,路由器选择**掩码最长(最具体)**的那条。
例子:目的 IP = 10.1.1.50
路由表:
10.0.0.0/8 via 172.16.0.1 # 匹配,掩码 8 位
10.1.0.0/16 via 172.16.0.2 # 匹配,掩码 16 位
10.1.1.0/24 via 192.168.1.1 # 匹配,掩码 24 位
0.0.0.0/0 via 192.168.1.1 # 匹配,掩码 0 位
选择:10.1.1.0/24,因为 /24 比 /16、/8、/0 都长。
生活例子:你要去"广东省广州市天河区前程似锦路 88 号"。导航软件有:
- "广东省"的导航(/8)
- "广州市"的导航(/16)
- "天河区"的导航(/24)
- "默认路线"(/0)
当然选最具体的"天河区"路线。
最长前缀匹配是路由器查表的核心算法。当多条路由都匹配目的 IP 时,前缀越长(掩码位数越多),表示网络范围越小,路由越具体,优先级越高。默认路由 0.0.0.0/0 前缀长度为 0,永远是最后的兜底选择。
RIB vs FIB:控制平面与转发平面
现代路由器把"决策"和"执行"分离:
RIB(Routing Information Base)
- 控制平面,由路由协议(OSPF/BGP/静态配置)生成
- 可能包含多条到同一目的的路径
- 包含丰富的信息(协议来源、度量、下一跳、出接口)
- 人类可读,用于排障
FIB(Forwarding Information Base)
- 转发平面,由 RIB 优化生成,供硬件高速查表
- 只保留最优路径(或 ECMP 的多条等价值路径)
- 格式紧凑,适合 TCAM/ASIC 硬件查找
- 不关心"怎么学来的",只关心"往哪送"
类比:RIB 是参谋部的作战地图(标注了所有情报来源),FIB 是前线士兵口袋里的简图(只标最优路线)。
CEF(Cisco Express Forwarding)
Cisco 的 FIB 实现,把 RIB 预计算成硬件表,实现线速转发(不经过 CPU,直接由 ASIC 处理)。
ECMP:等价多路径
如果 RIB 中有多条到同一目的、度量相同的路径,可以同时放入 FIB,实现负载均衡。
Hash 因子
路由器用 Hash 算法决定某个包走哪条路径,保证同一流的包走同一条路径(避免乱序):
| Hash 模式 | 依据字段 | 粒度 |
|---|---|---|
| 五元组 | 源 IP、目的 IP、源 Port、目的 Port、Protocol | 最细,同一会话固定路径 |
| 三元组 | 源 IP、目的 IP、Protocol | 中等 |
| 二元组 | 目的 IP、Protocol | 较粗 |
| 目的 IP | 仅目的 IP | 最粗,所有到该目的走同一路径 |
生活例子:高速公路有 3 条车道,收费站按"车牌号末位"决定走哪条车道。同一辆车(同一个流)永远走同一条车道,不同车分散到各车道。
IP 转发流水线
路由器收到一个 IP 包后的完整处理流程:
1. 接收以太网帧 → 检查目的 MAC 是否是自己(或广播/组播)
2. 解封装到 IP 层 → 提取目的 IP 地址
3. 查 FIB(最长前缀匹配)→ 确定下一跳和出接口
4. TTL 减 1 → 如果 TTL=0,丢弃并返回 ICMP Time Exceeded
5. IPv4:重新计算 Header Checksum(因为 TTL 变了)
IPv6:跳过此步(无校验和)
6. 如果包长度 > 出接口 MTU:
IPv4:如果 DF=0,分片;如果 DF=1,丢弃并返回 ICMP
IPv6:丢弃并返回 ICMPv6 Packet Too Big
7. 根据出接口重新封装二层头:
- 查 ARP/NDP 表获取下一跳 MAC
- 写新的以太网首部(目的 MAC=下一跳,源 MAC=自己出接口)
8. 按 DSCP 标记进入对应 QoS 队列
9. 从出接口发送
关键优化:步骤 3~9 由硬件(ASIC/NP)完成,不经过 CPU,才能达到 10G/100G 线速。
现代路由器的转发流水线高度优化:查 FIB、TTL 减 1、校验和更新、查 ARP、重新封装全部由专用硬件(ASIC 或网络处理器)在纳秒级完成。只有首包或异常包(如 TTL=0、需要分片、选项处理)才会上送 CPU,这也是带选项的 IP 包会被丢弃或慢速处理的原因。
默认路由与黑洞路由
默认路由(Default Route)
0.0.0.0/0(IPv4)或 ::/0(IPv6),掩码长度 0,匹配所有目的地址。当没有更具体的路由时,走默认路由。
生活例子:默认路由是"如果不知道具体地址,先寄到市中心邮局"。
黑洞路由(Null Route / Blackhole)
ip route 10.1.1.0/24 Null0
目的为 10.1.1.0/24 的包直接丢弃,不转发。用途:
- 吸收攻击流量(如 DDoS 目标地址段)
- 防止路由环路(BGP 聚合时覆盖未宣告的子网)
生活例子:邮局收到寄往"废弃工业区"的信,直接扔进碎纸机,不浪费运力派送。
本篇小结
- 路由表决定包的下一跳,最长前缀匹配选择最具体的路由
- RIB 是控制平面的决策地图,FIB 是转发平面的执行简图
- ECMP 把等价值多路径同时放入 FIB,按 Hash 分流
- 转发流水线:收帧 → 查 FIB → TTL-1 → 校验和 → 查 ARP → 封装 → 发送
- 默认路由是最后兜底;黑洞路由主动丢弃特定流量
动手实践
查看本机路由表:
# Linux ip route # Windows route print追踪到某个目的的路径,观察每跳的 TTL:
traceroute 8.8.8.8在 Linux 上添加一条静态路由测试:
sudo ip route add 10.1.1.0/24 via 192.168.1.1 sudo ip route add 10.2.2.0/24 dev eth0 sudo ip route add 10.3.3.0/24 blackhole思考:为什么路由器用最长前缀匹配,而不是"最先匹配"或"度量最小优先"?如果路由表有 10.0.0.0/8 和 10.1.0.0/16,目的 10.1.1.1 走哪条?