免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: qtdszws
打印 上一主题 下一主题

我自己分析内核tc的一点心得 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2006-12-14 15:07 |只看该作者
关于sch_ingress.c

http://bbs.chinaunix.net/viewthr ... p;highlight=qtdszws

使用ingress的内核处理流程
tc qdisc add dev eth0 handle ffff: ingress
tc filter add dev eth0 parent ffff: pref 10 protocol ip u32

1.init_module->nf_register_hook
注册ingress的钩子到
static struct nf_hook_ops ing_ops =
{
        { NULL, NULL},
        ing_hook,
        PF_INET,// 2
        NF_IP_PRE_ROUTING,//注册到PRE_ROUTING
        NF_IP_PRI_FILTER + 1
};

2.网卡接收到一个ip数据包后调用ip_input.c中的ip_rcv
NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL,ip_rcv_finish)
NF_HOOK定义如下
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn)                        \
(list_empty(&nf_hooks[(pf)][(hook)])                                        \
? (okfn)(skb)                                                                \
: nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn)))
因此将调用nf_hook_slow,在core/netfilter.c中
nf_hook_slow->nf_iterate-> hook-> ing_hook(ingress的钩子函数)-> ingress_enqueue(入队)-> tc_classify(分类)

3.根据分类结果决定继续处理该包,还是丢弃(例如被管制器管制)

论坛徽章:
0
12 [报告]
发表于 2006-12-14 16:02 |只看该作者
sch_teql.c

teql原理

1.在Linux的高级路由和流量控制HOWTO.pdf有一些说明,可以参照

2.teql实现了一个简单的多网卡负载均衡.简单,是因为它不考虑实际的硬件情况,只是在关联的实际设备之间轮转转发包,即使是一个千兆网卡和MODEM被关联在一起.可以称做发包数负载均衡吧.

3.insmod sch_teql.o时, init_module会注册一个名为teql0的虚网络接口和一个名为teql0的队列规程,他们被集成在struct teql_master结构中,彼此分不开.
可以使用一下命令绑定实设备到队列规程teql0
tc qdisc add dev eth0 root teql0
tc qdisc add dev eth1 root teql0
然后用命令ip link set dev teql0 up激活虚设备teql0
这样一个teql设备就配置完成了
接下来可以再配置另一个teql设备
insmod –o sch_teql1 sch_teql.o
我这是RED HAT 7.2,由于已经加载了sch_teql.o模块,只能重命名加载了.
新版本内核已经实现一次insmod就可指定若干个teql
tc qdisc add dev eth2 root teql1
tc qdisc add dev eth3 root teql1
ip link set dev teql1 up

4.当有数据包到达teql0时先进入自己的队列,缺省为pfifo_fast,然后内核就调用teql_master_xmit来在从设备中循环轮转选择一个设备eth*发包.如果teql*是该实设备的根队列规程,就直接调用eth*的hard_start_xmit函数发包.如果不是就选择下一个设备,只至成功或失败.而配置在该设备上的teql*规程,它的行为就类似于pfifo规程.这是给那些直接通过该设备发送的包准备的规程.

teql.rar

11.78 KB, 下载次数: 48

论坛徽章:
0
13 [报告]
发表于 2006-12-14 18:03 |只看该作者
sch_red.c random early detection
随机早期探测

参考http://www.icir.org/floyd/papers/red/red.html 中的early.pdf

说明
1.qlen 为当前队列长度
2.qave 平均队列长度,它的计算公式是qave=qave*(1-W)+qlen*W,W为权重,W一般选得很小 ,这可以使突发包对qave不会产生太大波动
3.qmin,qmax 当qmin<=qave<=qmax时,开始随机标记/丢包,标记/丢包的概率为
max_P * (qave- qmin)/(qmax-qmin),,随着qave增长,概率逼近max_P
标记包是希望客户端知道目前网络已经开始拥挤,放慢发包速度吧
如果qave>=qmax,标记/丢弃所有的包
4.如果网络空闲了一段时间,就应该相应地减少qave的大小,qave=qave*(1-W)^m,m为空闲时间段长度

sch_red.rar

5.52 KB, 下载次数: 71

