5. 软件和工具

5.1. 内核版本要求

大多数发行版的内核都带有 Linux 流量控制系统(即 QoS ),一些发行版将其编译为内核模块,令一些发行版则是直接将其静态编译到内核内。用户自己编译或一些自定义的内核可能没有包含流量控制模块。若要内核支持流量控制,需要在编译内核的时候选择下文列出的编译选项。

建议没有内核编译经验的用户先阅读 Kernel HOWTO。对于有经验的用户,在对流量控制系统有一定了解的情况下,可以根据自己的需求自行判断以下列出的选项哪些是自己所需要的。

例 1. 内核编译选项 [8]

#
# QoS and/or fair queueing
# 服务质量和公平队列
# 译注:下面的选项中的缩写的意义如下:
# SCH,SCHED:调度
# CLS:分类器
# CBQ:类基队列
# HTB:分层令牌桶
# CSZ:Clark-Shenker-Zhang 调度算法,这是一种比较复杂的调度算法,以这三位开发者的名字命名。
#      个人用户一般用不到,本文也没有详细介绍
# PRIO:优先级队列
# RED:早期随机丢包
# SFQ:随机公平队列
# TBF:令牌桶
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CBQ=m
CONFIG_NET_SCH_HTB=m
CONFIG_NET_SCH_CSZ=m
CONFIG_NET_SCH_PRIO=m
CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TEQL=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_DSMARK=m
CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
CONFIG_NET_CLS_POLICE=y
      

只要开启了以上选项,内核就能支持本文描述的绝大部分功能。在使用某项功能之前,用户可能需要使用modprobe module 来开启相应功能。最后再次说明,看不懂本段内容的用户请先阅读 Kernel HOWTO 或有关内核编译的相关文档。

5.2. iproute2 工具 (tc)

iproute2 是一系列命令行工具,用于调整服务器的IP网络设定。本工具的使用文档请参考 iproute2 documentation,更详细的使用说明请参考 linux-ip.net。在 iproute2 工具集中,tc 是唯一一个用于流量控制的命令。本文档不会涉及 iproute2 工具集中除 tc 以外的命令。

由于 tc 在添加、修改和删除流量控制结构时直接和内核进行交互,所以编译 tc 必须先安装所有的 你想使用的 qdisc。特别地, HTB 在 iproute2 上游源码中还没有被支持。更多信息请参考 第 7.1 节 “HTB, 分层令牌桶”

由于 tc 要直接修改内核中的流量控制结构,所以 tc 的语法通常是比较晦涩难懂的。The utility takes as its first non-option argument one of three Linux traffic control components, qdisc, class or filter.

例 2. tc 命令用法

[root@leander]# tc
用法: tc [ 选项 ] 对象 { 命令 | help }
其中  对象 := { qdisc | class | filter }
       选项 := { -s[tatistics] | -d[etails] | -r[aw] }
      

每个对象都包含更多的选项,本文无法涉及所有的选项。这里给出的例子只包括了最常见的用法。更多例子请参考 LARTC HOWTO。如果想了解得更透彻,可以考虑阅读 iproute2 的源码。

例 3. tc qdisc

[root@leander]# tc qdisc add    \ 1
>                  dev eth0     \ 2
>                  root         \ 3
>                  handle 1:0   \ 4
>                  htb            5
      

1

增加一个排队规则。这里的动词也可以是 del。

2

指定一个设备,排队规则将会与这个设备相关联。

3

tc 命令中,这相当于 egress。在这里必须使用 root。ingress qdisc 也可以关联到这个设备上,只是其功能要少一些。

4

handle 可以由用户指定,格式是 主编号:子编号。排队规则的从必须是零(0)。编号可以简写为 “1:”的形式,这时子编号默认设为0.

5

这是要关联的排队规则,在这个例子中,排队规则的类型是 HTB。排队规则(qdisc)的参数跟在后面。在这个例子中,我们没有指定任何排队规则的参数。


上面的例子是 tc 最简单的使用。下面将会给出一个例子,使用 tc 将一个类添加到一个已经存在的父类上。

例 4. tc class

[root@leander]# tc class add    \ 1
>                  dev eth0     \ 2
>                  parent 1:1   \ 3
>                  classid 1:6  \ 4
>                  htb          \ 5
>                  rate 256kbit \ 6
>                  ceil 512kbit   7
      

1

添加一个分类,这里的动词也可以是del

2

指定一个设备,分类将会与这个设备相关联。

3

指定父类的 handle,我们添加的分类将会成为这个父类的子类。

4

这是一个唯一的 handle,(主编号:子编号)。子编号必须是非零值。

5

所有的 classful qdiscs 都要求其子类拥有和它相同的类型。也就是说,这里的 HTB 排队规则包含的子类必须是 HTB 的。

6 7

这里是分类器的参数。参数的意义请参考 第 7.1 节 “HTB, 分层令牌桶”


例 5. tc filter

[root@leander]# tc filter add               \ 1
>                  dev eth0                 \ 2
>                  parent 1:0               \ 3
>                  protocol ip              \ 4
>                  prio 5                   \ 5
>                  u32                      \ 6
>                  match ip port 22 0xffff  \ 7
>                  match ip tos 0x10 0xff   \ 8
>                  flowid 1:6               \ 9
>                  police                   \ 10
>                  rate 32000bps            \ 11
>                  burst 10240              \ 12
>                  mpu 0                    \ 13
>                  action drop/continue       14
      

1

增加一个过滤器。这里的动词也可以是del

2

指定一个设备,分类器将会与这个设备相关联。

3

指定一个对象的编号,过滤器将会与这个对象相关联。

4

这个参数是必需的,它的用处很明显,但是我不知道这个参数还有什么其他的作用。

5

prio 参数指定了过滤器的优先级。pref 是 prio 的同义词。

6

这是一个 classifier,所有的 tc filter 命令都必须包含这一项 。

7 8

这是分类器的参数。在这个例子中,端口为22且带有服务标记的数据包(交互型应用)将会被选中。

9

flowid 参数指定了一个分类或排队规则的 handle,被选中的数据包将会被发送到这个分类或排队规则上。

10

这是一个 policer。在 tc filter 命令中,这一项是可选的。

11

当流量大于此速率时,决策器将会执行一个操作,反之执行另一个操作(请参考 action parameter)。

12

The burst is an exact analog to burst in HTB (burst is a buckets concept).

13

最小决策单元。要统计所有的数据包,将 mpu 的值设为零(0)。

14

action 指定了决策器的操作。第一个词指定了当流量超过 rate 时的操作,第二个词指定了其他情况下的操作。


正如上面例子里面的一样,即使是很简单的操作,tc 的命令也是十分复杂。其实,有一种工具可以简化这些工作,请看下一节 第 5.3 节 “tcng, 下一代tc”

5.3. tcng, 下一代tc

FIXME; sing the praises of tcng. See also Traffic Control using tcng and HTB HOWTO and tcng documentation.

下一代tc(Traffic Control Next Generation)。 下一代tc提供强大的功能,让你不再为 tc 复杂的语法而头疼。

5.4. IMQ, 中间队列设备

FIXME; must discuss IMQ. See also Patrick McHardy's website on IMQ. 待完善。可以参考 Patrick McHardy 网站上有关 IMQ 的内容。IMQ,中间队列设备(Intermediate Queuing device)。



[8] 此处列出的选项来源于 2.4.20 版本的内核源码。如果内核版本比 2.4.20 新,或者内核源码已经打上了补丁,选项的名字可能会和这里列出的有些不同。