Chinaunix首页 | 论坛 | 博客
  • 博客访问: 230478
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 296
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-22 11:52
文章分类

全部博文(31)

文章存档

2018年(3)

2017年(11)

2016年(12)

2015年(5)

我的朋友

分类: 网络与安全

2016-08-19 17:16:21

整理了网上的tc介绍,并加上自己的理解,并记录未了解透彻的地方,以后补充。

1.两大类tc 命令
tc qdisc /tc class/tc filter [ add | change | replace | link | delete ],--->增删改替 qdisc/class/filter
tc qdisc/class/filter show  dev DEV ---->显示队列,类别,过滤器的结果,类似iptables -nvL

具体用法可以man tc
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

分析tc qdisc的用法,
tc qdisc:操作的是qdisc
[ add | change | replace | link ]:动作
dev DEV:操作的是哪个设备
[ parent qdisc-id | root ]:一个Qdisc 要么是root,要是是子Qdisc,如果是子Qdisc的话,要指明parent 是什么
[ handle qdisc-id ]:这个qdisc的id
qdisc:Qdisc的类型,如tbf,htb
[ qdisc specific parameters ]:各种Qdisc的参数,跟每个流控算法有关

2.两大类Qdisc
无类别Qdisc:如果是对一个DEV 的所有流量进行限速,排队,或者丢弃的话,可以用无类别的Qdisc
有类别Qdisc : 对一个DEV的流量需要分类的进行不同的处理的,就用有类别的Qdisc

3.tc 处理流量的三种处理方式
SHAPING/POLICING ,分别是对egress/ingress 两个方向的限速处理
SCHEDULING ,只对egress 有效,是排队,根据数据的优先级进行排队
DROPPING ,对egress 或者ingress ,如果带宽超过某个值,就丢掉数据包

4.无类别Qdisc类型有6种
[p|b]fifo : 使用最简单的Qdisc,纯粹的先进先出。只有一个参数:limit,用来设置队列的长度,pfifo是以数据包的个数为单位;bfifo是以字节数为单位
pfifo_fast:(没懂,先记录下解释) 在编译内核时,如果打开了高级路由器(Advanced Router)编译选项,pfifo_fast就是系统的标准Qdisc。它的队列包括三个波段(band)。在每个波段里面,使用先进先出规则。而三个波段(band)的优先级也不相同,band 0的优先级最高,band 2的最低。如果band里面有数据包,系统就不会处理band 1里面的数据包,band 1和band 2之间也是一样。数据包是按照服务类型(Type of Service,TOS)被分配多三个波段(band)里面的。
fq:(没懂)
red: 是Random Early Detection(随机早期探测)的简写。如果使用这种Qdisc,当带宽的占用接近于规定的带宽时,系统会随机地丢弃一些数据包。它非常适合高带宽应用
sfq: Stochastic Fairness Queueing(随机公平队列)的简写。它按照会话(session--对应于每个TCP连接或者UDP流)为流量进行排序,然后循环发送每个会话的数据包。
tbf: 是Token Bucket Filter(令牌桶过滤器)的简写,适合于把流速降低到某个值

man tc-pfifo, tc-bfifo, tc-pfifo_fast, tc-sfq,  tc-red, tc-tbf, 可以查看具体的各种无类别的Qdisc的具体用法和后面接着的参数

无类别的Qdisc 只能附属在网卡的根,用法如下
tc qdisc add dev DEV root Qdisc Qdisc-PARAMETERS
tc qdisc del dev DEV root

实例
tc qdisc add dev eth1  root tbf rate 10Mbit latency 50ms burst 10000 mpu 64 mtu 150000
tc qdisc del dev eth1  root
说明:tbf 是无类别的Qdisc 中的一种,后面的rate,latency,burst,mpu,mtu ,都是tbf 这种Qdisc 的参数令牌桶算法的参数,具体的可以对照令牌桶算法的一些参数进行分析

5.有类别qdisc的类型3种
CBQ: Class Based Queueing(基于类别排队)的缩写。它实现了一个丰富的连接共享类别结构,既有限制(shaping)带宽的能力,也具有带宽优先级管理的能力。带宽限制是通过计算连接的空闲时间完成的。空闲时间的计算标准是数据包离队事件的频率和下层连接(数据链路层)的带宽

HTB: 是Hierarchy Token Bucket(分层次的令牌桶)的缩写。通过在实践基础上的改进,它实现了一个丰富的连接共享类别体系。使用HTB可以很容易地保证每个类别的带宽,虽然它也允许特定的类可以突破带宽上限,占用别的类的带宽。HTB可以通过TBF(Token Bucket Filter)实现带宽限制,也能够划分类别的优先级。

PRIO: PRIO Qdisc不能限制带宽,因为属于不同类别的数据包是顺序离队的。使用PRIO QDisc可以很容易对流量进行优先级管理,只有属于高优先级类别的数据包全部发送完毕,才会发送属于低优先级类别的数据包。为了方便管理,需要使用iptables或者ipchains处理数据包的服务类型(Type Of Service,ToS)

ingress: 入方向的Qdisc,这个Qdisc本身的功能很有限,只能通过filter过滤出需要处理的数据包Drop掉。通过ingress Qdisc可以把输入方向的数据包重定向到一个虚拟设备ifb,然后在ifb的输出方向可以配置多种Qdisc,就可以达到对输入方向的流量做队列调度的目的

