Skip to content

Policer:限速与三色标记

Policer 是 VPP 的 QoS 里最实用、也最完整可用的部分。它做两件事:

text
  限速   超出速率的包直接丢掉
  标记   按"合规程度"改写 DSCP,交给下游区分对待

四种类型,区别在颜色数

text
  1r2c       单速率两色      conform / violate
  1r3c       单速率三色      RFC 2697 srTCM
  2r3c-2698  双速率三色      RFC 2698 trTCM
  2r3c-4115  双速率三色      RFC 4115

1r2c 只有两个颜色,exceed 恒为 0

实测 1r2c 打 30000 包:

text
  conform 3397 packets
  exceed     0 packets      ← 永远是 0
  violate 26603 packets

即使你配了 exceed-action mark-and-transmit CS1它永远不会触发。 要三色必须用 1r3c 或 2r3c。

(实测 1r3c 在本环境下 exceed 也是 0,只有 2r3c-2698 三个桶都工作。 后面那个例子用的就是它。)

配置

bash
policer add name <> \
    [type 1r2c | 1r3c | 2r3c-2698 | 2r3c-4115] \
    [color-aware] \
    [cir <承诺速率>] [cb <承诺突发>] \
    [eir <峰值速率>] [eb <峰值突发>] \
    [rate kbps | pps] \
    [round closest | up | down] \
    [conform-action drop | transmit | mark-and-transmit <DSCP>] \
    [exceed-action  ...] \
    [violate-action ...]

policer input  name <> <>
policer output name <> <>
policer del    name <>
show policer   [name <>]

单位可以是 kbpspps —— 后者在测试和按会话数限制时更直观。

纯限速

应用配置

bash
./labctl reset base
./labctl apply base 14
./labctl verify base 14
bash
vppctl policer add name p_rate type 1r2c cir 1000 cb 1000 rate pps \
    conform-action transmit exceed-action drop
vppctl policer input name p_rate host-eth1

打 30000 个包进去:

text
  已发出 30000 包
  conform 3397 packets, 360082 bytes
  exceed     0 packets, 0 bytes
  violate 26603 packets, 2819918 bytes
  通过 3397 包,丢弃 26603 包,合计 30000
✓ 绝大多数超额流量被丢弃,限速生效

数字完全对得上:3397 + 26603 = 30000。

为什么通过的比 1000 多

cir 1000 cb 1000 表示"每秒 1000 个包,另外允许 1000 个包的突发"。 测试用了约 0.4 秒,理论允许 ≈ 400 + 1000 = 1400。 实测 3397 偏高,是因为令牌桶的补充和计时粒度 —— 短时测试里这类偏差是正常的。

要测准确的限速值,把测试时间拉长到几十秒,突发的影响就摊薄了。

三色标记:这才是 Policer 真正有意思的地方

单纯丢包是很粗暴的处理。更常见的做法是: 超额的流量不丢,而是降级标记,让它在下游拥塞时优先被丢。

bash
vppctl policer add name p_color type 2r3c-2698 \
    cir 200 cb 200 eir 600 eb 600 rate pps \
    conform-action mark-and-transmit AF11 \
    exceed-action  mark-and-transmit CS1 \
    violate-action drop
vppctl policer input name p_color host-eth1

三个档位:

实测结果,客户端以 DSCP=46 (EF) 猛发 3000 个包:

text
── s1 实际收到的 DSCP 分布 ──
   117 DSCP=10        ← conform,被标成 AF11
   533 DSCP=8         ← exceed,被降级成 CS1

── policer 三色计数 ──
  conform 242 packets
  exceed 1647 packets
  violate 4111 packets    ← 丢弃

客户声称自己是最高优先级 EF,policer 按实际用量把它降级了。

DSCP 必须用大写名称

bash
conform-action mark-and-transmit AF11
conform-action mark-and-transmit af11
conform-action mark-and-transmit 10

小写和数字都被拒绝,而且报错被截断成 policer add: unknown input 'conform-action mark-and-transm...', 看不出是哪个参数的问题。第一次遇到会以为是整个 action 语法写错了。

参数怎么定

text
  cir   承诺速率    保证给到的带宽
  cb    承诺突发    允许瞬间超过 cir 多少(令牌桶深度)
  eir   峰值速率    超过 cir 但仍可用的部分(2r3c 才有)
  eb    峰值突发

cb 太小会误伤正常流量

突发桶太小时,即使平均速率没超,短时的正常波动也会被打成 violate。

经验值:cb 至少给到 cir 对应几十到一百毫秒的量。 比如 cir = 10 Mbps,cb 至少给 128 KB 左右 (10 Mbps × 0.1s ÷ 8 ≈ 125 KB)。

配太小的典型症状:平均带宽远没到限速值,用户却报告"卡顿、丢包"。

color-aware 模式

policer add ... color-aware 让 policer尊重包已有的标记

text
  非 color-aware(默认)   所有包一视同仁,只按速率分档
  color-aware             已经被上游标成黄色的包,
                          即使在 cir 以内也不会被提升为绿色

用在多级限速场景:上游边界已经做过一次标记, 下游的 policer 不应该把降级过的流量重新提升回去。

挂在哪个方向

bash
policer input  name p host-eth1     # 进这个接口的包
policer output name p host-eth1     # 从这个接口出去的包

方向的选择决定了 policer 看到的地址 —— 和 ACL 一样, 这取决于它在 feature arc 上相对 NAT 的位置。实测:

bash
vppctl show interface features host-eth1
text
ip4-unicast:
  ip4-sv-reassembly-feature
  policer-input             ← policer 在这
  nat-pre-in2out            ← NAT 在后

入向 policer 在 NAT 之前,所以它限的是内网侧的速率, 统计口径也是内网地址。下一篇完整讲这个顺序。

一个会打崩 VPP 的操作

unapply 一个"存在但从未挂过"的 policer → VPP 崩溃

这是本教程遇到的第四个同类崩溃(前三个见 故障速查)。

bash
# 建一个 policer,但不挂到任何接口
vppctl policer add name t1 type 1r2c cir 100 cb 100 rate pps \
    conform-action transmit exceed-action drop

# 直接 unapply —— VPP 段错误
vppctl policer input unapply name t1 host-eth1

有意思的是反过来是安全的

bash
vppctl policer input unapply name 不存在的名字 host-eth1
text
policer input: failed: `-6'          ← 优雅地失败,不崩
bash
vppctl policer del name 不存在的名字
text
policer del: No such policer          ← 也安全

只有"policer 存在、但没挂在这个接口上"这个组合会崩。

写清理脚本时必须先确认它真的挂着

bash
vppctl show interface features host-eth1 | grep policer-input

本教程的 policer_clean 就是这么做的 —— 先查 feature arc, 有才摘,绝不盲目 unapply。

小结

两个作用限速(丢弃超额)+ 标记(按合规程度改写 DSCP)
类型1r2c 两色;2r3c-2698 三色可用(1r3c 实测 exceed 为 0)
单位rate kbpsrate pps
标记mark-and-transmit <大写DSCP名>,小写和数字都不接受
参数要点cb 太小会误伤正常波动,建议给 cir 的几十~百毫秒量
位置入向 policer 在 NAT 之前,限的是内网速率
致命坑unapply 一个未挂载的 policer 会打崩 VPP

下一篇:Feature 顺序 —— 把 ACL、NAT、Policer 放在一起看。

实验环境基于 netlab + containerlab + VPP 26.06