Linux下使用TC模拟网络延迟/带宽

8 篇文章 0 订阅

TC

Traffic Control.
tc被用来在linux内核中进行流量控制。
tc使用三类对象对流量进行过滤、分组、排队,分别是filterclassqdisc.

TC的语法较为复杂,已有的教程大多仅限于netem这个classless qdisc,无法更深入的对流量进行控制。我看了很多文档才大概明白怎么使用,下面简单介绍一些基础知识和我用到的一些操作,详细内容见参考部分的链接。

handle

qdisc和filter用handle选项命名,class用classid选项命名。

major:minor

  1. 一般major从1开始,和qdisc有关;而minor只与class有关,只要唯一可以任意命名。(ffff:0保留给ingress qdisc
  2. class的minor必须大于0,qdisc的minor必须为0(qdisc也可以省略minor,默认为0)。
  3. 同属一个qdisc的class拥有相同的major。

tc通过这种命名方式形成一棵的结构。

qdisc

root/egress qdisc: 功能强大,主要使用这个。
ingress qdisc: 功能有限,只有policer。

每个interface都有一个默认的qdisc,pfifo_fast,可以替换。

qdisc可以分为两类,分别是classless qdiscclassful qdisc

classless qdisc

不能包含class。比如netem

可以参考这里:http://tldp.org/HOWTO/Traffic-Control-HOWTO/classless-qdiscs.html

FIFO, First-In First-Out (pfifo and bfifo)

简单的先进先出队列,不做其他任何操作。
需要指定队列的size,pfifobfifo分别以packet和byte作为size的单位。

SFQ, Stochastic Fair Queuing

随机公平队列。
由多个FIFO组成,通过哈希函数将packet送入不同的FIFO。
为了保证哈希函数的选取的公平性,通过perturb参数周期性的改变哈希函数。

netem

网上大多都是关于netem的资料,这里简单介绍一下。
netem是对tc的增强,可以增加延时、丢包等。

# set latency: 100ms
sudo tc qdisc add dev eth0 root netem delay 100ms

也可以增加一些latency的波动,设置丢包率等,这里不再介绍。

classful qdisc

可以包含class,继而通过filter对流量进行细分。比如HTBCBQ

HTB

参考这里:http://tldp.org/HOWTO/Traffic-Control-HOWTO/classful-qdiscs.html#qc-htb

大概就是基于令牌控制traffic rate,child可以向parent借用令牌,暂时的超出自己的rate。
下面是一些参数:

  • default: 指定minor-id, 将没有被分类的traffic放到default指定的class。默认是0不经过任何class交给发给网卡。
  • rate:期望的最小速率
  • ceil:期望的最大速率(通过借用令牌)
  • burst: size
  • cburst:size
  • prio:越小优先级越高

class

每一个class都有一个默认的qdisc,FIFO。可以替换成其它的qdisc。
class上可以挂载多个class,或者挂载一个qdisc。
leaf class挂载一个qdisc,不能再挂载class。

注意qdisc只能挂载同类的class。

filter

filter可以挂载到classful qdisc或者class。

u32是可以逐字节进行比较、过滤的一个过滤器,非常强大,需要使用者熟悉各种协议的格式。

u32

参考:http://linux-tc-notes.sourceforge.net/tc/doc/cls_u32.txt

以下面这个例子说明语法:

tc filter add dev eth0 parent 999:0 protocol ip prio 99 u32 \
    classid 1:1 \
	match u32 0xc0a80800 0xffffff00 at 12

第一行不再说明,所有的filter都差不多。
第二行指定如果traffic匹配该过滤器,就将traffic送入 1:1标识的class。
第三行是匹配的语法,分别是字节的长度valuebitmaskoffset,上面的意思就是:从IP packet从0偏移12个字节开始,取32个bit,将这32个bit与掩码0xffffff00进行异或,若果结果等于value0xc0a80800,那么该packet就匹配成功。

由于需要知道各个字段的偏移才能使用这个过滤器,较为麻烦,u32提供了一些语法糖,但最终还是转换为上面的匹配方式进行过滤。

举几个例子:

 tc filter add dev eth0 parent 999:0 protocol ip prio 99 u32 \
        classid 1:1 \
	match ip src 192.168.8.0/24
tc filter add dev eth0 parent 999:0 protocol ip prio 99 u32 \
        classid 1:1 \
	match ip src 192.168.8.0/24 \
	match ip tos 0x10 1e

一些参考命令

一般来说最常用的应该就是设置latency和bandwidth了。

sudo tc qdisc add dev $device root handle 1:0 root htb default 2
sudo tc class add dev $device parent 1:0 classid 1:1 htb rate 1000Mbps 
sudo tc class add dev $device parent 1:1 classid 1:2 htb rate 5Mbit
sudo tc qdisc add dev $device parent 1:2 handle 2:0 netem delay 20ms

wondershaper

wondershaper是对tc的一个包装,简化了使用,更加方便的控制网卡的上传下载速率,但同时也限制了其他功能。
可以去看一下源码,学习一下如何使用tc 😃

源码中设置了针对ssh的filter,因为不希望交互式的应用被延迟:

# start filters
# TOS Minimum Delay (ssh, NOT scp) in 1:10:
tc filter add dev $IFACE parent 1: protocol ip prio 10 u32 \
    match ip tos 0x10 0xff  flowid 1:10

去查了一下IP协议的ToS字段,学到了一点别的东西。

先附上IP header:
IP header

ToS是在RFC791中提出的,但好像并没有使用这些bit。
RFC791-ToS

之后在RFC1349中对这个字段进行了修改:
RFC1349-ToS
再之后又在RFC2474中进行了大的修改:
RFC2474-DSCP | ECN

交互式应用的设置为:0x10,也就是 b i t 4 bit_4 bit4设置为1.

参考这里:https://lartc.org/howto/lartc.qdisc.classless.html

tcng

好像是对tc复杂命令的简化。

TODO: http://tldp.org/HOWTO/Traffic-Control-tcng-HTB-HOWTO/

参考

  1. http://man7.org/linux/man-pages/man8/tc.8.html
  2. http://man7.org/linux/man-pages/man8/tc-u32.8.html
  3. http://linux-tc-notes.sourceforge.net/tc/doc/cls_u32.txt
  4. http://tldp.org/HOWTO/Traffic-Control-HOWTO/index.html
  5. https://lartc.org/howto/lartc.qdisc.classless.html
  6. https://github.com/magnific0/wondershaper
  7. https://en.wikipedia.org/wiki/IPv4#Header
  8. https://en.wikipedia.org/wiki/Type_of_service
  9. https://unix.stackexchange.com/questions/212503/how-to-discriminate-between-ssh-and-scp-for-qos-in-openwrt-and-other-systems
  10. https://serverfault.com/questions/507658/limit-incoming-and-outgoing-bandwidth-and-latency-in-linux
  11. https://tonydeng.github.io/sdn-handbook/linux/tc.html
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值