论坛徽章:
0
14 [报告]
发表于 2006-12-15 09:30 |只看该作者
路由分类器cls_route.c
路由分类器的原理很简单,就是在路由的时候由路由规则对数据包打标记.路由分类器就用这个标记来对数据包分类.
路由规则语法如下
ip route add Host/Network via Gateway dev Device realm RealmNumber

ip route add 192.168.10.0/24 via 192.168.10.1 dev eth1 realm 10
至于如何打标记,我现在还不了解
在设置了路由规则以后,就可以使用路由分类器分类数据了
tc filter add dev eth0 protocol ip prio 100 route to 10 classid :2
tc filter add dev eth0 protocol ip prio 100 route from 10 classid :1
路由分类器参考的参数有fromdev/from,to,fromdev和from互斥,只能使用其中一个,由他们在分类器的二层hash表中索引和查找.

资源预留协议分类器cls_rsvp.h
资源预留协议分类器的原理也很简单,就是用ip协议(也支持ipv6,此处不涉及)的目的地址,可能的目的端口,源地址,可能的源端口来索引和查找一个二层hash表.
"可能的"意思是不一定使用,由用户决定.也就是它是基于session(会话)的.
tc filter add dev eth0 pref 10 protocol ip rsvp ipproto tcp session 10.1.1.1/80 classid :1
这条规则的意思就是,到10.1.1.1:80的数据流分类到:1的队列
还可以加入sender,指定发送者,或者不指定端口,而指定一个GPI,也就是在offset处的值&mask==key方式更加灵活地指定一个匹配.

route_rsvp.rar

22.54 KB, 下载次数: 46

论坛徽章:
0
15 [报告]
发表于 2006-12-15 10:11 |只看该作者
sch_dsmark.c和cls_tcindex.c

diffserv是一个体系,需要一个有若干个路由和一定规模的网络来协作实现,就单个主机来说用处不大.在这个网络中,大家都遵守同样的diffserv协定,例如哪个dsfield的优先级高,哪个低,以及怎样处理等.

这里引入了域的概念,就是遵守某一diffserv协定的网络组成一个ds域.剩下的就是非ds域.一台域中的主机要发的包,可以在自己的出口队列分类,或在接入的路由上分类.
1.在本机分类,出口绑定dsmark队列规程和u32等分类器
2.在路由分类,路由入口绑定ingress队列规程和u32等分类器
注:上面的分类器一般不用tcindex分类器,因为是从非ds域到ds域的转换,而tcindex实用于使用已有ds field来分类流(见3)和不同ds域之间的转换,不同域之间的转换一般发生在入口上,例如上面的2,如果数据是从另外一个ds域来的话.
这样所有的流就被区分开了.
3.然后路由器就可以在自己的出口绑定dsmark队列规程(和一些内部队列,例如cbq)和tcindex分类器,让tcidnex分类来对不同级别的流(只根据ds field)进行整形和qos.

上面都是我的理解,化了我很长时间,不对之处,请大家指正.大家参考lartc上的说明.
下面的例子也是摘之lartc
tc qdisc add dev eth0 handle 1:0 root dsmark indices 64 set_tc_index#绑定dsmark队列规程
tc filter add dev eth0 parent 1:0 protocol ip prio 1 tcindex mask 0xfc shift 2#建立tcindex分类器
tc qdisc add dev eth0 parent 1:0 handle 2:0 cbq bandwidth 10Mbit cell 8 avpkt 1000 mpu 64 # EF traffic class内部队列
tc class add dev eth0 parent 2:0 classid 2:1 cbq bandwidth 10Mbit rate 1500Kbit avpkt 1000 prio 1 bounded isolated allot 1514 weight 1 maxburst 10 # Packet fifo qdisc for EF traffic子类
tc qdisc add dev eth0 parent 2:1 pfifo limit 5 #子类的队列规程
tc filter add dev eth0 parent 1:0 protocol ip prio 1 handle 0x2e tcindex classid 2:1 pass_on #例子中是parent 2:0,我认为是parent 1:0,把EF流分类到2:1子类,不懂EF流是怎么回事,半桶水^_^

dsmark_tcindex.rar

13.08 KB, 下载次数: 42

