TC-Traffic Control in Linux

Linux的流量控制器TC用于控制网络接口的流量,通过队列和排队规则实现。文章介绍了TC的基本原理,包括Simple(无类别)和Classful(有类别)的排队规则,如pfifo_fast、SFQ和TBF。pfifo_fast是默认队列,而SFQ提供随机公平的排队策略。TBF用于限速和整形,保证流量不超过预设速率。此外,文章还探讨了何时选择不同类型的队列,以及如何使用过滤器对流量进行分类。
摘要由CSDN通过智能技术生成

Linux中的流量控制, 一篇手册的翻译,很遗憾随着项目的结束对TC应用的不多,仅仅写到这里了。

1. TC原理

Linux操作系统中的流量控制器TC(Traffic Control)用于Linux内核的流量控制,主要是通过在输出端口处建立一个队列来实现流量控制。
接收包从输入接口进来后,经过流量限制丢弃不符合规定的数据包,由输入多路分配器进行判断选择:

  • 如果接收包的目的主机是本主机,那么将该包送给上层处理,否则需要进行转发,将接收包交到转发块(Forwarding Block)处理。
  • 转发块同时也接收本主机上层(TCP、UDP等)产生的包,通过查看路由表,决定所处理包的下一跳。
  • 然后,对包进行排列以便将它们送到输出接口。

一般只能限制网卡发送的数据包,不能限制网卡接收的数据包,所以可以通过改变发送次序来控制传输速率。Linux流量控制主要是在输出接口排列时进行处理和实现的。

2. 规则

2.1 队列(Queues) 和排队规则(Queueing Disciplines)

通过对包进行排队(queuing),我们可以决定数据的发送方式(the way in which data is SENT)。但理解下面这一点非常重要:我们只能对发送(transmit)的数据进行整形(shape the data)。

互联网的工作机制决定了接收端无法直接控制发送端的行为。这就像你家的 (实体!)邮箱一样:除非能联系到所有人(告诉他们未经同意不要寄信给你),否则 你无法控制别人寄多少东西过来。😉

但与实际生活不同的是,互联网基于 TCP/IP 协议栈,这多少会带来一些帮助。TCP/IP 无法提前知道两台主机之间的网络带宽,因此开始时它会以越来越快的速度发送数据(慢启 动),直到开始出现丢包,这时它知道已经没有可用空间来存储这些待发送的包了,因此就会 降低发送速度。TCP/IP 的实际工作过程比这个更智能一点,我们后面会再讨论。

这就好比你留下一半的信件在实体邮箱里不取,期望别人知道这个状况后会停止给你寄新的信件。 但不幸的是,这种方式只对互联网管用,对你的实体邮箱无效 😃

如果内网有一台路由器,你希望限制某几台主机的下载速度,那你应该找到发送数据到 这些主机的路由器内部接口(inner interface of your router),然后在这些 路由器内部接口上做 整流(traffic shaping,流量整形)。

此外,还要确保链路瓶颈(bottleneck of the link)也在你的控制范围内。例如,如果网 卡是 100Mbps,但路由器的链路带宽是 256Kbps,那首先应该确保不要发送过多数据给路由器,因为它可能扛不住。否则,链路控制和带宽整形的决定权就不在主机侧而到路由器侧了。要达到限速目的,我们需要对“发送队列”有完全的把控(”own the queue”),这里的“发送队列”也就是整条链路上最慢的一段(slowest link in the chain)。 幸运的是,大多数情况下这个条件都是能满足的。

2.2 Simple, classless qdisc(简单、不分类排队规则)

如前所述,排队规则(queueing disciplines)改变了数据的发送方式。

不分类(或称无类别)排队规则(classless queueing disciplines)可以对某个网络 接口(interface)上的所有流量进行无差别整形。包括对数据进行:

  • 重新调度(reschedule)
  • 增加延迟(delay)
  • 丢弃(drop)

与 classless qdisc 对应的是 classful qdisc,即有类别(或称分类别)排队规则,后者是一个排队规则中又包含其他排队规则(qdisc-containing-qdiscs)!😮 先理解了 classless qdisc,才能理解 classful qdisc。
目前最常用的 classless qdisc 是 pfifo_fast qdisc,这也是默认排队规则。 这也解释了为什么这些高级功能如此健壮:本质上来说,它们只不过是“另一个队列”而 已(nothing more than ‘just another queue’)。
每种队列都有自己的优缺点。其中一些可能测试的并不全面。

2.2.1 pfifo_fast(先入先出队列)

如名字所示,这是一个先入先出队列(First In, First Out),因此对所有包都一视同仁。

