http://arthurchiao.art/blog/understanding-tc-da-mode-zh/
在处理 action 方面有两种工作模式:
- 传统模式:分类之后执行
tcf_exts_exec()
-
direct-action 模式
随着 eBPF 功能越来越强大,它能做的事情不止是分类,例如,分类器自己就 能够(无需 action 参与)修改包的内容(mangle packet contents)、更新校验和 (update checksums)等。
因此,社区决定引入一个 direct action (da) mode [3]。
tc 术语
TC 是一个强大但复杂的框架(且文档[3]较少)。它的**几个核心概念**:
-
queueing discipline (qdisc):排队规则,根据某种算法完成限速、整形等功能
-
class:用户定义的流量类别
-
classifier (也称为 filter):分类器,分类规则
-
action:要对包执行什么动作
组合以上概念,下面是对某个网络设备上的流量进行分类和限速时,所需完成的大致步骤:
-
为网络设备**创建一个 qdisc**。
-
qdisc 是一个整流器/整形器(shaper),可以包含多个 class,不同 class 可以应用不同的策略。
-
qdisc 需要附着(attach)到某个网络接口(network interface),及流量方向(ingress or egress)。
-
创建流量类别(class),并 attach 到 qdisc。
-
-
例如,根据带宽分类,创建高、中、低三个类别。
-
-
创建 filter(classifier),并 attach 到 qdisc。
filters 用于对网络设备上的流量进行分类,并将包分发(dispatch)到前面定义的不同 class。
filter 会对每个包进行过滤,返回下列值之一:
-
-
0
:表示 mismatch。如果后面还有其他 filters,则**继续对这个包应用下一个 filter**。 -
-1
:表示这个 filter 上配置的**默认 classid**。 -
其他值:表示一个 classid。系统接下来应该将包送往这个指定的 class。可以看到,通过这种方式可以实现非线性分类(non-linear classification)。
-
-
另外,可以给 filter 添加 action。例如,将选中的包丢弃(drop),或者将流量镜像到另一个网络设备等等。
-
除此之外,qdisc 和 class 还可以循环嵌套,即:class 里加入新 qdisc,然后新 qdisc 里又可以继续添加新 class, 最终形成的是一个以 root qdisc 为根的树。但对于本文接下来的内容,我们不需要了解这么多。
1.2 tc 示例:匹配 IP 和 Port 对流量进行分类
# x:y 格式: # * x 表示 qdisc, y 表示这个 qdisc 内的某个 class # * 1: 是 1:0 的简写 # # "default 11":any traffic that is not otherwise classified will be assigned to class 1:11 $ tc qdisc add dev eth0 root handle 1: htb default 11 $ tc class add dev eth0 parent 1: classid 1:1 htb rate 100kbps ceil 100kbps $ tc class add dev eth0 parent 1:1 classid 1:10 htb rate 30kbps ceil 100kbps $ tc class add dev eth0 parent 1:1 classid 1:11 htb rate 10kbps ceil 100kbps $ tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip src 1.2.3.4 match ip dport 80 0xffff flowid 1:10 $ tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip src 1.2.3.4 action drop
以上设置表示以下顺序逻辑: 如果包匹配 src_ip==1.2.3.4 && dst_port==80,则将其送到第一个队列。这个队列对应的 class 目标速率是 30kbps;否则, 如果包匹配 src_ip==1.2.3.4,则将其 drop; 所有其他包将被送到第二个队列,对应的 class 目标速率是 10kbps
传统 classifier+action 模式的限制
上面看到,
-
classifer 能对包进行匹配,但**返回的 classid**;它只能告诉系统接下来把这个包送到那个 class(队列), 但无法让系统对这个包执行动作(drop、allow、mirror 等)。
-
action 返回的是动作,告诉系统接下来要对这个包做什么(drop、allow、mirror 等),但它无 法对包进行分类(规则匹配)。
所以,如果要实现”匹配+执行动作“的目的—— 例如,如果源 IP 是 10.1.1.1
,则 drop 这 个包 —— 就需要两个步骤:一个 classifier 和一个 action,即 classfifier+action
模式