论坛徽章:
0
16 [报告]
发表于 2006-12-15 10:48 |只看该作者
sch_gred.c  Generic Random Early Detection

这个算法是在red的基础上扩展引入virtual queue的概念形成的.
在gred中最多可以引入16个vq,其中至少有一个缺省vq.
每个vq都基本按red算法来操作(有区别),但所有的这些vq都公用一个实际的队列
sch->q.

gred算法有四种模式,由参数eqp和grio控制(不知道是什么的缩写)
(注意是否开始随机丢包由qave+q->qave<q->qth_min控制)
eqp   grio
0     0  每个vq一个独立red (qave=0),但共享一个实队列
0     1  每个vq和比它优先级高的vq构成一个部分相关red,保证优先级高的vq优先发包
qave+q->qave的值是按照相关的每个vq自己计算的ave的总和
1     0  每个vq一个部分相关red,和sch->backlog相关 (qave=0)
q->qave的值是把sch->backlog按本vq的方式计算ave的值
1     1  每个vq一个全部相关red (qave=0)
q->qave的值是把sch->backlog按本vq的方式计算ave的累计总和

我认为比较有用的是(0,0)(有点类似于sfq)和(0,1)(有点类似于prio)
gred实际上和red一样都比较难配置,主要应用于路由器上
因为它是采用skb->tc_index来选择vq的,可以和dsmark规程和tcindex分类器协作

gred.rar

5.28 KB, 下载次数: 42

论坛徽章:
0
17 [报告]
发表于 2006-12-15 12:56 |只看该作者
楼主能不能整理一个all in one的包?

谢谢!

论坛徽章:
0
18 [报告]
发表于 2006-12-15 14:32 |只看该作者
不好意思,我也是一点点的分析的,不可能一下子给出所有的学习结果,等我把csz和cbq等看完后,会给出总结和all in one的包.

论坛徽章:
0
19 [报告]
发表于 2006-12-16 11:52 |只看该作者
estimator.c和police.c

--------------------------------------------------------------
estimator用于估计包的速度,包括bps(每秒字节数)和pps(每秒包数).
estimator的调用独立于qos架构,每个estimator一个内核定时器,可以每1/4s,1/2s,1s,2s,4s,8s被调用一次,定时计算

它可以应用在队列规程上和分类器上.
1.在队列规程上,它把计算结果放在qdisc->stats中,到目前为止我还没有看到谁在使用这个结果,不过这可以让用户监视和评估该规程上的流量
2.在分类器上,在分类器的每个策略中都有一个tcf_police结构,估计结果就放入该结构的stats成员中.在策略被命中后,将调用tcf_police,如果使用了估计器,tc_police就根据估计结果决定通过该策略的数据流量是否超限,是的话就执行规定的动作,ok,drop,reclassify,unspec.

Usage: ... estimator INTERVAL TIME-CONST
interval为定时间隔,time-const的计算方法是w=interval/time-const,w为加权比,例est 1s 8s,则定时间隔为1s,w=1/8=0.125

------------------------------------------------------------------
police用于分类器上,前面已经提到,策略被命中就会调用tcf_police,对通过该策略数据的进行管制

除了使用可选的estimator的结果进行管制以外,police主要使用tbf(令牌桶过滤器)对流进行管制操作.tbf的理论在前面已经叙述过了.tbf使用常规桶和峰值桶来控制流量.对于超限的包执行规定的动作.

Usage: ... police rate BPS burst BYTES[/BYTES] [ mtu BYTES[/BYTES] ]  
                [ peakrate BPS ] [ avrate BPS ]                       
                [ ACTION ]                                            
Where: ACTION := reclassify | drop | continue
avrate用于estimator,判断流量是否超限
lartc上有一个"防护SYN洪水攻击例子"用到police
iptables -A PREROUTING -i $INDEV -t mangle -p tcp --syn -j MARK --set-mark 1
$TC qdisc add dev $INDEV handle ffff: ingress
$TC filter add dev $INDEV parent ffff: protocol ip prio 50 handle 1 fw
police rate 1kbit burst 40 mtu 9k drop flowid :1

论坛徽章:
0
20 [报告]
发表于 2006-12-17 23:23 |只看该作者
GOOD
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP