TC流速流量控制分析 - 图文

2026/1/26 23:38:02

本文档的Copyleft归wwwlkk所有,使用GPL发布,可以自由拷贝、转载,转载时请保持文档的完整性,严禁用于任何商业用途。

E-mail: wwwlkk@126.com

来源: http://passport.http://m.china-audit.com//?business&aid=6&un=wwwlkk#7

TC流量控制初步分析

(一)基本概念 ........................................................................................................................................... 1 (二)运行出口流控对象 ........................................................................................................................... 2 (三)流控对象的具体实现 ....................................................................................................................... 3 (3.1)建立一个根流控对象 ................................................................................................................ 3 (3.2)建立一个子流控对象 ................................................................................................................ 6 (3.3)添加一个过滤器 ........................................................................................................................ 8 (3.4)流控类和过滤器类型的的组织 .............................................................................................. 10 (3.5)入口流控对象 .......................................................................................................................... 11 (四)用户空间如何和内核通信 ............................................................................................................. 12

(一)基本概念

为了更好的描述TC流量控制,先明确一些概念。 流控对象:队列规定。

无类流控对象:无类队列规定。 分类流控对象:分类的队列规定。

每个分类流控对象都有默认的子流控对象,默认的子流控对象必定是无类流控对象。 子流控对象:分类流控对象中包含的流控对象。

无类流控对象必定包含一个或者多个的数据包队列,用于存储数据包。 无类和分类流控对象都有默认的分类规定,也可以使用过滤器增加分类规则。

分类流控对象是流控对象的容器(包含无类和分类),无类流控对象是数据包的容器。(注意:一些复杂的流控对象可同时作为流控对象和数据包的容器,比如分层的令牌桶)

数据包进入一个分类流控对象,分类流控对象将根据分类规则(默认的或者过滤器),决定将数据包送到某个子流控对象。

数据包进入一个无类流控对象,无类流控对象将根据分类规则(默认的或者过滤器),决定将数据包加入到某个数据包队列。

分类流控对象出队操作:分类流控对象将根据出队规则(固定的),选择一个子流控对象,并执行子流控对象的出队操作。

无类流控对象出队操作:无类流控对象将根据出队规则(固定的),选择一个数据包出队。 每块网卡都有一个出口根流控对象。每个流控对象都指定一个句柄,以便以后的配置语句能够引用这个流控对象。除了出口流控对象之外,每块网卡还有一个入口流控对象,入口流控对象的类型是固定的(是ingress类型)。

运行流控对象:都是指运行出口流控对象,也就是根据出口流控对象的出队规则(固定的),发送流

TC流量控制初步分析 3/26/2013

1 /14

控对象中的所有数据包。

流控对象为空:流控对象中没有数据包。

入口流控对象没有真正意义上的出队和入队操作,只是根据过滤规则来决定是否丢弃数据包,流控的实现主要在出口流控对象,下面先分析出口流控的实现。

(二)运行出口流控对象

数据到达出口流控时,上层的所有处理已经完成,数据包已经可以交到网卡设备进行发送,在数据交到网卡设备发送前将会进入出口流控,进入出口流控的函数为dev_queue_xmit(); 如果是入口流控, 数据只是刚从网卡设备中收到, 还未交到网络上层处理, 不过网卡的入口流控不是必须的, 缺省情况下并不进行流控,进入入口流控函数为ing_filter()函数,该函数被skb_receive_skb()调用。

dev_queue_xmit中进入出口流控对象的函数段如下:

txq = dev_pick_tx(dev, skb);//获取出口流控的控制结构

q = rcu_dereference(txq->qdisc);//获取出口流控的根流控对象 if (q->enqueue) { rc = __dev_xmit_skb(skb, q, dev, txq);//使用流控对象发送数据包(包含入队和出队) goto out; }

__dev_xmit_skb函数主要做两件事情:

1. 如果流控对象为空的,试图直接发送数据包。

2. 如果流控对象不空,将数据包加入流控对象,并运行流控对象。

调用qdisc_run()将会运行一个流控对象,有两个时机将会调用qdisc_run(): 1.__dev_xmit_skb()

2. 软中断服务线程NET_TX_SOFTIRQ

软中断线程NET_TX_SOFTIRQ中将会运行的流控对象组织如下:

图1 软中断中的流控对象组织

static inline void qdisc_run(struct Qdisc *q)

TC流量控制初步分析 3/26/2013

2 /14

{ }

if (!test_and_set_bit(__QDISC_STATE_RUNNING, &q->state))//测试是否有其他例程正在运行本对象 __qdisc_run(q);

__QDISC_STATE_RUNNING标志用于保证一个流控对象不会同时被多个例程运行。

软中断线程的动作:运行加入到output_queue链表中的所有流控对象,如果试图运行某个流控对象时,发现已经有其他内核路径在运行这个对象,直接返回,并试图运行下一个流控对象。

void __qdisc_run(struct Qdisc *q)//运行流控对象q { unsigned long start_time = jiffies; while (qdisc_restart(q)) {//返回值大于0,说明流控对象非空。 /* * Postpone processing if * 1. another process needs the CPU; * 2. we've been doing it for too long. */ if (need_resched() || jiffies != start_time) {//已经不允许继续运行本流控对象。 __netif_schedule(q);//将本队列加入软中断的output_queue链表中。 break; } } clear_bit(__QDISC_STATE_RUNNING, &q->state); }

如果发现本队列运行的时间太长了,将会停止队列的运行,并将队列加入output_queue链表头。

1. 2. 3.

4. 5.

现在数据包的发送流程可以总结如下:(流控对象为空表示对象中没有数据包)

调用dev_queue_xmit()发送一个数据包,如果出口流控对象为空,试图直接发送数据包。 如果出口流控对象非空,数据包加入出口流控对象。

调用qdisc_run(struct Qdisc *q)运行出口流控对象,也就是,调用对象对象的出队函数选择一个数据包,并发送这个数据包,如果时间允许就循环执行这个过程,直到流控对象为空。注意:如果已经有其他内核路径正在运行队列,函数将不做任何事情,并提前返回。

本流控对象运行时间太长了,停止本对象运行,并且将本流控对象加入软中断服务NET_TX_SOFTIRQ的output_queue链表头。

当执行软中断服务线程NET_TX_SOFTIRQ时,将从output_queue链表头开始顺序运行链表中的所有流控对象。

(三)流控对象的具体实现

(3.1)建立一个根流控对象

下面使用具体的例子来说明流控对象的具体实现 首先使用如下命令在eth0建立一个根流控对象。 #tc qdisc add dev eth0 root handle 22 prio bands 4

TC流量控制初步分析 3/26/2013

3 /14

其中流控对象的类型是”prio”,对象句柄是22,对象使用4个带(也就是包含4个子流控对象,默认的子流控对象类型是”pfifo”,出队时第一个子流控对象的优先级最高)

则内核中建立的流控对象如图2,3所示:

图2 建立”prio”类型的根流控对象_1

TC流量控制初步分析 3/26/2013 4 /14


TC流速流量控制分析 - 图文.doc 将本文的Word文档下载到电脑
搜索更多关于: TC流速流量控制分析 - 图文 的文档
相关推荐
相关阅读
× 游客快捷下载通道(下载后可以自由复制和排版)

下载本文档需要支付 10

支付方式:

开通VIP包月会员 特价:29元/月

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信:xuecool-com QQ:370150219