Linux下的网络输入输出流量的带宽控制
整理者:高压锅
QQ:280604597
1 概念
Linux中的QoS分为入口(Ingress)部分和出口(Egress)部分,入口部分主要用于进行输入流量的带宽控制,出口部分主要用于进行输出流量的带宽控制。
Linux是通过队列规则对网络流量的带宽进行控制,大多数队列规则(qdisc)都是用于输出方向的,例如HTB队列,而输入方向只有一个队列规则,即ingress队列。HTB队列的功能很强大,但是ingress队列的功能很简单,不可指定复杂的队列规则,但可用于重定向incoming packets。通过Ingress qdisc把输入方向的数据包重定向到虚拟设备ifb,然后对ifb的输出方向配置队列,就可以达到对输入流量做复杂的队列调度。
当队列的带宽被占满时,就开始延迟发送数据包,再不行就丢弃。
2 HTB队列
队列等级:一个HTB队列只能有一个根分类队列,一个根分类队列下可以有零至多个主分类队列,一个主分类队列下可以有零至多个子分类队列,一个子分类队列下可以有零至多个子分类队列,……
所有队列的流量统计是在这个队列的入口做的。
所有队列的流量带宽控制是在这个队列的队列通道里做的。
只有根分类队列入口上能添加过滤器,其他队列入口只做分流,即使添加过滤器也不会触发。
过滤器只能把数据包扔给最底层的队列,如果该队列有子分类队列,则数据包不能扔给这个队列,因为有子分类队列的主分类或子分类队列是没有队列通道的。注意:如果一定要扔给父队列,这个过滤器能添加成功,且过滤器还能匹配成功,但是数据包就是不走这个队列。
经过测试,发现子分类队列的带宽不受父分类队列的带宽控制。
网络设备名:网络设备的名字,一般叫ethX,用ifconfig或ip link命令查看。
虚拟网络设备名:虚拟网络设备的名字,一般叫ifbX,用ifconfig或ip link命令查看。
优先级:优先处理的等级,为整数,数值越低优先级越高。经过测试,发现htb队列的优先级高低没有对数据包产生影响。
队列的优先级由高到低为1、2、3、4、5、6、7,最高为1,最低为7。如果过滤器的优先级为0,会导致无法删除此过滤器。
3 输出流量控制
查看根分类队列:
tc [-s] qdisc show dev 网络设备名
添加根分类队列:
tc qdisc add dev 网络设备名 root handle 1:0 htb [default 默认分类队列句柄]
注意:如果默认分类队列不存在,就走根分类队列。
删除根分类队列:
tc qdisc del dev 网络设备名 root
查看主分类队列:
tc [-s] class show dev 网络设备名
添加主分类队列:
tc class add dev 网络设备名 parent 1:0 classid 1:1 htb rate 最小带宽{MBps|KBps|Bps|Mbit|Kbit|bit} [ceil 最大共享带宽{MBps|KBps|Bps|Mbit|Kbit|bit}] [prio 优先级]
Bps表示每秒传输字节
KBps表示每秒传输千字节
MBps表示每秒传输兆字节
1MBps=1000KBps
1KBps=1000Bps
使用Mbit、Kbit、bit单位控制输出流量带宽时,会导致控制不准,控制输入流量带宽时没问题。
使用MBps、KBps、Bps单位控制输入输出流量带宽都很准。
删除主分类队列:
tc class del dev 网络设备名 classid 分类队列句柄
注意:如果有过滤器的与要删除的队列有关联,必须先删除过滤器,然后才能删除该队列。
注意:如果要删除的队列有子队列时,必须先删除子队列,然后才能删除该队列。
查看过滤器:
tc [-s] filter {show|ls} dev 网络设备名
添加过滤器:
tc filter add dev 网络设备名 parent 1:0 protocol ip [prio 优先级] u32 [match ip src XXX.XXX.XXX.XXX/XX] [match ip dst XXX.XXX.XXX.XXX/XX] [match ip sport XXX 0xffff] [match ip dport XXX 0xffff] flowid 1:1
过滤器的优先级必须大于0,如果为0会导致此过滤器无法删除。
删除过滤器:
tc filter del dev 网络设备名 prio 优先级
tc filter del dev 网络设备名 parent 队列句柄 protocol ip prio 优先级 handle 句柄 u32
4 输入流量控制
加载虚拟网络设备驱动:
modprobe ifb
启用虚拟网络设备:
ip link set dev 虚拟网络设备名 up [txqueuelen 1000]
给网络设备添加ingress队列,ingress队列用于对输入流量控制:
tc qdisc add dev 网络设备名 ingress
注意:ingress队列的句柄默认是ffff:,无法修改。
将网络设备的输入流量重定向到虚拟网络设备的输出流量上:
tc filter add dev 网络设备名 parent ffff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev 虚拟网络设备名
5 tc命令
tc qdisc
tc class {add | replace | change | del}
tc filter
6 例子
l 一个:
以下eth1为内网网卡地址
tc qdisc del root dev eth1 #删除以前的规则
tc qdisc add dev eth1 root handle 1: htb #开启限速规则为htb(分层令牌桶)
tc class add dev eth1 parent 1: classid 1:1 htb rate 3mbit burst 15k #规划限制带宽为3M峰值15k
tc qdisc add dev eth1 parent 1:1 handle 10: sqf perturb 10 #设定平均分配带宽
tc filter add dev eth1 protocol ip parent 1:0 prio 1 u32 match ip dst 192.168.8.17 flowid 1:1 #限制192.168.8.17速度为3mbit