Шейпим трафик, используя hash фильтры tc (Повесть о моих мучениях.)

Обсуждение настройки и работы сервисов, резервирования, сетевых настроек и вопросов безопасности ОС.

Модератор: SLEDopit

Ответить
Tokra
Сообщения: 399

Шейпим трафик, используя hash фильтры tc

Сообщение Tokra »

Недавно, я решил разобраться, что такое hash фильтры в tc и с чем их едят. Может быть кому-то будет полезно, особенно для начинающих в этом вопросе, как я сам.

Взял для себя простейший пример:
Изображение

Все опыты я проводил под управлением wmvare.
Для этого нам понадобится:
Виртуальная машина на которую мы поставим любой дистрибутив gnu/linux (я не заморачивался и установил себе ubuntu server).
Две виртуальные машины под управлением windows xp.
Как настроить сеть на gnu/linux и windows, я описывать не буду, думаю, с этим сложностей возникнуть не должно.

Итак на нашем сервере присутствуют две сетевых каты:
eth0 - ip 192.168.0.10/24, она у нас смотрит в мир и на ней поднят nat (iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.0.10)
eth1 - ip 192.168.200.254/24 у нас смотрит в локалку.

Шейпить мы можем только исходящий трафик с интерфейса. Для наших клиентов (pc0 - ip 192.168.200.10 и pc1 - ip 192.168.200.20) скорость закачки (download) мы будем шейпить на интерфейсе eth1, т.к. для этого интерфейса трафик будет исходящим в сторону клиента.

Логично для отдачи (upload) использовать eth0, но тут есть один нюанс, на этом интерфейсе у нас висит nat и шейпить на нем исходящий трафик от клиентов у нас не получиться. Что бы решить данную проблему, мы будет заворачивать весь входящий трафик от клиентов на интерфейсе eth1 в виртуальный интерфейс ifb0, тем более, на данный момент, поддержка IFB есть в ядре.

И так приступим.
Для начала нарежем для наших пользователей download:

1. Создаем корневую дисциплину на интерфейсе eth1
tc qdisc add dev eth1 root handle 1: htb default 20
2. Далее создаем корневой класс для наших клиентских классов. Скорость у него будет 1 mbit, для тестов нам достаточно
tc class add dev eth1 parent 1: classid 1:1 htb rate 1024kbit
3. Теперь создадим таблицу 10 на 256 ячеек
tc filter add dev eth1 parent 1:0 prio 1 handle 10: protocol ip u32 divisor 256
4. Создаем фильтр, направлящий весь трафик в хеш таблицу с ID 10
tc filter add dev eth1 parent 1:0 protocol ip u32 ht 800:: match ip dst 192.168.200.0/24 hashkey mask 0x000000ff at 16 link 10:
5. Ну а теперь мы будем нарезать скорость для наших двух клиентов, для pc0 - 256 kbit, а для pc1 - 512 kbit
5.1. Созадем класс 100 со скоростью 256 kbit для pc0

tc class add dev eth1 parent 1:1 classid 1:100 htb rate 256kbit ceil 256kbit prio 2 quantum 15365
5.2. Создаем дисциплину шейпирования для конечного класса
tc qdisc add dev eth1 parent 1:100 handle 100: sfq perturb 10
5.3. Заворачиваем весть трафик для ip 192.168.200.10 в класс 100
tc filter add dev eth1 protocol ip prio 2 u32 ht 10:a: match ip dst 192.168.200.10/32 flowid 1:100
5.4. То же самое, но для pc1
tc class add dev eth1 parent 1:1 classid 1:200 htb rate 512kbit ceil 512kbit prio 2 quantum 15365
tc qdisc add dev eth1 parent 1:200 handle 200: sfq perturb 10
tc filter add dev eth1 protocol ip prio 2 u32 ht 10:14: match ip dst 192.168.200.20/32 flowid 1:200

6. Весь трафик, который не подпадает под указанные правила будет заворачиваться в класс по умолчанию 20
tc class add dev eth1 parent 1:1 classid 1:20 htb rate 32kbit ceil 32kbit prio 2 quantum 15365
tc qdisc add dev eth1 parent 1:20 handle 20: sfq perturb 10


Теперь нам необходимо нарезать upload, как я писал ранее. Для этого мы будем использовать виртуальный интерфейс ifb0, куда будет заворачиваться весь входящий трафик от пользователей на интерфейс eth1.

Приступим:
1. Подключаем модуль ядра для ifb
modprobe ifb
2. Поднимаем интерфейс ifb0
ip link set dev ifb0 up
3. Создаем корневую дисциплину для входящего трафика на интерфейсе eth1
tc qdisc add dev eth1 ingress
4. Теперь непосредственно заворачиваем трафик в ifb0
tc filter add dev eth1 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0
5. А далее по аналогии с исходящим трафиком с интерфейса eth1
5.1. Создаем корневую дисциплину и класс

tc qdisc add dev ifb0 root handle 1: htb default 20
tc class add dev ifb0 parent 1: classid 1:1 htb rate 1024kbit

5.2. Описываем правила для pc0
tc class add dev ifb0 parent 1:1 classid 1:100 htb rate 256kbit ceil 256kbit prio 2 quantum 15365
tc qdisc add dev ifb0 parent 1:100 handle 100: sfq perturb 10
tc filter add dev ifb0 protocol ip prio 2 u32 ht 800:: match ip src 192.168.200.10/32 flowid 1:100

5.3. Теперь для pc1
tc class add dev ifb0 parent 1:1 classid 1:200 htb rate 512kbit ceil 512kbit prio 2 quantum 15365
tc qdisc add dev ifb0 parent 1:200 handle 200: sfq perturb 10
tc filter add dev ifb0 protocol ip prio 2 u32 ht 800:: match ip src 192.168.200.20/32 flowid 1:200

6. Ну и про класс по умолчанию не забываем
tc class add dev ifb0 parent 1:1 classid 1:20 htb rate 32kbit ceil 32kbit prio 2 quantum 15365
tc qdisc add dev ifb0 parent 1:20 handle 20: sfq perturb 10


Ну а теперь запускаем speedtest на наших клиентах и получаем результат.
Чуть не забыл, ht 10:14: ; ht 10:a: ; ht 800:: - это значения не в десятичной, а шестнадцатеричной системе исчисления.


Данная статья не претендует на эталон и писалась как шпаргалка для самого себя. В ней могут быть и, скорее всего, будут ошибки. Буду благодарен за конструктивную критику и за найденные ошибки.
Спасибо сказали:
Аватара пользователя
kisil
Сообщения: 204
ОС: Slackware 13,37-14

Re: Шейпим трафик, используя hash фильтры tc

Сообщение kisil »

Нормальная статья. :notworthy:
Спасибо сказали:
Tokra
Сообщения: 399

Re: Шейпим трафик, используя hash фильтры tc

Сообщение Tokra »

kisil писал(а):
02.03.2011 22:16
Нормальная статья. :notworthy:

Спасибо!!!!
Вообще у tc есть проблема - он достаточно слабо документирован. А тем более на русском языке. До многих моментов просто приходится доходить методом тыка...
Спасибо сказали:
Аватара пользователя
kisil
Сообщения: 204
ОС: Slackware 13,37-14

Re: Шейпим трафик, используя hash фильтры tc

Сообщение kisil »

Ага точно. Я пробывал настроить обрезку трафика только с помощью HTB. Долго мучалса пока понял как обрезать трафик и настроил резалку. Но всёравно что то не дошло, ну ничего когда нибуть разберусь.
Спасибо сказали:
Аватара пользователя
Alex2ndr
Сообщения: 443
ОС: Debian Lenny

Re: Шейпим трафик, используя hash фильтры tc

Сообщение Alex2ndr »

