预览加载中,请您耐心等待几秒...
1/10
2/10
3/10
4/10
5/10
6/10
7/10
8/10
9/10
10/10

亲,该文档总共22页,到这已经超出免费预览范围,如果喜欢就直接下载吧~

如果您无法下载资料,请参考说明:

1、部分资料下载需要金币,请确保您的账户上有足够的金币

2、已购买过的文档,再次下载不重复扣费

3、资料包下载后请先用软件解压,在使用对应软件打开

22Linux内核QoS实现机制QoS介绍QoS(QualityofService)即服务质量。对于网络业务,服务质量包括传输的带宽、传送的时延、数据的丢包率等。在网络中可以通过保证传输的带宽、降低传送的时延、降低数据的丢包率以及时延抖动等措施来提高服务质量。网络资源总是有限的,只要存在抢夺网络资源的情况,就会出现服务质量的要求。服务质量是相对网络业务而言的,在保证某类业务的服务质量的同时,可能就是在损害其它业务的服务质量。例如,在网络总带宽固定的情况下,如果某类业务占用的带宽越多,那么其他业务能使用的带宽就越少,可能会影响其他业务的使用。因此,网络管理者需要根据各种业务的特点来对网络资源进行合理的规划和分配,从而使网络资源得到高效利用。流量控制包括以下几种方式:SHAPING(限制)当流量被限制,它的传输速率就被控制在某个值以下。限制值可以大大小于有效带宽,这样可以平滑突发数据流量,使网络更为稳定。shaping(限制)只适用于向外的流量。SCHEDULING(调度)通过调度数据包的传输,可以在带宽范围内,按照优先级分配带宽。SCHEDULING(调度)也只适于向外的流量。POLICING(策略)SHAPING用于处理向外的流量,而POLICIING(策略)用于处理接收到的数据。DROPPING(丢弃)如果流量超过某个设定的带宽,就丢弃数据包,不管是向内还是向外。内核实现过程图表1流量控制过程绿色部分就是Linux内核实现的QoS模块,其中ingresspolicing是处理输入数据包的,而outputqueueing则是处理输出数据包的。Ingress实现机制IngressQOS在内核的入口点有两个,但是不能同时启用,这取决于内核编译选项。当打开了CONFIG_NET_CLS_ACT(from2.6.8releasestillavailableon2.6.39release)时,入口点在src/net/core/dev.c的netif_receive_skb函数中;当没有打开CONFIG_NET_CLS_ACT,而是打开了CONFIG_NET_CLS_POLICE(from2.6.9releaseto2.6.24,thusthisisanobsoleteconfiguration)和CONFIG_NETFILTER时,就会在netfilter的PREROUTING钩子点处调用ing_hook函数。图表2ingress策略实现当filter中有规则时,遍历规则表,寻找与skb->mark(由ebtables或iptables来配置)相匹配的表项,如果找到了则会进一步调用tcf_exts_exec函数对扩展的action进行处理。图表3FW分类器实现过程Egress实现机制系统在注册网络设备时会在register_netdevice函数中调用dev_init_scheduler函数注册一个qdisc的接口,它是一个特殊的qdisc,不做任何处理。当创建好设备,用ifconfigup命令把设备拉起后,会调用到内核的src/net/core/dev.c中的dev_open函数,在dev_open函数中又会调用到src/net/sched/sch_generic.c中的dev_activate函数,给设备配置默认的rootqdisc处理机制:pfifo_fast。图表4以prioqdisc为例的egress初始化过程出口队列调度的入口点在src/net/core/dev.c的dev_queue_xmit函数中,通过q=rcu_dereference(dev->qdisc)可以获取到设备上rootqdisc的指针q(structQdisc*)。在下面的处理过程中并没有判断q是否为NULL,这就说明设备上一定会存在egressqdisc,这一点和ingress是不同的,一个设备上可以没有ingressqdisc,即dev->qdisc_ingress指针一般是NULL,除非通过tcqdisc命令配置了ingressqdisc。图表5以htb+pfifoqdisc为例的egress处理流程内核与TC的交互交互方式Netlink内核处理接口Qdisc和class交互接口tcqdisc和tcclsss配置命令对应的配置函数在src/net/sched/sch_api.c的pktsched_init函数中进行了初始化注册,由subsys_initcall函数对系统进行申明,该函数在linux系统初始化的时候会被调用到。代码片断如下:if(link_p){link_p[RTM_NEWQDISC-RTM_BASE].doit=tc_modify_qdisc;link_p[RTM_DELQDISC-RTM_BASE].doit=tc_get_qdis