Linux tc filter u32 / flower 的分类与 policing 限速规则模板

1次阅读

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

Linux tc filter u32 / flower 的分类与 policing 限速规则模板

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 1priority 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 fragip6 nh,u32 只能靠偏移硬算,极易出错
  • flower 的 action mirred egress redirect 在多队列网卡上比 u32 + mirred 更稳定,尤其在高吞吐下不易丢包
  • 但 flower 的 skip_sw 默认关着,如果没显式加 skip_sw 1,部分匹配会 fallback 到软件路径,性能反而不如 u32

police action 中 rate/burst/mtu 的真实含义

police 不是“限速器”,它是令牌桶的实时决策模块:每来一个包,按速率补令牌,够就放行,不够就丢或重标记——所以 rateburst 的单位、换算关系必须对得上,否则限速会漂移。

  • 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 容量会被进一步压缩,建议 burstrate / 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 个才开始受令牌约束。这个窗口期容易被误判为“限速没生效”。

text=ZqhQzanResources