Linuxstream量控制器(Linux tc):分层令牌桶(htb)数据包队列大小

在我的Linux路由器中,我使用以下configuration来限制局域网中客户端端口44444的stream量(客户端地址是192.168.10.2,通过路由器的eth1 iface连接):

tc qdisc add dev eth1 root handle 1: htb default 2 tc class add dev eth1 parent 1: classid 1:1 htb rate $RATE tc class add dev eth1 parent 1: classid 1:2 htb rate 100mbit tc filter add dev eth1 protocol ip parent 1: prio 1 u32 match ip dst 192.168.10.2 dport 44444 0xffff flowid 1:1 

我对这个configuration的期望是,stream向192.168.10.2:44444的stream量将根据$ RATE参数形成,而所有其他stream量基本上保持不变(因为LAN是100Mbit / s)。

为了testing这个configuration,我以各种速率向192.168.10.2:44444发送UDP数据包,logging丢包数量和单向延迟变化。 我在testing中观察到的情况是,超过速率的数据包永远不会被丢弃。 相反,数据包在一个缓冲区中排队,这个缓冲区在没有(显然)达到大小限制的情况下保持增长。

例如:

使用RATE = 30kbit并以大约2Mbit / s的速度发送数据包(数据包有效负载1400字节,数据包间隔5ms)10秒钟,我从tc获得以下数据:

 qdisc htb 1: root refcnt 2 r2q 10 default 2 direct_packets_stat 0 ver 3.17 Sent 104901 bytes 85 pkt (dropped 0, overlimits 185 requeues 0) backlog 0b 0p requeues 0 

(通过tc -s -d qdisc show dev eth1统计信息)

实际上,数据包通过192.168.10.2接收超过26秒(即发送者完成后16秒)。

使用RATE = 5mbit并在20mbit发送数据包,我得到以下统计信息:

 qdisc htb 1: root refcnt 2 r2q 10 default 2 direct_packets_stat 0 ver 3.17 Sent 6310526 bytes 4331 pkt (dropped 0, overlimits 8667 requeues 0) backlog 0b 0p requeues 0 

虽然这次单向延时不会高于160ms。

我也得到了类似的结果,指定了burst大小,但是我没有观察到任何明显的变化,不pipe我设置了多less(我把它减小到1kbit)。

不幸的是,尽pipe已经阅读了关于Linux tc和htb的各种手册和参考资料,但我无法find合理的解释。 如果有人能帮我弄明白这一点,我会很高兴。

谢谢


更新。 我发现Linuxstream量控制器的内部非常有用和清晰的描述。 你可以在这里find它。 另一个有用的资源是OpenWRT Wiki 。 事实上,我已经知道前一篇文章,但显然我错过了重要的一点。

长话短说,我的数据包排队的缓冲区当然是networking接口的出口队列。 根据通过tc命令设置的排队规则,select出口队列中的包。 有趣的是,出口队列不是以字节为单位,而是以数据包(不pipe数据包有多大)来衡量。 部分原因是,在我的实验中,我从来没有达到排队规模的限制。

出口队列大小通过ifconfig命令( txqueue字段)显示。 在我的Linux机器中,默认出口大小是1000个数据包,但是您可以通过ifconfig DEV txqueuelen SIZE轻松更改它。 通过将队列大小减less到1个数据包,我最终设法强制整形数据包被丢弃(永远不会到达客户端)。 所以我想这基本上是这样的。

我注意到的最后一个有趣的事实是,与hierarchycal bucketfilter相反的令牌桶filter( tbf确实提供了一个额外的缓冲区,其中包在发送之前排队。 我想用一个足够小的队列来使用这个filter,不pipe出口队列有多大,都可以强制丢弃数据包。 虽然我没有尝试过。

希望这可以帮助。