linux QOS(TC) 功能实现分析
- 格式:doc
- 大小:234.50 KB
- 文档页数:23
Linux下利用TC提高带宽利用率方法研究与实现潘杰【期刊名称】《计算机工程与设计》【年(卷),期】2012(033)010【摘要】介绍了Linux操作系统下TC模块实现流量控制的方法,设计了一种能够提高带宽利用率的方法,并对此方法进行了详细的实施与分析.此方法在以太网中的两台服务器之间进行文件传输,利用建立socket时选择的tos字段对传输的数据进行过滤,数据文件通过不同的通道进行传输.最后对传输过程中带宽利用率的变化进行了详细的描述,并且用实例表明了提高带宽利用率的方法.%The TC module under Linux operating system is introduced for traffic control methods, a method for improving bandwidth utilization is designed, and this method is implemented and analyzed detailed. This method transfer files between two servers in Ethernet According to the different choice of Tos filed when establish the socket, filtering the data of transmission, data files transport via different channels. Finally, the trend is described in bandwidth utilization during transmission. And it proves the method improves bandwidth utilization.【总页数】5页(P3739-3742,3782)【作者】潘杰【作者单位】中国电子科技集团公司第十五研究所,北京100083【正文语种】中文【中图分类】TP393.01【相关文献】1.Linux下P2P流量控制的研究及利用TC实现 [J], 王卫星;2.利用"捎带"技术提高HFC网络TCP性能的方法 [J], 吕迅;赵姚同;朱洪海3.基于状态检测的TCP包过滤在Linux下的实现方法 [J], 张佳;赵静凯;崔伟;黄皓4.一种嵌入式平台下提高SCTP偶联带宽利用率的方法 [J], 黄东明;郑善贤5.Linux下P2P流量控制的研究及利用TC实现 [J], 王卫星因版权原因,仅展示原文概要,查看原文内容请购买。
Linux⾼级路由-QOS服务质量:在带宽⼀定的情况下,提供更好的服务质量多端⼝使⽤宽带,在各种服务抢带宽的时候以太⽹模型是慢启动模式延时ssh吞吐web先⼊先出快速通道和慢速通道++++++++++++++QOS服务质量++++++++++++[root@localhost ~]# tc qdisc ls[root@localhost ~]# tc qdisc ls dev eth0qdisc pfifo_fast 0: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1默认情况下,⽹卡的队列规则为pfifo_fast。
不分类,尽可能快的先⼊先出队列规则分为两种: ⽆类队列规则pfifo/bfifopfifo_fastred⾻⼲⽹路由器上⽤,随机早期预测sfq 完全公平队列 tbf 令牌桶过滤 --- 流量整形(限速)添加删除队列规则]# tc qdisc add dev eth0 root pfifo]# tc qdisc del dev eth0 root什么叫做队列默认1个情况下,默认⽹卡的队列规则为pfifo_fast。
不分类,尽可能快的先进先出tc qdisc ls 查看队列规则设置流量控制tc class 创建tc filter 过滤:数据包优先级问题---通过队列来实现• 只有⼀个⽹卡,我们要设置⼀个队列规则• ⼀般情况下,应⽤程序产⽣数据包,⽹卡处理数据包,原则是先到先发(FIFO),队列。
• ⽽有些数据包需要先发出----再开⼀个队列,让队列与队列的优先级不⼀样。
==================什么叫做队列规则:• 队列规定:管理设备输⼊(ingress)或输出(egress)的⼀个算法。
• ⽆类的队列规定:⼀个内部不包含可配置⼦类的队列规定。
• 分类的队列规定:⼀个分类的队列规定内可⼀包含更多的类。
其中每个类⼜进⼀步地包含⼀个队列规定,这个队列规定可以是分类的,也可以是⽆类的。
linux qos 参数摘要:1.Linux QoS 简介2.Linux QoS 参数的作用3.重要的Linux QoS 参数a.流量控制参数b.延迟和丢包率参数c.带宽限制参数4.Linux QoS 参数的配置方法a.配置工具和命令b.配置流程和实例5.Linux QoS 参数调整的实际应用a.网络优化场景b.服务器负载均衡c.安全性考虑6.Linux QoS 参数的未来发展和趋势正文:Linux QoS(Quality of Service)是一种网络技术,用于在网络中为不同类型的流量提供优先级,以确保关键应用的性能和稳定性。
Linux QoS 通过调整不同参数来实现对网络流量的控制,这些参数包括流量控制、延迟和丢包率、带宽限制等。
流量控制参数是Linux QoS 中的重要部分,它们用于控制数据包的发送和接收速率。
通过调整这些参数,可以防止网络拥塞,确保关键应用的数据包能够优先发送和接收。
延迟和丢包率参数对于实时性要求较高的应用至关重要。
通过调整这些参数,可以降低网络延迟,减少数据包丢失,从而提高应用的性能和用户体验。
带宽限制参数用于限制特定流量的带宽使用,以保证网络中的其他流量能够正常运行。
这对于在有限带宽的环境中优化网络性能尤为重要。
Linux QoS 参数的配置方法主要包括使用配置工具和命令行命令。
配置流程通常包括选择需要调整的参数、设置参数值、应用配置等步骤。
具体的配置实例可以根据实际需求进行调整。
在实际应用中,Linux QoS 参数的调整可以广泛应用于网络优化、服务器负载均衡、安全性考虑等多个场景。
例如,在数据中心中,可以通过调整Linux QoS 参数来优化网络连接,提高服务器的性能和稳定性;在企业网络中,可以通过配置Linux QoS 来确保关键应用的带宽需求得到满足,提高员工的工作效率。
随着网络技术的不断发展,Linux QoS 参数在未来将会发挥越来越重要的作用。
在5G、物联网等新兴技术的推动下,网络流量将呈现爆炸式增长,对网络性能和稳定性的要求也将更高。
tc qdisc 原理TC(Traffic Control)是Linux系统中的一个网络流量控制工具,通过对网络流量进行管理和调度,可以实现对网络带宽的合理分配和流量控制。
而Qdisc(Queueing Discipline)是TC中的一种队列规则,用于管理和调度网络数据包的排队和发送。
本文将围绕着TC Qdisc的原理展开,介绍其作用、分类、工作原理以及常见的应用场景。
一、TC Qdisc的作用在计算机网络中,当多个主机同时进行数据传输时,往往会出现网络拥塞的情况,导致网络性能下降、延迟增加等问题。
TC Qdisc的作用就是通过对网络数据包进行管理和调度,实现对网络带宽的合理分配和流量控制,从而提高网络的性能和稳定性。
二、TC Qdisc的分类TC Qdisc根据其实现的功能和特点可以分为多种类型,常见的有以下几种:1. pfifo(Priority First In, First Out):按照数据包的到达顺序进行排队和发送,没有对数据包进行任何处理。
适用于对延迟要求较低的应用场景。
2. bfifo(Byte First In, First Out):按照数据包的大小进行排队和发送,较大的数据包会优先发送。
适用于对带宽要求较高的应用场景。
3. sfq(Stochastic Fairness Queueing):采用随机算法对数据包进行排队和发送,实现公平的带宽分配。
适用于对带宽公平分配要求较高的应用场景。
4. tbf(Token Bucket Filter):通过令牌桶算法对数据包进行排队和发送,实现对网络流量的限制和控制。
适用于对网络流量进行严格控制的应用场景。
三、TC Qdisc的工作原理TC Qdisc的工作原理主要包括以下几个步骤:1. 分类(Classification):根据规则将网络数据包进行分类,可以根据源IP地址、目标IP地址、端口号等进行分类。
2. 排队(Queueing):将分类后的数据包按照一定的规则放入相应的队列中,等待发送。
linux下tc简介Linux从kernel 2.1.105开始支持QOS,不过,需要重新编译内核。
运行 'make config'时将 EXPERIMENTAL _OPTIONS 设置成 'y',并且将 Class Based Queueing (CBQ), Token Bucket Flow, Traffic Shapers 设置为 'y' ,运行 'make dep; make clean; make bzilo',生成新的内核。
在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字节。
Linux 高级流控在IBM Bluemix 云平台上开发并部署您的下一个应用。
开始您的试用Linux 高级流量控制本篇主要讲用TC 对Linux 进行高级流量控制通过大量实践结合TC 流控HOWTO 文档整理而得如果你对Linux 流控感兴趣,如果你需要搭建高性能的Linux 网关, 本文将会使你受益颇多。
注:至少具备Linux OS 的中级水平知识,熟悉TCP/IP, Linux 网卡工作原理,以及配置Linux 网关的经验,将有助于对本文的理解。
本文参考文档:Tc 流控HOWTO 文档/HOWTO/html_single/Traffic-Control-H OWTO/ Linux TC 流量控制工具/view/f02078db50e2524de5187e45 .html回页首一 . Linux 流控简介Linux 流控的意义: 有效的控制Linux 网卡进出流量, 了解网卡工作原理, 搭建高性能的Linux 网关, 对Linux 高级系统流控有进一步的认识。
Linux 流量控制方法: 控发不控收, 所以只能对产生瓶颈网卡处的发包速率进行控制, 而网络瓶颈分析亦为Linux 网络流控的第一步 .Linux 流量控制过程分二种:队列控制即QOS, 瓶颈处的发送队列的规则控制,常见的有SFQ PRIO流量控制即带宽控制, 队列的排队整形,一般为TBF HTBLinux 流量控制算法分二种:无类算法用于树叶级无分支的队列,例如:SFQ分类算法用于多分支的队列,例如:PRIO TBF HTBLinux 流控实现工具TC: Linux 下流量控制工具, 从Linux2.2 版开始已并入内核,功能非常强大,详见参考文档。
回页首二 . 以下文章将以二种算法的不同流控分别介绍:1. 无类算法SFQa. 队列控制的无类算法SFQSFQ(Stochastic Fairness Queueing 随机公平队列) 是公平队列算法家族中的一个简单实现 . 它的精确性不如其它的方法, 但实现了高度的公平, 需要的计算量亦很少 . SFQ 算法主要针对一个TCP 会话或者UDP 流 . 流量被分成相当多数量的FIFO 队列中, 每个队列对应一个会话 . 数据按照简单轮转的方式发送, 每个会话都按顺序得到发送机会 . 这种方式非常公平, 保证了每一个会话都不会没其它会话所淹没 . SFQ 之所以被称为"随机", 是因为它并不是真的为每一个会话创建一个队列, 而是使用一个散列算法, 把所有的会话映射到有限的几个队列中去 . 因为使用了散列, 所以可能多个会话分配在同一个队列里, 从而需要共享发包的机会, 也就是共享带宽 . 为了不让这种效应太明显,SFQ 会频繁地改变散列算法, 以便把这种效应控制在几秒钟之内( 时间由参数设定). 注:SFQ 只会发生在数据发生拥堵, 产生等待队列的网卡上 .. 出口网卡若无等待队列,SFQ 亦不起作用 ...清单1. 在网卡上建立SFQ#tc qdisc add dev eth0 root handle 1: sfqSFQ 参数有perturb( 重新调整算法间隔) quantum 基本上不需要手工调整:handle 1: 规定算法编号 .. 可以不用设置由系统指定 ..#tc qdisc sh dev eth0 显示算法#tc qd del dev eth0 root 删除注: 默认eht0 支持TOS SFQ 队列一般用在树叶级, 配合其它流量整形算法一并使用……b. 流量控制的无类算法TBF令牌桶过滤器(TBF)是一个简单的队列规定: 只允许以不超过事先设定的速率到来的数据包通过, 但可能允许短暂突发流量朝过设定值 . TBF 很精确, 对于网络和处理器的影响都很小, 实现是针对数据的字节数进行的, 而不是针对数据包进行, 常用于网关限速 . TBF 的实现在于一个缓冲器( 桶), 不断地被一些叫做"令牌"的虚拟数据以特定速率填充着 . (token rate). 桶最重要的参数就是它的大小, 也就是它能够存储令牌的数量 . 每个到来的令牌从数据队列中收集一个数据包, 然后从桶中被删除 . 这个算法关联到两个流上——令牌流和数据流, 于是我们得到3 种情景: A. 数据流以等于令牌流的速率到达TBF. 这种情况下, 每个到来的数据包都能对应一个令牌, 然后无延迟地通过队列 . B. 数据流以小于令牌流的速度到达TBF. 通过队列的数据包只消耗了一部分令牌, 剩下的令牌会在桶里积累下来, 直到桶被装满 . 剩下的令牌可以在需要以高于令牌流速率发送数据流的时候消耗掉, 这种情况下会发生突发传输 . C. 数据流以大于令牌流的速率到达TBF. 这意味着桶里的令牌很快就会被耗尽 . 导致TBF 中断一段时间, 称为"越限". 如果数据包持续到来, 将发生丢包 . 此种情况最重要, 因为它可以用来对数据通过过滤器的速率进行整形 . 令牌的积累可以导致越限的数据进行短时间的突发传输而不必丢包, 但是持续越限的话会导致传输延迟直至丢包 .清单2. 在网卡建立TBF#tc qd add dev eth1 root handle 1: tbf rate 256kbit burst 10000 latency 50ms速率256kbit 突发传输10k 最大延迟50ms #tc -s qd sh dev eth1 统计#tc qd del dev eth1 root 删除rate 限制的传输速率用位来计算latency 确定了一个包在TBF 中等待传输的最长等待时间 .burst 桶的大小, 以字节计 . 指定了最多可以有多少个令牌能够即刻被使用 .注: 管理的带宽越大, 需要的缓冲器就越大 . 在Intel 体系上,10 兆bit/s 的速率需要至少10k 字节的缓冲区才能达到期望的速率 . 缓冲区太小导致潜在的丢包 .c. 无类算法除这二种队列以外, 另有pfifo_fast( 网卡出口默认根队列规定)经常使用的也就是SFQ/TBF ……这二种用法如下:单纯地降低出口速率, 使用令牌桶过滤器 . 调整桶的配置后可用于控制很高的带宽 .链路已经塞满, 保证不会有某一个会话独占出口带宽, 使用随机公平队列 .当然最要的还是工作中得来的经验, 就其应用方面只要能满足需求即可 .. 要做到灵活应用还得大量的实践 ..2. 分类算法—— PRIO/CBQ/HTB 分类算法主要作用是可以对多种数据流区别对待 . 一旦数据包进入一个分类的队列规定, 它就得被送到某一个类中分类, 对数据包进行分类的工具是过滤器 . 过滤器会返回一个决定, 队列规定就根据这个决定把数据包送入相应的类进行排队 . 每个子类都可以再次使用它们的过滤器进行进一步的分类 . 直到不需要进一步分类时, 数据包才进入该类包含的队列规定排队 . 除了能够包含其它队列规定之外, 绝大多数分类的队列规定能够流量整形注: 过滤器对数据包进行分类的工具, 是从队列规定内部调用的, 而不是从别处 .( 用在分叉的分支上)列规定家族: 根, 句柄, 兄弟和父辈每块网卡都有一个出口"根队列规定", 缺省情况下是前面提到的pfifo_fast 队列规定 . 每个队列规定都指定一个句柄, 以便以后的配置语句能够引用这个队列规定 . 除了出口队列规定之外, 每块网卡还有一个入口, 以便policies 进入的数据流 . 队列规定的句柄有两个部分: 一个主号码和一个次号码 . 习惯上把根队列规定称为"1:", 等价于"1:0". 队列规定的次号码永远是0. 类的主号码必须与它们父辈的主号码一致 .数据包如何出队并交给硬件当内核决定把一个数据包发给网卡的时候, 根队列规定1: 会得到一个出队请求, 然后把它传给1:1, 然后依次传给10:,12: 和13:( 子类自定义), 然后试图从它们中进行dequeue() 操作 . 也就是说, 内核需要遍历整颗树, 换句话说, 类及其兄弟仅仅与其"父队列规定"进行交谈, 而不会与网卡进行交谈 . 只有根队列规定才能由内核进行出队操作! 更进一步, 任何类的出队操作都不会比它们的父类更快 . 我们可以把SFQ 作为一个子类, 放到一个可以进行流量整形的父类中, 从而能够同时得到SFQ 的调度功能和其父类的流量整形功能 .a. 队列控制的分类算法PRIO PRIO 分类优先算法( 从左至右优先发包), 队列规定并不进行整形, 它仅仅根据你配置的过滤器把流量进一步细分 . 你可以认为PRIO 队列规定是pfifo_fast 的一种衍生物, 区别在每个频道都是一个单独的类, 而非简单的FIFO. 当数据包进入PRIO 队列规定后, 将根据你给定的过滤器设置选择一个类 . 缺省情况下有三个类, 这些类仅包含纯FIFO 队列规定而没有更多的内部结构 . 你可以把它们替换成你需要的任何队列规定 . 每当有一个数据包需要出队时, 首先处理:1 类 . 只有当标号更小的类中没有需要处理的包时, 才会标号大的类 .PRIO 配置范例示意图:大批量数据使用30:, 交互数据使用20: 或10:.清单3. 在网卡建立PRIO #tc qdisc add dev eth0 root handle 1: prio# 此命令立即创建了类: 1:1, 1:2, 1:3 ( 缺省三个子类) #tc qdisc add dev eth0 parent 1:1 handle 10: sfq#tc qdisc add dev eth0 parent 1:2 handle 20: tbf rate20kbit buffer 1600 limit 3000注: 此为TBF 限速的另一写法, 前文有讲解 .#tc qdisc add dev eth0 parent 1:3 handle 30: sfq 主要参数有:( 后续有实例) bands 创建频道的数目 . 每个频道实际上就是一个类跟priomap 参数配合使用注: 频道是类, 缺省情况下命名为主标号:1 到主标号:3. 如果你的PRIO 队列规定是12:, 把数据包过滤到12:1 将得到最高优先级 . 0 频道的次标号是1!1 频道的次标号是2, 以此类推 . priomap 给tc 提供过滤器, 如不提供PRIO 队列规定将参考TC_PRIO 的优先级来决定如何给数据包入队 .b. 流量整形的分类算法CBQ CBQ 的工作机制是确认链路的闲置时间足够长, 以达到降低链路实际带宽的目的 . 为此, 它要计算两个数据包的平均发送间隔 . 操作期间, 有效闲置时间的测量使用EWMA(exponential weighted moving average, 指数加权移动均值) 算法, 也就是说最近处理的数据包的权值比以前的数据包按指数增加 .UNIX 的平均负载也是这样算出来的 . 计算出来的平均时间值减去EWMA 测量值, 得出的结果叫做"avgidle". 最佳的链路负载情况下, 这个值应当是0: 数据包严格按照计算出来的时间间隔到来 . 在一个过载的链路上,avgidle 值应当是负的 . 如果这个负值太严重,CBQ 就会暂时禁止发包, 称为"overlimit"( 越限). 相反地, 一个闲置的链路应该有很大avgidle 值, 这样闲置几个小时后, 会造成链路允许非常大的带宽通过 . 为了避免这种局面, 我们用maxidle 来限avgidle的值不能太大 . 理论上讲, 如果发生越限,CBQ 就会禁止发包一段时间( 长度就是事先计算出来的传输数据包之间的时间间隔), 然后通过一个数据包后再次禁止发包 .清单4. WEB 服务器的流量控制为5Mbps,SMTP 流量控制在3Mbps 上 . 而且二者一共不得超过6Mbps, 互相之间允许借用带宽#tc qdisc add dev eth0 root handle 1:0 cbq bandwidth 100Mbit avpkt 1000 cell 8#tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 100Mbit rate 6Mbit weight0.6Mbit prio 8 allot 1514 cell 8 maxburst 20 avpkt 1000 bounded这部分按惯例设置了根为1:0, 并且绑定了类1:1. 也就是说整个带宽不能超过6Mbps.#tc class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 100Mbit rate 5Mbit weight0.5Mbit prio 5 allot 1514 cell 8 maxburst 20 avpkt 1000#tc class add dev eth0 parent 1:1 classid 1:4 cbq bandwidth 100Mbit rate 3Mbit weight0.3Mbit prio 5 allot 1514 cell 8 maxburst 20 avpkt 1000建立了2 个类 . 注意我们如何根据带宽来调整weight 参数的 . 两个类都没有配置成"bounded", 但它们都连接到了类1:1 上, 而1:1 设置了"bounded". 所以两个类的总带宽不会超过6Mbps. 别忘了, 同一个CBQ 下面的子类的主号码都必须与CBQ 自己的号码相一致!#tc qdisc add dev eth0 parent 1:3 handle 30: sfq#tc qdisc add dev eth0 parent 1:4 handle 40: sfq缺省情况下, 两个类都有一个FIFO 队列规定 . 但是我们把它换成SFQ 队列, 以保证每个数据流都公平对待 .#tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip sport 80 0xffff flowid1:3#tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32match ip sport 25 0xffff flowid1:4 CBQ 流量整形算法相对比较复杂, 工作中还常用 ... 示例中的各参数请参阅:HOWTO 中文文档 ..Linux 流量控制II--- 分类算法PRIO/CBQ/HTBc. 流量整形的分类算法HTB HTB(Hierarchical Token Bucket) 分层的令牌桶一个分类的令牌桶过滤器, 工作原理和相关配置同于TBF.. 拥有TBF 的各项性能, 可参阅TBF 的工作细节 ...清单5. 环境与要求同上述CBQ 的例子#tc qdisc add dev eth0 root handle 1: htb default 30#tc class add dev eth0 parent 1: classid 1:1 htb rate6mbit burst 15k#tc class add dev eth0 parent 1:1 classid 1:10 htb rate 5mbit burst 15k#tc class add dev eth0 parent 1:1 classid 1:20 htb rate 3mbit ceil 6mbit burst 15k#tc class add dev eth0 parent 1:1 classid 1:30 htb rate 1kbit ceil 6mbit burst 15k#tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10#tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10#tc qdisc add dev eth0 parent 1:30 handle 30: sfqperturb 10# 添加过滤器, 直接把流量导向相应的类:#U32="tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32"#$U32 match ip dport 80 0xffff flowid 1:10#$U32 match ip sport 25 0xffff flowid 1:20回页首三 . Linux 流量控制之U32 过滤规则过滤器是对数据包进行分类工具, 过滤器用与把数据包分类并放入相应的子队列, 这些过滤器在分类的队列规定内部被调用 . 为了决定用哪个类处理数据包, 必须调用所谓的"分类器链" 进行选择 . 这个链中包含了这个分类队列规定所需的所有过滤器 . 常用到的为U32 过滤器分类的一示例图:当一个数据包入队的时候, 每一个分支处都会咨询过滤器链如何进行下一步 . 典型的配置是在1:1 处有一个过滤器把数据包交给12:,然后12: 处的过滤器在把包交给12:2. 你可以把后一个过滤器同时放在1:1 处, 而得到效率的提高 . 另外, 你不能用过滤器把数据包向"上"送 . 而且, 使用HTB 的时候应该把所有的规则放到根上 .. 注: 数据包只能向"下"进行入队操作! 只有处队的时候才会上到网卡所在的位置来 . 他们不会落到树的最底层后送到网卡 ...清单6. 过滤器过滤示例#tc filter add dev eth0 protocol ip parent 10: prio 1 u32 match ip dport 22 0xffff flowid 10:1在10: 节点添加一个过滤规则, 优先权1: 凡是去往22 口( 精确匹配) 的IP 数据包, 发送到频道10:1..#tc filter add dev eth0 protocol ip parent 10: prio 1 u32 match ip sport 80 0xffff flowid 10:1在10: 节点添加一个过滤规则, 优先权1: 凡是来自80 口( 精确匹配) 的IP 数据包, 发送到频道10:1..#tc filter add dev eth0 protocol ip parent 10: prio 2 flowid 10:2在eth0 上的10: 节点添加一个过滤规则, 它的优先权是2: 凡是上二句未匹配的IP 数据包, 发送到频道10:2..#tc filter add dev eth0 parent 10:0 protocol ip prio 1 u32 match ip dst 4.3.2.1/32 flowid 10:1去往4.3.2.1 的包发送到频道10:1 其它参数同上例#tc filter add dev eth0 parent 10:0 protocol ip prio 1 u32 match ip src 1.2.3.4/32 flowid 10:1来自1.2.3.4 的包发到频道10:1#tc filter add dev eth0 protocol ip parent 10: prio 2 flowid 10:2凡上二句未匹配的包送往10:2#tc filter add dev eth0 parent 10:0 protocol ip prio 1 u32 match ip src 4.3.2.1/32 matchip sport 80 0xffff flowid 10:1可连续使用match, 匹配来自1.2.3.4 的80 口的数据包常用到的过滤命令一览#tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 -------根据源/ 目的地址源地址段'match ip src 1.2.3.0/24'目的地址段'match ip dst4.3.2.0/24'单个IP 地址'match ip 1.2.3.4/32'根据源/ 目的端口, 所有IP 协议源'match ip sport 80 0xffff' 0xffff表所有数据包目的'match ip dport 80 0xffff'根据IP 协议(tcp, udp, icmp, gre, ipsec)icmp 是1:'match ip protocol 1 0xff' 1 是根据/etc/protocols 协议号来定根据fwmark#iptables -A PREROUTING -t mangle -i eth0 -j MARK --set-mark 6#tc filter add dev eth1 protocol ip parent 1:0 prio 1 handle 6 fw flowid 1:1注:handle 根据过滤器的不同, 含义也不同按TOS 字段#tc filter add dev ppp0 parent 1:0 protocol ip prio 10 u32 match ip tos 0x10 0xffflowid 1:4 选择交互和最小延迟的数据流匹配大量传输, 使用"0x080xff".#tc filter add dev eth0 protocol ip parent 1:0 pref 10 u32 match u32 00100000 00ff0000at 0 flowid 1:10 匹配那些TOS 字段带有'最小延迟'属性的数据包回页首四 . Linux 流量控制--- 实例解析以下实例由实际工作环境要求编写而得:1. PRIO 分类优先算法( 从左至右优先发包)网卡工作示例图:清单7. PRIO 分类优先算法示例( 从左至右优先发包) #tc ad add dev eth0 root handle 1: prio hands 3 priomap 1---1 16 个1(tos 比特) 表示所有数据包注: 此命令自动在1: 下创建三子类1:1 1:2 1:3 此例中只用到1:1#tc qd add dev eth0 parent 1:1 handle 11:sfq#tc qdisc add dev eth0 parent 1:1 handle 12: tbf rate20kbitbuffer 1600 limit 3000#tc qd add dev eth0 parent 1:1 handle 13:sfq#tc filter add dev eth0 parent 1:1 prio 1003 protocol ip u32 match ip src 192.168.1.0/24 flowid 1:13#tc filter add dev eth0 parent 1:1 prio 1001 protocol ip u32 match ip src 10.0.0.0/8 flowid 1:12#tc filter add dev eth0 parent 1:1 protocol ip prio 1001 u32 match ip tos 0x10 0xff flowid 1:11 交互和最小延迟的数据流2. HTB 分层令牌桶网卡工作示例图:清单8. HTB 分层令牌桶示例#tc qd del dev eth1 root#tc qdisc add dev eth1 root handle 1: htb default 12#tc class add dev eth1 parent 1: classid 1:1 htb rate2Mbit burst 1500000 在1: 下定义子类1:1#tc class add dev eth1 parent 1:1 classid 1:11 htb rate512kbit burst 150000 ceil 1Mbit#tc qd add dev eth1 parent 1:11 handle 111: sfq#tc class add dev eth1 parent 1:1 classid 1:12 htb rate1Mbit burst 150000 ceil 1Mbit#tc qd add dev eth1 parent 1:12 handle 122: sfq 注: 亦可不在1:12 class 下定义122: qd#tc class add dev eth1 parent 1:1 classid 1:13 htb rate2Mbit burst 150000 ceil 2Mbit#tc qd add dev eth1 parent 1:13 handle 133: sfq#tc filter add dev eth1 parent 1: prio 10001 protocol ip u32 match ip src 192.168.1.0/24 flowid 1:12 其它二类亦如此 ..3. ADSL 上网流量限控脚本ADSL 带宽是下行3200Kbit, 上行只有320Kbit网卡工作示例图:清单9. 上网流量限控脚本示例tc qdisc add dev eth0 root handle 1: htb default 24tc class add dev eth0 parent 1: classid 1:1 htb rate300kbit ceil 300kbit prio 0tc class add dev eth0 parent 1: classid 1:2 htb rate150kbit prio 3tc class add dev eth0 parent 1:1 classid 1:11 htb rate 300kbit ceil 300kbit prio 1tc class add dev eth0 parent 1:1 classid 1:12 htb rate150kbit ceil 250kbit prio 2tc class add dev eth0 parent 1:2 classid 1:21 htb rate 100kbit ceil 150kbit prio 4tc class add dev eth0 parent 1:2 classid 1:22 htb rate 30kbit ceil 140kbit prio 5tc class add dev eth0 parent 1:2 classid 1:23 htb rate 15kbit ceil 130kbit prio 6tc class add dev eth0 parent 1:2 classid 1:24 htb rate5kbit ceil 50kbit prio 7tc qdisc add dev eth0 parent 1:11 handle 111: sfq perturb 5tc qdisc add dev eth0 parent 1:12 handle 112: sfq perturb 5tc qdisc add dev eth0 parent 1:21 handle 121: sfq perturb 10tc qdisc add dev eth0 parent 1:22 handle 122: sfq perturb 10tc qdisc add dev eth0 parent 1:23 handle 133: sfq perturb 10tc qdisc add dev eth0 parent 1:24 handle 124: sfq perturb 10tc filter add dev eth0 parent 1:0 protocol ip prio 1 handle1 fw classid 1:11tc filter add dev eth0 parent 1:0 protocol ip prio 2 handle 2 fw classid 1:12tc filter add dev eth0 parent 1:0 protocol ip prio 3 handle 3 fw classid 1:21tc filter add dev eth0 parent 1:0 protocol ip prio 4 handle 4 fw classid 1:22tc filter add dev eth0 parent 1:0 protocol ip prio 5 handle 5 fw classid 1:23tc filter add dev eth0 parent 1:0 protocol ip prio 6 handle 6 fw classid 1:241:11 最高优先级的数据包通道优先通过, 主要为一些ACK SYN 确认包 .. 必要时全部占用 .. 全速1:12 是很重要的数据道, 给多点, 最少给一半, 但需要时可以再多一点 .rate 规划1:2 = 1:21 + 1:22 + 1:23 + 1:24 一般总数在50%-80% 左右1:21 http,pop 最常用, 人数较多, 易导致堵塞, 不能给得太多, 但不益太少 .1:22 smtp 通道, 优先低于1:21 以防发大的附件大量占用带宽1:23 ftp-data 数据通道可能大量上传文件,rate 不能给得太多,ceil 设置大些( 其它通道剩余带宽应用)1:24 无所谓通道, 就是一般不是平时工作上需要的通道了, 给小点, 防止这些人在妨碍有正常工作需要的人其次的工作即在iptables 端对相应数据包打上标记 ...4.Linux+NAT+TC 脚本是Linux NAT 网关实例, 根据此脚本思路, 可进一步细致的进行针对于数据包的限制 ..清单10. Linux Nat 网关实例echo 1 >/proc/sys/net/ipv4/ip_forwardiptables -Fiptables -t nat -Fiptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o eth0 -j SNAT--to-source 124.42.97.36iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT--to-source 124.42.97.36iptables -I PREROUTING -t mangle -p tcp -s192.168.0.0/24 -j MARK--set-mark 1iptables -I PREROUTING -t mangle -p tcp -s192.168.1.0/24 -j MARK--set-mark 2注: 可分数据包类型标记tc qdisc del dev eth0 root# 加一个根队列, 速率用网卡的速率10Mbit,也可用上传的速率tc qdisc add dev eth0 root handle 100: cbq bandwidth 10Mbit avpkt 1000# 加一个根类tc class add dev eth0 parent 100:0 classid 100:1 cbq bandwidth 10Mbitrate 10Mbit allot 1514 weight 1Mbit prio 8 maxburst8 avpkt 1000 bounded# 加一个子类用于内网1 速率限制为300Kbittc class add dev eth0 parent 100:1 classid 100:2 cbq bandwidth 10Mbitrate 300Kbit allot 1513 weight 30Kbit prio 5 maxburst8 avpkt 1000 bounded# 加一个子类用于内网2 速率限制为320Kbittc class add dev eth0 parent 100:1 classid 100:3 cbq bandwidth 10Mbitrate 320Kbit allot 1513 weight 32Kbit prio 6 maxburst8 avpkt 1000 bounded# 设置队列规则tc qdisc add dev eth0 parent 100:2 sfq quantum 1514bperturb 15tc qdisc add dev eth0 parent 100:3 sfq quantum 1514b perturb 15# 将队列和fw 过滤器映射起来其中hand 1 的1 是开始用iptables 做的标记hand 2 的2 也是开始用iptables 做的标记tc filter add dev eth0 parent 100:0 protocol ip prio 1 handle1 fw classid 100:2tc filter add dev eth0 parent 100:0 protocol ip prio 2 handle2 fw classid 100:3流量监测相关命令:tc -s qdisc/class ls dev eth0tc -s qdisc/class ls dev eth15. Linux 网关/ 服务器限速---HTB清单11. Linux 网关/ 服务器HTB 限速#!/bin/shPWD=/home/huaying/netTC=/sbin/tc$TC class ls dev eth0$TC qdisc del dev eth0 root$TC qdisc add dev eth0 root handle 1: htb r2q 1U32="$TC filter add dev eth0 parent 1: protocol ip prio 16 u32"while read linedoip=`echo $line | awk '{print $1}'`limit=`echo $line | awk '{print $2}'`$TC class add dev eth0 parent 1: classid 1:$ip htb rate"$limit"kbit burst 1k$U32 match ip dst 192.168.1.$ip/32 flowid 1:$ipdone < $PWD/ip_limit注:ip_limit 分行记录, 第一列为ip, 第二列为限制的带宽, 二列以tables 分开 ..服务器限速#!/bin/sh/sbin/tc qdisc del dev eth0 root/sbin/tc qdisc add dev eth0 root handle 1:0 htb r2q 1/sbin/tc class add dev eth0 parent 1:0 classid 1:1 htb rate75mbit burst 10k/sbin/tc filter add dev eth0 parent 1: protocol ip prio 16 u32 match ip dst 0.0.0.0/0 flowid 1:1/sbin/tc class ls dev eth0最大限制服务器eth0 流量在75Mbit/s。
Linux下TC(trafficcontrol)以及netem的使⽤⼀:综述: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过滤器,由⼀个过滤器和⼀个动作组成,选择器⽤来对数据包进⾏匹配,⼀旦匹配成功就执⾏该动作。
基于Linux的Qo醐程接口研究与分析(7)[完]基于Linux的QoS编程接口研究与分析(7)[完]第四章Linux的QoS编程接口 4.1 QoS数据通道全局的数据通道的略图见图 4.1,灰色部分是QoS :图4.1网络数据加工数据包的处理过程是:Input Interface 宀Ingress PolicingT Input Demultiplexing (判断分组是本地使用还是转发) —Forwarding T Output Queuing T Output Interface。
入口的流量限制(Ingress Policing)和出口的队列调度(Output Queuing )是由Linux核心的流量控制的代码实现的。
入口的流量限制(Ingress Policing)丢弃不符合规定的分组,确保进入的各个业务流分组速率的上限,出口的队列调度(Output Queuing )依据配置实现分组的排队、丢弃。
以下是分析Linux 2.4的代码得出的数据通道,根据在图4.1中的位置,分为Ingress policing的数据通道和OutputQueuing的数据通路,一下分别阐述:4.1.1 Ingress policing 的数据通道Ingress policing的QoS的部分是通过HOOK 实现的。
HOOK 是Linux实现netfilter的重要手段,数据从接收到转发得通路上有5个HOOK 点①,每个HOOK点有若干个挂钩处理函数:(typedef unsigned int nf_hookfn(unsigned int hooknum,struct sk_buff **skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff *)); )。
Ingress policing 用的是NF IP PRE ROUTING 这个HOOK 点,其挂钩处理函数用的是net/sched/sch_ingress.c ing_hook。
公司一台服务器,网络环境太高,那台服务器和源服务器连接下载,就跑到 400M-500M,为了控制一下, 所以研究了一下 TC。
来做流量控制.给他控制到小点,不要让这一台占了所有的网络。
TC 很是强大啊,很 多所谓的硬件路由器,都是基于这个做的。
TC 介绍在 linux 中,TC 有二种控制方法 CBQ 和 HTB.HTB 是设计用来替换 CBQ 的。
它是一个层次式的过 滤框架.TC 包括三个基本的构成块:队列规定 qdisc(queueing discipline )、类(class)和分类器(Classifiers)TC 中的队列 中的队列(queueing discipline): 用来实现控制网络的收发速度.通过队列,linux 可以将网络数据包缓存起来,然后根据用户的设置,在尽 量不中断连接(如 TCP)的前提下来平滑网络流量.需要注意的是,linux 对接收队列的控制不够好,所以我 们一般只用发送队列,即“控发不控收”.它封装了其他两个主要 TC 组件(类和分类器)。
内核如果需要通 过某个网络接口发送数据包,它都需要按照为这个接口配置的 qdisc(排队规则)把数据包加入队列。
然后, 内核会尽可能多地从 qdisc 里面取出数据包,把它们交给网络适配器驱动模块。
最简单的 QDisc 是 pfifo 它不对进入的数据包做任何的处理, 数据包采用先入先出的方式通过队列。
不过,它会保存网络接口一时无法处理的数据包。
队列规则包括 FIFO (先进先出) RED , (随机早期探测) SFQ , (随机公平队列) 和令牌桶 (Token Bucket) , 类基队列(CBQ),CBQ 是一种超级队列,即它能够包含其它队列(甚至其它 CBQ)。
TC 中的 Class 类 class 用来表示控制策略.很显然,很多时候,我们很可能要对不同的 IP 实行不同的流量控制策略,这时 候我们就得用不同的 class 来表示不同的控制策略了.TC 中的 Filter 规则 filter 用来将用户划入到具体的控制策略中(即不同的 class 中).比如,现在,我们想对 xxa,xxb 两个 IP 实行不同的控制策略(A,B),这时,我们可用 filter 将 xxa 划入到控制策略 A,将 xxb 划入到控制策 略 B, filter 划分的标志位可用 u32 打标功能或 IPtables 的 set-mark (大多使用 iptables 来做标记) 功能来实现。
linux QOS 功能实现分析文档编号:00-6201-100当前版本:1.0.0.0创建日期:2008-7-24编写作者:wanghuaijialinux QOS 功能实现分析前言 (3)关于此文档 (3)参考资料 (3)Linux内核对QoS的支持 (5)对于入口数据包控制 (6)发送数据包的控制 (8)TC的具体设计与实现 (11)struct Qdisc_ops 说明 (15)LINUX 内核中安装策略对象过程 (17)前言关于此文档此文档是本人这段时间内学习QOS相关知识,总结并且整理出来的文档。
供大家参考。
本文档描述QOS相关知识,各章节说明如下:1前言,即此章节;2 QOS简介,介绍QOS基本知识、QOS提出的意义,以及QOS 的三种不同的服务模型;3:介绍QOS相关的技术,介绍了报文分类以及标记,拥塞管理技术,拥塞避免技术,以及流量整形和流量监管。
并且介绍了链路层相关的速度限制。
参考资料网络资源。
linux QOS 功能实现分析Linux内核对QoS的支持 (5)对于入口数据包控制 (6)发送数据包的控制 (8)TC的具体设计与实现 (11)struct Qdisc_ops 说明 (15)LINUX 内核中安装策略对象过程 (17)在传统的TCP/IP网络的路由器中,所有的IP数据包的传输都是采用FIFO(先进先出),尽最大努力传输的处理机制。
在早期网络数据量和关键业务数据不多的时候,并没有体现出非常大的缺点,路由器简单的把数据报丢弃来处理拥塞。
但是随着计算机网络的发展,数据量的急剧增长,以及多媒体,VOIP数据等对延时要求高的应用的增加。
路由器简单丢弃数据包的处理方法已经不再适合当前的网络。
单纯的增加网络带宽也不能从根本上解决问题。
所以网络的开发者们提出了服务质量的概念。
概括的说:就是针对各种不同需求,提供不同服务质量的网络服务功能。
提供QoS能力将是对未来IP网络的基本要求。
第一章Linux内核对QoS的支持Linux内核网络协议栈从2.2.x开始,就实现了对服务质量的支持模块。
具体的代码位于net/sched/目录。
在Linux里面,对这个功能模块的称呼是Traffic Control ,简称TC。
我们首先看看数据包传递的过程:如下图然后我们添加了TC模块以支持我们的QOS 功能如下图:其中绿色部分就是我们添加的TC模块,其中ingress policing 是处理输入数据包的,而output queueing 则是处理输出数据包的。
1.0 流入口数据包控制对于入口数据包的控制是通过HOOK函数来实现的,。
HOOK是Linux实现netfilter的重要手段,数据从接收到转发得通路上有5个HOOK点,每个HOOK点有若干个挂钩处理函数(typedef unsigned int nf_hookfn(unsigned int hooknum,struct sk_buff **skb,const struct net_device *in,const struct net_device *out,int (*okfn)(struct sk_buff *))。
对于入口数据部分的控制,LINUX 中挂载的HOOK点如下/* after ipt_filter */static struct nf_hook_ops ing_ops = {.hook = ing_hook,.owner = THIS_MODULE,.pf = PF_INET,.hooknum = NF_IP_PRE_ROUTING,.priority = NF_IP_PRI_FILTER + 1,};Ingress policing用的是NF_IP_PRE_ROUTING这个HOOK点,其挂钩处理函数用的是net/sched/sch_ingress.c ing_hook()。
函数处理流程如下所示:接收数据包的过程中,通过软中断调用net_rx_action()将硬件层得到的数据传输到IP层。
ip_rcv() #net/ipv4/ip_input.c 丢弃校验和不正确的ip包。
nf_hook_slow()#net/core/netfilter.c。
nf_iterate() #net/core/netfilter.c。
ing_hook() 4#net/sched/sch_ingress.c。
QoS:如果设置了qdisc_ingress,则调用ingress_dequeue(),此处可以对流量进行限制#net/sched/sch_ingress.c 。
ip_rcv_finish()#net/ipv4/ip_input.c(sch_ingress.c 的enqueue()有限流制作用,然而dequeue()却是空函数。
)。
以下路由:ip_route_input() #net/ipv4/route.c 。
如果转发ip_route_input_slow() #net/ipv4/route.c,如果本地处理ip_route_input_mc() #net/ipv4/route.c 。
2.0 流出数据包的控制首先我们了解一下Linux网络协议栈在没有TC模块时发送数据包的大致流程。
如图1。
从上图可以看出,没有TC的情况下,每个数据包的发送都会调用dev_queue_xmit,然后判断是否需要向AF_PACKET协议支持体传递数据包内容,最后直接调用网卡驱动注册的发送函数把数据包发送出去。
发送数据包的机制就是本文开始讲到的FIFO机制。
一旦出现拥塞,协议栈只是尽自己最大的努力去调用网卡发送函数。
所以这种传统的处理方法存在着很大的弊端。
为了支持QoS,Linux的设计者在发送数据包的代码中加入了TC模块。
从而可以对数据包进行分类,管理,检测拥塞和处理拥塞。
为了避免和以前的代码冲突,并且让用户可以选择是否使用TC。
内核开发者在上图中的两个红色圆圈之间添加了TC模块。
为了实现QOS的支持LINUX 内核中添加如下的代码:net/core/dev.c: dev_queue_xmit函数中略了部分代码:int dev_queue_xmit(struct sk_buff *skb){……………….q = dev->qdisc;if (q->enqueue) {/*如果这个设备启动了TC,那么把数据包压入队列*/int ret = q->enqueue(skb, q);/*启动这个设备发送*/qdisc_run(dev);return;}if (dev->flags&IFF_UP) {………….if (netdev_nit)dev_queue_xmit_nit(skb,dev);/*对AF_PACKET协议的支持*/if (dev->hard_start_xmit(skb, dev) == 0) {/*调用网卡驱动发送函数发送数据包*/return 0;}}}从上面的代码中可以看出,当q->enqueue为假的时候,就不采用TC处理,而是直接发送这个数据包。
如果为真,则对这个数据包进行QoS处理。
处理流程如下图:QoS:如果有排队方式,那么skb先进入排队q->enqueue(skb,q),然后运行qdisc_run() #include/net/pkt_sched.h:while (!netif_queue_stopped(dev) &&qdisc_restart(dev)<0);qdisc_restart(dev) #net/sched/sch_generic.c #linux/net/pkt_sched.h而后,q->dequeue(q)上图中q->enqueue是对数据包入队,而q->dequeue是选择队列中的一个数据包然后取出。
进行数据包的发送。
当然入队,出队根据不同的策略有不同的动作具体后面讨论。
3.0 TC的具体设计与实现LINUX 内核中设计的TC QoS有很多的拥塞处理机制,如FIFO Queueing(先入先出队列),PQ(优先队列),CQ(定制队列),WFQ(加权公平队列)等等。
QoS还要求能够对每个接口分别采用不同的拥塞处理。
为了能够实现上述功能,Linux采用了基于对象的实现方法。
上图是一个数据发送队列管理机制的模型图。
其中的QoS策略可以是各种不同的拥塞处理机制。
我们可以把这一种策略看成是一个类,策略类。
在实现中,这个类有很多的实例对象,策略对象。
使用者可以分别采用不同的对象来管理数据包。
策略类有很多的方法。
如入队列(enqueue),出队列(dequeue),重新入队列(requeue),初始化(init),撤销(destroy)等方法。
在Linux中,用Qdisc_ops结构体来代表上面描述的策略类。
struct Qdisc_ops{struct Qdisc_ops *next;struct Qdisc_class_ops *cl_ops;char id[IFNAMSIZ];int priv_size;int (*enqueue)(struct sk_buff *, struct Qdisc *);struct sk_buff * (*dequeue)(struct Qdisc *);int (*requeue)(struct sk_buff *, struct Qdisc *);unsigned int (*drop)(struct Qdisc *);int (*init)(struct Qdisc *, struct rtattr *arg);void (*reset)(struct Qdisc *);void (*destroy)(struct Qdisc *);int (*change)(struct Qdisc *, struct rtattr *arg);int (*dump)(struct Qdisc *, struct sk_buff *);int (*dump_stats)(struct Qdisc *, structgnet_dump *);struct module *owner;};前面提到,每个设备可以采用不同的策略对象。
所以在设备和对象之间需要有一个桥梁,使设备和设备采用的对象相关。
在Linux中,起到桥梁作用的是Qdisc结构体。
struct Qdisc{int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev);struct sk_buff * (*dequeue)(struct Qdisc *dev);unsigned flags;#define TCQ_F_BUILTIN 1#define TCQ_F_THROTTLED 2#define TCQ_F_INGRES 4int padded;struct Qdisc_ops *ops;u32 handle;atomic_t refcnt;struct sk_buff_head q;struct net_device *dev;struct list_head list;struct tc_stats stats;spinlock_t *stats_lock;struct rcu_head q_rcu;int (*reshape_fail)(struct sk_buff *skb, struct Qdisc *q);/* This field is deprecated, but it is still used by CBQ* and it will live until better solution will be invented.*/struct Qdisc *__parent;};通过上面的描述,整个TC的架构也就出来了。