中间排队设备不是一个 qdisc,但其用法与 qdisc 紧密相关。在 Linux 中,qdisc 被附加到网络设备,并且所有排队到设备的内容首先被排队到 qdisc。由此概念,产生了两个限制:
1. 仅出口整形是可能的(存在入口 qdisc,但其可能性与 classful qdisc 相比非常有限)。
2. 一个 qdisc 只能看到一个接口的流量,无法设置全局限制。
IMQ 的存在是为了帮助解决这两个限制。简而言之,您可以将您选择的任何内容放入 qdisc 中。特别标记的数据包在 netfilter NF_IP_PRE_ROUTING 和 NF_IP_POST_ROUTING 钩子中被拦截,并通过附加到 imq 设备的 qdisc。iptables target 用于标记数据包。
这使您能够进行入口整形,因为您可以标记从某处进入的数据包和/或将接口视为类来设置全局限制。您还可以做很多其他事情,例如仅将您的 http 流量放入 qdisc,将新连接请求放入 qdisc,等等...
首先想到的可能是使用入口整形来为自己提供高保证带宽。;)配置就像任何其他接口一样
tc qdisc add dev imq0 root handle 1: htb default 20 tc class add dev imq0 parent 1: classid 1:1 htb rate 2mbit burst 15k tc class add dev imq0 parent 1:1 classid 1:10 htb rate 1mbit tc class add dev imq0 parent 1:1 classid 1:20 htb rate 1mbit tc qdisc add dev imq0 parent 1:10 handle 10: pfifo tc qdisc add dev imq0 parent 1:20 handle 20: sfq tc filter add dev imq0 parent 10:0 protocol ip prio 1 u32 match \ ip dst 10.0.0.230/32 flowid 1:10 |
iptables -t mangle -A PREROUTING -i eth0 -j IMQ --todev 0 ip link set imq0 up |
IMQ iptables targets 在 mangle 表的 PREROUTING 和 POSTROUTING 链中有效。它的语法是
IMQ [ --todev n ] n : number of imq device |
请注意,流量不是在命中 target 时排队的,而是在之后。流量进入 imq 设备的准确位置取决于流量的方向(入/出)。这些是 iptables 使用的预定义 netfilter 钩子
enum nf_ip_hook_priorities { NF_IP_PRI_FIRST = INT_MIN, NF_IP_PRI_CONNTRACK = -200, NF_IP_PRI_MANGLE = -150, NF_IP_PRI_NAT_DST = -100, NF_IP_PRI_FILTER = 0, NF_IP_PRI_NAT_SRC = 100, NF_IP_PRI_LAST = INT_MAX, }; |
对于入口流量,imq 在 NF_IP_PRI_MANGLE + 1 优先级注册自己,这意味着数据包在通过 mangle PREROUTING 链后直接进入 imq 设备。
对于出口,imq 使用 NF_IP_PRI_LAST,这尊重了过滤器表丢弃的数据包不会占用带宽的事实。
补丁和更多信息可以在 imq 站点找到。