QoS分为入口(Ingress)部分和出口(Egress)部分,入口部分主要用于进行入口流量限速(policing),出口部分主要用于队列调度(queuing scheduling),大多数排队规则(qdisc)都是用于输出方向的,输入方向只有一个排队规则,即ingress qdisc


1.开始思路

3-ifb虚拟接口_上传


  • 对于wan口来说:下载是ingress,上传是egress
  • 对于lan口来说:下载是egress,上传是ingress

因此,常规做法是,在lan口做下载流控,在wan口做上传流控

2.遇到问题

按上面的做法,LAN口到LAN口的流量也会被控制了。


尝试对lan-lan流量进行过滤,但是1.不灵活,IP识别困难,外网IP也可以当做内网IP用;2.对不关注的流量进行操作,有性能损耗。


如何只对外网流量(lan-wan)进行控制,不对内网流量(lan-lan)进行控制

3.增加虚拟接口ifb

ifb原理就是开一个接口,把实际接口的ingress流量转到这些ifb接口的egress上,所以我们就把wan口的ingress转发到ifb口的egress,这时候相当于只需要对ifb的输出控制即可,不对lan口进行控制。

WAN口控制上传,ifb口控制下载。

3-ifb虚拟接口_外网_02

4.如何区分lan口的IP,使用mark标记

上面虽然把lan口释放了,不去控制lan-lan口的数据,但是我们要对lan口的上传/下载做控制。

egress的流量,经过nat以后,源IP不再是lan段的IP,因此无法标识具体的IP/用户。

(SNAT基于原地址的转换一般用在我们的许多内网用户通过一个外网的口上网的时候,这时我们将我们内网的地址转换为一个外网的IP,我们就可以实现连接其他外网IP的功能)

解决方法是使用fw分类器。在netfilter的forward上挂一个自定义的模块(如:MyMark),根据需求打mark,这里可以任意发挥想象,直觉可以实现任意你想到的功能。

fw分类器,根据mark来分类:先在父类20:1下面穿件一个子类20:17,(这个类里面做了限速规则)再把打了257/0xfffff标记的分类到20:17,而打了257/0xfffff标记的又在iptable的FORWARD表里面做了对应。

iptables -t mangle -A QOS_RULES_FORWARD_eth1 -m mac --mac-source 14:75:90:F7:97:7D -d 0.0.0.0/0 -j MARK --set-mark 257/0xfffff
/usr/sbin/tc class add dev eth1 parent 20:1 classid 20:17 hfsc sc rate 204800kbit ul rate 204800kbit
/usr/sbin/tc filter add dev eth1 parent 20:0 protocol ip handle 257/0xfffff fw flowid 20:17
/usr/sbin/tc class add dev ifb4eth1 parent 20:1 classid 20:17 hfsc sc rate 102400kbit ul rate 102400kbit
/usr/sbin/tc filter add dev ifb4eth1 parent 20:0 protocol ip handle 257/0xfffff fw flowid 20:17

5.实例

以eth1为例

1).创建入队列

/usr/sbin/tc qdisc add dev eth1 handle ffff: ingress
/usr/sbin/tc qdisc del dev ifb4eth1 root


2).把eth1的入口流量导入ifb4eth1

/usr/sbin/tc filter add dev eth1 parent ffff: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action connmark action mirred egress redirect dev ifb4eth1

tc filter add dev eth0 parent fff: protocol ip u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0

3).TC工具对ifb4eth1设置QoS规则

/usr/sbin/tc qdisc add dev ifb4eth1 root handle 1: prio bands 2 priomap 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
/usr/sbin/tc qdisc add dev ifb4eth1 parent 1:1 handle 10: pfifo limit 3000
/usr/sbin/tc qdisc add dev ifb4eth1 parent 1:2 handle 20: hfsc default 3
/usr/sbin/tc class add dev ifb4eth1 parent 20: classid 20:1 hfsc ls rate 1000Mbit ul rate 1024000kbit
/usr/sbin/tc filter add dev ifb4eth1 parent 1: protocol ip prio 1 handle 0xf0/0xf0 fw flowid 1:1
/usr/sbin/tc filter add dev ifb4eth1 parent 1: protocol ip prio 2 u32 match ip protocol 1 0xf0/0xf0 flowid 1:1
。。。

4).启动ifb4eth1端口

/usr/sbin/ip link set dev ifb4eth1 up

启动成功会有如下端口信息

root@zihome:~# ifconfig ifb4eth1
ifb4eth1 Link encap:Ethernet HWaddr 6E:ED:FD:76:56:8B
UP BROADCAST RUNNING NOARP MTU:1500 Metric:1
RX packets:2764 errors:0 dropped:0 overruns:0 frame:0
TX packets:2764 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:32
RX bytes:2622255 (2.5 MiB) TX bytes:2622255 (2.5 MiB)