【网络】inux流量控制器TC(Traffic Control)

发布于:2021-12-02 23:43:23

目录


实施


实施步骤概览


实施步骤


原理


经验之谈:



实施

原文:https://blog.csdn.net/tycoon1988/article/details/40832325


实施步骤概览

  在Linux操作系统中流量控制器(TC)主要是在输出端口处建立一个队列进行流量控制,控制的方式是基于路由,亦即基于目的IP地址或目的子网的网络号的流量控制


流量控制器TC,其基本的功能模块为队列、分类和过滤器。



Linux内核中支持的队列有,Class?Based?Queue?,Token?Bucket?Flow?,CSZ?,First?In?First?Out?,Priority?,TEQL?,SFQ?,ATM?,RED。


这里我们讨论的队列与分类都是基于CBQ(Class?Based?Queue)的,而过滤器是基于路由(Route)的。



  配置和使用流量控制器TC,主要分以下几个方面:分别为建立队列、建立分类、建立过滤器和建立路由,另外还需要对现有的队列、分类、过滤器和路由进行监视。?

其基本使用步骤为:
  1)?针对网络物理设备(如以太网卡eth0)绑定一个CBQ队列;
  2)?在该队列上建立分类;
  3)?为每一分类建立一个基于路由的过滤器;
  4)?最后与过滤器相配合,建立特定的路由表。


?


先假设一个简单的环境,如下所示:
  流量控制器上的以太网卡(eth0)?的IP地址为192.168.1.66,在其上建立一个CBQ队列。假设包的*均大小为1000字节,包间隔发送单元的大小为8字节,可接收冲突的发送最长包数目为20字节。
  


? ? ? 假如有三种类型的流量需要控制:
  1)?是发往主机1的,其IP地址为192.168.1.24。其流量带宽控制在8Mbit,优先级为2;
  2)?是发往主机2的,其IP地址为192.168.1.26。其流量带宽控制在1Mbit,优先级为1;
  3)?是发往子网1的,其子网号为192.168.1.0,子网掩码为255.255.255.0。流量带宽控制在1Mbit,优先级为6。


实施步骤

1.?建立队列?



  一般情况下,针对一个网卡只需建立一个队列。


  将一个cbq队列绑定到网络物理设备eth0上,其编号为1:0;网络物理设备eth0的实际带宽为10?Mbit,包的*均大小为1000字节;包间隔发送单元的大小为8字节,最小传输包大小为64字节。
  



? ? ? ? ?tc?qdisc?add?dev?eth0?root?handle?1:?cbq?bandwidth?10Mbit?avpkt?1000?cell?8?mpu?64
?????????rate:?是一个类保证得到的带宽值.如果有不只一个类,请保证所有子类总和是小于或等于父类.?
?????????prio:用来指示借用带宽时的竞争力,prio越小,优先级越高,竞争力越强.
?????????ceil:?ceil是一个类最大能得到的带宽值,缺省的ceil是和速率一样.



2.?建立分类



  分类建立在队列之上。一般情况下,针对一个队列需建立一个根分类,然后再在其上建立子分类。对于分类,按其分类的编号顺序起作用,编号小的优先;一旦符合某个分类匹配规则,通过该分类发送数据包,则其后的分类不再起作用。


1)?创建根分类1:1;分配带宽为10Mbit,优先级别为8。



tc?class?add?dev?eth0?parent?1:0?classid?1:1?cbq?bandwidth?10Mbit?rate?10Mbit?maxburst?20?allot?1514?prio?8?avpkt?1000?cell?8?weight?1Mbit



  该队列的最大可用带宽为10Mbit,实际分配的带宽为10Mbit,可接收冲突的发送最长包数目为20字节;最大传输单元加MAC头的大小为1514字节,优先级别为8,包的*均大小为1000字节,包间隔发送单元的大小为8字节,相应于实际带宽的加权速率为1Mbit。


2)创建分类1:2,其父分类为1:1,分配带宽为8Mbit,优先级别为2。



tc?class?add?dev?eth0?parent?1:1?classid?1:2?cbq?bandwidth?10Mbit?rate?8Mbit?maxburst?20?allot?1514?prio?2?avpkt?1000?cell?8?weight?800Kbit?split?1:0?bounded



  该队列的最大可用带宽为10Mbit,实际分配的带宽为?8Mbit,可接收冲突的发送最长包数目为20字节;最大传输单元加MAC头的大小为1514字节,优先级别为1,包的*均大小为1000字节,包间隔发送单元的大小为8字节,相应于实际带宽的加权速率为800Kbit,分类的分离点为1:0,且不可借用未使用带宽。


3)创建分类1:3,其父分类为1:1,分配带宽为1Mbit,优先级别为1。



tc?class?add?dev?eth0?parent?1:1?classid?1:3?cbq?bandwidth?10Mbit?rate?1Mbit?maxburst?20?allot?1514?prio?1?avpkt?1000?cell?8?weight?100Kbit?split?1:0



  该队列的最大可用带宽为10Mbit,实际分配的带宽为?1Mbit,可接收冲突的发送最长包数目为20字节;最大传输单元加MAC头的大小为1514字节,优先级别为2,包的*均大小为1000字节,包间隔发送单元的大小为8字节,相应于实际带宽的加权速率为100Kbit,分类的分离点为1:0。


4)创建分类1:4,其父分类为1:1,分配带宽为1Mbit,优先级别为6。



