Помогите советом!!!
Нужно шейпить траффик, идущий в интернет - через PPPoE, подключен к WAN(скорости заданы явно), но при этом, чтобы не резался канал к роутеру!
Что для этого лучше поставить? Хочется чтобы качалка тоже работала!
Просто стандартый шейпер (в Вебе) режет скорость на LAN и только на прием
А объясните дураку, плиз, как оно работает для траффика VoIP?
На исходящем все понятно - ограничиваем весь канал на "чуть меньше чем оно есть на самом деле", чтобы оно не скапливалось в узком месте (я так понимаю, что если VPN-соединение и DSL-модема просто нету - то тотальное ограничение не нужно?), далее делим это дело на три трубки, в первую пихаем исходящий VOIP (по портам или ToS - не важно), в третью - всякую фигню типа bittorrent, во второй остается все остальное (я еще http туда с prio 2 добавил).
Итого, если у нас есть пакеты, классифицируемые как VOIP - пихаем их в первую очередь.
Но ведь к нам тоже идет поток "оттуда". Как его шейпить? Во всех wshaper я нашел тока зажатие входящего канала на DOWNLINK.
Вопросы:
1. Правильно ли я понимаю, что если нет DSL-модема, то ограничение в классе 1:1 можно снять? Можно ли убрать весь класс, переставив паренты для 1:10, 1:20 и 1:30 на 1:0?
2. Для чего делается шейпинг DOWNLINK?
3. Как он реально работает? Посылаем ли мы "отлупы" исходящей стороне, если пакет все равно к нам пролез?
4. Почему нельзя в случае наличия входящих пакетов VOIP ограничивать входящий траффик для остального?
5. Как правильно классифицировать входящий VOIP траффик в случае, если у него нет ToS? Только по портам? Какой критерий можно считать подходящим в общем случае сферического IP-телефона в вакууме?
Спасибо за ответы, если они будут
нет, это на входящем. а на исходящем не важно, где дропаются пакеты, у нас или у провайдера.
почему? Параметры тарифа скажите.
да, но в начале темы написано: тогда не будет работать динамическое распределение. это значит, что для bittorrent выставлена скорость 1/10 от общей, то она так и останется, даже если другие классы не заняты
Last edited by leniviy; 30-03-2008 at 08:58.
как это для чего?
если вы говорите про ingress в wshaper : независимо от того, wshaper или shape-test, отправитель не получает уведомления, что пакет дошел, и снижает скорость отправки. Но shape-test лучше, хоть режте.
можо
да. еще можно считать весь UDP высокоприоритетным.
king2, скажите ваш город, провайдера, тариф и есть ли локалка провайдера
Как это не важно? Если мы не зашейпим у себя исходящий поток, то оно ввалится по 100 мегабит в DSL-модем, и уже там будет кучковаться. Значит, когда мы что-то изменим в исходящем потоке у себя на асусе, реально оно уйдет в узкий канал только после того, как пройдет вся та куча, которая уже накопилась в DSL-модеме. И получается, что время реакции становится сильно больше, плюс модем тоже начинает регулировать поток (давать отлупы на то что не лезет в канал). То есть полный дестрой и разруха..
Стало быть, мы должны ограничить поток на асусе на 95-99% от того что есть в самом узком месте исходящего потока, чтобы пакет через DSL пролетал гарантированно быстро. А вот у провайдера исходящий поток, как правило, не дропается, по крайней мере на первой паре хопов, у них каналы широкие
А вот зато если интерфейс терминируется УЖЕ у провайдера (l2tp/pptp/pppoe) - то вроде бы ограничивать и не надо. Другое дело, может ядро должно знать заранее, на что ему рассчитывать, чтобы упираться в заранее заданный цифрами потолок, а не в ситуацию "не лезет по факту"?
Москва, Корбина, 9200/9200 мегабит, L2TP VPN соединение поверх MAN. Локалка имеется, стало быть шейпим на ppp0, а не на физических интерфейсах..
Ага, понял. То есть классы, привязанные к другому parent классу, могут делить друг с другом траффик, а привязанные к root qdisc - не могут?
Но это все касается UPLINK, то есть от нас к провайдеру.
Касательно DOWNLINK (от провайдера к нам). Как я понял, ограничение сделано как раз, чтобы мы не посылали ACK к провайдеру, если нам прислали "больше чем надо", тем самым регулируя входящий поток аж на передающей стороне. И тем самым мы гарантируем, что избыток пакетов не будет скапливаться у провайдера в очереди "к нам".
Вопрос в том, можно ли к ingress привязвать классы так же, как это сделано для UPLINK, чтобы регулировать потоки на той стороне, а также почему это не сделано в изначальном wshaper? Ведь регулирование только исходящего VoIP никак не влияет на входящий VoIP...
p.s. Пошел разбираться в shape-test.
UPD: aх да, забыл сказать. С самого роутера траффика практически нет, торренты качаются с одного из компов. VoIP отдельной железякой, но надо чтобы и с компа можно было софтфонами звонить.
Last edited by king2; 30-03-2008 at 16:03.
хз, как это делается с асусом. штука называется
Linux IMQ - Intermediate Queueing Device. Я бы сам не отказался от этого. Но поиск по этому форуму ничего не дал.
Я считаю так, раз у вас нет исходящего трафика, повесьте шейпер только на br0. а пакеты из локалки надо отфильтровать в отдельный быстрый класс
Простите но кто нибуть сможет ответить на заданный тут вопрос-
http://wl500g.info/showpost.php?p=89921&postcount=48
Для начала, я попытался разобраться в том, как работает wshaper. Я был удивлен двумя фактами:
1. Входящая в локалку очередь поджимается полисингом только для того, чтобы избежать очереди на стороне провайдера, а приоретизация и шейпинг не используются.
2. Используется тупой метод влияния на траффик - дропание пакетов. Не используется ни ECN (Explicit Congestion Notification), ни icmp source quench.
Я долго медитировал и пытался понять, как wshaper может обеспечивать приоритетную полосу для ВХОДЯЩЕГО VoIP траффика, перечитал много доков, но так
ничего и не понял. Глаза мне открыл leniviy, рассказав, что wshaper этой задачей не занимается, а следовательно, ее и не решает. Полумерой является
шейпинг исходящих от нас ACK пакетов, но он позволяет выделить для VoIP полосу очень неточно и оценочно. Фактически, мы не можем судить о входящем
трафике по количеству исходящих ACK пакетов, потому что размер данных во входящих пакетах нам неизвестен, известно только количество собственно пакетов.
А в shape-test все было сделано так просто потому, что у leniviy в роутере стоит качалка и поэтому траффик, который хочется зажать, просто не уходит в
локалку. Таким образом, shape-test является вынужденным решением-полумерой для тех людей, у кого качалка стоит на роутере, и весьма хреновым для тех,
у кого сам роутер трафик почти не потребляет и не генерирует (ssh/telnet/web-интерфейс не считаем). Оригинальный же wshaper плевать хотел на входящий
траффик, просто поджимая ему полосу для того, чтобы пакеты не скапливались в очереди провайдера. Однако, ingress полисинг дропает ВСЕ не попавшие в
разрешенную полосу пакеты, не разбираясь, VOIP это было или еще что. Таким образом, если у провайдера и были какие-то настройки QoS на роутере, тем
самым мы не даем им работать, пришибая у себя все пакеты без разбора.
Таким образом, после выяснения, что все сделано так не из каких-то хитрых соображений, которые я не могу догнать в силу ничтожности своего мозга, а
по некоторым определенным (shape-test+качалка на роутере) либо неопределенным (wshaper) причинам, родилось очевидное решение:
Устаналиваем исходящий фильтр а-ля wshaper на WAN интерфейс + такой же фильтр на br0 (разрешая unlimited для того что живет на стороне MAN) и все,
золотой ключик у нас в кармане. ingress же в таком случае не нужен вовсе.
По поводу второй непонятки:
ICMP source quench, насколько я понял, не поддерживается самой шейпилкой, а по поводу ECN выяснилось, что ECN поддерживется только начиная с Windows
Vista, да и то по умолчанию отключен (значит, будет работать хреново для потока изнутри нашей сети). И для предудыщего случая (shaping только исходящего
трафика) он бесполезен. С другой стороны, и в linux, и в freebsd оно давно есть и работает, так что потоки с серверов (входящие) им пришибать вполне
получится. Это даст нам возможность более мягко влиять на канал, а в случае, если передающая сторона не понимает, мы переходим к обычному дропу.
Чтобы работало ECN, надо использовать RED (random early detection). Ее преимущество в том, что оно умеет плавно грохать трафик посредством отсылания
пакетов с выставленными битами ECN и таким образом заставлять посылающую сторону временно прикрыть фонтан. Также оно умеет случайным образом с какой-то
вероятностью (чем больше очередь тем больше вероятность) грохать пакеты в очереди, не дожидаясь, пока они забьют всю очередь и больше не будет возможности
выбирать, что грохнуть (а придется грохать все что в очередь не влезло). Эта штука не работает для UDP траффика, потому что вместо плавной регулировки
скорости мы получаем некий гарантированный процент дропов (вполне возможно, что и на пустом месте). А UDP не предусматривает средств для перепосылки пакетов.
Таким образом, мы можем использовать этот метод только для мусорного _TCP_ траффика, и в этом случае не будет работать SFQ, что может вызывать затыки.
Второе ограничение дает нам использовать RED только для торрентов, то есть для траффика, который в основной своей массе генерится компьютерами под
windows (которые, напомню, ECN не особо умеют). Итого, решение как таковое существует, но для практического применения сейчас бесполезно.
Несколько пояснений для тех, кто хочет разобраться и для самопроверки (если я неправ, поправьте меня):
Все растет от qdisc root. Мы даем ей handle и говорим, как будем распределяться траффик внутри нее (htb). Можно указать default, но не обязательно.
Далее мы привязываем к root qdisc некий класс 1:1. Ему мы тоже говорим, что внутри него все будет распределяться через htb. Также можно привязать
промежуточный класс 1:2, и зашейпить уже на нем, тогда можно будет пропускать траффик мимо шейпера (например, MAN траффик). Все подклассы, привязанные
к 1:1 (или 1:2) будут перетаскивать друг у друга свободную часть канала (можно делиться друг с другом каналом только в пределах класса, в пределах
root - нельзя). Это, кстати, можно использовать для того, чтобы выделять гарантированный канал для чего-либо (который не будет занят, даже если там
нет никаких данных).
Далее имеется несколько классов, привязанных к классу 1:2. Им мы указываем 4 параметра:
ceil - скорость, выше которой данные этого класса передаваться не будут (никогда).
rate - скорость, на которой данные этого класса будут передаваться при полной загрузке канала
По идее, сумма всех rate классов одного parent должна быть равна rate, указанного для parent этих классов. Для ceil та же фигня.
Тогда при полной загрузке канал будет делиться так же, как соотносятся между собой rate.
prio - приоритет передачи данных. При выборе данных для передачи сначала выбираются пакеты с мЕньшим приоритетом.
burst - количество данных, которых мы можем послать на скорости ceil до того, как упадем до скорости rate при загруженном канале. Если у нас для HTTP
установлен rate 100kbit cail 300kbit, первые burst байтов мы пошлем на высокой скорости, затем упадем до rate (или даже ниже, чтобы скомпенсировать
первоначальную большую скорость). то есть, если мы будем качать много данных, мы быстро скачаем первые burst байтов, затем медленнее rate скачаем еще
сколько-то, и постепенно выровняемся на скорости rate. Но если нам надо только одна страничка на 64 килобайта, мы скачаем ее БЫСТРО и затем, пока мы
ее читаем, burst "перезарядится", чтобы дать нам скачать еще burst байтов быстро. Не должен быть больше чем burst, указанный для parent.
Также нам необходимо сказать, каким образом внутри класса будет происходить выбор пакета для отправки. По умолчанию это PRIO, что нам не подходит, ибо
тогда, пока у нас в очереди имеется что-то с prio 0 - все, что имеет мЕньший приоритет, просто не будет послано.
Простейший способ - это назначить Stochastic Fairness Queueing (sfq). Эта штука делит все, что лежит в очереди, на части по некоторому алгоритму, и затем
простым перебором посылает по одному пакету из каждой части. Раз в perturb секунд алгоритм меняется, чтобы обеспечить справедливость. Это даст нам возможность
распределять полосу равномерно между потоками. Заметим, что если запихать в один класс торренты и скачивание по HTTP, то HTTP получит примерно ту же полосу,
что и один из 50 торрентовских потоков. Нинада так делать.
Назначать SFQ для торрентов не надо, иначе полоса будет делиться между обычными скачами и торрентами тоже *понятно, что 50 торрентов заберут больше
чем одно скачивание по http). По крайней мере у меня оно было именно так.
Далее займемся классификацией трафика:
Приоритеты фильтров - это по пусти, порядок, в котором фильтры будут просматриваться. Если мы словили совпадение,
пакет относится к тому классу, к какому сказал фильтр. Поэтому делаем так:
1 приоритет, 50-100% канала:
prio 1. VOIP (по полю TOS - настраивается на моем шлюзе)
prio 1. ICMP - чтобы контроллировать, что QoS работает
prio 1. весь протокол UDP, сюда же попадают пакеты от хреновых софтофонов
prio 1. ACK пакеты, чтобы не задерживать данные в обратном (к нам) канале
prio 1. TOS minimum delay (0x10)
2 приоритет, 40-100% канала:
prio 1. HTTP траффик (по src/dst port = 80|443)
prio 7. все остальное
3 приоритет, 10-100% канала:
prio 5. uTorrent, патченный, чтобы маркировать свои пакеты как TOS=0x30
prio 5. uTorrent, TCP на порт 4663 (мой входящий порт).
prio 5. uTorrent, TCP на порты, помеченные в моем торренте как исходящие (255 штук)
То есть сначала пытаемся привязать пакет по признакам prio1, потом турренты, все остальное - неприякаянное и идет во класс 1:20.
Получилось вот что:
shape.sh:
wshaper-king2.sh:Code:#!/bin/sh # Wonder Shaper, last modified by Oleg King (aka king2) # # shape.sh DEV SPEED DEV="$1" SPEED="$2" # install root HTB, shape everything to collect all the queue in our router, and divide traffic into 3 parts tc qdisc add dev $DEV root handle 1: htb default 777 tc class add dev $DEV parent 1:0 classid 1:1 htb burst 256k rate 100mbit ceil 100mbit tc class add dev $DEV parent 1:1 classid 1:2 htb burst 64k rate ${SPEED}kbit ceil ${SPEED}kbit # setclass: device, class_id, prio, total uplink, percentage of uplink tc class add dev $DEV parent 1:2 classid 1:10 htb burst 64k rate $((50*$SPEED/100))kbit ceil ${SPEED}kbit prio 1 tc class add dev $DEV parent 1:2 classid 1:20 htb burst 64k rate $((40*$SPEED/100))kbit ceil ${SPEED}kbit prio 2 tc class add dev $DEV parent 1:2 classid 1:30 htb burst 64k rate $((10*$SPEED/100))kbit ceil ${SPEED}kbit prio 3 tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10 tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10 #tc qdisc add dev $DEV parent 1:30 handle 30: sfq perturb 10 # PRIO1 --- Business class traffic --- # high priority for VoIP traffic (by TOS) tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \ match ip tos 0x68 0xff \ match ip protocol 0x11 0xff \ flowid 1:10 tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \ match ip tos 0xb8 0xff \ match ip protocol 0x11 0xff \ flowid 1:10 # ICMP (ip protocol 1) in the interactive class tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \ match ip protocol 1 0xff \ flowid 1:10 # all UDP traffic are interractive tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \ match ip protocol 0x11 0xff \ flowid 1:10 # to make downloads fast while an upload is going on, speed up ACK packets tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \ match ip protocol 6 0xff \ match u8 0x05 0x0f at 0 \ match u16 0x0000 0xffc0 at 2 \ match u8 0x10 0xff at 33 \ flowid 1:10 # TOS Minimum Delay (ssh, NOT scp) tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \ match ip tos 0x10 0xff \ flowid 1:10 # PRIO2 --- Economy class traffic --- # web browsing is better than other traffic tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \ match ip sport 80 0xffff flowid 1:20 tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \ match ip dport 80 0xffff flowid 1:20 tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \ match ip sport 433 0xffff flowid 1:20 tc filter add dev $DEV parent 1:0 protocol ip prio 1 u32 \ match ip dport 433 0xffff flowid 1:20 # other traffic goes to default 1:20 tc filter add dev $DEV parent 1:0 protocol ip prio 7 u32 \ match ip dst 0.0.0.0/0 flowid 1:20
Комментарии?Code:#!/bin/sh # Wonder Shaper, last modified by Oleg King (aka king2) # # wshaper-king2 (start|stop|status) WAN LAN UPLINK DOWNLINK WAN=$2 LAN=$3 UPLINK=$4 DOWNLINK=$5 # show status and exit if [ "$1" = "status" ] then echo "Outgoing traffic:"; echo "-----------------"; tc -s class ls dev $WAN echo "Incoming traffic:"; echo "-----------------"; tc -s class ls dev $LAN exit fi # clean existing downlink and uplink qdiscs, hide errors tc qdisc del dev $WAN root 2> /dev/null > /dev/null tc qdisc del dev $LAN root 2> /dev/null > /dev/null if [ "$1" = "stop" ] then exit fi ### WAN ### /usr/local/sbin/shape.sh $WAN $UPLINK # PRIO3 --- torrents will fly with laggage ToS=0x3f and ports 4663 + 21760-22015 --- tc filter add dev $WAN parent 1:0 protocol ip prio 5 u32 \ match ip tos 0x3f 0xff \ flowid 1:30 tc filter add dev $WAN parent 1:0 protocol ip prio 5 u32 \ match ip sport 0x5500 0xff00 \ flowid 1:30 tc filter add dev $WAN parent 1:0 protocol ip prio 5 u32 \ match ip sport 4663 0xffff \ flowid 1:30 ### LAN ### /usr/local/sbin/shape.sh $LAN $DOWNLINK # PRIO0 --- MAN always first and unlimited tc filter add dev $LAN parent 1:0 protocol ip prio 1 u32 \ match ip src 192.168.1.1/32 \ flowid 1:2 tc filter add dev $LAN parent 1:0 protocol ip prio 1 u32 \ match ip dst 192.168.1.1/32 \ flowid 1:2 MANLIST=`ip route | grep vlan1 | grep -v default | awk '{print $1}'` for a in $MANLIST do echo "adding $a to MAN filter..." tc filter add dev $LAN parent 1:0 protocol ip prio 1 u32 \ match ip src $a flowid 1:2 tc filter add dev $LAN parent 1:0 protocol ip prio 1 u32 \ match ip dst $a flowid 1:2 done # PRIO3 --- torrents will fly with laggage --- (dst ports 4663 + 21760-22015) tc filter add dev $LAN parent 1:0 protocol ip prio 5 u32 \ match ip dport 4663 0xffff \ flowid 1:30 tc filter add dev $LAN parent 1:0 protocol ip prio 5 u32 \ match ip dport 0x5500 0xff00 \ flowid 1:30
Last edited by king2; 11-04-2008 at 16:53.