И еще немного про tc и честное распределение скорости

При использовании очереди sfq в получаем практически честное распределения трафика между пользователям, точнее между сетевыми соединениями пользователей. Получается, что чем больше у пользователя соединений, тем больше скорости он получает, а это значит, что не совсем честные пользователи и p2p получают преимущество. Описанных недостатков лишена очередь esfq, поскольку позволяет разделять трафик на основе адреса источника или назначения. Однако у esfq есть другой недостаток — он не входит в ядро .

О том как как собрать его для вашей версии ядра здесь речи не пойдет. Пользователям достаточно просто установить его из пакета:

 [email protected]:~# opkg install kmod-sched-esfq 

Далее я привожу адаптированный для esfq вариант скрипта управления трафиком с помощью tc.

Кроме адаптации под esfq изменилось еще кое-что. Вместо двух интерфейсов используется один + устройство ifb, кроме того практика показала что в большинстве случаев 6 классов трафика избыточны и 3-х классов вполне достаточно.

 IF_E="eth0" IF_I="ifb0" RATE="135mbit" BW="2mbit" 

Переменные:
IF_E — сетевой интерфейс, на котором производится ограничение трафика
IF_I — Intermediate Functional Block, с помощью которого ограничивается входящий трафик
RATE — скорость подключения к сети интернет (для того чтобы работал, -10% от реальной скорости)
BW — минимальная гарантированная скорость для того или иного класса трафика.

Основные планировщики пакетов и классы для входящего трафика:

 # Egress policing  qdisc del dev $IF_E root 2> /dev/null > /dev/null  qdisc add dev $IF_E root handle 1: htb default 103  class add dev $IF_E parent 1: classid 1:1 htb rate $RATE burst 32k ## Prio 1  class add dev $IF_E parent 1:1 classid 1:101 htb rate $BW \ ceil $RATE burst 2k prio 1  qdisc add dev $IF_E parent 1:101 handle 101: esfq perturb 2 hash src  filter add dev $IF_E parent 1:0 prio 1 protocol ip handle 101 fw \ classid 1:101 ## Prio 2  class add dev $IF_E parent 1:1 classid 1:102 htb rate $BW \ ceil $RATE burst 2k prio 2  qdisc add dev $IF_E parent 1:102 handle 102: esfq perturb 2 hash src  filter add dev $IF_E parent 1:0 prio 2 protocol ip handle 102 fw \ classid 1:102 ## Prio 3  class add dev $IF_E parent 1:1 classid 1:103 htb rate $BW \ ceil $RATE burst 2k prio 3  qdisc add dev $IF_E parent 1:103 handle 103: esfq perturb 2 hash src  filter add dev $IF_E parent 1:0 prio 3 protocol ip handle 103 fw \ classid 1:103 

Зеркалирование входящего трафика на устройство ifb, а так же планировщики пакетов и классы для исходящего трафика:

 # Ingress policing and ifb mirroring ifconfig $IF_I up tc qdisc del dev $IF_E ingress 2> /dev/null > /dev/null tc qdisc add dev $IF_E ingress tc filter add dev $IF_E parent ffff: protocol ip u32 match u32 0 0 \ action mirred egress redirect dev $IF_I tc qdisc del dev $IF_I root 2> /dev/null > /dev/null tc qdisc add dev $IF_I root handle 1: htb default 103 tc class add dev $IF_I parent 1: classid 1:1 htb rate $RATE burst 32k ## Prio 1 tc class add dev $IF_I parent 1:1 classid 1:101 htb rate $BW \ ceil $RATE burst 2k prio 1 tc qdisc add dev $IF_I parent 1:101 handle 101: esfq perturb 2 hash dst tc filter add dev $IF_I parent 1:0 prio 1 protocol ip handle 101 fw \ classid 1:101 ## Prio 2 tc class add dev $IF_I parent 1:1 classid 1:102 htb rate $BW \ ceil $RATE burst 2k prio 2 tc qdisc add dev $IF_I parent 1:102 handle 102: esfq perturb 2 hash dst tc filter add dev $IF_I parent 1:0 prio 2 protocol ip handle 102 fw \ classid 1:102 ## Prio 3 tc class add dev $IF_I parent 1:1 classid 1:103 htb rate $BW \ ceil $RATE burst 2k prio 3 tc qdisc add dev $IF_I parent 1:103 handle 103: esfq perturb 2 hash dst tc filter add dev $IF_I parent 1:0 prio 3 protocol ip handle 103 fw \ classid 1:103 

С помощью раскладываем трафик по классам:

 # Delete Chains iptables -t mangle -D POSTROUTING -o $IF_E -j qos_tc iptables -t mangle -D PREROUTING -i $IF_E -j qos_tc iptables -t mangle -F qos_tc iptables -t mangle -X qos_tc iptables -t mangle -F iptables -t mangle -X # Create Chain iptables -t mangle -N qos_tc iptables -t mangle -I POSTROUTING -o $IF_E -j qos_tc iptables -t mangle -I PREROUTING -i $IF_E -j qos_tc # ICMP iptables -t mangle -A qos_tc -p icmp -j MARK \ --set-mark 101 # ACK & Other small packets iptables -t mangle -A qos_tc -p tcp -m length \ --length :64 -j MARK --set-mark 101 # DNS iptables -t mangle -A qos_tc -p tcp --dport 53 \ -j MARK --set-mark 101 iptables -t mangle -A qos_tc -p udp --dport 53 \ -j MARK --set-mark 101 iptables -t mangle -A qos_tc -p tcp --sport 53 \ -j MARK --set-mark 101 iptables -t mangle -A qos_tc -p udp --sport 53 \ -j MARK --set-mark 101 # Web-client iptables -t mangle -A qos_tc -m multiport -p tcp \ --dports 80,443 -j MARK --set-mark 102 iptables -t mangle -A qos_tc -m multiport -p tcp \ --sports 80,443 -j MARK --set-mark 102 # IM-client && SSH-Client iptables -t mangle -A qos_tc -m multiport -p tcp \ --dports 22,5190,5222,5223 -j MARK --set-mark 102 iptables -t mangle -A qos_tc -m multiport -p tcp \ --sports 22,5190,5222,5223 -j MARK --set-mark 102 

Для работоспособности скрипта может потребоваться вручную загрузить соответствующие модули ядра:

 insmod ip_queue 2> /dev/null > /dev/null insmod sch_htb 2> /dev/null > /dev/null insmod sch_esfq 2> /dev/null > /dev/null insmod cls_u32 2> /dev/null > /dev/null insmod sch_ingress 2> /dev/null > /dev/null insmod cls_fw 2> /dev/null > /dev/null insmod ipt_TOS 2> /dev/null > /dev/null insmod sch_prio 2> /dev/null > /dev/null insmod xt_physdev 2> /dev/null > /dev/null insmod ifb 2> /dev/null > /dev/null insmod act_mirred 2> /dev/null > /dev/null 

Если используется мост, необходимо включить обработку трафика проходящего через него средствами iptables, чтобы корректно проставлялись метки.

 echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables 

Скачать скрипт целиком: qos_tc_new.sh.gz