tc?class?add?dev?eth0?parent?1:1?classid?1:4?cbq?bandwidth?10Mbit?rate?1Mbit?maxburst?20?allot?1514?prio?6?avpkt?1000?cell?8?weight?100Kbit?split?1:0



  该队列的最大可用带宽为10Mbit,实际分配的带宽为?64Kbit,可接收冲突的发送最长包数目为20字节;最大传输单元加MAC头的大小为1514字节,优先级别为1,包的*均大小为1000字节,包间隔发送单元的大小为8字节,相应于实际带宽的加权速率为100Kbit,分类的分离点为1:0。


3.?建立过滤器



过滤器主要服务于分类。一般只需针对根分类提供一个过滤器,然后为每个子分类提供路由映射。


1)?应用路由分类器到cbq队列的根,父分类编号为1:0;过滤协议为ip,优先级别为100,过滤器为基于路由表。



tc?filter?add?dev?eth0?parent?1:0?protocol?ip?prio?100?route



2)?建立路由映射分类1:2,?1:3,?1:4



tc?filter?add?dev?eth0?parent?1:0?protocol?ip?prio?100?route?to?2?flowid?1:2
tc?filter?add?dev?eth0?parent?1:0?protocol?ip?prio?100?route?to?3?flowid?1:3
tc?filter?add?dev?eth0?parent?1:0?protocol?ip?prio?100?route?to?4?flowid?1:4 //创建分类1:4



4.建立路由



该路由是与前面所建立的路由映射一一对应。



1)?发往主机192.168.1.24的数据包通过分类2转发(分类2的速率8Mbit)



ip?route?add?192.168.1.24?dev?eth0?via?192.168.1.66?realm?2



2)?发往主机192.168.1.30的数据包通过分类3转发(分类3的速率1Mbit)



ip?route?add?192.168.1.30?dev?eth0?via?192.168.1.66?realm?3



3)发往子网192.168.1.0/24的数据包通过分类4转发(分类4的速率1Mbit)



ip?route?add?192.168.1.0/24?dev?eth0?via?192.168.1.66?realm?4



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


?


5.?监视



主要包括对现有队列、分类、过滤器和路由的状况进行监视。


1)显示队列的状况


简单显示指定设备(这里为eth0)的队列状况



tc?qdisc?ls?dev?eth0
qdisc?cbq?1:?rate?10Mbit?(bounded,isolated)?prio?no-transmit



详细显示指定设备(这里为eth0)的队列状况



tc?-s?qdisc?ls?dev?eth0
qdisc?cbq?1:?rate?10Mbit?(bounded,isolated)?prio?no-transmit
Sent?7646731?bytes?13232?pkts?(dropped?0,?overlimits?0)
borrowed?0?overactions?0?avgidle?31?undertime?0



 这里主要显示了通过该队列发送了13232个数据包,数据流量为7646731个字节,丢弃的包数目为0,超过速率限制的包数目为0。


2)显示分类的状况


简单显示指定设备(这里为eth0)的分类状况



tc?class?ls?dev?eth0
class?cbq?1:?root?rate?10Mbit?(bounded,isolated)?prio?no-transmit
class?cbq?1:1?parent?1:?rate?10Mbit?prio?no-transmit?#no-transmit表示优先级为8
class?cbq?1:2?parent?1:1?rate?8Mbit?prio?2
class?cbq?1:3?parent?1:1?rate?1Mbit?prio?1
class?cbq?1:4?parent?1:1?rate?1Mbit?prio?6



?


详细显示指定设备(这里为eth0)的分类状况



tc?-s?class?ls?dev?eth0
class?cbq?1:?root?rate?10Mbit?(bounded,isolated)?prio?no-transmit
Sent?17725304?bytes?32088?pkts?(dropped?0,?overlimits?0)
borrowed?0?overactions?0?avgidle?31?undertime?0
class?cbq?1:1?parent?1:?rate?10Mbit?prio?no-transmit
Sent?16627774?bytes?28884?pkts?(dropped?0,?overlimits?0)
borrowed?16163?overactions?0?avgidle?587?undertime?0
class?cbq?1:2?parent?1:1?rate?8Mbit?prio?2
Sent?628829?bytes?3130?pkts?(dropped?0,?overlimits?0)
borrowed?0?overactions?0?avgidle?4137?undertime?0
class?cbq?1:3?parent?1:1?rate?1Mbit?prio?1
Sent?0?bytes?0?pkts?(dropped?0,?overlimits?0)
borrowed?0?overactions?0?avgidle?159654?undertime?0
class?cbq?1:4?parent?1:1?rate?1Mbit?prio?6
Sent?5552879?bytes?8076?pkts?(dropped?0,?overlimits?0)
borrowed?3797?overactions?0?avgidle?159557?undertime?0



  这里主要显示了通过不同分类发送的数据包,数据流量,丢弃的包数目,超过速率限制的包数目等等。其中根分类(class?cbq?1:0)的状况应与队列的状况类似。
  例如,分类class?cbq?1:4发送了8076个数据包,数据流量为5552879个字节,丢弃的包数目为0,超过速率限制的包数目为0。


显示过滤器的状况




tc?-s?filter?ls?dev?eth0
filter?parent?1:?protocol?ip?pref?100?route
filter?parent?1:?protocol?ip?pref?100?route?fh?0xffff0002?flowid?1:2?to?2
filter?parent?1:?protocol?ip?pref?100?route?fh?0xffff0003?flowid?1:3?to?3
filter?parent?1:?protocol?ip?pref?100?route?fh?0xffff0004?flowid?1:4?to?4



这里flowid?1:2代表分类class?cbq?1:2,to?2代表通过路由2发送。


显示现有路由的状况



