前面两篇日志都是为了做使用IMQ设备的准备。因为IMQ模块并没有包括在标准核心中,所以,需要我们另行编译。而这今天的日志中,我用一个几乎是最简单的例子,来说明如何使用IMQ设备模块。其中使用到tc的相关知识,如果您还不知道该怎么做,请先回头看看前几天的日志,否则会有点不知所云的。
一、准备工作
首要的准备工作,当然是要让您的系统支持IMQ模块,有三个条件:
1、核心支持imq设备
Linux openvz91 2.6.9-42.7AX.imq #1 Fri May 30 10:50:00 CST 2008 i686 i686 i386 GNU/Linux
# ll /lib/modules/2.6.9-42.7AX.imq/kernel/drivers/net/imq.ko
-rwxr–r– 1 root root 8340 5月 30 14:05 /lib/modules/2.6.9-42.7AX.imq/kernel/drivers/net/imq.ko
2、netfilter支持IMQ模块
-rwxr–r– 1 root root 3264 5月 30 14:05 /lib/modules/2.6.9-42.7AX.imq/kernel/net/ipv4/netfilter/ipt_IMQ.ko
# ll /lib/modules/2.6.9-42.7AX.imq/kernel/net/ipv6/netfilter/ip6t_IMQ.ko
-rwxr–r– 1 root root 3264 5月 30 14:05 /lib/modules/2.6.9-42.7AX.imq/kernel/net/ipv6/netfilter/ip6t_IMQ.ko
3、iptables支持IMQ模块
-rwxr-xr-x 1 root root 3860 6月 2 17:04 /lib/iptables/libip6t_IMQ.so
-rwxr-xr-x 1 root root 3856 6月 2 17:04 /lib/iptables/libipt_IMQ.so
以上要求缺一不可。(如果不需要支持ipv6,可以不考虑ipv6的模块)
4、加载模块
# modprobe ipt_IMQ
# ifconfig imq0 up
# ifconfig imq1 up
一切正常的话,会发现多了两个虚拟网卡,他们是支持tc的:
imq0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING NOARP MTU:1500 Metric:1
RX packets:9726 errors:0 dropped:0 overruns:0 frame:0
TX packets:9726 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:30
RX bytes:3903679 (3.7 MiB) TX bytes:3903679 (3.7 MiB)
imq1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING NOARP MTU:1500 Metric:1
RX packets:12223 errors:0 dropped:0 overruns:0 frame:0
TX packets:12220 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:30
RX bytes:13794660 (13.1 MiB) TX bytes:13791620 (13.1 MiB)
# tc qdisc show
qdisc pfifo_fast 0: dev eth0 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: dev imq0 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: dev imq1 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
二、演示脚本
IMQ模块虚拟出来的两个网卡(默认两个:imq0、imq1),可用于把队列规定qdiscs分别附加到它们上面,然后由iptables转发数据包到这两个设备,以实现利用egress qdiscs (出口队列规定)来对流经设备的数据整形。这样结果就是,无论出口流量,还是入口流量都可得到分类和控制的目的了。
脚本如下:
modprobe imq numdevs=2
modprobe ipt_IMQ
ifconfig imq0 up
ifconfig imq1 up
tc qdisc del dev imq0 root
tc qdisc del dev imq1 root
#IMQ 0
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 1:0 protocol ip prio 1 u32 match ip dst 192.168.228.30 flowid 1:10
iptables -t mangle -A PREROUTING -i eth0 -j IMQ –todev 0
#IMQ 1
tc qdisc add dev imq1 root handle 2: htb default 20
tc class add dev imq1 parent 2: classid 2:1 htb rate 4mbit burst 15k
tc class add dev imq1 parent 2:1 classid 2:10 htb rate 1mbit ceil 4mbit
tc class add dev imq1 parent 2:1 classid 2:20 htb rate 1mbit ceil 4mbit
tc qdisc add dev imq1 parent 2:10 handle 10: pfifo
tc qdisc add dev imq1 parent 2:20 handle 20: sfq
tc filter add dev imq1 parent 2:0 protocol ip prio 1 u32 match ip dst 192.168.228.30 flowid 2:10
iptables -t mangle -A POSTROUTING -o eth0 -j IMQ –todev 1
这里的机器只有一块网卡eth0,而根据tc的原理,原来只能对上传进行整形(限速)的。但通过该脚本,我们即可发现,下载时,数据流会由iptables转交给imq0,以实现入口整形的效果。(下载被分类、限速了)同样的,上传时,也会由imq1处理。
※请特别留意,不能让一个imq设备同时处理PREROUTING和POSTROUTING,否则,会出现kernel panic的。
脚本下载:
这例子比较简单,但能充分的说明问题:把imq设备作为一个中间介质,对经其发送的数据整形以达到最终目的。分类可通过u32或iptables MARK实现,这里就不再详细说明了。有需要的话,可参考前面的日志内容,或这里:
linux下TC控制流量文档(脚本)
使用 IMQ+HTB+iptable 统一流量控制心得
编译IMQ(中介队列设备)模块
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/112305.html