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

Linux ip rule 优先级冲突时如何判断实际路由表

来源:17golang原创

时间:2026-09-14 15:25:37 357浏览 收藏

Linux ip rule 出现多条规则都能匹配时,不要按命令输出的感觉猜最终路由。正确判断方法是:先把 RPDB 按 priority 从小到大排列,再把真实数据包的源地址、目标地址、入口网卡和 mark 原样带入 ip route get,最后确认返回结果对应的 table 和下一跳。

priority 数字越小,规则越先处理。规则命中了某张表,不等于这张表一定能给出可用路由;如果该动作没有成功,RPDB 可能继续检查后面的规则。
要点速览
  • 先看完整规则和 selector,再看 table,不能只盯着 priority。
  • ip route get 要带上与故障流量相同的条件,否则复现的不是同一个查询。
  • 修正时使用明确、唯一的 priority,并同步记录临时规则的删除命令。

先列出 RPDB,确认谁会先匹配

ip rule 操作的是路由策略数据库。每条规则由匹配条件和动作组成,动作通常是查询某张路由表。先用详细列表保留现场:

# 显示所有策略规则,包含协议和更完整的属性
ip -details rule show

# 同时查看常见数字表名,避免把 100、200 看成规则优先级
ip route show table 100
ip route show table 200

重点记录三列:priority、selector 和 lookup/table。常见默认规则是 priority 0 查询 local 表、32766 查询 main 表、32767 查询 default 表。自定义规则如果用 100 和 200,100 会先于 200;不要把“写在前面”当成真正的排序依据。

Linux ip rule 按 priority 递增排列并将匹配条件指向不同路由表的操作示意
图1:操作示意图,展示如何把 priority、selector 和 table 目标整理成一条可追踪的规则链。

用同一组条件复现实际查询

只执行 ip route get 目标地址 容易漏掉源地址、入口网卡或 mark,结果可能走到 main 表而不是故障流量使用的路径。排障时应尽量补齐上下文:

# 用真实源地址和目标地址复现一次策略路由查询
ip route get 198.51.100.10 from 192.0.2.10

# 流量从指定网卡进入时,把入口条件也带上
ip route get 198.51.100.10 from 192.0.2.10 iif eth0

# 规则依赖防火墙标记时,使用同一个 mark 值复现
ip route get 198.51.100.10 from 192.0.2.10 mark 0x1

把输出中的设备、网关和表信息与规则逐项对照。若 iproute2 支持 fibmatch,可以在查询末尾追加它查看更完整的 FIB 匹配过程;不支持时以本机 ip route get help 的提示为准。

区分“规则命中”与“表里没有路由”

这是最容易误判的地方。假设 priority 100 的规则匹配 fwmark 0x1 并查询 table 100,但 table 100 没有覆盖目标地址的路由,查询可能继续到后面的 main 规则。此时“最后走了 main”不一定表示 100 规则没有匹配,而可能表示它匹配后没有产生成功的路由决定。

观察到的现象先检查什么判断方向
所有流量都走 mainselector 是否真的满足源地址、入口网卡、mark 可能不一致
命中自定义表但无网关ip route show table N表缺少目标前缀或默认路由
调低 priority 后仍不变local 规则和更具体 selector前面的规则已经终止或查询条件没有变化
Linux ip route get 根据源地址入口网卡和 mark 返回实际路由表与下一跳的结果示意
图2:结果示意图,强调最终表、设备和下一跳必须与同一组查询条件一起记录。

用唯一 priority 修正,并保留回滚动作

修规则前先保存当前状态。临时实验可以使用一段明确且未占用的 priority;生产变更则应由配置管理系统维护,避免手工命令与 NetworkManager、systemd-networkd 或其他网络管理器互相覆盖。

# 保存当前规则,便于变更前后对照
ip rule save > /tmp/ip-rule.before

# 示例:给来自指定源网段的流量分配明确且唯一的优先级
sudo ip rule add priority 100 from 192.0.2.0/24 table 100

# 用同样的查询条件确认修正后的设备和路由表
ip route get 198.51.100.10 from 192.0.2.10

# 实验结束后按完整 selector 删除,避免留下隐性规则
sudo ip rule del priority 100 from 192.0.2.0/24 table 100

不要用“再加一条更优规则”掩盖重复配置。记录 priority、selector、table、变更时间和验证命令;如果故障涉及 mark,还要记录 mark 是在哪里设置的。这样才能区分规则排序问题、标记丢失问题和路由表内容问题。

常见问题

priority 越大是不是越优先?

不是。数字越小越早处理,priority 100 会先于 200。建议给自定义规则显式指定唯一值。

为什么规则匹配了却最后显示 main 表?

可能是前面的规则动作没有找到成功路由,RPDB 继续检查后面的规则;也可能是你执行 route get 时遗漏了源地址、iif 或 mark。

只看 ip route show 能判断 ip rule 吗?

不能。它只能说明某张表里有什么路由,不能说明数据包是否会先进入这张表。需要先看 ip rule,再用对应条件执行 ip route get。

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