linux tc模拟弱网环境(丢包)

  • Post author:
  • Post category:linux




0. 背景

项目需要模拟弱网环境下,测试音视频的编解码功能。

在linux系统下可以使用tc工具模拟弱网环境,包括出/入流量的丢包等。



1. tc工具介绍



2. 网卡出数据

netem(Network Emulator)可以用来对网卡发出的数据包进行增加延迟、丢包、重复、乱序等处理,来模拟复杂网络环境。netem的设置依赖tc命令,tc是Linux内核提供的流量控制工具。

具体的弱网配置,参考

本文第4部分



3. 网卡入数据

为了处理网卡接收的数据包,需要使用linux内核听过的ifb(Intermeidate Functional Block)模块。


个人理解

:启动ifb0虚拟网卡,将原输入到eth0的入流量导入到ifb0虚拟网卡中。之后,通过ifb0网卡的中转,返回给应用的数据是ifb0网卡出流量,之后对ifb0网卡便可以复用netem模块设置网络规则。

  1. 加载fib模块,启动ifb0网卡
sudo modprobe ifb
sudo ip link set dev ifb0 up
  1. 将网卡入流量导入到ifb网卡
sudo tc qdisc add dev eth0 handle ffff: ingress
sudo tc filter add dev eth0 parent ffff: u32 match u32 0 0 action mirred egress redirect dev ifb0
  1. 使用tc配置ifb0网卡入数据规则,举例
# 网卡丢包率设为10%
sudo tc qdisc add dev ifb0 root netem loss 10%



4. 网卡的处理

端口延时命令

网卡配置项,下面的eth0为出流量网卡,若为入流量只需将其替换为ifb0

# 表示对端口廷时100ms
tc qdisc add dev eth0 root netem delay 100ms 
# 表示对端口廷时命令删除
tc qdisc del dev eth0 root netem delya 100ms 
#表示对改变端口廷时命100ms ± 10ms 延时范围(90到110)
tc qdisc add dev eth0 root netem delay 100ms 10ms 
# 表示廷时范围100ms ,同时有25%以± 10ms波动延迟
tc qdisc add dev eth0 root netem delay 100ms 10ms 25%

# 端口丢包命令:
# 丢包率为0.1%
tc qdisc add dev eth0 root netem loss 0.1% 
# 丢包率为范围(0.3%- 25%)
tc qdisc add dev eth0 root netem loss 0.3% 25% 

# 数据包重包命令
# 随机产生 1% 的重复数据包
tc qdisc add dev eth0 root netem duplicate 1% 

# 数据包分发命令
# 数据包重发每格5的整数倍的包将不被延时。其它的将延时10ms
tc qdisc add dev eth0 root netem gap 5 delay 10ms

#速率控制命令:两条命令共同完成
tc qdisc add dev eth0 root handle 1:0 netem delay 100ms
tc qdisc add dev eth0 parent 1:1 handle 10: tbf rate 256kbit buffer 1600 limit 3000

#查看规则信息
tc -s qdisc ls dev eth0
tc qdisc show

#删除规则
tc qdisc del dev eth0 root



5. 特定IP或端口的处理

步骤:

  1. 针对网络物理设备(如以太网卡eth0)绑定一个队列QDisc;
  2. 在该队列上建立分类class;
  3. 为每一分类建立一个基于路由的过滤器filter;
  4. 最后与过滤器相配合,建立特定的路由表。

对IP进行限速

#查看现有的队列
tc -s qdisc ls dev eth0

#查看现有的分类
tc -s class ls dev eth0

#创建队列
tc qdisc add dev eth0 root handle 1:0 htb default 1 
#添加一个tbf队列,绑定到eth0上,命名为1:0 ,默认归类为1
#handle:为队列命名或指定某队列

#创建分类
tc class add dev eth0 parent 1:0 classid 1:1 htb rate 10Mbit burst 15k
#为eth0下的root队列1:0添加一个分类并命名为1:1,类型为htb,带宽为10M
#rate: 是一个类保证得到的带宽值.如果有不只一个类,请保证所有子类总和是小于或等于父类.
#ceil: ceil是一个类最大能得到的带宽值.

#创建一个子分类
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 10Mbit ceil 10Mbit burst 15k
#为1:1类规则添加一个名为1:10的类,类型为htb,带宽为10M

#为了避免一个会话永占带宽,添加随即公平队列sfq.
tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
#perturb:是多少秒后重新配置一次散列算法,默认为10秒
#sfq,他可以防止一个段内的一个ip占用整个带宽

#使用u32创建过滤器
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip sport 22 flowid 1:10

#删除队列
tc qdisc del dev eth0 root

对PORT进行限速

#清空原有规则
tc qdisc del dev eth0 root

#创建根序列
tc qdisc add dev eth0 root handle 1: htb default 1

#创建一个主分类绑定所有带宽资源(20M)
tc class add dev eth0 parent 1:0 classid 1:1 htb rate 20Mbit burst 15k

#创建子分类
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 20Mbit ceil 10Mbit burst 15k
tc class add dev eth0 parent 1:1 classid 1:20 htb rate 20Mbit ceil 20Mbit burst 15k

#避免一个ip霸占带宽资源
tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10

#创建过滤器
#对所有ip限速
tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 match ip dst 0.0.0.0/0 flowid 1:10
#对内网ip放行
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst 12.0.0.0/8 flowid 1:20



6. 使用tcconfig配置(推荐)

裸tc的配置难以使用,通过tcconfig工具,可以方便的配置netem的功能,就具体使用可参考

官方文档

举例:

# 对发往1.1.1.1的出数据包增加500ms延迟
tcset eth0 --delay 500ms --dst-address 1.1.1.1 --direction outgoing 

# 对发往1.1.1.1的80端口的出数据包增加随机丢包5%。
tcset eth0 --loss 5% --dst-address 1.1.1.1 --dst-port 80 --direction outgoing

# 对从1.1.1.1的80端口发来的数据包增加随机丢包5%。
tcset eth0 --loss 5% --src-address 1.1.1.1 --src-port 80 --direction incoming

# 通过tcshow命令可以查看现有的规则
tcshow eth0

# 通过tcdel命令删除现有规则
tcdel eth0 --all


参考链接



https://my.oschina.net/u/2539854/blog/3149307

https://cloud.tencent.com/developer/article/1409664



版权声明:本文为qq_25821689原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。