ip?route
192.168.1.66?dev?eth0?scope?link
192.168.1.24?via?192.168.1.66?dev?eth0?realm?2
202.102.24.216?dev?ppp0?proto?kernel?scope?link?src?202.102.76.5
192.168.1.30?via?192.168.1.66?dev?eth0?realm?3
192.168.1.0/24?via?192.168.1.66?dev?eth0?realm?4
192.168.1.0/24?dev?eth0?proto?kernel?scope?link?src?192.168.1.66
172.16.1.0/24?via?192.168.1.66?dev?eth0?scope?link
127.0.0.0/8?dev?lo?scope?link
default?via?202.102.24.216?dev?ppp0
default?via?192.168.1.254?dev?eth0



  如上所示,结尾包含有realm的显示行是起作用的路由过滤器。


6.?维护



  主要包括对队列、分类、过滤器和路由的增添、修改和删除。
  增添动作一般依照"队列->;分类->;过滤器->;路由"的顺序进行;修改动作则没有什么要求;删除则依照"路由->;过滤器->;分类->;队列"的顺序进行。


1)队列的维护
一般对于一台流量控制器来说,出厂时针对每个以太网卡均已配置好一个队列了,通常情况下对队列无需进行增添、修改和删除动作了。


2)分类的维护


增添
增添动作通过tc?class?add命令实现,如前面所示。


修改
修改动作通过tc?class?change命令实现,如下所示:
?tc?class?change?dev?eth0?parent?1:1?classid?1:2?cbq?bandwidth?10Mbit?rate?7Mbit?maxburst?20?allot?1514?prio?2?avpkt?1000?cell?8?weight?700Kbit?split?1:0?bounded
对于bounded命令应慎用,一旦添加后就进行修改,只可通过删除后再添加来实现。


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


3)过滤器的维护


增添
增添动作通过tc?filter?add命令实现,如前面所示。


修改
修改动作通过tc?filter?change命令实现,如下所示:
?tc?filter?change?dev?eth0?parent?1:0?protocol?ip?prio?100?route?to?10?flowid?1:8


删除
删除动作通过tc?filter?del命令实现,如下所示:
?tc?filter?del?dev?eth0?parent?1:0?protocol?ip?prio?100?route?to?10


4)与过滤器一一映射路由的维护


增添
增添动作通过ip?route?add命令实现,如前面所示。


修改
修改动作通过ip?route?change命令实现,如下所示:
?ip?route?change?192.168.1.30?dev?eth0?via?192.168.1.66?realm?8


删除
删除动作通过ip?route?del命令实现,如下所示:
?ip?route?del?192.168.1.30?dev?eth0?via?192.168.1.66?realm?8
?ip?route?del?192.168.1.0/24?dev?eth0?via?192.168.1.66?realm?4
原文链接:https://blog.csdn.net/tycoon1988/article/details/40832325


?


原理

?


原文:?https://www.cnblogs.com/endsock/archive/2011/12/09/2281519.html


一、TC原理介绍


Linux操作系统中的流量控制器TC(Traffic Control)用于Linux内核的流量控制,主要是通过在输出端口处建立一个队列来实现流量控制。(因为我们无法控制自己网络之外的设备,入口处的流量控制相对较难。)


量控制的一个基本概念是队列(Qdisc),每个网卡都与一个队列(Qdisc)相联系,每当内核需要将报文分组从网卡发送出去,都会首先将该报文分组添加到该网卡所配置的队列中,由该队列决定报文分组的发送顺序。因此可以说,所有的流量控制都发生在队列中,详细流程图见图1。


?图1报文在Linux内部流程图



报文分组从输入网卡(入口)接收进来,经过路由的查找,以确定是发给本机的,还是需要转发的。如果是发给本机的,就直接向上递交给上层的协议,比如TCP,如果是转发的,则会从输出网卡(出口)发出。


?


有些队列的功能是非常简单的,它们对报文分组实行先来先走的策略。有些队列则功能复杂,会将不同的报文分组进行排队、分类,并根据不同的原则,以不同的顺序发送队列中的报文分组。为实现这样的功能,这些复杂的队列需要使用不同的过滤器(Filter)来把报文分组分成不同的类别(Class)。这里把这些复杂的队列称为可分类(Classiful)的队列。通常,要实现功能强大的流量控制,可分类的队列是必不可少的。因此,类别(Class)和过滤器(Filter)也是流量控制的另外两个重要的基本概念。图2所示的是一个可分类队列的例?子。


??????



?


?由图2可以看出,类别(Class)和过滤器(Filter)都是队列的内部结构,并且可分类的队列可以包含多个类别,同时,一个类别又可以进一步包含有子队列,或者子类别。所有进入该类别的报文分组可以依据不同的原则放入不同的子队列?或子类别中,以此类推。而过滤器(Filter)是队列用来对数据报文进行分类的工具,它决定一个数据报文将被分配到哪个类别中。


?


二、使用TC
??????在Linux中,流量控制都是通过TC这个工具来完成的。通常,要对网卡进行流量控制的配置,需要进行如下的步骤:


  ◆?为网卡配置一个队列;


  ◆?在该队列上建立分类;


  ◆?根据需要建立子队列和子分类;


  ◆?为每个分类建立过滤器。


??????在Linux中,可以配置很多类型的队列,比如CBQ、HTB等,其中CBQ?比较复杂,不容易理解。HTB(Hierarchical?Token?Bucket)是一个可分类的队列,?与其他复杂的队列类型相比,HTB具有功能强大、配置简单及容易上手等优点。在TC中,使用"major:minor"这样的句柄来标识队列和类别,其中major和minor都是数字。


