linux中不能直接限制特定路由的带宽开销,因为路由仅决定转发路径,限速必须作用于出口接口或匹配目标网络/下一跳的流量,需结合tc、iptables和策略路由实现按路由意图的流量整形。

Linux 中不能直接“限制特定路由的带宽开销”,因为路由本身只是转发路径决策(即数据包该往哪个接口、下一跳走哪),不承载流量也不消耗带宽;真正可限速的是经过某条路由所对应出口接口的流量,或匹配特定目标网络/下一跳的报文流。实际操作中,需结合路由表、tc 流量控制与 iptables/ipset 标记来实现“按路由意图限速”。
明确路由与限速的关系
路由表决定“去往 10.0.2.0/24 的包从 eth1 出”,但限速动作必须落在:
• eth1 接口的出方向(egress)队列上(用 tc qdisc)
• 或对目的为 10.0.2.0/24 的流量单独分类并限速(用 tc class + filter)
不能对“路由条目”本身设带宽上限——那是语义错误。
按目标网络(即典型路由前缀)限速
这是最贴近“限制特定路由带宽”的做法。例如:所有发往 192.168.100.0/24 的流量限制为 5Mbps。
- 先清空旧规则:
tc qdisc del dev eth0 root 2>/dev/null - 添加 HTB 根队列:
tc qdisc add dev eth0 root handle 1: htb default 12 - 建主类(总带宽假设为 100mbit):
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 - 用 u32 匹配目的网段并导向子类:
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.100.0/24 flowid 1:10
按下一跳网关限速(适用于多出口场景)
当不同路由指向不同网关(如 via 10.0.1.1 和 via 10.0.2.1),可通过匹配出口网关的 IP 实现分流限速:
- 确保路由已存在,例如:
ip route add 172.16.0.0/16 via 10.0.1.1 dev eth0 - 用 iptables 对经该网关发出的包打标记:
iptables -t mangle -A OUTPUT -d 172.16.0.0/16 -j MARK --set-mark 100 - 在 tc 中识别标记并分类:
tc filter add dev eth0 protocol ip parent 1:0 prio 2 handle 100 fw flowid 1:10
配合策略路由做更精细控制
若需让某类应用(如数据库备份)强制走特定路由并同时限速,可组合使用:
- 创建独立路由表(如 table 200),添加专用路由:
ip route add default via 10.0.3.1 dev eth2 table 200 - 用 iptables 给备份流量打 mark:
iptables -t mangle -A OUTPUT -p tcp --dport 3306 -j MARK --set-mark 200 - 用 ip rule 将 mark=200 的包导向 table 200:
ip rule add fwmark 200 table 200 - 最后对 eth2 接口单独配置 tc 限速(如用 wondershaper 或手动 HTB)
本质上,所谓“限制特定路由的带宽”,就是把路由目标转化为可匹配的报文特征(dst IP、fwmark、output interface),再用 tc 在对应出口施加整形。不复杂但容易忽略底层机制。











