Linux 路由逻辑详解
关键要点
- 路由决策基础:Linux 内核使用路由表决定 IP 数据包转发路径,主要遵循最长前缀匹配(LPM)原则,相同前缀下优先选择 metric 值较小的路由;主表 ID 为 254,本地表为 255,支持自定义表实现策略路由。
- 递归路由作用:当路由条目的下一跳(via)不是直连接口时,内核会递归查询路由表以解析实际出接口和路径,直至找到直连路由;这适用于多级网络拓扑,但需防范递归路由问题(如隧道端点通过隧道学习,导致路由振荡)。
- 邻接表与 ARP 表区别:邻接表(Neighbor Table)是通用结构,包含 IPv4 的 ARP 缓存和 IPv6 的 ND 缓存,用于 IP 到 MAC 地址映射;ARP 表特指 IPv4 部分,邻接表更广义,支持多协议。
- 协作机制:路由表处理 L3 路径决策,邻接表负责 L2 封装;缺失邻接条目时触发 ARP/ND 请求,故障(如未解析)导致数据包丢弃。
- 常见类型与来源:包括默认路由、直连路由(proto kernel,自动生成)、静态路由(proto static,手动添加)和动态路由;优先级由 metric 主导,不同协议有隐式偏好。
核心字段与类型
路由条目字段包括目标网络、via、dev 等;类型扩展包括 unicast、unreachable 等。以下表格总结核心字段与常见路由类型:
| 类别 | 描述 | 示例或细节 |
|---|---|---|
| 核心字段 | 目标网络(prefix 或 default):目的子网或所有未知目标。 | 10.2.15.0/24 或 default |
| via(下一跳网关 IP):非直连时指定,需递归解析。 | 10.2.15.1 | |
| dev(出接口名称):数据包发送接口。 | enp1s0 | |
| proto(来源):kernel(自动直连)、static(手动)、boot(引导时)。 | kernel | |
| metric(优先级):越小越优,默认 0 不显示。 | 101 | |
| scope(范围):link(直连)、global(经网关)、host(本地)。 | link | |
| src(源 IP):多接口场景下指定源地址。 | 10.2.15.31 | |
| 其他(如 mtu、rtt、状态):MTU(最大传输单元)、RTT(往返时延)、linkdown(接口不可用)。 | linkdown | |
| 路由类型 | unicast:标准转发路径。 | 默认类型 |
| unreachable:不可达,发送 ICMP host unreachable。 | 用于黑洞路由 | |
| blackhole:静默丢弃数据包。 | 安全过滤 | |
| prohibit:行政禁止,发送 ICMP administratively prohibited。 | 策略控制 | |
| local:本地回环地址。 | 127.0.0.1 | |
| broadcast:链路广播。 | 链路本地 | |
| throw:用于策略规则,终止查找并发送 ICMP net unreachable。 | 策略路由 | |
| multicast:组播路由,不在标准表。 | IGMP 等 |
路由逻辑概述
Linux 内核路由逻辑用于决定 IP 数据包的转发路径,核心是基于路由表(FIB)的查询与链路层处理。逻辑强调逐跳独立:每台路由器独立决策,只在目的 IP 匹配本机地址时终止转发并本地投递(否则继续转发)。避免重复:路由查询优先最长前缀匹配(LPM),metric 值小的优先;邻接表(Neighbor Table)是通用结构,包含 ARP(IPv4 IP-MAC 映射)和 ND(IPv6),而 ARP 表仅指 IPv4 部分,支持超时刷新和垃圾回收。
路由逻辑步骤
-
路由表匹配:使用目的 IP 在路由表中进行最长前缀匹配(LPM),获取出接口(dev)和下一跳 IP(nexthop)。
- 如果匹配直连路由(scope link,proto kernel),下一跳通常为空(或隐式为目的 IP 本身),直接使用出接口。
- 如果匹配网关路由(via 指定),下一跳为网关 IP;若网关非直连,触发递归路由:内核递归查询路由表解析实际出接口和路径,直至找到直连路由(避免手动配置多级路径,支持分层拓扑,但需防递归问题如路由振荡)。
- 特殊:默认路由(default)匹配未知目标;metric 优先级主导相同前缀选择。
-
邻接解析:查询邻接表(ip neigh show)获取下一跳 IP 的 MAC 地址,用于 L2 封装。
- 邻接表区别于 ARP 表:前者通用(IPv4/IPv6),后者仅 IPv4;缺失时触发 ARP 请求(IPv4)或 ND(IPv6)。
- 未命中:缓存数据包,发起 ARP/ND 请求;重试超时后丢弃,并可选发送 ICMP(destination unreachable)。
-
数据包处理与发送:修改数据包目的 MAC 为邻接解析结果,源 MAC 为出接口 MAC;检查 MTU(若超限且 DF 位设,碎片化或发送 ICMP too big);通过出接口发送。
- 发送前确保 ARP 完成(否则缓存待发);支持多路径路由(负载均衡)。
-
逐跳转发:每跳独立处理数据包(TTL 递减),直到某跳判断目的 IP 为本机地址(本地表匹配),终止转发并投递到上层协议栈(e.g., TCP/UDP);否则继续下一跳。
举例场景:数据包从主机 A 到主机 B 的路由过程
假设主机 A(IP: 192.168.1.10)发送数据包到远程主机 B(IP: 10.0.0.5),A 的路由表有默认路由 via 192.168.1.1(网关,非直连)。
- 步骤 1:A 用 10.0.0.5 匹配路由表,命中默认路由,获取 via 192.168.1.1。但 192.168.1.1 非直连于 A 的接口 eth0,触发递归路由:再匹配 192.168.1.1,命中直连路由(192.168.1.0/24 dev eth0),解析出接口 eth0 和下一跳 192.168.1.1。
- 步骤 2:查询邻接表获取 192.168.1.1 的 MAC;若缺失,发送 ARP 请求("谁是 192.168.1.1?"),缓存数据包等待回复。
- 步骤 3:收到 ARP 回复后,设置目的 MAC 为网关 MAC,源 MAC 为 eth0 MAC;检查 MTU 无超限,通过 eth0 发送。
- 步骤 4:网关(192.168.1.1)接收后,检查目的 IP 非本机,继续逐跳转发(类似步骤 1-3),直至某路由器判断 10.0.0.5 为其本地地址,投递给 B。
此场景展示递归路由简化配置(无需显式多级路径),邻接表确保 L2 转发效率。
常用指令与作用
ip route show:查看主路由表(支持 table 指定其他表)。ip route add/del <prefix> via <nexthop> dev <dev> metric <value>:添加/删除路由条目。ip route get <dst_ip>:模拟目的 IP 的路由决策(显示递归结果)。ip neigh show:查看邻接表(包括 ARP/ND 缓存)。