登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

Linux ip route读取策略路由表的命中路径的实现方法

来源:17golang原创

时间:2026-09-19 23:52:11 451浏览 收藏

Linux 多网卡主机出现“同一个目的地址走了不同出口”时,直接执行 ip route show 往往不够。它默认展示 main 表,而策略路由还可能受 ip rule、源地址、入口接口和防火墙标记影响。更稳妥的排查顺序是:先读规则,再看规则引用的表,最后用 ip route get 带着真实查询条件复现一次路径。

要点速览
  • ip rule list 决定按什么优先级查表,数字越小越先检查。
  • ip route show table N 展开某张候选表,不能代替实际路径解析。
  • ip route get ... fibmatch 能看到匹配的 FIB 路由,但不是完整的规则执行日志。

步骤一:先读取规则优先级与策略表编号

策略路由的第一现场不是 main 表,而是规则链。先把优先级和条件抄下来,尤其注意 fromiiffwmark 以及 lookup 后的表号。不要只记住表名,因为临时配置常直接使用数字。

# 先列出策略规则;数字越小,越早参与查找
ip rule list

# 展开规则中可能出现的自定义表,100 只是示例编号
ip route show table 100
ip route show table main
ip route show table default

常见的 local 表编号是 255,main 是 254,default 是 253。它们是约定俗成的内置表;自定义表仍应以本机规则和 /etc/iproute2/rt_tables 中的映射为准。若规则带有 lookup 100,就必须把 100 的内容展开后再判断。

Linux ip rule优先级连接local、main和自定义路由表的策略路由结构说明图
图1:策略规则到路由表的静态结构说明图,不是终端截图或运行证据。

步骤二:按表查看候选路由与终止类型

看到一条更具体的前缀并不等于它一定被采用。策略路由会先受规则条件约束,再在被选中的表里找路由。查看时把候选项按“目的前缀、类型、网关、设备、首选源地址”记录下来。

字段排查意义容易误判的地方
table说明路由属于哪张表只看 main 会漏掉自定义表
via / dev说明下一跳与出口设备直连路由可能没有 via
src提示优先使用的源地址不等于所有应用最终绑定的源地址
throw / unreachable控制继续查找或直接失败不能当作普通可转发路径

throw 常用于策略路由表之间的继续查找;unreachableblackholeprohibit 则分别代表带错误反馈、静默丢弃或管理性禁止的终止结果。出现这些类型时,先确认它们来自哪张表,不要只修改默认网关。

步骤三:用 ip route get 复现一次实际查询

ip route get 的价值在于把查询条件交给内核解析。它不是简单地把现有表打印出来,而是返回内核针对这个目的地址解析出的结果,并且不实际发送数据包。排查多出口问题时,至少把目的地址和候选源地址写出来:

# 复现从指定源地址发往目标地址的出口选择
ip route get 203.0.113.10 from 192.0.2.20

# 模拟报文从 eth0 进入,再查看转发方向
ip route get 203.0.113.10 from 192.0.2.20 iif eth0

# 模拟带防火墙标记的流量;标记值必须与规则中的 fwmark 对应
ip route get 203.0.113.10 mark 0x20

结果里的 dev 是出口设备,via 是下一跳,src 是内核偏好的源地址。若不带 from,你复现的可能只是默认源地址场景;若规则依赖入口接口或 mark,却没有带上相应条件,结论也只覆盖了另一条路径。

Linux ip route get根据目的源地址入口接口和mark解析出口的查询路径说明图
图2:ip route get 与 fibmatch 查询条件和结果字段的静态说明图,不是运行截图。

步骤四:用 fibmatch 区分命中 FIB 与最终解析结果

普通查询更接近“最终要从哪里发出”;加入 fibmatch 后,可以要求返回完整的 FIB 查找命中路由。两者用途不同:前者适合确认应用流量会走哪个设备,后者适合判断到底是哪条前缀、哪种路由类型被匹配。

# 先看最终解析结果,记录 dev、via 和 src
ip route get 203.0.113.10 from 192.0.2.20

# 再请求完整的 FIB 匹配路由,核对前缀和路由类型
ip route get fibmatch 203.0.113.10 from 192.0.2.20

这里要留一个边界:fibmatch 能帮助你确认匹配的 FIB 路由,但不会自动输出一份“每条 ip rule 都执行过”的审计日志。因此完整定位仍要把规则列表、各表内容和两次 get 的结果放在一起对比。

步骤五:按边界条件复查并形成排障清单

最后做一次小范围矩阵复查,避免把偶然的默认路由当成策略结果:

  • 同一目的地址分别替换两个合法源地址,比较 devviasrc
  • 对转发流量补上 iif,对防火墙分类流量补上 mark
  • 分别用 IPv4 和 ip -6 route get 查询,不把两套规则混为一谈。
  • 若出现“无路由”,检查自定义表是否真的存在,以及 throw 后是否还有可用规则。

只有当复现条件和线上流量一致时,命中的 devvia 才能作为配置调整依据。修改策略前先保存 ip rule list 与相关表的文本结果,便于回滚和比较。

常见问题

为什么 ip route show 与 ip route get 的结果不一样?

show 展示已有路由条目,通常还要指定正确的表;get 则根据查询条件解析一次路径,源地址、入口接口和 mark 不同,结果自然可能不同。

ip route get 能直接告诉我命中了哪一条 ip rule 吗?

它主要返回解析后的路径;结合 fibmatch 可确认匹配的 FIB 路由,但不能替代规则链审计,所以仍要对照 ip rule list 和被引用的表。

看到 default 路由后就能判断出口吗?

不能。default 只是某张表中的兜底前缀,策略规则可能先让流量进入另一张表,或者由 throwunreachable 等类型改变结果。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>