Linux 基础体系 · 第 66/85 篇。示例面向现代主流 Linux 发行版;发行版差异、权限和生产风险会明确说明。

Linux 路由深入:多表、策略路由、ECMP、VRF 和反向路径检查

Linux 中的“路由”不只是“根据目标地址选择下一跳”。现代 Linux 的路由决策通常同时受到以下因素影响:

  • 目标地址、源地址和入接口;
  • 路由表及表内的最长前缀匹配;
  • 策略路由规则(RPDB,Routing Policy Database);
  • 防火墙标记、用户 ID、服务类型等选择条件;
  • 多路径路由(ECMP);
  • VRF 对路由表和网络命名空间的隔离;
  • IPv4 反向路径检查(rp_filter);
  • 邻居解析、链路状态、防火墙和网络命名空间。

理解这些机制的关键,是把“路由表”和“策略路由规则”区分开:

路由表回答“这个数据包可以通过哪些路径到达目标”;
策略路由规则回答“这次查找应该使用哪张路由表”。


一、一个数据包如何完成路由决策

先定义一次路由查找的输入:

F=(s,d,iif,mark,uid,tos,proto,)F = (s, d, iif, mark, uid, tos, proto, \ldots)

其中:

  • ss:源地址;
  • dd:目标地址;
  • iifiif:输入接口;
  • mark:数据包防火墙标记;
  • uid:产生该数据包的本地进程用户 ID;
  • tos:IPv4 TOS 或 IPv6 Traffic Class;
  • proto:协议相关信息。

Linux 首先按照规则优先级扫描 RPDB。每条规则包含:

  1. 匹配条件;
  2. 动作,例如查某张表或直接返回 unreachable
  3. 优先级。

如果某条规则匹配,系统通常会查询它指定的路由表。如果表中找到了可用结果,查找结束;如果只是“没有匹配路由”,还可能继续处理后续规则。

典型默认规则如下:

$ ip rule show
0:      from all lookup local
32766:  from all lookup main
32767:  from all lookup default

含义是:

  1. 优先查询 local 表;
  2. 再查询 main 表;
  3. 最后查询 default 表。

local 表不是普通意义上的“默认本地路由表”,而是内核自动维护的本机地址、广播地址和本地路由表。直接删除或修改其中的路由,可能导致本机地址无法正确处理。

1. 路由表内的最长前缀匹配

进入一张表后,Linux 会根据目标地址选择匹配程度最高的前缀。

假设表中有:

10.0.0.0/8       via 192.0.2.1 dev eth0
10.20.0.0/16     via 192.0.2.2 dev eth1
10.20.30.0/24    via 192.0.2.3 dev eth2
default          via 192.0.2.254 dev eth0

目标为 10.20.30.40 时,三个前缀都可能匹配,但 /24 最长,因此选择:

10.20.30.0/24 via 192.0.2.3 dev eth2

目标为 10.20.50.1 时,选择 /16;目标为 10.30.1.1 时,只能使用 /8;不匹配任何具体前缀时,才使用 default

这就是最长前缀匹配(Longest Prefix Match,LPM)。它与路由协议的管理距离不是同一个概念。Linux 内核路由表中的 metric 主要用于同一前缀、同一类型等候选路由之间的优先级比较;不能用“低 metric”替代更长前缀。

2. ip route get 查看内核实际判断

不要只查看配置文件或 ip route 的摘要。排查某个具体数据包时,应直接让内核进行一次查询:

ip route get 203.0.113.10

可能输出:

203.0.113.10 via 192.0.2.1 dev eth0 src 192.0.2.10

这表示:

  • 目标是 203.0.113.10
  • 下一跳为 192.0.2.1
  • 出接口为 eth0
  • 内核选择的源地址为 192.0.2.10

如果需要模拟来自某个源地址或接口的查询,可以使用:

ip route get 203.0.113.10 from 198.51.100.10
ip route get 203.0.113.10 from 198.51.100.10 iif eth1
ip route get 203.0.113.10 mark 100

不同发行版所带的 iproute2 版本对可选参数支持可能不同;实际语法应以本机 ip route get help 为准。


二、多路由表:把不同路径分开保存

Linux 并不只有一张路由表。表通过数字 ID 标识,也可以在 /etc/iproute2/rt_tables 中设置名称:

100 isp_a
200 isp_b

查看某张表:

