u32 filter匹配失败主因是未设flowid、协议层顺序错(需ip protocol+ip dport)、端口掩码误用(须0xffff)、priority顺序混乱;flower适用于需隧道/vlan/conntrack的现代场景;police限速需协同mtu与burst,且drop不可省略。

u32 filter 匹配失败的典型现象和定位方法
你加了 tc filter add 却发现流量完全没被分类,tc -s filter show 里计数器始终为 0——大概率是匹配条件没生效,不是规则写错了,而是没走到那条规则。
- 检查是否漏了
flowid:u32 必须显式指定flowid才能真正分类,只写match不设flowid等同于“看一眼就放行” - 确认协议层顺序:u32 默认在 IP 层匹配,TCP/UDP 端口必须用
ip protocol+ip dport组合,单独写ip dport会被忽略 - 注意掩码写法:端口匹配要用
0xffff(16 位全掩),写成0xff或省略会导致高位被截断,80 端口可能匹配到 32848 - 优先级顺序不能乱:u32 按
priority数值升序执行,priority 1比priority 10先匹配;默认不写 priority 是 0,容易被后续规则覆盖
flower filter 替代 u32 的实际适用场景
flower 不是 u32 的“升级版”,而是更贴近现代内核网络栈的分类接口——它原生支持隧道、VLAN、conntrack 状态等,但代价是某些老设备或低版本内核(flower。
- 需要匹配
ct_state(如只限速 ESTABLISHED 连接)或enc_key_id(VXLAN 流量)时,必须用 flower,u32 做不到 - 匹配 IPv6 扩展头(如 ESP、AH)时,flower 支持
ip6 frag和ip6 nh,u32 只能靠偏移硬算,极易出错 - flower 的
action mirred egress redirect在多队列网卡上比 u32 +mirred更稳定,尤其在高吞吐下不易丢包 - 但 flower 的
skip_sw默认关着,如果没显式加skip_sw 1,部分匹配会 fallback 到软件路径,性能反而不如 u32
police action 中 rate/burst/mtu 的真实含义
police 不是“限速器”,它是令牌桶的实时决策模块:每来一个包,按速率补令牌,够就放行,不够就丢或重标记——所以 rate 和 burst 的单位、换算关系必须对得上,否则限速会漂移。
-
rate单位是 bit/s(不是 byte/s),写rate 10mbit就是 10,000,000 bit/s ≈ 1.25 MB/s,别按文件下载速度去估 -
burst单位是字节(byte),不是 bit,且它决定的是“瞬时突发容量”,不是缓冲区大小;设太小(如burst 1kb)会导致小包密集时频繁触发 drop -
mtu参数仅影响 police 对“超大包”的处理逻辑:当包长 >mtu时,直接按 exceed 处理,不查令牌;不设mtu则所有包都走令牌桶,但巨型帧可能被误限 - 实际限速效果受 qdisc 类型影响:用
fq_codel底层时,police的 burst 容量会被进一步压缩,建议burst≥rate / 200(即 5ms 等效字节数)
一条能跑通的 u32 + police 规则模板
以下命令限制目标端口 80 的 TCP 流量为 5Mbit/s,burst 64KB,只作用于 eth0 出向:
tc qdisc add dev eth0 root handle 1: htb default 30 tc class add dev eth0 parent 1: classid 1:1 htb rate 100mbit tc class add dev eth0 parent 1:1 classid 1:10 htb rate 5mbit ceil 5mbit tc filter add dev eth0 parent 1: protocol ip u32 match ip protocol 6 0xff match ip dport 80 0xffff flowid 1:10 tc filter add dev eth0 parent 1: protocol ip u32 classid 1:10 \ match ip protocol 6 0xff match ip dport 80 0xffff \ police rate 5mbit burst 64kb mtu 1500 drop flowid 1:10
注意:第二条 tc filter 必须带 classid 1:10,否则 police 无法绑定到对应 class;drop 是动作,不是选项,漏掉就变成 pass(透传)。
复杂点在于 burst 和 mtu 的协同——mtu 设 1500,burst 却设 64kb,意味着前 42 个满载 MTU 包可以无损通过,第 43 个才开始受令牌约束。这个窗口期容易被误判为“限速没生效”。