6.命名规则
所有的Qdisc、class,filter都有ID。ID可以手工设置,也可以有内核自动分配。ID由一个主序列号和一个从序列号组成,两个数字用一个冒号分开。

Qdisc,一个Qdisc会被分配一个主序列号,叫做句柄(handle),然后把从序列号作为类的命名空间。句柄采用象10:一样的表达方式。习惯上,需要为有子类的Qdisc显式地分配一个句柄。
class,在同一个Qdisc里面的class分享这个Qdisc的主序列号,就是在同一个Qdisc中的class 的主序列号与Qdisc的主序列号是一样的,但是每个类都有自己的从序列号,叫classid。classid与父Qdisc有关,和父class无关。类的命名习惯和Qdisc的相同。
filter,filter的ID有三部分,只有在对filter进行散列组织才会用到。详情请参考tc-filters手册页

这里有两个特殊的值
root 的主序列号和从序列号都是1,没有显式指明的就是0

7.数据包经过流控tc模块的规则
class的组织是树状的,每个类都只有一个父类,可以有多个子类。
每个类都有一个叶子Qdisc,默认情况下,这个叶子Qdisc使用pfifo,当然,我们也可以使用其它类型的Qdisc代替这个默认的Qdisc。而且,这个叶子Qdisc也可以分类,不过每个子类最终只能有一个叶子Qdisc。

当一个数据包进入一个有类别的QDisc,它会被归入某个子类。可以通过这三种方式分别是filter,TOS,skb->priority这三种方式归类,不过不是所有的QDisc都能够使用这三种方式。

某些Qdisc(例如:CBQ和HTB)允许在运行时动态添加类,而其它的Qdisc(例如:PRIO)不允许动态建立类。允许动态添加类的Qdisc可以有零个或者多个子类,由它们为数据包排队。

如果过滤器附属于一个类,相关的指令就会对它们进行查询。过滤器能够匹配数据包头所有的域,也可以匹配由ipchains或者iptables做的标记。
树的每个节点都可以有自己的过滤器,但是高层的过滤器也可以直接用于其子类。如果数据包没有被成功归类,就会被排到这个类的叶子QDisc的队中。相关细节在各个QDisc的手册页中。

8.流控的步骤
建立队列、建立分类和建立过滤器

9.其他
单队列网卡默认的qdisc 是pfifo_fast ,在高版本的内核上多队列的网卡默认的qdisc 是mq
ifconfig ethX down 不会删除ethX上的qdisc,

Qdisc ,class,filter的删除可以通过删除Qdisc 来进行,删除了Qdisc ,那么这个Qdisc 下的class ,filter 也会被自动删除,root 也可以删除

一般对于流量控制器所直接连接的网段建议使用IP主机地址流量控制限制,不要使用子网流量控制
限制。如一定需要对直连子网使用子网流量控制限制,则在建立该子网的路由映射前,需将原先由系统建立的路由删除,才可完成相应步骤

删除动作只在该分类没有工作前才可进行,一旦通过该分类发送过数据, 则无法删除它了。因此,需要通过shell文件方式来修改,通过重新启动来完成删除动作

一般一个设备有一个根Qdisc ,如果有多个子class的,还会建立根class

10.实例
(1).限制web 服务器的下载速率
tc qdisc add dev eth0 root handle 1: htb default 20
tc class add dev eth0 parent 1: classid 1:1 htb rate 800kbit ceil 800kbit burst 80k
tc filter add dev eth0 parent 1: prio 1 protocol ip u32 match ip src 1.1.1.1/32 match ip sport 80 0xffff flowid 1:1

其中u32 是个过滤器,可以根据数据包中的字段进行匹配,详细查看filter的时候显示match 相关的内容如下:
#match 0a795f40 /ffffffff at 12 #   0a795f40转换为10进制就是上面的IP,ffffffff是掩码,at 12 代表从数据包的ip头的12字节开始匹配,从IP头结构可知第13字节开始是IP源地址,

#match 00500000 /ffff0000 at 20 #  00500000实际是源端口和目的端口组合,一共占4个字节,前2个字节是源端口,50转换成10进制就是80端口,ffff0000相当于掩码,源端口严格限定80,目的端口不限

(2).限制web 服务器的上传速率
 是入站流量,因此只能通过Ingress qdisc来处理,但Ingress qdisc本身功能很弱,所以我们这里使用虚拟设备ifb来处理入站数据

首先需要加载内核模块,启用虚拟网卡设备ifb0
modprobe ifb
ip link set dev ifb0 up

然后对入站流量做设置,镜像到ifb0上
tc qdisc add dev eth0 ingress
tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0

然后我们就可以对ifb0接口的out方向流量做各种限制了
tc qdisc add dev ifb0 root handle 1: htb default 1
tc class add dev ifb0 parent 1: classid 1:1 htb rate 800kbit ceil 800kbit burst 80k
tc filter add dev ifb0 parent 1: prio 1 protocol ip u32 match ip dst 1.1.1.1/32 match ip dport 80 0xffff flowid 1:1

11.疑问
htb 排队规则中burst和cburst的作用?只知道burst 是令牌桶的容量大小,cburst 与ceil 相关,具体这两个参数怎么设置,没有找到依据,而且man 和HOWTO的解释好像不一致(可能是个人理解问题)。
filter是怎么与一个class关联起来的,还是filter 只与Qdisc有关?

12.HOWTO 文档链接
 man 也有很详细的介绍
阅读(11919) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~