ip route show table main
ip route show table isp_a
ip route show table 100

添加路由:

ip route add 203.0.113.0/24 via 192.0.2.1 dev eth0 table isp_a

删除时应明确指定表:

ip route del 203.0.113.0/24 via 192.0.2.1 dev eth0 table isp_a

否则可能误操作 main 表。生产环境中,ip route flush table ... 会一次性删除表内大量路由,必须先确认表 ID 和业务影响。

1. 为什么需要多表

考虑一台服务器有两个出口:

eth0:192.0.2.10/24,网关 192.0.2.1
eth1:198.51.100.10/24,网关 198.51.100.1

如果只把两条默认路由放在 main 表中:

default via 192.0.2.1 dev eth0 metric 100
default via 198.51.100.1 dev eth1 metric 200

通常只有低 metric 的默认路由优先,所有流量都倾向于从 eth0 发出。这不等于“按源地址从对应出口发出”。

若要求:

  • 源地址为 192.0.2.10 的连接从 eth0 出口;
  • 源地址为 198.51.100.10 的连接从 eth1 出口;

可以建立两张表:

ip route add 192.0.2.0/24 dev eth0 src 192.0.2.10 table isp_a
ip route add default via 192.0.2.1 dev eth0 src 192.0.2.10 table isp_a

ip route add 198.51.100.0/24 dev eth1 src 198.51.100.10 table isp_b
ip route add default via 198.51.100.1 dev eth1 src 198.51.100.10 table isp_b

再添加规则:

ip rule add pref 100 from 192.0.2.10/32 lookup isp_a
ip rule add pref 110 from 198.51.100.10/32 lookup isp_b

查询结果应分别指向不同出口:

ip route get 8.8.8.8 from 192.0.2.10
ip route get 8.8.8.8 from 198.51.100.10

规则中的 pref 越小,优先级越高。建议显式指定优先级,而不要依赖系统自动分配的优先级。

2. 策略规则不是“覆盖所有后续规则”

下面的规则:

ip rule add pref 100 from 192.0.2.10/32 lookup isp_a

只表示“匹配该源地址时,先查 isp_a 表”。如果 isp_a 中没有匹配目标的路由,查找可能继续到下一条规则。

这在使用“专用表只放部分路由”时很重要。例如:

ip route add 10.0.0.0/8 via 192.0.2.254 dev eth0 table isp_a
ip route add throw 0.0.0.0/0 table isp_a

throw 路由表示该表对本次查找明确放弃,允许继续处理后续 RPDB 规则。与之相反,以下路由类型会终止查找并返回错误:

ip route add blackhole 203.0.113.0/24
ip route add unreachable 203.0.113.0/24
ip route add prohibit 203.0.113.0/24

它们分别表示静默丢弃、不可达和策略禁止。使用这些类型可以实现黑洞或拒绝策略,但误加到优先级过高的规则中会直接阻断业务。

3. 根据防火墙标记选择表

基于源地址的规则适合本机固定地址;基于业务、连接或入接口的策略,通常使用 fwmark

ip rule add pref 200 fwmark 0x64/0xff lookup isp_b

这里:

  • 数据包标记与 0xff 做掩码;
  • 结果为 0x64 时查询 isp_b

仅添加 ip rule 不会自动产生标记。需要由 nftables、iptables 或其他内核组件设置 skb mark。例如 nftables 的概念性配置:

nft add table inet pbr
nft 'add chain inet pbr prerouting { type filter hook prerouting priority mangle; policy accept; }'
nft add rule inet pbr prerouting iifname "eth1" meta mark set 0x64

实际生产配置通常还要考虑:

  • 是否只给新连接打标;
  • 是否将连接标记保存到后续数据包;
  • 本机发出的流量应在 output 路径处理;
  • NAT 是否改变了用于分类的地址;
  • 标记是否在路由重新查找前已经设置。

如果标记只存在于第一个数据包,后续数据包可能走回 main 表,产生“首包正常、后续包异常”的现象。连接跟踪和 ct mark 的具体配置依赖系统的 nftables/iptables 版本,不应把 meta mark 和连接标记混为一谈。

4. 常见策略路由错误

忘记添加直连路由

只添加默认路由:

ip route add default via 192.0.2.1 dev eth0 table isp_a

并不一定足够。下一跳 192.0.2.1 必须能够通过该接口解析到邻居,否则可能报:

Error: Nexthop has invalid gateway.

