Linux Traffic Shaper ifb interface
Често се случва Линукс рутера да има няколко мрежови интерфейса а още по често когато клиентите на които трябва да се ограничи скороста да се намират зад един интерфейс. В този случай естествено ограничението на скороста трябва да важи за всички интерфейси и решението което избрах аз е ifb. Оказа се, че ifb не е от скоро но незнам защо не е придобил голяма популярност или поне аз с такова чувство останах. ifb всъщност е вируален интерфейс насочен към същия интерфейс в който сме конфигурирали download скороста но на ifb интерфейса конфигурираме upload скороста. В интернет намерих малко разпокъсана информация и решението по долу е сглобено от няколко статии. При мен работи добре и съм доволен макар и машината да е малко слаба и процесора да бие 100% на htop, latency на ping не мърда.
modprobe ifb numifbs=1 ip link set dev ifb0 up tc qdisc del dev eth0 root 2>/dev/null tc qdisc del dev eth0 ingress 2>/dev/null tc qdisc del dev ifb0 root 2>/dev/null tc qdisc add dev eth0 handle ffff: ingress tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0 tc qdisc add dev eth0 root handle 1: htb r2q 625 default 65 tc class add dev eth0 parent 1: classid 1:1 htb rate 1000Mbit tc qdisc add dev ifb0 root handle 1: htb r2q 625 default 65 tc class add dev ifb0 parent 1: classid 1:1 htb rate 1000Mbit tc class add dev eth0 parent 1:1 classid 1:10 htb rate 10Mbit tc filter add dev eth0 parent 1: protocol all prio 1 u32 match ip dst 192.168.0.2 classid 1:10 tc qdisc add dev eth0 parent 1:10 handle 10: sfq tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 10Mbit tc filter add dev ifb0 parent 1: protocol all prio 1 u32 match ip src 192.168.0.2 classid 1:10 tc qdisc add dev ifb0 parent 1:10 handle 10: sfq tc class add dev eth0 parent 1:1 classid 1:11 htb rate 20Mbit tc filter add dev eth0 parent 1: protocol all prio 1 u32 match ip dst 192.168.0.3 classid 1:11 tc qdisc add dev eth0 parent 1:11 handle 11: sfq tc class add dev ifb0 parent 1:1 classid 1:11 htb rate 20Mbit tc filter add dev ifb0 parent 1: protocol all prio 1 u32 match ip src 192.168.0.3 classid 1:11 tc qdisc add dev ifb0 parent 1:11 handle 11: sfq |
Script
Ако се стигне до там, че трябва да управляваме няколкостотин адреса ще ни трябва скрипт. Решението на тази задача съм го изпълнил с два файла. Конфигурационен в който съхраняваме адресите и скоростите с които ще ги ограничаваме –
/etc/ipclient
192.168.0.2 speed1
192.168.0.3 speed2
#192.168.0.4 speed1
192.168.0.5 speed1 |
И изпълним файл, самият скрипт – /etc/init.d/netscript
DB=/etc/ipclient IN1=10Mbit OUT1=10Mbit IN2=20Mbit OUT2=20Mbit tc qdisc del dev eth0 root 2>/dev/null tc qdisc del dev eth0 ingress 2>/dev/null tc qdisc del dev ifb0 root 2>/dev/null tc qdisc add dev eth0 handle ffff: ingress tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0 tc qdisc add dev eth0 root handle 1: htb r2q 625 default 65 tc class add dev eth0 parent 1: classid 1:1 htb rate 1000Mbit tc qdisc add dev ifb0 root handle 1: htb r2q 625 default 65 tc class add dev ifb0 parent 1: classid 1:1 htb rate 1000Mbit echo "start TRAFFIC SHAPER IP speed1" ADDR=$(grep -v \# $DB | grep speed1 | awk '{ print $1 }') for IP in $ADDR; do MARK=$(cat $DB | grep -w -n $IP | cut -d":" -f1) ID=$(($MARK + 1000)) tc class add dev eth0 parent 1:1 classid 1:$ID htb rate $IN1 tc filter add dev eth0 parent 1: protocol all prio 1 u32 match ip dst $IP classid 1:$ID tc qdisc add dev eth0 parent 1:$ID handle $ID: sfq tc class add dev ifb0 parent 1:1 classid 1:$ID htb rate $OUT1 tc filter add dev ifb0 parent 1: protocol all prio 1 u32 match ip src $IP classid 1:$ID tc qdisc add dev ifb0 parent 1:$ID handle $ID: sfq done; echo "start TRAFFIC SHAPER IP speed2" ADDR=$(grep -v \# $DB | grep speed2 | awk '{ print $1 }') for IP in $ADDR; do MARK=$(cat $DB | grep -w -n $IP | cut -d":" -f1) ID=$(($MARK + 1000)) tc class add dev eth0 parent 1:1 classid 1:$ID htb rate $IN2 tc filter add dev eth0 parent 1: protocol all prio 1 u32 match ip dst $IP classid 1:$ID tc qdisc add dev eth0 parent 1:$ID handle $ID: sfq tc class add dev ifb0 parent 1:1 classid 1:$ID htb rate $OUT2 tc filter add dev ifb0 parent 1: protocol all prio 1 u32 match ip src $IP classid 1:$ID tc qdisc add dev ifb0 parent 1:$ID handle $ID: sfq done; |
Всичко това е провокирано от старото ми решение за такива случаи “police rate drop” което работи добре при мен до 100 клиента.
tc qdisc del dev eth0 root 2>/dev/null tc qdisc add dev eth0 root handle 1 htb r2q 625 default 65 tc class add dev eth0 parent 1: classid 1:1 htb rate 1000Mbit tc qdisc del dev eth0 handle ffff: ingress 2>/dev/null tc qdisc add dev eth0 handle ffff: ingress tc class add dev eth0 parent 1:1 classid 1:10 htb rate 10Mbit burst 1Mbit tc filter add dev eth0 parent 1: protocol all prio 1 u32 match ip dst 192.168.0.2 classid 1:10 tc qdisc add dev eth0 parent 1:10 handle 10: sfq tc filter add dev eth0 parent ffff: protocol all prio 20 u32 match \ ip src 192.168.0.2 police rate 10Mbit burst 1Mbit drop flowid :10 |
“police rate drop” дефакто отхвърля пакети когато те достигнат лимита. Това не е много добре и често води до “счупване” на някоя връзка. ifb не отхвърля а забавя пакетите което си е чисто решение на проблема.
Linux Traffic Shaper ifb interface