TC--Traffic Control
TC是linux中的流量控制模块,利用队列规定创建起数据包队列,并定义了队列中数据包的发送方式,从而实现对流量的控制。linux
TC在流量控制中使用的队列分为两类:1 无类队列 2 有类队列。无类队列比较简单,分类队列则有分类和过滤器等概念,比较复杂。api
无类队列对进入网卡的数据流统一对待,不进行区分,无类队列造成的队列可以接受数据包以及从新编排、延迟、丢包,它能够对网卡流量进行整形,可是不能细分各类状况,无类队列规定主要有pfifo_fast、tbf、sfq等,无类队列的流量整形手段主要是排序、限速、丢包。网络
有类队列规定则是对进入网卡的数据包根据不一样的需求以分类的方式区分对待的分类规定,数据包进入分类队列后,经过过滤器对数据包进行分类,过滤器返回一个决定,队列就根据这个返回的决定把数据包发送到相应的某一类队列中进行排队。每一个子类能够再次使用他们的过滤器进行进一步的分类,直到不须要分类为止,数据包才会进入相关类的队列中进行排队。
TC流量控制方式
SHAPING 限制--流量被限制时,它的传输速率就被控制在某个值如下,限制阈值能够大大的小于有效带宽,这样能够平滑网络的突发流量,是网络更稳定,shaping适用于限制外出的流量。
SCHEDULING 调度--经过调度数据包的传输,能够在带宽范围内按照优先级分配,也只适用于限制外出流量。
POLICING 策略--用于处理接收到的数据
DROPPING 丢弃--若是流量超过设置的带宽就丢弃数据包,向内向外皆管用。
TC流量控制处理对象
流量的处理由三种对象控制,分别是:qdisc-排队规则、class-类别、filter-过滤器。
QDISC
qdisc是流量控制的基础,不管什么时候,内核若是须要经过某个网络接口发送数据包,它都须要按照该接口配置的qdisc把数据包加入队列中。内核会尽量多的从qdisc中取出数据包,而后交给网络适配器进行处理。而qdisc又分为CLASSLESS QDisc--不可分类队列规则、CLASSFUL QDISC--分类队列规则。
CLASSLESS QDisc--不可分类队列规则
无类qdisc包括如下队列:
[p|b]fifo 最简单的qdsic,先进先出策略,只有一个limit参数用来设置队列长度,pfifo是以数据包个数为单位,bfifo是以字节数为单位。pfifo_fast包含三个波段,band0~band2,每一个波段也使用先进先出策略,band0优先级最高,band2最低,若是band0中有数据包,系统就不会去处理band1的数据包,直到band0的数据包处理完。同理band1和band2。
red 是Random Early Detection的简写--随机早起检测。当带宽的占用接近指定带宽时随机的丢弃一些数据包。
sfq 是Stochastic Fairness Queueing的简写--随机公平队列,它会按照会话为流量进行排序,通常对应于每一个tcp或者udp数据流,而后循环发送每一个会话的数据包。
tbf 是Token Bucket Filter的简写--xx 适合把速率降到某个值。
若是没有设置可分类队列规则,则无分类队列规则只能属于设备的根。以下设置:tc qdisc add dev DEV root QDISC QDISC-PARAMETERS,若是一个接口没有设置qdisc,则pfifo_fast是默认的缺省qdisc。
CLASSFUL QDISC--分类队列规则
分类队列规则包括如下队列:
CBQ 是Class Based Queueing的简写,它实现了一个丰富的链接共享类别结构,既有限制带宽能力又有带宽优先级管理能力。带宽限制是经过计算链接的空闲时间完成的,空闲时间的计算标准是数据包离队事件的频率和下层链接的带宽。
HTB 是 Hierarchy Token Bucket的简写,它实现了一个丰富的链接共享类别结构,使用HTB能够很容易的保证每一个类的带宽,同时也容许特定类能够突破上限,占用其余类等宽等。HTB经过TFB实现带宽限制,也能够为类划分优先级。
PRIO 不能限制带宽,由于属于不一样类别的数据包是顺序离队的。使用PRIO qdisc能够很容易对流量进行优先级管理,只有属于高优先级类别的数据包所有发送完毕,才会发送属于低优先级类别的数据包。为了方便管理,须要使用 iptables或者ipchains处理数据包的服务类型(Type Of Service,ToS)。
CLASS
一些qdisc能够包含一些类,不一样的类中又能够包含更深刻的qdisc,经过这些细分的qdisc能够为进入队列的数据包排队,经过设置各类类数据包的离队次序,能够设置网络数据流量的优先级。例如,咱们要对不一样的IP实施不一样的流量控制策略,这时就须要用不一样的类来控制。
FILTER
filter用于为数据包分类,决定数据包进入何种qdisc队列,分类的方法有多种filter是一种方法,使用filter时内核会调用属于这个类的全部过滤器,直到返回一个决定,若是么有返回决定,就作进一步处理,处理方式和qdisc有关。filter是在qdisc内部的。目前可用的过滤器有:u3二、rsvp、fwmark等。
操做原理
类组成一个树,每一个类都只有一个父类,却能够有多个子类,某些qdisc容许在运行时动态添加类,如cbq、htb,而有些qdisc在运行时不准动态添加类,如prio。容许动态添加类的qdisc能够有多个子类,由他们为数据包排队。每一个类都有一个叶子qdisc,默认这个叶子qdisc使用pfifo的队列,固然也能够用其余队列替换,并且,这个qdisc能够再次包含其余类,可是每一个类只能有一个叶子qdisc。当一个数据包进入一个qdisc时,可使用三种方式为其分类:tc filters、Type of Service、skb->priority。可是并非全部的qdisc均可以使用这三种方式。
命名规则
全部的qdiscs, classes and filters都有本身的ID,能够手动指定也能够自动获取,ID包含一个主号码和一个从号码,用冒号分开。
QDISC
一个qdisc会被分配一个主号码,叫作handle,把从号码做为类的命名空间,习惯上须要为有子类的qdisc分配一个handle。一个qdisc若是是根节点,则parent的值就是root,若是qdisc下面有划分类,这时就须要指定handle,handle的值是major:minor格式的,对于root来讲,格式是1:,后面不须要指定minor,要指定的话,qdisc的minor必须为0。非根的qdisc的handle的major能够本身设置,minor不用设置,非根的parent的值也是major:minor格式,值是一个已存在的类。
CLASS
在同一个qdisc里面的类共享这个qdisc的主号码,每一个类都有本身的从号码,叫作classid,classid只和父qdisc有关,和父class无关,parent值的格式也是major:minor的,major这个指定该类的父节点的handle的major值,父节点能够是class也能够是qdisc,若是是qdisc,则minor能够不用设置或者设置为0,若是是class,则parent的值是其父类的classid值,classid的值格式也是major:minor的,major是父qdisc的handle的major的值,minor值是本身设置。
FILTER
过滤器的ID有三部分,只有在对过滤器进行散列组织才会用到。
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 spe‐cific parameters ]
tc filter [ add | change | replace ] dev DEV [ parent qdisc-id | root ] protocol protocol prio pri‐ority filtertype [ filtertype specific parameters ] flowid flow-id
tc [ FORMAT ] qdisc show [ dev DEV ]
tc [ FORMAT ] class show dev DEV
tc filter show dev DEV
使用tc命令能够对qdisc、class、filter进行以下操做:
add 在一个节点上添加qdisc、class、filter,添加时,须要传递一个parent,传递参数时既能够用ID也可使用设备的根,在创建qdisc和filter时,可使用handle来命名,在创建class时可使用classid来命名
remove 删除某个handle指定的qdisc,也可删除根qdisc。被删除的qdisc上的全部子类以及过滤器都会被自动删除。
change 以替代的方式修改某些条目,除了handle和parent不能被修改外,其他语法同add,change命令不能移除一个节点
replace 添加或者删除一个节点,是一个原子操做,若是节点不存在,则创建节点。
link 只适用于qdisc,替代一个存在的节点。
实施
主要是创建队列、分类、过滤器三步。
1 给物理设备创建一个队列qdisc
2 在相关队列上创建分类,通常是在该qdisc上创建一个根分类,而后在此根分类上创建子类。
3 为每个分类创建基于路由的过滤器,并把过滤规则与特定的路由结合。通常只须要针对根分类提供一个过滤器,而后为每一个子类提供路由映射。
关于各个策略的参数能够man tc-cbq tc-htb tc-sfq tc-red tc-tbf tc-pfifo tc-bfifo tc-pfifo_fast查看。