因此通常还要在同一张表中添加:

ip route add 192.0.2.0/24 dev eth0 src 192.0.2.10 table isp_a

把入接口规则误认为源地址规则

ip rule add iif eth1 table isp_b

只影响经过 eth1 接收后进行转发的流量;本机进程主动产生的数据包没有输入接口,不能用它匹配本地输出流量。对于本地流量,应根据源地址、目的地址、用户、标记等条件设计规则。

规则匹配但表中没有回程路径

策略路由经常造成单向路径。请求从 isp_b 进入,回复却按照 main 表从 isp_a 发出,远端或中间防火墙可能丢弃这个连接。排查时应同时查询两个方向:

ip route get <client-ip> from <server-ip>
ip route get <server-ip> from <client-ip> iif <incoming-iface>

三、ECMP:同一目标的等价多路径

ECMP(Equal-Cost Multi-Path)表示对同一个目标前缀存在多个等价的下一跳。

示例:

ip route add 203.0.113.0/24 \
    nexthop via 192.0.2.1 dev eth0 weight 1 \
    nexthop via 198.51.100.1 dev eth1 weight 1

前置条件通常包括:

  • 两个下一跳都可达;
  • 对内核而言,它们属于同一个目标前缀的等价候选;
  • 接口、邻居和网关状态正常;
  • 上游网络能够接受这种转发设计。

查看结果:

ip route show 203.0.113.0/24
ip route get 203.0.113.10

1. ECMP 不是简单的轮询

现代 Linux 通常按流进行哈希,而不是每个数据包轮流选择下一跳。哈希输入通常与五元组相关:

源地址、目标地址、源端口、目标端口、协议

因此:

  • 同一 TCP 连接通常固定使用一个下一跳;
  • 多条不同连接可以分散到不同下一跳;
  • 只有一个大流时,带宽通常不会自动叠加到所有路径;
  • 哈希策略和可调参数受内核版本、协议族和实现影响。

weight 表示加权路径的相对权重,例如:

ip route replace 203.0.113.0/24 \
    nexthop via 192.0.2.1 dev eth0 weight 3 \
    nexthop via 198.51.100.1 dev eth1 weight 1

这表示流量分配倾向为 3:1,而不是严格保证每四个数据包精确分配三个和一个。

2. ECMP 的故障边界

ECMP 本身不等于健康检查。内核通常能够感知:

  • 接口被置为 down;
  • 邻居解析失败;
  • 下一跳设备不可用等本地状态。

但“远端服务已经故障”“中间链路黑洞”“BGP 邻居失效”等情况,不能仅靠一条静态 ECMP 路由可靠判断。通常需要:

  • 动态路由协议撤销下一跳;
  • BFD 或其他探测机制;
  • 运营商或控制器同步路由状态。

如果只是删除某个接口上的默认路由,而连接哈希仍在使用另一个路径,已有连接的行为也可能发生变化。路径变化会导致 TCP 重传、连接抖动,甚至因为 NAT 状态不一致而断开。

3. ECMP 与策略路由的组合

ECMP 发生在“某张表已经被选中之后”。例如:

规则 100:源地址 192.0.2.10 -> table isp_a
规则 110:源地址 198.51.100.10 -> table isp_b

即使两张表内部都有 ECMP,首先仍然要由 RPDB 决定查哪张表。ECMP 不能替代源地址策略,也不会自动解决两个 ISP 的回程路径问题。


四、VRF:按路由域隔离三层转发

VRF(Virtual Routing and Forwarding)把多个接口和路由表组织成相互隔离的三层路由域。

它与网络命名空间不同:

  • 网络命名空间隔离接口、地址、路由、iptables/nftables 状态等整套网络栈;
  • VRF 通常在同一个网络命名空间内提供多个三层路由域;
  • 同一个命名空间内的进程和 socket 仍可能需要显式绑定 VRF;
  • VRF 适合多租户、多业务路由域或网络设备风格的隔离。

1. 创建 VRF

一个基本示例:

ip link add vrf-blue type vrf table 100
ip link set vrf-blue up

ip link set eth1 master vrf-blue
ip addr add 10.10.1.1/24 dev eth1
ip link set eth1 up

ip route show table 100
ip rule show

table 100 是该 VRF 使用的路由表。将 eth1 加入 vrf-blue 后,面向该接口的三层路由通常会进入对应 VRF 表,而不是普通的 main 表。