Нормальная шпаргалка. Только уберите пожалуйста больщое кол-во пустых строк, а то читать трудно. И возможно при таком способе подачи материалов(т е небольшое объяснение и строка кода) стоило бы оформлять команды не тегом code, а просто жирным шрифтом, ибо большое кол-во красных заголовков сбивает с толку и не дает сосредоточится на самом коде под этим заголовком. Но это все имхо...
Спасибо сказали:
Tokra
Сообщения: 399

Re: Шейпим трафик, используя hash фильтры tc

Сообщение Tokra »

Alex2ndr писал(а):
03.03.2011 10:39
Нормальная шпаргалка. Только уберите пожалуйста больщое кол-во пустых строк, а то читать трудно. И возможно при таком способе подачи материалов(т е небольшое объяснение и строка кода) стоило бы оформлять команды не тегом code, а просто жирным шрифтом, ибо большое кол-во красных заголовков сбивает с толку и не дает сосредоточится на самом коде под этим заголовком. Но это все имхо...

Спасибо за дельное замечание, подправил, а то, действительно, сильно растянуто получилось.

kisil писал(а):
03.03.2011 09:01
Ага точно. Я пробывал настроить обрезку трафика только с помощью HTB. Долго мучалса пока понял как обрезать трафик и настроил резалку. Но всёравно что то не дошло, ну ничего когда нибуть разберусь.

Я вообще еще не видел ни одного админа, который полностью разобрался с tc!!! А хеш фильтры в документации практически не освещены.
Спасибо сказали:
Pchol
Сообщения: 88

Re: Шейпим трафик, используя hash фильтры tc

Сообщение Pchol »

Хеш фильтры актуальны если у вас "горизонтально" расположено огромное количество фильтров (овер 2-3к). Дают неслабый прирост производительности.
И насколько я помню если у вас на этой же машине НАТ, то схема с ifb не прокатит. остаётся только ingress
... Весь ужас заключается в том что предают только свои ...
Спасибо сказали:
Tokra
Сообщения: 399

Re: Шейпим трафик, используя hash фильтры tc

Сообщение Tokra »

Pchol писал(а):
03.03.2011 15:04
Хеш фильтры актуальны если у вас "горизонтально" расположено огромное количество фильтров (овер 2-3к). Дают неслабый прирост производительности.
И насколько я помню если у вас на этой же машине НАТ, то схема с ifb не прокатит. остаётся только ingress

Да хеш фильтры дают неплохую производительность. Да и заморачиваться с iptables не надо.
На счет ната и ifb: все прекрасно работает. Я как раз такую схему в этом примере и рассматривал

Логично для отдачи (upload) использовать eth0, но тут есть один нюанс, на этом интерфейсе у нас висит nat и шейпить на нем исходящий трафик от клиентов у нас не получиться. Что бы решить данную проблему, мы будет заворачивать весь входящий трафик от клиентов на интерфейсе eth1 в виртуальный интерфейс ifb0, тем более, на данный момент, поддержка IFB есть в ядре.
Спасибо сказали:
Аватара пользователя
Ленивая Бестолочь
Бывший модератор
Сообщения: 2760
ОС: Debian; gentoo

Re: Шейпим трафик, используя hash фильтры tc

Сообщение Ленивая Бестолочь »

я тоже присоединюсь и скажу, что очень хорошая статья. полезная тема, респект. :-)
Солнце садилось в море, а люди с неоконченным высшим образованием выбегали оттуда, думая, что море закипит.
Спасибо сказали:
Tokra
Сообщения: 399

Re: Шейпим трафик, используя hash фильтры tc

Сообщение Tokra »

Ленивая Бестолочь писал(а):
03.03.2011 21:51
я тоже присоединюсь и скажу, что очень хорошая статья. полезная тема, респект. :-)

Спасибо большое!!!
Просто сам очень много времени потратил, пока разобрался в таком простом примере, много подводных камней и недокументированных возможностей.
Решил запостить, что бы другие не тратили времени.
Спасибо сказали:
harry
Сообщения: 2
ОС: Ubuntu