??????对于队列来说,minor总是为0,即"major:0"这样的形式,也可以简写为"major: "比如,队列1:0可以简写为1:。需要注意的是,major在一个网卡的所有队列中必须是惟一的。对于类别来说,其major必须和它的父类别或父队列的major相同,而minor在一个队列内部则必须是惟一的(因为类别肯定是包含在某个队列中的)。举个例子,如果队列2:包含两个类别,则这两个类别的句柄必须是2:x这样的形式,并且它们的x不能相同,比如2:1和2:2。


??????下面,将以HTB队列为主,结合需求来讲述TC的使用。假设eth0出口有100mbit/s的带宽,分配给WWW、E-mail和Telnet三种数据流量,其中分配给WWW的带宽为40Mbit/s,分配给Email的带宽为40Mbit/s,分配给Telnet的带宽为20Mbit/S。


??????需要注意的是,在TC?中使用下列的缩写表示相应的带宽:


??????◆?Kbps?:?kilobytes?per?second,千字节每秒?;


??????◆?Mbps?:?megabytes?per?second,兆字节每秒?,


??????◆?Kbit?:?kilobits?per?second,千比特每秒?;


??????◆?Mbit?:?megabits?per?second,?兆比特每秒?。


三、创建HTB队列
??????有关队列的TC命令的一般形式为:


#tc?qdisc?[add?|?change?|?replace?|?link]?dev?DEV?[parent?qdisk-id?|root]?[handle?qdisc-id]?qdisc?[qdisc?specific?parameters]


??????首先,需要为网卡eth0配置一个HTB队列,使用下列命令:


??????#tc?qdisc?add?dev?eth0?root?handle?1:htb?default?11


??????这里,命令中的”add”表示要添加,”dev?eth0”表示要操作的网卡为eth0。”root”表示为网卡eth0添加的是一个根队列。”handle?1:”表示队列的句柄为1:?。”htb”表示要添加的队列为HTB队列。命令最后的”default?11”是htb特有的队列参数,意思是所有未分类的流量都将分配给类别1:11。


四、为根队列创建相应的类别
??????有关类别的TC?命令的一般形式为:


#tc?class?[add?|?change?|?replace]?dev?DEV?parent?qdisc-id?[classid?class-id]?qdisc?[qdisc?specific?parameters]


