我自己分析内核tc的一点心得(5)

2020-05-28 00:00:00 队列 子类 路由 分类 规程

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流是怎么回事,半桶水^_^


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分类器协作

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 


文章来源CU社区: 我自己分析内核tc的一点心得


相关文章