Re: Шейпим трафик, используя hash фильтры tc

Сообщение harry »

Добрый день. Решаю похожую задачу - вот и решил обратиться к вам.
Есть сервер, eth0 - смотрит в инет, eth1 - смотрит в локалку, NAT включен, и клиенты заходят через VPN (pptp)

Необходимо создать шейпер с динамической шириной канала, т.е. если качает один юзер - чтобы ему давался весь канал, если двое - то канал делился пополам и т.д. Вся сложность заключается в том что для каждого юзера при подключении поднимается свой интерфейс и некуда повесить корневой класс. Если же заворачивать:

Код: Выделить всё

tc qdisc add dev eth0 ingress handle ffff:
tc filter add dev eth0 parent ffff: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0

то все равно не получается с помощью фильтров завернуть пользователей. Как можно решить данную задачу?
Спасибо сказали:
Tokra
Сообщения: 399

Re: Шейпим трафик, используя hash фильтры tc

Сообщение Tokra »

harry писал(а):
11.03.2011 10:50
Добрый день. Решаю похожую задачу - вот и решил обратиться к вам.
Есть сервер, eth0 - смотрит в инет, eth1 - смотрит в локалку, NAT включен, и клиенты заходят через VPN (pptp)

Необходимо создать шейпер с динамической шириной канала, т.е. если качает один юзер - чтобы ему давался весь канал, если двое - то канал делился пополам и т.д. Вся сложность заключается в том что для каждого юзера при подключении поднимается свой интерфейс и некуда повесить корневой класс. Если же заворачивать:

Код: Выделить всё

tc qdisc add dev eth0 ingress handle ffff:
tc filter add dev eth0 parent ffff: protocol all prio 10 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ifb0

то все равно не получается с помощью фильтров завернуть пользователей. Как можно решить данную задачу?


Вам необходимо шейпить абонентов на pppX интерфейсах.
Вот хорошая ссылка, там используют радиус атрибуты, но, я думаю, Вам не составит труда адоптировать под свои нужды.

Вот еще здесь можно почитать и позадавать вопросов по этой теме. Там сидят зубры по этим делам.
Спасибо сказали:
harry
Сообщения: 2
ОС: Ubuntu

Re: Шейпим трафик, используя hash фильтры tc

Сообщение harry »

Tokra писал(а):
11.03.2011 22:36
Вот еще здесь можно почитать и позадавать вопросов по этой теме. Там сидят зубры по этим делам.

ок, спасибо - пойду к зубрам :)
Спасибо сказали:
Аватара пользователя
watcher
Сообщения: 396
Статус: интересующийся
ОС: openSUSE,Mandriva
Контактная информация:

Re: Шейпим трафик, используя hash фильтры tc

Сообщение watcher »

а можно поподробнее, для тех кто в танке, что это?
ht 10:14: ; ht 10:a: ; ht 800

отвечаю сам себе. разжёвывание тут http://www.rusnauka.com/4_SWMN_2010/Inform...a/58922.doc.htm
"Я просто пытаюсь растить свой сад и не портить прекрасный вид.
И начальник заставы поймёт меня и беспечный рыбак простит" Б.Г.

http://zooom.com.ua/
Спасибо сказали:
aleksey200505
Сообщения: 1

Re: Шейпим трафик, используя hash фильтры tc

Сообщение aleksey200505 »

Статья сильная.
Вопрос есть, у меня 27 vlans и думаю не все еще, если заворачивать все VLANS интерфейсы на ifb0 получиться резать Upload траффик.
Пока что я терплю с этим фиаско. Download у меня давно работает, но вот Upload не поддается.
У кого есть мысли в один ifb0 все интерфейсы заворачивать, а потом фильтровать или придется создавать ifb[...] ?
Спасибо сказали:
Аватара пользователя
sunny1983
Сообщения: 357
ОС: GNU/Linux 4.x (Fedora, Debian)
Контактная информация:

Re: Шейпим трафик, используя hash фильтры tc

Сообщение sunny1983 »

Нужно очень научиться шейпить трафик. Статью вообще не понял, Читал различные руководства по tc, тоже непонятно какие такие дисциплины, классы и таблицы. И вообще по каком принцыпу работает шейпирование я не понимаю.

знаю что все сетевые функции в линукс выполняет ядро, а административные инструменты, такие как ifconfig, route, networking, iptables и tc сами ничего не делают, а являются только инструментами для управления сетевыми возможностями ядра. Для того, чтобы ограничить трафик до адресата, нужно чтобы ядро пропускало только часть пакетов, а остальные отбрасывало. Вот более понятно описано в другой теме Как настроить шейпер на локальную сеть, с корректным/справедливым делением входящего и исходящего трафика?. Там предлагается пакеты, подлежащие шейпингу сначала маркировать.

Это я у себя сделал. У нас есть арендаторы подключённые к сетевой карте eth2. Хочу ограничить им трафик до 10Мбит/c:

Код: Выделить всё

iptables -t mangle -A FORWARD -i ppp0 -o eth2 -j MARK --set-mark 7001
iptables -t mangle -A FORWARD -i eth2 -o ppp0 -j MARK --set-mark 7001

Теперь нужно написать правила для tc, а вот тут я не знаю куда все эти дисциплины, классы и таблицы совать.
Спасибо сказали:
Аватара пользователя
Olden Gremlin
Сообщения: 365
Статус: RAP22-RIPE
ОС: Debian GNU/Linux Wheezy
Контактная информация:

Re: Шейпим трафик, используя hash фильтры tc

Сообщение Olden Gremlin »