??????可以利用下面这三个命令为根队列1创建三个类别,分别是1:1?1、1:12和1:13,它们分别占用40、40和20mb[t的带宽。


??????#tc?class?add?dev?eth0?parent?1:?classid?1:1?htb?rate?40mbit?ceil?40mbit


??????#tc?class?add?dev?eth0?parent?1:?classid?1:12?htb?rate?40mbit?ceil?40mbit


??????#tc?class?add?dev?eth0?parent?1:?cllassid?1:13?htb?rate?20mbit?ceil?20mbit


??????命令中,”parent?1:”表示类别的父亲为根队列1:?。”classid1:11”表示创建一个标识为1:11的类别,”rate?40mbit”表示系统将为该类别确保带宽40mbit,”ceil?40mbit”,表示该类别的最高可占用带宽为40mbit。


五、为各个类别设置过滤器
??????有关过滤器的TC?命令的一般形式为:


#tc?filter?[add?|?change?|?replace]?dev?DEV?[parent?qdisc-id | root] protocol?protocol?prio?priority?filtertype?[filtertype?specific?parameters]?flowid?flow-id


??????由于需要将WWW、E-mail、Telnet三种流量分配到三个类别,即上述1:11、1:12和1:13,因此,需要创建三个过滤器,如下面的三个命令:


??????#tc?filter?add?dev?eth0?protocol?ip?parent?1:0?prio?1?u32?match?ip?dport?80?0xffff?flowid?1:11


??????#tc?filter?add?dev?eth0?prtocol?ip?parent?1:0?prio?1?u32?match?ip?dport?25?0xffff?flowid?1:12


??????#tc?filter?add?dev?eth0?protocol?ip?parent?1:0?prio?1?u32?match?ip?dport?23?oxffff?flowid?1:13


??????这里,”protocol?ip”表示该过滤器应该检查报文分组的协议字段。”prio?1”?表示它们对报文处理的优先级是相同的,对于不同优先级的过滤器,系统将按照从小到大的优先级顺序来执行过滤器,对于相同的优先级,系统将按照命令的先后顺序执行。这几个过滤器还用到了u32选择器(命令中u32后面的部分)来匹配不同的数据流。以第一个命令为例,判断的是dport字段,如果该字段与Oxffff进行与操作的结果是8O,则”flowid?1:11”表示将把该数据流分配给类别1:1?1。更加详细的有关TC的用法可以参考TC的手册页。


六、复杂的实例
??????在上面的例子中,?三种数据流(www、Email、Telnet)之间是互相排斥的。当某个数据流的流量没有达到配额时,其剩余的带宽并不能被其他两个数据流所借用。在这里将涉及如何使不同的数据流可以共享一定的带宽。


??????首先需要用到HTB的一个特性,?即对于一个类别中的所有子类别,它们将共享该父类别所拥有的带宽,同时,又可以使得各个子类别申请的各自带宽得到保证。这也就是说,当某个数据流的实际使用带宽没有达到其配额时,其剩余的带宽可以借给其他的数据流。而在借出的过程中,如果本数据流的数据量增大,则借出的带宽部分将收回,以保证本数据流的带宽配额。


??????下面考虑这样的需求,同样是三个数据流WWW、E-mail和Telnet,?其中的Telnet独立分配20Mbit/s的带宽。另一方面,WWW?和SMTP各自分配40Mbit/s的带宽。同时,它们又是共享的关系,即它们可以互相借用带宽。如图3所示。


?


??????需要的TC命令如下:


??????#tc?qdisc?add?dev?eth0?root?handle?1:?htb?default?21


??????#tc?class?add?dev?eth0?partent?1:?classid?1:1?htb?rate?20mbit?ceil?20mbit


??????#tc?class?add?dev?eth0?parent?1:?classid?1:2?htb?rate?80mbit?ceil?80mbit


??????#tc?class?add?dev?eth0?parent?1:?classid?1:21?htb?rate?40mbit?ceil?20mbit


??????#tc?class?add?dev?eth0?parent?1:2?classid?1:22?htb?rate?40mbit?ceil?80mbit


??????#tc?filter?add?dev?eth0?protocol?parent?10?prio?1?u32?match?ip?dport?80?0xffff?flowid?1:21


??????#tc?filter?add?dev?eth0?protocol?parent?1:0?prio?1?u32?match?ip?dport?25?0xffff?flowid?1:22


??????#tc?filter?add?dev?eth0?protocol?parent?1:0?prio?1?u32?match?ip?dport?23?0xffff?flowid?1:1


??????这里为根队列1创建两个根类别,即1:1和1:2,其中1:1对应Telnet数据流,1:2对应80Mbit的数据流。然后,在1:2中,创建两个子类别1:21和1:22,分别对应WWW和E-mail数据流。由于类别1:21和1:22是类别1:2的子类别,因此他们可以共享分配的80Mbit带宽。同时,又确保当需要时,自己的带宽至少有40Mbit。


??????从这个例子可以看出,利用HTB中类别和子类别的包含关系,可以构建更加复杂的多层次类别树,从而实现的更加灵活的带宽共享和独占模式,达到企业级的带宽管理目的。
原文链接:https://blog.csdn.net/zhaobryant/article/details/38797655


?


二、TC规则


1、流量控制方式


流量控制包括以下几种方式:


SHAPING(限制) ???? 当流量被限制,它的传输速率就被控制在某个值以下。限制值可以大大小于有效带宽,这样可以*滑突发数据流量,使网络更为稳定。shaping(限制)只适用于向外的流量。


SCHEDULING(调度) ???? 通过调度数据包的传输,可以在带宽范围内,按照优先级分配带宽。SCHEDULING(调度)也只适于向外的流量。


POLICING(策略) ???? SHAPING用于处理向外的流量,而POLICIING(策略)用于处理接收到的数据。


DROPPING(丢弃) ???? 如果流量超过某个设定的带宽,就丢弃数据包,不管是向内还是向外。


2、流量控制处理对象


流量的处理由三种对象控制,它们是:qdisc(排队规则)class(类别)filter(过滤器)


QDISC(排队规则) ???? QDisc(排队规则)是queueing discipline的简写,它是理解流量控制(traffic control)的基础。无论何时,内核如果需要通过某个网络接口发送数据包,它都需要按照为这个接口配置的qdisc(排队规则)把数据包加入队列。然后,内核会尽可能多地从qdisc里面取出数据包,把它们交给网络适配器驱动模块。最简单的QDisc是pfifo它不对进入的数据包做任何的处理,数据包采用先入先出的方式通过队列。不过,它会保存网络接口一时无法处理的数据包。


QDISC的类别如下:


(1)、CLASSLESS QDisc(不可分类QDisc)


1>无类别QDISC包括:


[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)里面的。


red


red是Random Early Detection(随机早期探测)的简写。如果使用这种QDISC,当带宽的占用接*于规定的带宽时,系统会随机地丢弃一些数据包。它非常适合高带宽应用。


sfq


sfq是Stochastic Fairness Queueing的简写。它按照会话(session--对应于每个TCP连接或者UDP流)为流量进行排序,然后循环发送每个会话的数据包。


tbf


tbf是Token Bucket Filter的简写,适合于把流速降低到某个值。


2>不可分类QDisc的配置


如果没有可分类QDisc,不可分类QDisc只能附属于设备的根。它们的用法如下:


????tc?qdisc add dev DEV root QDISC QDISC-PARAMETERS


要删除一个不可分类QDisc,需要使用如下命令:


????tc?qdisc del dev DEV root


一个网络接口上如果没有设置QDisc,pfifo_fast就作为缺省的QDisc。


(2)、CLASSFUL QDISC(分类QDisc)


可分类的QDisc包括:


CBQ


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


HTB


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


PRIO


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


CLASS(类) ????? 某些QDisc(排队规则)可以包含一些类别,不同的类别中可以包含更深入的QDisc(排队规则),通过这些细分的QDisc还可以为进入的队列的数据包排队。通过设置各种类别数据包的离队次序,QDisc可以为设置网络数据流量的优先级。


FILTER(过滤器) ???? Filter(过滤器)用于为数据包分类,决定它们按照何种QDisc进入队列。无论何时数据包进入一个划分子类的类别中,都需要进行分类。分类的方法可以有多种,使用fileter(过滤器)就是其中之一。使用filter(过滤器)分类时,内核会调用附属于这个类(class)的所有过滤器,直到返回一个判决。如果没有判决返回,就作进一步的处理,而处理方式和QDISC有关。需要注意的是,filter(过滤器)是在QDisc内部,它们不能作为主体。


3、操作原理


类(Class)组成一个树,每个类都只有一个父类,而一个类可以有多个子类。某些QDisc(例如:CBQ和HTB)允许在运行时动态添加类,而其它的QDisc(例如:PRIO)不允许动态建立类。允许动态添加类的QDisc可以有零个或者多个子类,由它们为数据包排队。此外,每个类都有一个叶子QDisc,默认情况下,这个叶子QDisc使用pfifo的方式排队,我们也可以使用其它类型的QDisc代替这个默认的QDisc。而且,这个叶子叶子QDisc有可以分类,不过每个子类只能有一个叶子QDisc。 当一个数据包进入一个分类QDisc,它会被归入某个子类。我们可以使用以下三种方式为数据包归类,不过不是所有的QDisc都能够使用这三种方式。


tc过滤器(tc?filter)


如果过滤器附属于一个类,相关的指令就会对它们进行查询。过滤器能够匹配数据包头所有的域,也可以匹配由ipchains或者iptables做的标记。


服务类型(Type of Service)


某些QDisc有基于服务类型(Type of Service,ToS)的内置的规则为数据包分类。


skb->priority


用户空间的应用程序可以使用SO_PRIORITY选项在skb->priority域设置一个类的ID。


树的每个节点都可以有自己的过滤器,但是高层的过滤器也可以直接用于其子类。


如果数据包没有被成功归类,就会被排到这个类的叶子QDisc的队中。相关细节在各个QDisc的手册页中。


4、命名规则


所有的QDisc、类和过滤器都有ID。ID可以手工设置,也可以有内核自动分配。ID由一个主序列号和一个从序列号组成,两个数字用一个冒号分开。


QDISC


一个QDisc会被分配一个主序列号,叫做句柄(handle),然后把从序列号作为类的命名空间。句柄采用象10:一样的表达方式。*惯上,需要为有子类的QDisc显式地分配一个句柄。


类(CLASS)


在同一个QDisc里面的类分享这个QDisc的主序列号,但是每个类都有自己的从序列号,叫做类识别符(classid)。类识别符只与父QDisc有关,和父类无关。类的命名*惯和QDisc的相同。


过滤器(FILTER)


过滤器的ID有三部分,只有在对过滤器进行散列组织才会用到。详情请参考tc-filters手册页。


5、单位


tc命令的所有参数都可以使用浮点数,可能会涉及到以下计数单位。


1》带宽或者流速单位:


kbps??????????????????????????? 千字节/秒


mbps?????????????????????????? 兆字节/秒


kbit???????????????????????????? KBits/秒


mbit??????????????????????????? MBits/秒


bps或者一个无单位数字????? 字节数/秒


2》数据的数量单位:


kb或者k????????????????????? 千字节


mb或者m??????????????????? 兆字节


mbit????????????????????????? 兆bit


kbit?????????????????????????? 千bit


b或者一个无单位数字?????? 字节数


3》时间的计量单位:


s、sec或者secs????????????????????????????? 秒


ms、msec或者msecs?????????????????????? 分钟


us、usec、usecs或者一个无单位数字??? 微秒


三、TC命令


tc可以使用以下命令对QDisc、类和过滤器进行操作:


add


在一个节点里加入一个QDisc、类或者过滤器。添加时,需要传递一个祖先作为参数,传递参数时既可以使用ID也可以直接传递设备的根。如果要建立一个QDisc或者过滤器,可以使用句柄(handle)来命名;如果要建立一个类,可以使用类识别符(classid)来命名。


remove


删除有某个句柄(handle)指定的QDisc,根QDisc(root)也可以删除。被删除QDisc上的所有子类以及附属于各个类的过滤器都会被自动删除。


change


以替代的方式修改某些条目。除了句柄(handle)和祖先不能修改以外,change命令的语法和add命令相同。换句话说,change命令不能一定节点的位置。


replace


对一个现有节点进行*于原子操作的删除/添加。如果节点不存在,这个命令就会建立节点。


link


只适用于DQisc,替代一个现有的节点。


例:


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


四、具体操作


Linux流量控制主要分为建立队列、建立分类和建立过滤器三个方面。


1、基本实现步骤为:


(1) 针对网络物理设备(如以太网卡eth0)绑定一个队列QDisc;


(2) 在该队列上建立分类class;


(3) 为每一分类建立一个基于路由的过滤器filter;


(4) 最后与过滤器相配合,建立特定的路由表。


2、环境模拟实例:


流量控制器上的以太网卡(eth0) 的IP地址为192.168.1.66,在其上建立一个CBQ队列。假设包的*均大小为1000字节,包间隔发送单元的大小为8字节,可接收冲突的发送最长包数目为20字节。


假如有三种类型的流量需要控制: ???   1) 是发往主机1的,其IP地址为192.168.1.24。其流量带宽控制在8Mbit,优先级为2; ???   2) 是发往主机2的,其IP地址为192.168.1.30。其流量带宽控制在1Mbit,优先级为1; ???   3) 是发往子网1的,其子网号为192.168.1.0,子网掩码为255.255.255.0。流量带宽控制在1Mbit,优先级为6。