Linux 内核的 VRF 实现会使用 l3mdev 相关策略规则把 VRF 设备关联到其路由表。不同 iproute2 版本显示的规则文字可能不同,例如可能看到与 l3mdev 或具体 VRF 设备相关的规则。不要仅依据规则的显示形式判断 VRF 是否生效,应同时检查:

ip -d link show vrf-blue
ip route show table 100
ip route get 10.10.1.20 oif vrf-blue

在一些发行版中,网络管理器会接管手工创建的接口和地址;重启网络服务后,临时配置可能被删除。

2. VRF 中的路由和默认路由

在 VRF 表中添加默认路由:

ip route add table 100 default via 10.10.1.254 dev eth1

如果网关不在接口的直连前缀内,内核通常会拒绝该下一跳。只有在确定链路确实支持这种用法时,才考虑:

ip route add table 100 default via 10.10.1.254 dev eth1 onlink

onlink 强制内核把网关视作二层可达,错误使用会导致 ARP/邻居解析在错误链路上发送,不能用来掩盖地址规划问题。

VRF 中的本地路由仍然会进入 local 表;但目的地址属于哪个 VRF、数据包从哪个接口进入,以及 socket 是否绑定到 VRF,会共同影响实际处理路径。因此,检查 VRF 问题时至少应观察:

ip addr show dev eth1
ip route show table 100
ip rule show
ss -lntup

3. 本地进程如何使用 VRF

对于监听服务,常见做法是让 socket 绑定到 VRF 设备,或使用发行版提供的 ip vrf exec

ip vrf exec vrf-blue ping 10.10.1.254

并非所有程序都能正确处理 VRF 场景。常见限制包括:

  • 程序显式绑定了某个物理接口;
  • 程序只绑定地址,没有绑定 VRF;
  • 服务管理器没有为进程设置 VRF 上下文;
  • 同一端口在不同 VRF 中的复用行为与预期不同;
  • 监听地址属于某个 VRF,但客户端从默认路由域发起连接。

VRF 的“隔离”主要是三层路由选择隔离,不自动提供防火墙意义上的完整安全边界。跨 VRF 通信仍可通过显式路由、策略规则、网络命名空间或防火墙设计实现,但不应默认认为 VRF 之间完全不可达。

4. VRF 与网络命名空间的选择

若需要隔离:

  • 路由表;
  • 接口视图;
  • 本地地址空间;
  • 防火墙规则;
  • 网络服务和进程;

网络命名空间更彻底。

若只需要在同一系统内维护多个独立的三层路由域,并允许控制面或运维工具统一管理,VRF 通常更直接。两者也可以组合使用,但组合后排障必须明确当前命令运行在哪个命名空间、哪个 VRF 中。


五、反向路径检查:为什么请求到了,回复却没有发送

反向路径检查(Reverse Path Filtering,RPF)是对入站 IPv4 数据包源地址进行校验的机制。它试图回答:

如果现在要把一个包发往它的源地址,内核认为应该从哪个接口出去?

设数据包:

  • 源地址为 ss
  • 目标地址为本机地址;
  • 进入接口为 ii

内核对 ss 做一次反向路由查询,得到反向路径接口 R(s)R(s)

严格模式要求:

R(s)=iR(s) = i

也就是,返回源地址的最佳路径必须与入接口相同。

宽松模式要求:

R(s) 存在R(s) \text{ 存在}

即只要系统认为源地址可达即可,不强制要求从同一个接口返回。

Linux IPv4 rp_filter 的常见值为:

0:关闭
1:严格模式
2:宽松模式

查看配置:

sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.conf.default.rp_filter
sysctl net.ipv4.conf.eth0.rp_filter

Linux 对 all 和具体接口的有效值处理通常取较严格的配置,常见实现中相当于取二者最大值。因此只修改:

sysctl -w net.ipv4.conf.all.rp_filter=0

不一定能让 eth0 实际关闭检查;必须同时检查具体接口配置。

1. 典型非对称路径反例

假设:

eth0:默认出口 ISP-A
eth1:默认出口 ISP-B

客户端从 ISP-B 通过 eth1 进入:

client -> ISP-B -> eth1 -> server

但服务器查询客户端源地址时,main 表的最佳路由却指向 eth0

server --eth0--> ISP-A -> client

