1、Linux内核QoS实现机制1. QoS介绍QoS(Quality of Service)即服务质量。对于网络业务,服务质量包括传输的带宽、传送的时延、数据的丢包率等。在网络中可以通过保证传输的带宽、降低传送的时延、降低数据的丢包率以及时延抖动等措施来提高服务质量。网络资源总是有限的,只要存在抢夺网络资源的情况,就会出现服务质量的要求。服务质量是相对网络业务而言的,在保证某类业务的服务质量的同时,可能就是在损害其它业务的服务质量。例如,在网络总带宽固定的情况下,如果某类业务占用的带宽越多,那么其他业务能使用的带宽就越少,可能会影响其他业务的使用。因此,网络管理者需要根据各种业务的特点来对网络资
2、源进行合理的规划和分配,从而使网络资源得到高效利用。流量控制包括以下几种方式:n SHAPING(限制)当流量被限制,它的传输速率就被控制在某个值以下。限制值可以大大小于有效带宽,这样可以平滑突发数据流量,使网络更为稳定。shaping(限制)只适用于向外的流量。n SCHEDULING(调度)通过调度数据包的传输,可以在带宽范围内,按照优先级分配带宽。SCHEDULING(调度)也只适于向外的流量。n POLICING(策略)SHAPING用于处理向外的流量,而POLICIING(策略)用于处理接收到的数据。n DROPPING(丢弃)如果流量超过某个设定的带宽,就丢弃数据包,不管是向内还是
3、向外。2. 内核实现过程图表 1 流量控制过程绿色部分就是Linux内核实现的QoS模块,其中ingress policing 是处理输入数据包的,而output queueing 则是处理输出数据包的。2.1. Ingress实现机制Ingress QOS在内核的入口点有两个,但是不能同时启用,这取决于内核编译选项。当打开了CONFIG_NET_CLS_ACT(from 2.6.8 release still available on 2.6.39 release)时,入口点在src/net/core/dev.c的netif_receive_skb函数中;当没有打开CONFIG_NET_CL
4、S_ACT,而是打开了CONFIG_NET_CLS_POLICE (from 2.6.9 release to 2.6.24, thus this is an obsolete configuration)和CONFIG_NETFILTER时,就会在netfilter的PREROUTING钩子点处调用ing_hook函数。图表 2 ingress策略实现当filter中有规则时,遍历规则表,寻找与skb-mark(由ebtables或iptables来配置)相匹配的表项,如果找到了则会进一步调用tcf_exts_exec函数对扩展的action进行处理。图表 3 FW分类器实现过程2.2. E
5、gress实现机制系统在注册网络设备时会在register_netdevice函数中调用dev_init_scheduler函数注册一个qdisc的接口,它是一个特殊的qdisc,不做任何处理。当创建好设备,用ifconfig up命令把设备拉起后,会调用到内核的src/net/core/dev.c中的dev_open函数,在dev_open函数中又会调用到src/net/sched/sch_generic.c中的dev_activate函数,给设备配置默认的root qdisc处理机制:pfifo_fast。图表 4 以prio qdisc为例的egress初始化过程出口队列调度的入口点在s
6、rc/net/core/dev.c的dev_queue_xmit函数中,通过q = rcu_dereference(dev-qdisc)可以获取到设备上root qdisc的指针q(struct Qdisc *)。在下面的处理过程中并没有判断q是否为NULL,这就说明设备上一定会存在egress qdisc,这一点和ingress是不同的,一个设备上可以没有ingress qdisc,即dev- qdisc_ingress指针一般是NULL,除非通过tc qdisc命令配置了ingress qdisc。图表 5 以htb+pfifo qdisc为例的egress处理流程3. 内核与TC的交互3
7、.1. 交互方式Netlink3.2. 内核处理接口n Qdisc和class交互接口tc qdisc和tc clsss配置命令对应的配置函数在src/net/sched/sch_api.c的pktsched_init函数中进行了初始化注册,由subsys_initcall函数对系统进行申明,该函数在linux系统初始化的时候会被调用到。代码片断如下:if (link_p) link_pRTM_NEWQDISC-RTM_BASE.doit = tc_modify_qdisc;link_pRTM_DELQDISC-RTM_BASE.doit = tc_get_qdisc;link_pRTM_GE
8、TQDISC-RTM_BASE.doit = tc_get_qdisc;link_pRTM_GETQDISC-RTM_BASE.dumpit = tc_dump_qdisc;link_pRTM_NEWTCLASS-RTM_BASE.doit = tc_ctl_tclass;link_pRTM_DELTCLASS-RTM_BASE.doit = tc_ctl_tclass;link_pRTM_GETTCLASS-RTM_BASE.doit = tc_ctl_tclass;link_pRTM_GETTCLASS-RTM_BASE.dumpit = tc_dump_tclass;n filter交互
9、接口tc filter配置命令对应的配置函数在src/net/sched/cls_api.c的tc_filter_init函数中进行了初始化注册,该函数也会在系统初始化的时候被调用到。代码片段如下:if (link_p) link_pRTM_NEWTFILTER-RTM_BASE.doit = tc_ctl_tfilter;link_pRTM_DELTFILTER-RTM_BASE.doit = tc_ctl_tfilter;link_pRTM_GETTFILTER-RTM_BASE.doit = tc_ctl_tfilter;link_pRTM_GETTFILTER-RTM_BASE.dum
10、pit = tc_dump_tfilter;3.3. TC与netlink交互的数据格式Netlink数据头部+tc消息头部n Netlink头部struct msg_to_kernel /*自定义消息首部,它仅包含了netlink的消息首部*/ struct nlmsghdr hdr;struct nlmsghdr _u32 nlmsg_len; /* Length of message */ _u16 nlmsg_type; /* Message type*/ _u16 nlmsg_flags; /* Additional flags */ _u32 nlmsg_seq; /* Seque
11、nce number */ _u32 nlmsg_pid; /* Sending process PID */;n TC数据头部:struct tcmsg unsigned chartcm_family;unsigned chartcm_pad1;unsigned shorttcm_pad2;inttcm_ifindex;_u32tcm_handle;_u32tcm_parent;_u32tcm_info;4. TC规则4.1. 流量控制模型图表 6 流量控制实现模型4.2. 流量控制处理对象流量的处理由三种对象控制,它们是:qdisc(排队规则)、class(类别)和filter(过滤器)。
12、4.2.1. QdiscQDisc(排队规则)是queueing discipline的简写,它是理解流量控制(traffic control)的基础。无论何时,内核如果需要通过某个网络接口发送数据包,它都需要按照为这个接口配置的qdisc(排队规则)把数据包加入队列。然后,内核会尽可能多地从qdisc里面取出数据包,把它们交给网络适配器驱动模块。最简单的QDisc是pfifo它不对进入的数据包做任何的处理,数据包采用先入先出的方式通过队列。不过,它会保存网络接口一时无法处理的数据包。QDISC分为无类队列(CLASSLESS QDisc)和分类队列(CLASSFUL QDISC)类别。使用中
13、,无类队列只能作为叶子节点出现,而分类队列作为双亲节点出现,不能作为叶子节点出现。4.2.1.1. 无类队列a) Pfifo_fast默认参数,先进先出的队列,内核参照数据包的TOS标记,将数据包分为3个频道。如果在0频道有数据包等待发送,1频道的包就不会被处理,1频道和2频道之间的关系也是如此。n TOS字段说明:TOS字段的4个bit定义:二进制十进制意义10008最小延迟 (md) 01004最大throughput (mt) 00102最大可靠性 (mr) 00011最小成本 (mmc) 00000正常服务图表 7 TOS值与频道的对应b) TBF只允许以不超过事先设定的速率到来的数据
14、包通过,但可能允许短暂突发流量超过设定值。3种情景:1) 数据流以等于令牌流的速率到达TBF。这种情况下,每个到来的数据包都能对应一个令牌,然后无延迟地通过队列。2) 数据流以小于令牌流的速度到达TBF。通过队列的数据包只消耗了一部分令牌,剩下的令牌会在桶里积累下来,直到桶被装满。剩下的令牌可以在需要以高于令牌流速率发送数据流的时候消耗掉,这种情况下会发生突发传输。3) 数据流以大于令牌流的速率到达TBF。这意味着桶里的令牌很快就会被耗尽。导致TBF中断一段时间,称为“越限”。如果数据包持续到来,将发生丢包。n 参数选项: limit/latency:limit确定最多有多少数据(字节数)在队
15、列中等待可用令牌。你也可以通过设置latency参数来指定这个参数,latency参数确定了一个包在TBF中等待传输的最长等待时间。后者计算决定桶的大小、速率和峰值速率。 burst/buffer/maxburst:桶的大小,以字节计。这个参数指定了最多可以有多少个令牌能够即刻被使用。通常,管理的带宽越大,需要的缓冲器就越大。在Intel体系上,10兆bit/s的速率需要至少10k字节的缓冲区才能达到期望的速率。如果你的缓冲区太小,就会导致到达的令牌没有地方放(桶满了),这会导致潜在的丢包。 Mpu:一个零长度的包并不是不耗费带宽。比如以太网,数据帧不会小于64字节。Mpu(Minimum P
16、acket Unit,最小分组单位)决定了令牌的最低消耗。 Rate:速度操纵杆,参见上面的limits。 Peakrate:如果有可用的令牌,数据包一旦到来就会立刻被发送出去,就象光速一样。那可能并不是你希望的,特别是你有一个比较大的桶的时候。峰值速率可以用来指定令牌以多块的速度被删除。用书面语言来说,就是:释放一个数据包,但后等待足够的时间后再释放下一个。我们通过计算等待时间来控制峰值速率。然而,由于UNIX定时器的分辨率是10毫秒,如果平均包长10k bit,我们的峰值速率被限制在了1Mbps。 mtu/minburst:但是如果你的常规速率比较高,1Mbps的峰值速率对我们就没有什么价
17、值。要实现更高的峰值速率,可以在一个时钟周期内发送多个数据包。最有效的办法就是:再创建一个令牌桶!n 配置范例:# tc qdisc add dev ppp0 root tbf rate 220kbit latency 50ms burst 1540c) SFQSFQ(Stochastic Fairness Queueing,随机公平队列)是公平队列算法家族中的一个简单实现。它的精确性不如其它的方法,但是它在实现高度公平的同时,需要的计算量却很少。SFQ的关键词是“会话”(或称作“流”) ,主要针对一个TCP会话或者UDP流。流量被分成相当多数量的FIFO队列中,每个队列对应一个会话。数据按照
18、简单轮转的方式发送, 每个会话都按顺序得到发送机会。n 参数选项: Perturb:多少秒后重新配置一次散列算法。如果取消设置,散列算法将永远不会重新配置(不建议这样做)。10秒应该是一个合适的值。 Quantum:一个流至少要传输多少字节后才切换到下一个队列。却省设置为一个最大包的长度(MTU的大小)。不要设置这个数值低于MTU!n 配置范例:# tc qdisc add dev ppp0 root sfq perturb 10d) p|bfifo使用最简单的qdisc,纯粹的先进先出。只有一个参数:limit,用来设置队列的长度,pfifo是以数据包的个数为单位;bfifo是以字节数为单位
19、。n 参数选项 Limit:规定了队列的长度。对于bfifo用字节计,对于pfifo用包的个数计。缺省值就是网卡的txqueuelen个包那么长(参见pfifo_fast那一章),对于bfifo就是txqueuelen*mtu个字节。e) redred是Random Early Detection(随机早期探测)的简写。如果使用这种QDISC,当带宽的占用接近于规定的带宽时,系统会随机地丢弃一些数据包。它非常适合高带宽应用。为了使用RED,你必须确定三个参数:min、max和burst。Min设置了队列达到多少字节时开始进行丢包,Max是一个软上限,让算法尽量不要超过,burst设置了最多有多
20、少个数据包能够突发通过。4.2.1.2. 分类队列a) HTBHTB是Hierarchy Token Bucket的缩写。通过在实践基础上的改进,它实现了一个丰富的连接共享类别体系。使用HTB可以很容易地保证每个类别的带宽,虽然它也允许特定的类可以突破带宽上限,占用别的类的带宽。HTB可以通过TBF(Token Bucket Filter)实现带宽限制,也能够划分类别的优先级。n 参数选项 Rate:限速; Burst:令牌桶的大小; Ceil:上行限速,用于满带宽时对总带宽的占有比; Prio:配置优先级;b) CBQCBQ是Class Based Queueing(基于类别排队)的缩写。它
21、实现了一个丰富的连接共享类别结构,既有限制(shaping)带宽的能力,也具有带宽优先级管理的能力。带宽限制是通过计算连接的空闲时间完成的。空闲时间的计算标准是数据包离队事件的频率和下层连接(数据链路层)的带宽。n CBQ常规参数: Avpkt:平均包大小,以字节计。计算maxidle时需要,maxidle从maxburst得出。 Bandwidth:网卡的物理带宽,用来计算闲置时间。 Cell:一个数据包被发送出去的时间可以是基于包长度而阶梯增长的。一个800 字节的包和一个806字节的包可以认为耗费相同的时间。也就是说它设置时间粒度。通常设置为8,必须是2的整数次幂。 Maxburst:这
22、个参数的值决定了计算maxidle所使用的数据包的个数。在avgidle跌落到0之前,这么多的数据包可以突发传输出去。这个值越高,越能够容纳突发传输。你无法直接设置maxidle的值,必须通过这个参数来控制。 Minburst:如前所述,发生越限时CBQ会禁止发包。实现这个的理想方案是根据事先计算出的闲置时间进行延迟之后,发一个数据包。然而,UNIX的内核一般来说都有一个固定的调度周期(一般不大于10ms),所以最好是这样:禁止发包的时间稍长一些,然后突发性地传输minburst个数据包,而不是一个一个地传输。等待的时间叫做offtime。从大的时间尺度上说,minburst值越大,整形越精确
23、。但是,从毫秒级的时间尺度上说,就会有越多的突发传输。 Minidle:如果avgidle值降到0,也就是发生了越限,就需要等待,直到avgidle的值足够大才发送数据包。为避免因关闭链路太久而引起的以外突发传输,在avgidle的值太低的时候会被强制设置为minidle的值。参数minidle的值是以负微秒记的。所以10代表avgidle被限制在-10us上。 Mpu:最小包尺寸,因为即使是0长度的数据包,在以太网上也要生成封装成64字节的帧,而需要一定时间去传输。为了精确计算闲置时间,CBQ需要知道这个值。 Rate:期望中的传输速率n WRR(weighted round robin,加
24、权轮转)参数: Allot:当从外部请求一个CBQ发包的时候,它就会按照“priority”参数指定的顺序轮流尝试其内部的每一个类的队列规定。当轮到一个类发数据时,它只能发送一定量的数据。“allot”参数就是这个量的基值。更多细节请参照“weight”参数。 Prio:CBQ可以象PRIO设备那样工作。其中“prio”值较低的类只要有数据就必须先服务,其他类要延后处理。 Weight:“weight”参数控制WRR过程。每个类都轮流取得发包的机会。如果其中一个类要求的带宽显著地高于其他的类,就应该让它每次比其他的类发送更多的数据。CBQ会把一个类下面所有的weight值加起来后归一化,所以数
25、值可以任意定,只要保持比例合适就可以。人们常把“速率/10”作为参数的值来使用,实际工作得很好。归一化值后的值乘以“allot”参数后,决定了每次传输多少数据。n 决定链路的共享和借用的CBQ参数: Isolated/sharing:凡是使用“isolated”选项配置的类,就不会向其兄弟类出借带宽。如果你的链路上同时存在着竞争对手或者不友好的其它人,你就可以使用这个选项。选项“sharing”是“isolated”的反义选项。 bounded/borrow:一个类也可以用“bounded”选项配置,意味着它不会向其兄弟类借用带宽。选项“borrow”是“bounded”的反义选项。c) PR
26、IOPRIO QDisc不能限制带宽,因为属于不同类别的数据包是顺序离队的。使用PRIO QDisc可以很容易对流量进行优先级管理,只有属于高优先级类别的数据包全部发送完毕,才会发送属于低优先级类别的数据包。为了方便管理,需要使用iptables或者ipchains处理数据包的服务类型(Type Of Service,ToS)。n 参数选项 Bands:创建频道的数目,每个频道实际上就是一个类。 Priomap:如果你不给tc提供任何过滤器,PRIO队列规定将参考TC_PRIO的优先级来决定如何给数据包入队。4.2.2. Class某些QDisc(排队规则)可以包含一些类别,不同的类别中可以包
27、含更深入的QDisc(排队规则),通过这些细分的QDisc还可以为进入的队列的数据包排队。通过设置各种类别数据包的离队次序,QDisc可以为设置网络数据流量的优先级。4.2.3. FilterFilter(过滤器)用于为数据包分类,决定它们按照何种QDisc进入队列。无论何时数据包进入一个划分子类的类别中,都需要进行分类。分类的方法可以有多种,使用fileter(过滤器)就是其中之一。使用filter(过滤器)分类时,内核会调用附属于这个类(class)的所有过滤器,直到返回一个判决。如果没有判决返回,就作进一步的处理,而处理方式和QDISC有关。需要注意的是,filter(过滤器)是在QDi
28、sc内部,它们不能作为主体。过滤器在使用时结合具体的分类器使用:a) fw根据防火墙如何对这个数据包做标记进行判断,结合iptable工具进行使用。b) u32根据数据包中的各个字段进行判断,如源IP地址等等。c) route根据数据包将被哪条路由进行路由来判断。d) rsvp, rsvp6根据数据包的RSVP情况进行判断。只能用于你自己的网络,互联网并不遵守RSVP。e) tcindex用于DSMARK队列规定,参见相关章节。4.3. TC操作命令 tc qdisc add | change | replace | link dev DEV parent qdisc-id | root ha
29、ndle 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
30、-id tc -s | -d qdisc show dev DEV tc -s | -d class show dev DEV tc filter show dev DEVtc可以使用以下命令对QDisc、类和过滤器进行操作: add:在一个节点里加入一个QDisc、类或者过滤器。添加时,需要传递一个祖先作为参数,传递参数时既可以使用ID也可以直接传递设备的根。如果要建立一个QDisc或者过滤器,可以使用句柄(handle)来命名;如果要建立一个类,可以使用类识别符(classid)来命名。 Remove:删除有某个句柄(handle)指定的QDisc,根QDisc(root)也可以删除。被删
31、除QDisc上的所有子类以及附属于各个类的过滤器都会被自动删除。 Change:以替代的方式修改某些条目。除了句柄(handle)和祖先不能修改以外,change命令的语法和add命令相同。换句话说,change命令不能一定节点的位置。 Replace:对一个现有节点进行近于原子操作的删除添加。如果节点不存在,这个命令就会建立节点。 Link:只适用于DQisc,替代一个现有的节点。4.4. 流量控制建立步骤1) 针对网络物理设备(如以太网卡eth0)绑定一个队列QDisc;2) 在该队列上建立分类class;3) 为每一分类建立一个基于路由的过滤器filter;4) 最后与过滤器等相配合,建
32、立特定分类规则,如路由表(可选)。4.5. TC规则如何选择下列提示可以帮你决定使用哪一种队列: 如果想单纯地降低出口速率,使用令牌桶过滤器。调整桶的配置后可用于控制很高的带宽。 如果你的链路已经塞满了,而你想保证不会有某一个会话独占出口带宽,使用随机公平队列。 如果你有一个很大的骨干带宽,并且了解了相关技术后,可以考虑前向随机丢包(参见“高级”那一章)。 如果希望对入口流量进行“整形”(不是转发流量),可使用入口流量策略,注意,这不是真正的“整形”。 如果你正在转发数据包,在数据流出的网卡上应用TBF。除非你希望让数据包从多个网卡流出,也就是说入口网卡起决定性作用的时候,还是使用入口策略。
33、如果你并不希望进行流量整形,只是想看看你的网卡是否有比较高的负载而需要使用队列,使用pfifo队列(不是pfifo_fast)。它缺乏内部频道但是可以统计backlog。 最后,你可以进行所谓的“社交整形”。你不能通过技术手段解决一切问题。用户的经验技巧永远是不友善的。正确而友好的措辞可能帮助你的正确地分配带宽!5. 实例分析5.1. HTB实例分析5.1.1. 实例要求图表 8 虚拟机网络环境为了实现虚拟机环境中通过网桥bridge实现对虚拟网卡vif之间的流量控制,我们选择分别在各自的vif*上建立QoS的egress策略,实现数据的限速与分流。流量控制需要:1) 发往vif1.0设备的网
34、络流量带宽控制在6Mbit,最大缓冲15K;2) 发往vif1.0设备,目的端口为80的网络数据包,网络流量带宽控制在5Mbit,缓冲控制在15K;3) 发往vif1.0设备,源端口为25的网络数据包,网络流量带宽控制在3Mbit,缓冲控制在15K;4) 发往vif1.0设备的其余数据包,网络流量带宽控制在1Mbit,缓冲控制在15K;5.1.2. HTB策略配置#tc qdisc add dev vif1.0 root handle 1: htb default 30#tc class add dev vif1.0 parent 1: classid 1:1 htb rate 6mbit b
35、urst 15k#tc class add dev vif1.0 parent 1:1 classid 1:10 htb rate 5mbit burst 15k#tc class add dev vif1.0 parent 1:1 classid 1:20 htb rate 3mbit ceil 6mbit burst 15k#tc class add dev vif1.0 parent 1:1 classid 1:30 htb rate 1mbit ceil 6mbit burst 15k#在叶子节点中使用sfq规则:#tc qdisc add dev eth0 parent 1:10 h
36、andle 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: sfq perturb 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 flo
37、wid 1:205.1.3. 逻辑图Root qdisc1:0|Root class 1:1 / | / | / | Leaf class 10: leaf class 20: leaf class 30:5.2. CBQ实例分析5.2.1. 实例要求流量控制器上的以太网卡(eth0) 的IP地址为192.168.1.66,在其上建立一个CBQ队列。假设包的平均大小为1000字节,包间隔发送单元的大小为8字节,可接收冲突的发送最长包数目为20字节。假如有三种类型的流量需要控制:1) 发往主机1的,其IP地址为192.168.1.24。其流量带宽控制在8Mbit,优先级为2;2) 发往主机2的,
38、其IP地址为192.168.1.30。其流量带宽控制在1Mbit,优先级为1;3) 发往子网1的,其子网号为192.168.1.0,子网掩码为255.255.255.0。流量带宽控制在1Mbit,优先级为6。5.2.2. 建立跟队列tc qdisc add dev eth0 root handle 1: cbq bandwidth 100Mbit avpkt 1000 cell 8 mpu 64将一个cbq队列绑定到网络物理设备eth0上,其编号为1:0;网络物理设备eth0的实际带宽为100 Mbit,包的平均大小为1000字节;包间隔发送单元的大小为8字节,最小传输包大小为64字节。5.2
39、.3. 建立分类分类建立在队列之上。一般情况下,针对一个队列需建立一个根分类,然后再在其上建立子分类。对于分类,按其分类的编号顺序起作用,编号小的优先;一旦符合某个分类匹配规则,通过该分类发送数据包,则其后的分类不再起作用。1) 创建根分类1:1;分配带宽为10Mbit,优先级别为8。tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 100Mbit rate 10Mbit maxburst 20 allot 1514 prio 8 avpkt 1000 cell 8 weight 1Mbit该队列的最大可用带宽为100Mbit
40、,实际分配的带宽为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 100Mbit rate 8Mbit maxburst 20 allot 1514 prio 2 avpkt 1000 cell 8 weight 800Kbit split 1:0
41、bounded该队列的最大可用带宽为100Mbit,实际分配的带宽为 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 100Mbit rate 1Mbit maxburst 20 allot 1514
42、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 100Mbit rate
43、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。5.2.4. 建立过滤器过滤器主要服务于分类。一般只需针对根分类提供一个过滤器,然后为每个子分类提供路由映射。tc filter add dev eth0 par
44、ent 1:0 protocol ip prio 100 route1) 应用路由分类器到cbq队列的根,父分类编号为1:0;过滤协议为ip,优先级别为100,过滤器为基于路由表。tc filter add dev eth0 parent 1:0 protocol ip prio 100 route to 2 flowid 1:2tc filter add dev eth0 parent 1:0 protocol ip prio 100 route to 3 flowid 1:3tc filter add dev eth0 parent 1:0 protocol ip prio 100 rou
45、te to 4 flowid 1:42) 建立路由映射分类1:2, 1:3, 1:45.2.5. 建立路由该路由是与前面所建立的路由映射一一对应。ip route add 192.168.1.24 dev eth0 via 192.168.1.66 realm 21) 发往主机192.168.1.24的数据包通过分类2转发(分类2的速率8Mbit)ip route add 192.168.1.30 dev eth0 via 192.168.1.66 realm 32) 发往主机192.168.1.30的数据包通过分类3转发(分类3的速率1Mbit)ip route add 192.168.1.
46、0/24 dev eth0 via 192.168.1.66 realm 43)发往子网192.168.1.0/24的数据包通过分类4转发(分类4的速率1Mbit)注:一般对于流量控制器所直接连接的网段建议使用IP主机地址流量控制限制,不要使用子网流量控制限制。如一定需要对直连子网使用子网流量控制限制,则在建立该子网的路由映射前,需将原先由系统建立的路由删除,才可完成相应步骤。5.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 rate 20kbit buffer 1600 limit 3000# tc qdisc add dev eth0 parent 1:3 handle 30: sfq6. 遗留问题:1) Ingress策略应该如何配置? 2) Ingress策略中如何实现U32和FW的分类? 3) QoS与ACL之间的关系? 4) 交换机中实现的QoS机制与内核中QoS之间的关系? 22