1. 建立队列


一般情况下,针对一个网卡只需建立一个队列。


将一个cbq队列绑定到网络物理设备eth0上,其编号为1:0;网络物理设备eth0的实际带宽为10 Mbit,包的*均大小为1000字节;包间隔发送单元的大小为8字节,最小传输包大小为64字节。


?tc?qdisc add dev eth0 root handle 1: cbq bandwidth 10Mbit avpkt 1000 cell 8 mpu 64


2. 建立分类


分类建立在队列之上。


一般情况下,针对一个队列需建立一个根分类,然后再在其上建立子分类。对于分类,按其分类的编号顺序起作用,编号小的优先;一旦符合某个分类匹配规则,通过该分类发送数据包,则其后的分类不再起作用。


1) 创建根分类1:1;分配带宽为10Mbit,优先级别为8。


?tc?class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 10Mbit rate 10Mbit maxburst 20 allot 1514 prio 8 avpkt 1000 cell 8 weight 1Mbit


该队列的最大可用带宽为10Mbit,实际分配的带宽为10Mbit,可接收冲突的发送最长包数目为20字节;最大传输单元加MAC头的大小为1514字节,优先级别为8,包的*均大小为1000字节,包间隔发送单元的大小为8字节,相应于实际带宽的加权速率为1Mbit。


