1. Поресерчил кучу дистров. pfSense, m0n0wall, smoothwall, zeroshell, untangle
2. Осознал, что untangle - то, что нужно для моей задачи
3. Осознал, что я не хочу ничего менять на шлюзе и принял решение спизди^W мигрировать решение с untangle на офисный шлюз
4. Танцы с бубном и "классами" траффика.
Лирическое отступление. Если бы на шлюзе стояла бы FreeBSD, то текущую задачу решить довольно легко. Но стоит Debian и очень лениво поднимать всё с нуля на FreeBSD.
Из моих заметок я заметил, что по дефолту с помощью tc и iptables можно шейпить только исходящий трафф. Входящий не получится. В итоге, нашел способ шейпить входящий трафф с помощью imq девайса.
Для начала надо пропатчить и пересобрать ядро, чтобы добавить поддержку IMQ. Второе - пропатчить и пересобрать iptables.
все патчи есть тут
Теперь, что у нас дано.
1. 100 мбит по кг
2. 512 кбит на внешку
допустим, нам надо не резать кг, а всему остальному выделить полосу в 128к
Маркируем пакеты в iptables
Код: Выделить всё
#!/bin/bash
iptables=$(which iptables)
wan_dev=br0
imq_dev=imq0
kg_nets=/tmp/kgnets
wget=$(which wget)
$wget -O $kg_nets http://elcat.kg/ip/kg-nets.txt
# Initializing qos chains
flush_iptables_chains()
{
$iptables -t mangle -F qos-input
$iptables -t mangle -F qos-output
$iptables -t mangle -X qos-input
$iptables -t mangle-X qos-output
}
add_iptables_chains()
{
$iptables -t mangle -N qos-input
$iptables -t mangle -F qos-input
$iptables -t mangle -N qos-output
$iptables -t mangle -F qos-output
}
iptables_qos_in()
{
$iptables -t mangle -A PREROUTING -j qos-input
while read line; do
$iptables -t mangle -A qos-input -s `echo $line` -j MARK --set-mark 0x00100000/0x00700000
done < $kg_nets
}
iptables_qos_out()
{
$iptables -t mangle -A POSTROUTING -j qos-output
while read line;do
$iptables -t mangle -A qos-output -d `echo $line` -j MARK --set-mark 0x00100000/0x00700000
done < $kg_nets
}
flush_iptables_chains
add_iptables_chains
iptables_qos_in
iptables_qos_out
$iptables -t mangle -A qos-input -j IMQ
Теперь идут пляски с tc и htb.
Кусок кода, отвечающий за добавление правил tc
Код: Выделить всё
add_htb_rules(){
add_qdisc="tc qdisc add dev "
add_class="tc class add dev "
add_filtr="tc filter add dev "
SFQ="sfq perturb 10 "
# egress shaping
# создаем корень
$add_qdisc $wan_dev root handle 1: htb default 13
# создаем класс, с пропускной способностью в 100 mbit/s
$add_class $wan_dev parent 1: classid 1:1 htb rate ${KGUB}
# вешаем на него правило
$add_class $wan_dev parent 1:1 classid 1:11 htb rate $KGUR ceil $KGUL
# делим оставшееся поровну
$add_qdisc $wan_dev parent 1:11 handle 11: $SFQ
# создаем класс, с пропускной способностью в 128к
$add_class $wan_dev parent 1:1 classid 1:12 htb rate $ALLUB
$add_class $wan_dev parent 1:12 classid 1:13 htb rate $AUR ceil $AUL
$add_qdisc $wan_dev parent 1:13 handle 13: $SFQ
# добавляем фильтры
$add_filtr $wan_dev parent 1: prio 11 protocol ip u32 match mark 0x100000 0x700000 flowid 1:11 # КГ - 100 мбит
$add_filtr $wan_dev parent 1: prio 13 protocol ip u32 match mark 0x200000 0x700000 flowid 1:13 # все, что не кг - 128к
#ingress shaping
ifconfig $imq_dev up
# создаем корень
$add_qdisc $imq_dev root handle 1: htb default 13
# создаем класс, с пропускной способностью в 100 mbit/s
$add_class $imq_dev parent 1: classid 1:1 htb rate ${KGUB}
# вешаем на него правило
$add_class $imq_dev parent 1:1 classid 1:11 htb rate $KGUR ceil $KGUL
# делим оставшееся поровну
$add_qdisc $imq_dev parent 1:11 handle 11: $SFQ
# создаем класс, с пропускной способностью в 128к
$add_class $imq_dev parent 1:1 classid 1:12 htb rate $ALLUB
$add_class $imq_dev parent 1:12 classid 1:13 htb rate $AUR ceil $AUL
$add_qdisc $imq_dev parent 1:13 handle 13: $SFQ
# добавляем фильтры
$add_filtr $imq_dev parent 1: prio 11 protocol ip u32 match mark 0x100000 0x700000 flowid 1:11 # КГ - 100 мбит
$add_filtr $imq_dev parent 1: prio 13 protocol ip u32 match mark 0x200000 0x700000 flowid 1:13 # все, что не кг - 128к
}
Принцип думаю понятен.
ЗЫ возможны ошибки и вопросы. Брал куски кода из скриптов