pfifo_fast 有三个所谓的 “band”(可理解为三个队列),编号分别为 0、1、2:

  • 每个 band 上分别执行 FIFO 规则
  • 如果 band 0 有数据,就不会处理 band 1;同理,band 1 有数据时, 不会去处理 band 2。
  • 内核会检查数据包的 TOS 字段,将**“最小延迟”的包放到 band 0**。

不要将 pfifo_fast qdisc 与后面介绍的 PRIO qdisc 混淆,后者是 classful 的! 虽然二者行为类似,但 pfifo_fast 是无类别的,这意味你无法通过 tc 命令向 pfifo_fast 内添加另一个 qdisc。

2.2.1.1 参数与用法

pfifo_fast qdisc 默认配置是写死的(the hardwired default),因此无法更改

下面介绍这份写死的配置是什么样的。

  • priomap
    priomap 决定了如何将内核设置的 packet priority 映射到 band。priority 位于包的 TOS 字段:
     0     1     2     3     4     5     6     7
  +-----+-----+-----+-----+-----+-----+-----+-----+
  |                 |                       |     |
  |   PRECEDENCE    |          TOS          | MBZ |
  |                 |                       |     |
  +-----+-----+-----+-----+-----+-----+-----+-----+s

TOS 字段占用 4 个比特,各 bit 含义如下:

  Binary Decimcal  Meaning
  -----------------------------------------
  1000   8         Minimize delay (md)
  0100   4         Maximize throughput (mt)
  0010   2         Maximize reliability (mr)
  0001   1         Minimize monetary cost (mmc)
  0000   0         Normal Service

tcpdump -vv 会打印包的 TOS 字段,其中的 TOS 值对应下面的第一列:

  TOS     Bits  Means                    Linux Priority    Band
  ------------------------------------------------------------
  0x0     0     Normal Service           0 Best Effort     1
  0x2     1     Minimize Monetary Cost   1 Filler          2
  0x4     2     Maximize Reliability     0 Best Effort     1
  0x6     3     mmc+mr                   0 Best Effort     1
  0x8     4     Maximize Throughput      2 Bulk            2
  0xa     5     mmc+mt                   2 Bulk            2
  0xc     6     mr+mt                    2 Bulk            2
  0xe     7     mmc+mr+mt                2 Bulk            2
  0x10    8     Minimize Delay           6 Interactive     0
  0x12    9     mmc+md                   6 Interactive     0
  0x14    10    mr+md                    6 Interactive     0
  0x16    11    mmc+mr+md                6 Interactive     0
  0x18    12    mt+md                    4 Int. Bulk       1
  0x1a    13    mmc+mt+md                4 Int. Bulk       1
  0x1c    14    mr+mt+md                 4 Int. Bulk       1
  0x1e    15    mmc+mr+mt+md             4 Int. Bulk       1

第二列是对应的十进制表示,第三列是对应的含义。例如,15 表示这个包期望 Minimal Monetary Cost + Maximum Reliability + Maximum Throughput + Minimum Delay。我把这样的包称为“荷兰包”(a ‘Dutch Packet’。荷兰人比较 节俭/抠门,译注)。第四列是对应到 Linux 内核的优先级;最后一列是 映射到的 band,从命令行输出看,形式为:

  1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1

例如,priority 4 会映射到 band 1。priomap 还能列出 priority > 7 的那些 不是由 TOS 映射、而是由其他方式设置的优先级。例如,下表列出了应用(application)是如何设置它们的 TOS 字段的,来自 RFC 1349(更多信息可阅读全文)

  TELNET                   1000           (minimize delay)
  FTP     Control          1000           (minimize delay)
          Data             0100           (maximize throughput)
    
  TFTP                     1000           (minimize delay)
    
  SMTP    Command phase    1000           (minimize delay)
          DATA phase       0100           (maximize throughput)
    
  DNS     UDP Query        1000           (minimize delay)
          TCP Query        0000
          Zone Transfer    0100           (maximize throughput)
    
  NNTP                     0001           (minimize monetary cost)
    
  ICMP    Errors           0000
          Requests         0000 (mostly)
          Responses        <same as request> (mostly)
  • txqueuelen
    发送队列长度,是一个网络接口(interface)参数,可以用 ifconfig 命令设置。例 如,ifconfig eth0 txqueuelen 10
    tc 命令无法修改这个值。

    2.2.2 TBF(Token Bucket Filter,令牌桶过滤器)

    TBF 是一个简单 qdisc,对于没有超过预设速率的流量直接透传,但也能容忍超过预 设速率的短时抖动(short bursts in excess of this rate)。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值