计算机 · 2021年12月14日 0

Linux tc命令

因为工作中测试TCP拥塞控制算法的需要而接触了tc命令,因此系统学习一下关于这个命令的东西。
关于tc的比较权威的资料:

基本概念

qdisc

如manual中所说,每个网口都有一个root qdisc,用来控制如何发包到外面的网络上去。qidscqueueing discipline的缩写,每个网口都有一个队列,内核要发包时先把包放到这个队列里面,然后再从队列里取出包进行发送,这个队列以及入队出队的规则合在一起就是qdisc的职责所在了。

class

qdisc内部可以不是一个队列,而是多个class,每个class包含了一个leaf qdisc,包进入qdisc的时候被分配到其中的一个class也就是进入到这个class连着的leaf qdisc。然后这个leaf qdisc可以继续套娃,内部继续分成多个class。这样就形成了一颗树。

filter

filter用来决定包进入qdisc内部的哪一个class

tc命令可以实现哪些网络流量控制功能

  • SHAPING
    可以理解为速率控制,流量平滑这类功能。
  • SCHEDULING 可以理解为能够同时照顾传输文件和交互应用的网络需求,其实就是根据流量的不同需求按照不同的策略进行发送。
  • POLICING
    处理入口流量。
  • DROPPING 设置丢包,出口入口都可以。

实用例子

通过tc设置对网卡入口流量进行整形

有两种方案:

1.traffic policing

通过对ingress这个特殊的qdisc应用filter进行整形,不过这种方法不能实现模拟延时;
tc-police的manual种,有一个通过filter对入口流量进行限速的例子:

tc qdisc add dev eth0 handle ffff: ingress
tc filter add dev eth0 parent ffff: u32 \
   match u32 0 0 \
   police rate 1mbit burst 100k

这个方法的另一个缺点是在Android上得不到支持,至少在小米5上的实验结果是不行的。

2.traffic shaping

把入口流量导入到ifb0(也可以是ifb1,ifb2,总之看自己要对多少个网口的入口流量进行整形了),然后再对ifb0的出口流量进行一般的整形;具体可以看StackOverflow上的这个问答,在小米5测试机上亲测有效。对ingress和ifb的一个介绍。

关键命令:

# 加载内核模块
modprobe ifb numifbs=1

# 启用虚拟设备ifb0
ip link set dev ifb0 up # repeat for ifb1, ifb2, ...

# 将入口流量导入到ifb0
tc qdisc add dev eth0 handle ffff: ingress
tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0

# 现在可以对ifb0应用tc命令对入口流量进行整形了

参考文档

别人的TC学习总结