在严格 rp_filter=1 下,入包可能在到达 TCP 服务之前就被丢弃,因为:

反向最佳接口 eth0 != 实际入接口 eth1

这会表现为:

  • tcpdump -i eth1 能看到数据包;
  • 应用程序日志没有连接记录;
  • ss 看不到预期连接;
  • 客户端持续重传 SYN;
  • 修改服务端监听地址并不能解决问题。

2. 反向检查使用哪条路由

反向检查不是简单读取 main 表。在存在策略路由时,反向查询还可能受到:

  • 源地址;
  • 输入接口;
  • fwmark
  • VRF;
  • 相关 sysctl 配置;

影响。IPv4 的 src_valid_mark 可以控制反向路径验证是否考虑数据包标记:

sysctl net.ipv4.conf.all.src_valid_mark

使用基于 mark 的多出口策略时,如果反向检查和正向路由使用了不同的标记语义,就可能出现正向包能到达、反向校验却失败的情况。该参数的具体行为与内核版本和策略设计有关,不能在不了解流量标记生命周期的情况下盲目开启或关闭。

3. 调整模式的风险

关闭或放宽 rp_filter 可以适应非对称路由,但也会降低对源地址欺骗的基础防护。以下配置只是示例,不能直接作为所有生产系统的通用方案:

sysctl -w net.ipv4.conf.all.rp_filter=2
sysctl -w net.ipv4.conf.default.rp_filter=2
sysctl -w net.ipv4.conf.eth0.rp_filter=2
sysctl -w net.ipv4.conf.eth1.rp_filter=2

更重要的原则是先解释非对称路径,再决定配置:

  • 如果网络设计要求严格对称,修正策略路由和回程路由通常优于关闭检查;
  • 如果 ECMP 或双 ISP 必然产生非对称路径,宽松模式可能更符合设计;
  • 如果接口面向不可信网络,放宽源地址验证要配合入口过滤、反欺骗规则和上游控制;
  • IPv4 的 rp_filter 不能直接等同于 IPv6 的完整源地址验证机制。

六、从收包到转发:路由、标记和反向检查的相互位置

转发路径可以抽象为:

flowchart LR
    A[数据包进入接口] --> B[邻居与链路处理]
    B --> C[IPv4 反向路径检查]
    C --> D[PREROUTING]
    D --> E[策略路由与路由查找]
    E --> F{本地投递还是转发}
    F -->|本地| G[INPUT]
    F -->|转发| H[FORWARD]
    H --> I[POSTROUTING]
    I --> J[输出接口与下一跳]

实际内核路径还会受到协议族、隧道、桥接、Netfilter hook 优先级、路由缓存和重新查找等影响,但这个模型足以解释很多问题:

  1. rp_filter 可能在应用层之前丢弃入包;
  2. PREROUTING 中设置的 mark 可以影响后续路由选择;
  3. 路由查找决定本地投递还是转发;
  4. 经过 NAT 或 mark 改变后,某些情况下会触发重新路由;
  5. 最终发送还需要邻居解析和设备状态正常。

因此,看到包进入接口并不代表它一定进入了服务进程。应分层观察:

tcpdump -ni eth1 host 10.10.1.20
ss -lntp
ip route get 10.10.1.20
ip neigh show dev eth1
nft list ruleset

tcpdump 能看到 SYN,但 ss 没有连接,可能是:

  • rp_filter 丢包;
  • 目的地址没有对应的本地路由;
  • 防火墙在 INPUT 前后丢包;
  • 服务只监听了另一个地址或 VRF;
  • TCP 包经过策略路由后被错误转发。

七、一个可验证的双出口排障流程

假设有以下策略:

源地址 192.0.2.10    -> isp_a -> eth0
源地址 198.51.100.10 -> isp_b -> eth1

先检查接口、地址和链路:

ip -br addr
ip -br link

再检查规则顺序:

ip rule show

确认两张表中的直连路由和默认路由:

ip route show table isp_a
ip route show table isp_b

分别模拟两个源地址:

ip route get 1.1.1.1 from 192.0.2.10
ip route get 1.1.1.1 from 198.51.100.10

预期是第一条使用 eth0,第二条使用 eth1。如果两条都使用同一接口,优先检查:

  • 规则优先级是否正确;
  • 源地址是否确实存在;
  • 自定义表是否包含默认路由;
  • 是否有更高优先级的 tofwmarkiif 规则;
  • 是否查询到了 local 表中的本地结果。

