看图理解linux内核网络流量控制工具tc(Traffic Control)

原创 吴就业 104 0 2024-06-26

本文为博主原创文章,未经博主允许不得转载。

本文链接:https://www.wujiuye.com/article/86e72cd0579b42c0afc364f1602ee549

作者:吴就业
链接:https://www.wujiuye.com/article/86e72cd0579b42c0afc364f1602ee549
来源:吴就业的网络日记
本文为博主原创文章,未经博主允许不得转载。

tc是Traffic Control的缩写,即流量控制,是 Linux 内核中用于流量控制的一套功能强大的工具和框架、是内核的一个子系统。提供有命令行工具tc命令,不需要安装,内核自带。

tc提供的能力:控制网络流量,包括带宽限制、流量整形等。

tc的核心概念理解

概念比较抽象,我们画图来理解:

whiteboard_exported_image

关系:

流量:

什么是排队规则?

qdisc 是一种排队机制,决定了数据包在发送前如何在队列中等待。不同类型的 qdisc 实现了不同的排队和传输策略,例如 FIFO、优先级队列、令牌桶等。

action概念的理解

action 与 filter 的关联:

支持的action:

实战一下

我们做个使用tc实现丢包的小实验来加深理解。

实验说明:如何使用tc命令实现把来自某个ip发往某个ip的流量做丢包处理?

实验环境:笔者在gcp启动了一个用来临时做实验的机器,IP是xx.yy.zz.kk,然后我想丢包的是这个机器访问www.google.com的流量,用ip138工具获取一个这个域名解析出来的ip,然后拿这个ip实验,例如:31.13.68.169。

实验步骤:

先验证是否能访问这个目的ip。

img

很好,能访问。

现在开始实现丢包。

一、ifconfig查一下本机的网络接口名,这里是enp1s0。

二、给enp1s0网络接口添加(attach)一个qdisc(流量整形规则)。

tc qdisc add dev enp1s0 root handle 1: htb

三、创建一个filter并关联drop这个action,将这个filter添加(attach)到我们创建的qdisc。filter关联drop action后,是不需要将流量分派到某个class的,所以我们并没有创建class。

tc filter add dev enp1s0 protocol ip parent 1: prio 1 u32 match ip src xx.yy.zz.kk/32 match ip dst 31.13.68.169/32 action drop

实验结果:

img

可以看到,100%丢包了。

清理环境需要删除filter:

tc filter del dev enp1s0 parent 1: protocol ip prio 1 u32
# 如需删除qdisc
# tc qdisc del dev enp1s0 root handle 1:

基于这个实验,那如果我们想实现限速,而不是全部丢包,怎么做呢?

一、还是使用我们前面创建的qdisc,如果删除了需要重新创建回来。

二、创建一个class,并将这个class添加(attach)到我们创建的qdisc。

tc class add dev enp1s0 parent 1: classid 1:1 htb rate 1kbit ceil 1kbit

我们指定了qdisc是哪个,并且这个qdisc是htb,为何创建class还要指定htb?

三、创建filter,并将匹配的流量分配给这个class。

tc filter add dev enp1s0 parent 1: protocol ip prio 1 u32 match ip src 45.32.123.96/32 match ip dst 31.13.68.169/32 flowid 1:1

flowid 1:1是将匹配的流量分派到前面创建的class,1:1是class的id。

清理:

// 删除filter 
tc filter del dev enp1s0 parent 1: protocol ip prio 1 u32
// 删除dc
tc class del dev enp1s0 classid 1:1
// 删除qdisc
tc qdisc del dev enp1s0 root handle 1:

参考文献:[译] 深入理解 tc ebpf 的 direct-action (da) 模式(2020)

#eBPF

声明:公众号、CSDN、掘金的曾用名:“Java艺术”,因此您可能看到一些早期的文章的图片有“Java艺术”的水印。

文章推荐

eBPF拦截文件写操作的可行性调研

折腾很久的一个技术方案调研,如何拦截文件写操作,拒绝用户超量使用nfs文件系统。

利用eBPF LSM实现Blocking写文件操作

LSM hook允许我们返回非0以Blocking掉系统调用,file_permission这个hook可以用来Blocking vfs_write。

一个稍微复杂的ebpf-go学习案例:给vfs_write写操作挂个hook

借助eBPF,给vfs_write写操作挂个hook,可以用这个hook实现一些可观察需求。本案例仅供参考学习,可以把案例中的vfs_write改成其它的。

ebpf-go c结构体和go结构体的映射

使用ebpf-go,假如bpf map的value需要用到结构体,而value由go程序写入,c程序读,value结构体在c中声明,那么怎么生成对应的go结构体呢?

踩坑记,如何使用ebpf-go,实战案例:拦截vfs_read函数获取文件名输出

新手入门调研学习使用ebpf-go的笔记, 记录了笔者在实现demo案例过程中踩的坑,很详细。

如何使用bpftrace追踪系统调用性能问题

所以,这个案例的用途是:在read函数调用之前,记录时间戳,在read函数return前计算方法执行耗时,将结果保存到`us`全局变量。使用`@`声明的全局变量,会在bpftrace脚本进程结束时输出到控制台。