一:综述:
linux系统中的流量控制器(TC)主要是在输出端口处建立一个队列进行流量控制。
TC是一个可以根据数据包的任何一个部分的特征对其进行分类的工具,并且可以为各类数据提供不同带宽,从而控制他们的传输速度。TC是iproute2的一部分,集成在2.2.及以上版本的内核中,还可以与linux内核里的各种架构(如Netfilter netem)协同工作。
二:TC的组件
TC主要由队列规定(qdisc),类(class)和过滤器(filter)这3个组件组成,绘图中一般用圆形表示队列规定,用矩形表示类:
1:qdisc:TC的核心组件,也被称为队列,是管理网卡输入,输出数据的一个算法,用于确定数据包的发送方式。
队列规定可分为两类:
(1) 不分类的qdisc:内部不包含可配置的子类,对进入队列的数据包不进行区分对待,而只是对数据包进行重新编排,延迟发送或者丢弃,主要有:pfifo-fast.TBF.SFQ等
(2) 分类队列规定:内部可包含一个或多个子类,使用过滤器对数据包进行分类,然后交给相应的子类处理,分类队列规定有CBQ,HTB等
2:类:
就是数据的类别,各种数据通过过滤器进行分类,最后被放入类的队列规定里面进行排队。
如果一个类没有子类,那么这个类被称为叶子类,否则就被成为内部类。1:1和1:12是内部类,其他均为叶子类,叶子类有一个负责为这个类发送数据的队列规定,而且这个qdisc可以是分类的,如1:10有一个分类的队列规定。TC中通常把类的队列规定称为叶子qdisc(只有叶子类才有队列规定)
3:过滤器
就是一些规则,根据这些规则对数据包进行分类,过滤器可以属于队列规定,也可以属于内部类,若需要在叶子类上再实现分类,那就必须将过滤器与叶子类的分类队列规定关联起来,而不能与叶子类相关联。
最常用的是U32过滤器,由一个过滤器和一个动作组成,选择器用来对数据包进行匹配,一旦匹配成功就执行该动作。
三:TC的结构
都是以一个根qdisc开始的,若根qdisc是不分类的队列规定,那它就没有子类,因此不可能包含其他的子对象,也不会有过滤器与之关联,发送数据时,数据包进入这个队列里面排队,然后根据该队列规定的处理方式将数据包发送出去。
分类的qdisc内部包含一个或多个类,而每个类可以包含一个队列规定或者包含若干个子类,这些子类友可以包含分类或者不分类的队列规定,如此递归,形成了一个树。
句柄号:qdisc和类都使用一个句柄进行标识,且在一棵树中必须是唯一的,每个句柄由主号码和次号码组成qdisc的次号码必须为0(0通常可以省略不写)
根qdisc的句柄为1:,也就是1:0。类的句柄的主号码与它的父辈相同(父类或者父qdisc),如类1:1的主号码与包含他的队列规定1:的主号码相同,1:10和1:11与他们的父类1:1的主号码相同,也为1。
新建一个类时,默认带有一个pfifo_fast类型的不分类队列规定,当添加一个子类时,这个类型的qdisc就会被删除,所以,非叶子类是没有队列规定的,数据包最后只能到叶子类的队列规定里面排队。
若一个类有子类,那么允许这些子类竞争父类的带宽,但是,以队列规定为父辈的类之间是不允许相互竞争带宽的。
四:TC的工作原理:
对互联网而言,一切都是数据包,操控网络实际上是在操控数据包,操控它如何产生,路由,传输,分片等等。TC在数据包离开系统的时候进行控制,在IP层与网卡之间做手脚,实际上,负责将数据包传递到物理层的正是TC模块,这意味着在系统内核中,TC作为数据包的调度者是一直运作的,甚至在你不想用他的时候,一般情况下,TC维持 一个先进先出的数据队列。
数据包入队的时候首先调用根队列规定的过滤器,根据过滤器定义的规则将数据包交给某个类,如果该类不是叶子类,将会调用该类定义的过滤器进一步分类,若该类没有定义过滤器,就会交给包含他的队列规定的默认类来处理,若接收到数据包的类是叶子类,数据包将进入到叶子类的队列规定里面排队,需要注意的是:过滤器只能将数据包交给某个类,类再将数据包放入自己的队列规定进行排队,而不能直接交给某个队列规定。
接受包从数据接口进来后,经过流量限制,丢弃不合规定的数据包,然后输入多路分配器判断:若接受包的目的地是本主机,那么将该包送给上册处理,否则需转发,将接受包交到转发块处理。转发块同时也接收本主机上层产生的包。转发块通过查看路由表,决定所处理包的下一跳,然后对包排序以便将他们传送到输出接口。
Linux的TC主要是在输出接口排列时进行处理和实现的。
五:TC命令
1:add命令:在一个节点里加入一个qdisc,类或者过滤器。添加时,需要传递一个祖先作为参数,传递参数时既可以使用ID也可以直接传递设备的根,若建一个qdisc或者filter,可以使用句柄来命名,若建一个类,使用类识别符来命名。
2:remove:删除由某个句柄指定的qdisc,根qdisc也可以被删除,被删除的qdisc上的所有子类以及附属于各个类的过滤器都会被自动删除。
3:change:以替代方式修改某些项目,句柄和祖先不能修改,change和add语法相同。
4:replace:对一个现有节点进行近于原子操作的删除/添加,如果节点不存在,这个命令就会建立节点。
5:link:只适用于qdisc,替代一个现有的节点
tc qdisc [add|change|replace|link] dev DEV [parent qdisc-id |root] [handle qdisc-id ] qdisc [qdisc specific parameters]
tc class [add|change|replace] dev DEV parent qdisc-id [classid class-id] qdisc [qdisc specific parameters]
tc filter [add|change|replace] dev DEV [parent qdisc-id|root] protocol Protocol prio Priority filtertype [filtertype specific parameters] flowid flow-id
tc [-s|-d] qdisc show [dev DEV]
tc [-s|-d] class show dev DEV
tc filter show dev DEV
六:TBF队列:(令牌桶队列)
tc qdisc add tbf limit BYTES burst BYTES rate KBPS [mtu BYTES] [peakrate KBPS] [latency TIME] [overhead BYTES] [linklayer TYPE]
rate是第一个令牌桶的填充速率
peakrate是第二个令牌桶的填充速率
peakrate>rate
burst是第一个令牌桶的大小
mtu是第二个令牌桶的大小
burst>mtu
若令牌桶中令牌不够,数据包就需要等待一定时间,这个时间由latency参数控制,如果等待时间超过latency,那么这个包就会被丢弃
limit参数是设置最多允许多少数据可以在队列中等待
latency=max((limit-burst)/rate,(limit-mtu)/peakrate);
burst应该大于mtu和rate
overhead表示ADSL网络对数据包的封装开销
linklayer指定了链路的类型,可以是以太网或者ATM或ADSL
ATM和ADSL报头开销均为5个字节。
七:netem模块
netem提供网络方针的功能,可以方针广域网的可变时延,丢包,数据包副本和重排序等性质。
netem被包含在内核中的iproute2中,netem模块被TC控制调用。
netem包含两部分:
(1) qdisc的内核模块:被整合到内核中
(2) 配置该模块的命令行功能:iproute2的一部分
两者通过netlink套接字练习,命令行将其请求编成一种格式,而内核进行解码。
1:模拟时延:
例:#tc qdisc add dev eth0 root netem delay 100ms
所有经过eth设备输出的数据包均延迟100ms
#tc qdisc change dev eth0 root netem delay 100ms 10ms
表示延迟具有随机性,延时范围是100+_10ms
#tc qdisc change dev eth0 root netem delay 100ms 10ms 25%
表示延时范围是:100+_10ms*25%
2:延时的分布:
在实际网络中,延时并不是均匀分布的,更像正态分布
#tc qdisc change dev eth0 root netem delay 100ms 20ms distribution normal
注意:分配(如normal,pareto,paretonormal)是iproute2编译出放在/usr/lib/tc下的,所以可以编译出自己的分布
3:丢包
可设置的最小丢包率为 232=0.000 000 0232%
#tc qdisc change dev eth0 root netem loss 0.1%
表示0.1%的随机性丢包
#tc qdisc change dev eth0 root netem loss 0.3% 25%
引起0.3%的丢包率
25%指的是相关性,相关性可以用来模拟突发造成的丢包
4:数据包副本
#tc qdisc change dev eth0 root netem duplicate 1%
5:数据包冲突错误:
实际网络中的随即噪声会导致包出错,可以用corrupt option模块模拟
#tc qdisc change dev eth0 root netem corrupt 0.1%
会引起0.1%的出错
6:数据包重排序
#tc qdisc change dev eth0 root netem gap 5 delay 10ms
只有5的倍数的数据包不被延迟,其他均延迟10ms
#tc qdisc change dev eth0 root netem delay 10ms recorder 25% 50%
25%的数据包被立即发送,其他包被延迟10ms
这里50%指的是25%的数据包具有的相关性
另外随机延迟的不同也会导致重排序
在构造丢包时,线性相关系数用来设定丢包的分布情况,若为0,表示丢包随机:从0-1,表示丢包的分布趋于集中。比如设定丢包率为10%,线性相关系数为1,则表示每100个数据包丢10个,但是这十个包非常集中(有可能20个连续包就丢了10个),需要特别说明的是,实际的丢包效果绝不是一个精确的数字,更多的是一个统计数。