接着检查邻居解析:

ip neigh show dev eth0
ip neigh show dev eth1

状态为 FAILED 表示下一跳邻居解析失败;STALE 不一定是故障,它表示缓存未被近期确认,发送时仍可能重新验证。

最后用抓包验证方向:

tcpdump -ni eth0 host 1.1.1.1
tcpdump -ni eth1 host 1.1.1.1

抓包应与 ip route get 的内核判断一致。如果命令显示走 eth1,但包从 eth0 出去,应继续检查:

  • 是否由容器、VRF 或其他网络命名空间发出;
  • 是否存在 mark 导致实际查找条件不同;
  • 是否有隧道、策略路由守护进程或网络管理器修改路由;
  • 抓包点是否位于实际发送路径。

ip monitor route rule link 可以持续观察路由、规则和链路变化:

ip monitor route rule link

这对发现 NetworkManager、systemd-networkd、DHCP 客户端或动态路由协议反复覆盖配置很有帮助。


八、常见误解与边界

1. ip route 显示正常,不代表所有包都能走

ip route 默认主要显示 main 表。策略路由、VRF 和 mark 可能使实际查找使用其他表。必须分别查看:

ip route show table all
ip rule show
ip route get <dst> from <src> mark <mark>

2. metric 不能实现按源地址分流

metric 只能影响同一表中候选路由的优先级,不能表达“来自某个源地址的包必须走某个出口”。源地址分流需要 RPDB 规则、独立路由表,或由 mark 驱动的策略。

3. ECMP 不保证每个数据包平均分配

ECMP 通常以流为单位哈希。单个 TCP 流通常不会同时使用多个路径。要观察分布,应使用多个独立连接,并确认上游和本机的哈希行为。

4. VRF 不等于网络命名空间

VRF 主要隔离路由域;进程、端口、防火墙状态和接口可见性仍有命名空间层面的语义。要求强隔离时,不能只创建 VRF。

5. rp_filter 失败不一定有明显日志

丢包可能没有清晰的应用日志,也可能没有默认内核日志。应同时对照:

tcpdump
ip route get
sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.conf.<iface>.rp_filter

6. 生产修改必须考虑持久化和回滚

ip route addip rule addsysctl -w 默认只修改当前运行状态。重启后是否保留取决于发行版和网络管理器:

  • NetworkManager;
  • systemd-networkd;
  • netplan;
  • ifupdown;
  • 发行版自带网络脚本。

临时验证时应记录原状态:

ip rule save
ip route save table all
sysctl -a 2>/dev/null | grep '^net.ipv4.conf'

修改策略路由时,优先通过控制台、带外管理或预设自动回滚机制操作,避免远程 SSH 因回程路径改变而断开。删除规则前使用:

ip rule del pref 100

比无条件删除匹配条件更安全,因为它明确指定了目标规则。


九、把几个机制统一起来

可以用下面的顺序理解复杂 Linux 路由:

  1. 路由表保存目的前缀、下一跳、设备、路由类型和度量;
  2. RPDB根据源地址、入接口、mark 等条件选择查表顺序;
  3. 最长前缀匹配在选定表中决定最具体的目标路径;
  4. ECMP在等价候选路径之间按流选择下一跳;
  5. VRF为不同三层路由域绑定不同表和接口;
  6. 反向路径检查对入站 IPv4 源地址再次进行反向可达性验证;
  7. 邻居协议和链路状态决定选定的下一跳是否真正能够发送;
  8. 防火墙、NAT 和连接跟踪可能改变后续查找条件或改变数据包可见性。

因此,遇到“路由不通”时,不应只问“默认网关是什么”。更准确的问题是:

这个数据包的完整查找输入是什么?
它命中了哪条 RPDB 规则?
该规则查询了哪张表?
表内选择了哪个前缀和下一跳?
是否经过 ECMP?
它属于哪个 VRF?
反向路径检查看到的回程接口是什么?
邻居解析和防火墙是否允许最终发送?

一旦按这个顺序逐层验证,多表、策略路由、ECMP、VRF 和反向路径检查就不再是彼此割裂的高级选项,而是同一套 Linux 路由决策系统中的不同阶段。


系列导航与关联阅读

官方资料

本文依据 Linux 内核、systemd 与主流发行版官方文档重新梳理;正文与实验由 WR BLOG 编写。