sunny1983 писал(а):
12.09.2012 13:05
Вот более понятно описано в другой теме Как настроить шейпер на локальную сеть, с корректным/справедливым делением входящего и исходящего трафика?. Там предлагается пакеты, подлежащие шейпингу сначала маркировать.
Маркировать ли, использовать ли ibf - это дело личных пристрастий. Пичалько состоит в том, что без понимания того чего хочется достигнуть, как в указанной статье, так и в этой, делать нечего, увы :(

В любом случае, для достижения понимания и облегчения работы, не перестаю нахваливать инструментарий tcng "Linux traffic control language interpreter":
Using /sbin/tc (to configure Linux network traffic flow control) is painful. This package attempts to reduce the pain with two new input languages (one for humans, and XML ;-). The output is XML, or /sbin/tc commands to configure the kernel.

«Когда у общества нет цветовой дифференциации штанов — то нет цели!»
nic-hdl: RAP22-RIPE
Спасибо сказали:
Аватара пользователя
sunny1983
Сообщения: 357
ОС: GNU/Linux 4.x (Fedora, Debian)
Контактная информация:

Re: Шейпим трафик, используя hash фильтры tc

Сообщение sunny1983 »

Olden Gremlin, почитал про tcng и понял что он ещё сложнее, чем просто tc, потому как тут нужно писать скрипты.
Но пытаюсь дальше разобраться с tc.
Вот я выполняю такую команду:

Код: Выделить всё

adminko@gate:~$ sudo tc qdisc show
qdisc pfifo_fast 0: dev eth0 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: dev eth1 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: dev eth2 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1

Я так понимаю, что исходящий трафик с трёх сетевых интерфейсов сервера управляется очередью pfifo_fast, которая трафик обрезать не умеет. А у меня задача - ограничить входящий трафик арендаторам до 10Мбит/с, которые подключены к eth2, то есть ограничить исходящий трафик с этого интерфейса.
Делаю, как описано в шапке этой темы:

Код: Выделить всё

adminko@gate:~$ sudo tc qdisc add dev eth2 root handle 2: htb default 20

И смотрю результат:

Код: Выделить всё

adminko@gate:~$ sudo tc qdisc show
qdisc pfifo_fast 0: dev eth0 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc pfifo_fast 0: dev eth1 root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
qdisc htb 2: dev eth2 root refcnt 2 r2q 10 default 20 direct_packets_stat 46

Так, неуправляемая очередь pfifo_fast заменилась на управляемую очередь htb. Теперь делаю дальше, как описано в шапке темы:

Код: Выделить всё

adminko@gate:~$ sudo tc class add dev eth2 parent 2: classid 2:1 htb rate 1024kbit

То есть, я создал класс для имеющейся у меня сейчас htb очереди с идентификатором 2: Почему же тогда команда "sudo tc class show" не выводит ничего?
Спасибо сказали:
Sizeoff
Сообщения: 1

Re: Шейпим трафик, используя hash фильтры tc

Сообщение Sizeoff »

Чтобы просмотреть классы "sudo tc class show" надо конкретно указать интерфейс:

Код: Выделить всё

# sudo tc class show dev eth2
Спасибо сказали:
Nexsys
Сообщения: 1
ОС: Linux

Re: Шейпим трафик, используя hash фильтры tc

Сообщение Nexsys »

Спасибо за описание статьи интересно но вот есть такая проблемка. описываю ситуацию есть клиентская база на более чем 3000 абонов. Также рассказываю настройки tc . Для раскидывания и принятия различного трафика используется система создающая виртуальные интерфейсы(их более 1000). Вот проблема в том что на каждом таком интерфейсе есть в среднем по 50 tc filter. Первый вопрос как эти правила загнать в хеш таблицу чтобы не гонять по 50 правил каждый раз. Дальше после того как он профильтруется он попадает на 4 указанных ifb интерфейса соответствующие входящим и исходящим определенным зонам . На этих интерфейсах висят tc class на зарезку скорости их там столько же сколько активных абонов. Вопрос второй как теперь за хешировать их через tc. Проблема вообще в том что из-за такого количества правил в tc проседает пинг и требуется как то все это оптимизировать. Просьба хотя бы приблизительно написать скелет того как будут строиться правила именно с хеш таблицами(ну так как описывается что hash таблицы это дело оптимизируют, но проблема в том что там хеширующая таблица которая описывается идет на разбиение подсетей, ну хорошо как это применить к моей системе буду очень благодарен!!!!) Пример Пример
Спасибо сказали:
THEDECAL!
Сообщения: 1
ОС: CentOS or Mint

Re: Шейпим трафик, используя hash фильтры tc

Сообщение THEDECAL! »

Здравствуйте... Подскажите пожалуйста... Если у меня на машине нет NAT`а (он на другой машине) и eth0 смотрит в Интернет, а eth1 поделён на 10 vlan`ов, то каким образом мне строить правила на исходящюю скорость?
Спасибо сказали:
Аватара пользователя
Olden Gremlin
Сообщения: 365
Статус: RAP22-RIPE
ОС: Debian GNU/Linux Wheezy
Контактная информация:

Re: Шейпим трафик, используя hash фильтры tc

Сообщение Olden Gremlin »

THEDECAL! писал(а):
08.04.2013 11:31
Здравствуйте... Подскажите пожалуйста... Если у меня на машине нет NAT`а (он на другой машине) и eth0 смотрит в Интернет, а eth1 поделён на 10 vlan`ов, то каким образом мне строить правила на исходящюю скорость?
Скорость из твоей сети должна нарезаться на eth0, а скорость в твою сеть на каждом конкретном vlan-е.
«Когда у общества нет цветовой дифференциации штанов — то нет цели!»
nic-hdl: RAP22-RIPE
Спасибо сказали:
vlad001
Сообщения: 55

Re: Шейпим трафик, используя hash фильтры tc

Сообщение vlad001 »

Приветствую! Использую скрипт htb.init отсюда. Проблема, если "пропадает" интерфейс ppp0, то шейпер перестаёт для него работать. Нужно заново рестартовать скрипт. Если использовать ifb можно эту проблему решить? Либо, есть ли ещё какое-то решение?
Спасибо сказали:
Ответить