2)创建分类1:2,其父分类为1:1,分配带宽为8Mbit,优先级别为2。


?tc?class add dev eth0 parent 1:1 classid 1:2 cbq bandwidth 10Mbit rate 8Mbit maxburst 20 allot 1514 prio 2 avpkt 1000 cell 8 weight 800Kbit split 1:0 bounded


该队列的最大可用带宽为10Mbit,实际分配的带宽为 8Mbit,可接收冲突的发送最长包数目为20字节;最大传输单元加MAC头的大小为1514字节,优先级别为1,包的*均大小为1000字节,包间隔发送单元的大小为8字节,相应于实际带宽的加权速率为800Kbit,分类的分离点为1:0,且不可借用未使用带宽。


3)创建分类1:3,其父分类为1:1,分配带宽为1Mbit,优先级别为1。


?tc?class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 10Mbit rate 1Mbit maxburst 20 allot 1514 prio 1 avpkt 1000 cell 8 weight 100Kbit split 1:0


该队列的最大可用带宽为10Mbit,实际分配的带宽为 1Mbit,可接收冲突的发送最长包数目为20字节;最大传输单元加MAC头的大小为1514字节,优先级别为2,包的*均大小为1000字节,包间隔发送单元的大小为8字节,相应于实际带宽的加权速率为100Kbit,分类的分离点为1:0。


4)创建分类1:4,其父分类为1:1,分配带宽为1Mbit,优先级别为6。


?tc?class add dev eth0 parent 1:1 classid 1:4 cbq bandwidth 10Mbit rate 1Mbit maxburst 20 allot 1514 prio 6 avpkt 1000 cell 8 weight 100Kbit split 1:0


该队列的最大可用带宽为10Mbit,实际分配的带宽为1Mbit,可接收冲突的发送最长包数目为20字节;最大传输单元加MAC头的大小为1514字节,优先级别为6,包的*均大小为1000字节,包间隔发送单元的大小为8字节,相应于实际带宽的加权速率为100Kbit,分类的分离点为1:0。


3. 建立过滤器


过滤器主要服务于分类。


一般只需针对根分类提供一个过滤器,然后为每个子分类提供路由映射


1) 应用路由分类器到cbq队列的根,父分类编号为1:0;过滤协议为ip,优先级别为100,过滤器为基于路由表。


?tc?filter add dev eth0 parent 1:0 protocol ip prio 100 route


2) 建立路由映射分类1:2, 1:3, 1:4


?tc?filter add dev eth0 parent 1:0 protocol ip prio 100 route to 2 flowid 1:2


?tc?filter add dev eth0 parent 1:0 protocol ip prio 100 route to 3 flowid 1:3


?tc?filter add dev eth0 parent 1:0 protocol ip prio 100 route to 4 flowid 1:4


4.建立路由


该路由是与前面所建立的路由映射一一对应。


1) 发往主机192.168.1.24的数据包通过分类2转发(分类2的速率8Mbit)


?ip route add 192.168.1.24 dev eth0 via 192.168.1.66 realm 2


2) 发往主机192.168.1.30的数据包通过分类3转发(分类3的速率1Mbit)


?ip route add 192.168.1.30 dev eth0 via 192.168.1.66 realm 3


3)发往子网192.168.1.0/24的数据包通过分类4转发(分类4的速率1Mbit)


?ip route add 192.168.1.0/24 dev eth0 via 192.168.1.66 realm 4


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


5. 监视


主要包括对现有队列、分类、过滤器和路由的状况进行监视。


1)显示队列的状况


简单显示指定设备(这里为eth0)的队列状况


?tc?qdisc ls dev eth0


qdisc cbq 1: rate 10Mbit (bounded,isolated) prio no-transmit


详细显示指定设备(这里为eth0)的队列状况


?tc?-s qdisc ls dev eth0


qdisc cbq 1: rate 10Mbit (bounded,isolated) prio no-transmit ???? Sent 7646731 bytes 13232 pkts (dropped 0, overlimits 0) ???? borrowed 0 overactions 0 avgidle 31 undertime 0


这里主要显示了通过该队列发送了13232个数据包,数据流量为7646731个字节,丢弃的包数目为0,超过速率限制的包数目为0。


2)显示分类的状况


简单显示指定设备(这里为eth0)的分类状况


?tc?class ls dev eth0


class cbq 1: root rate 10Mbit (bounded,isolated) prio no-transmit ????? class cbq 1:1 parent 1: rate 10Mbit prio no-transmit #no-transmit表示优先级为8 ???? class cbq 1:2 parent 1:1 rate 8Mbit prio 2 ???? class cbq 1:3 parent 1:1 rate 1Mbit prio 1 ???? class cbq 1:4 parent 1:1 rate 1Mbit prio 6


详细显示指定设备(这里为eth0)的分类状况


?tc?-s class ls dev eth0


class cbq 1: root rate 10Mbit (bounded,isolated) prio no-transmit ???? Sent 17725304 bytes 32088 pkts (dropped 0, overlimits 0) ???? borrowed 0 overactions 0 avgidle 31 undertime 0 ???? class cbq 1:1 parent 1: rate 10Mbit prio no-transmit ???? Sent 16627774 bytes 28884 pkts (dropped 0, overlimits 0) ???? borrowed 16163 overactions 0 avgidle 587 undertime 0 ???? class cbq 1:2 parent 1:1 rate 8Mbit prio 2 ???? Sent 628829 bytes 3130 pkts (dropped 0, overlimits 0) ???? borrowed 0 overactions 0 avgidle 4137 undertime 0 ???? class cbq 1:3 parent 1:1 rate 1Mbit prio 1 ???? Sent 0 bytes 0 pkts (dropped 0, overlimits 0) ???? borrowed 0 overactions 0 avgidle 159654 undertime 0 ???? class cbq 1:4 parent 1:1 rate 1Mbit prio 6 ???? Sent 5552879 bytes 8076 pkts (dropped 0, overlimits 0) ???? borrowed 3797 overactions 0 avgidle 159557 undertime 0


这里主要显示了通过不同分类发送的数据包,数据流量,丢弃的包数目,超过速率限制的包数目等等。其中根分类(class cbq 1:0)的状况应与队列的状况类似。


例如,分类class cbq 1:4发送了8076个数据包,数据流量为5552879个字节,丢弃的包数目为0,超过速率限制的包数目为0。


显示过滤器的状况


?tc?-s filter ls dev eth0


filter parent 1: protocol ip pref 100 route ???? filter parent 1: protocol ip pref 100 route fh 0xffff0002 flowid 1:2 to 2 ???? filter parent 1: protocol ip pref 100 route fh 0xffff0003 flowid 1:3 to 3 ???? filter parent 1: protocol ip pref 100 route fh 0xffff0004 flowid 1:4 to 4


这里flowid 1:2代表分类class cbq 1:2,to 2代表通过路由2发送。


显示现有路由的状况


?ip route


192.168.1.66 dev eth0 scope link ???? 192.168.1.24 via 192.168.1.66 dev eth0 realm 2 ???? 202.102.24.216 dev ppp0 proto kernel scope link src 202.102.76.5 ???? 192.168.1.30 via 192.168.1.66 dev eth0 realm 3 ???? 192.168.1.0/24 via 192.168.1.66 dev eth0 realm 4 ???? 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.66 ???? 172.16.1.0/24 via 192.168.1.66 dev eth0 scope link ???? 127.0.0.0/8 dev lo scope link ???? default via 202.102.24.216 dev ppp0 ???? default via 192.168.1.254 dev eth0


如上所示,结尾包含有realm的显示行是起作用的路由过滤器。


6. 维护


主要包括对队列、分类、过滤器和路由的增添、修改和删除。


增添动作一般依照"队列->分类->过滤器->路由"的顺序进行;修改动作则没有什么要求;删除则依照"路由->过滤器->分类->队列"的顺序进行。


1)队列的维护


一般对于一台流量控制器来说,出厂时针对每个以太网卡均已配置好一个队列了,通常情况下对队列无需进行增添、修改和删除动作了。


2)分类的维护


增添


增添动作通过tc?class add命令实现,如前面所示。


修改


修改动作通过tc?class change命令实现,如下所示:


?tc?class change dev eth0 parent 1:1 classid 1:2 cbq bandwidth 10Mbit rate 7Mbit maxburst 20 allot 1514 prio 2 avpkt 1000 cell 8 weight 700Kbit split 1:0 bounded


对于bounded命令应慎用,一旦添加后就进行修改,只可通过删除后再添加来实现。


删除


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


3)过滤器的维护


增添


增添动作通过tc?filter add命令实现,如前面所示。


修改


修改动作通过tc?filter change命令实现,如下所示:


?tc?filter change dev eth0 parent 1:0 protocol ip prio 100 route to 10 flowid 1:8


删除


删除动作通过tc?filter del命令实现,如下所示:


?tc?filter del dev eth0 parent 1:0 protocol ip prio 100 route to 10


4)与过滤器一一映射路由的维护


增添


增添动作通过ip route add命令实现,如前面所示。


修改


修改动作通过ip route change命令实现,如下所示:


?ip route change 192.168.1.30 dev eth0 via 192.168.1.66 realm 8


删除


删除动作通过ip route del命令实现,如下所示:


?ip route del 192.168.1.30 dev eth0 via 192.168.1.66 realm 8


?ip route del 192.168.1.0/24 dev eth0 via 192.168.1.66 realm 4


注:部分内容来自互联网,版权归原作者所有。


?


?


linux tc (traffic control 看了一些某些网上的文章,整理一下自身角度去理解的看法:


?1. tc 就是qos的一些东西(思科R&S IE部分内容对QOS队列说明结合来看就不错了)。


?2. tc 是质量保证,但是我们这种普通人基本上就用来限速啦。(你交换机不帮忙限速是不是。。我自己来。。。)。其实限速只是它已部分,但是我们目前用也是限速。。。


?3.tc步骤 先建立 队列(qdisc);分类(class);处理(filter)限速。##基本跟H3C的QOS限速类似..


?


?


经验之谈:

1.???????队列qdisc,用户定义的都是在root下面,自定义handle?树干(一个接口只能有1个队列处理方式(cbq,htb等);


2.???????类(class),不能删除,只能修改(如果要删除如何办?把树干干掉)


3.???????过滤器(filter关联处理动作);


场景1:不通的IP分配到不同的限速类,分别都是可以限速的。


场景2:不通的IP分配到相同的限速类,分别都可以限速。


?


理解图:




效果:


无限速前:



限速后:



https://blog.51cto.com/u_323248/1829698

相关推荐

最新更新

猜你喜欢