From: napTu3aH <napTu @ front . ru>
Newsgroups: email
Date: Mon, 20 May 2005 14:31:37 +0000 (UTC)
Subject: Подробнее об использовании pipe-s в IPFW
В данной статье хочу поделиться собственными наработками в части ограничения
и распределения трафика для клиентов с помощью pipes в IPFW. Существующая
информация дает поверхностное описание и не описывает всех тонкостей работы
с pipes. В своём изучении pipes я основывался на известной статье by Kuzmich
( http://www.hub.ru/modules.php?name=Sections&sop=viewarticle&artid=24&page=4 ),
которая может дать толчек для начальных знаний, но оставляет при этом множество
вопросов. Здесь я приведу пример настроек в моей сети и опишу как это работает.
Когда настраиваются правила для IPFW, то перед запуском скрипта с новыми
правилами обычно производится очистка от старого набора при помощи команды
ipfw -f flush
как выяснилось, тоже самое необходимо делать и для pipes, т.е.
ipfw -f pipe flush
- для очистки всех каналов.
Подобным образом можно применять команду
ipfw -f queue flush
Итак, перед тем как описывать каналы и очереди, нужно представить себе как
это выглядит. Я разобрался в этих понятиях только после того как нарисовал
на бумаге следующую конструкцию:
канал pipe с параметрами:
queue Q - размер очереди (отброс не поместившихся в очередь пакетов)
bw B - скорость выхода пакетов в [K|M]bit/s
delay D - дополнительная задержка каждого пакета на D ms
_____________________________________________
< очередь queue 1 описывается параметрами:
queue Q - размер очереди (отброс не поместившихся в очередь пакетов)
weight 50 - весовой коэффициент от 1 до 100 соответствует приоритету очереди
| пакет1 | пакет2|пакет3|...пакет Q|
_____________________________________________
< очередь queue 2 weight 40 | пакет1 | пакет2|пакет3|...пакет Q|
_____________________________________________
> очередь queue 3 weight 30 | пакет1 | пакет2|пакет3|...пакет Q|
_____________________________________________
> очередь queue 4 weight 20 | пакет1 | пакет2|пакет3|...пакет Q|
_____________________________________________
В правилах эта конструкция описыватся следующим образом:
"queue 20" приведено для примера и говорит о том что очередь имеет размер 20 пакетов
{
Место в скрипте, где описывается pipe не имеет значения. В множестве примеров
я видел это описание после обьявления правила для прохода пакетов через pipe,
однако сам описываю pipe в начале скрипта.
}
Но вернемся к приведенному выше рисунку нашей pipe.
---------
Из этого примера следует, что для работы группы пользователей по
ограниченному каналу с равными или разными приоритетами, необходимо
пакеты каждого отдельного пользователя ставить в отдельную очередь.
Тогда пакеты будут выходить из pipe в соответствии с приоритетами
очередей, в которых они находятся.
---------
Это и есть основная мысль, которая описывает разделение пакетов в pipe.
Теперь рассмотрим реализацию этого метода на практике.
Сперва задаем pipe
ipfw pipe 1 config bw 80Kbit/s queue 20
Если скорость pipe соответствует пропускной способности канала,
то установка правильного значения имеет большое влияние
на корректную работу системы разделения трафика.
К примеру, в моей сети установлен модем Sirius с выделенным каналом 115
Кбит/с, однако для правильной работы pipe я устанавливаю 80Кбит/с, т.к.
это примерно соответствует реальному значению скорости в канале. При
установке значения скорости большего, чем может обеспечить канал, вся
система разделения перестаёт работать.
Это можно показать на следующем примере. Пусть в сети через один канал
работают два пользователя через очереди с равными приоритетами. Реальная
пропускная способность канала 80Кбит/с, но мы устанавливаем pipe
110Кбит/с.
Оба пользователя непрерывно качают примерно одинаковый поток данных.
Один из них начал качать раньше. Когда появился второй, то система
начала ограничивать поток для первого до 110/2=55 Кбит/с. Считая что
второму также будет отведено 55Кбит/с, однако из-за того что реальная
пропускная способность канала 80Кбит/с, то второму пользователю будет
предоставлено всего 80-55=25Кбит/с. Кроме того возможно система будет
считать, что второй пользователь не использует выделенный ему канал и
давать еще больший приоритет первому, чтобы довести общий поток до
110Кбит/с.
После создания pipe нам необходимо создать очереди queue. Если всем
пользователям необходимо равномерно распределять поток, то создавать
вручную количество очередей соответствующее количеству пользователей не
нужно. Мы создаем всего одну очередь
но приписываем параметр mask, в котором указываем что для каждого
отдельного destination адреса будет создаваться своя очередь с такими же
параметрами, как у этой.
{
Здесь я не согласен с примерами приведенными у Кузмича, где
маска адреса установлена в 0x00000000. При такой маске не происходит
разделения на отдельные очереди и все пакеты на любые destination
адреса заносятся в одну единственную очередь, из которой они сходят
в таком же порядке в котором они туда попали. При этом не происходит
никакого реального разграничения по приоритетам
или равномерного разделения.
}
Реально работающую pipe с очередями можно просмотреть командой
ipfw pipe show
Эта команда практически нигде не описана, но очень сильно помогает
в настройке работы pipe и в понимании работы системы в целом.
Параметр mask можно установить в all. Казалось бы - это то что нужно
и каждый адрес будет выделен в отдельную queue,
но нет. mask all создает отдельные очереди не только для адресов, но еще и для
протоколов. Кроме того разграничиваются как входящие так и исходящие адреса.
В результате получается полный хаос - создается море очередей, где
трафик делится по интернет адресам, протоколам и месным адресам.
Для себя я нашел следующее решение.
Создаем две очереди для входящего и исходящего трафика
ipfw add queue 1 ip from any to 192.168.0.0/24
ipfw add queue 11 ip from 192.168.0.0/24 to any
Таким образом очередь 1 будет являться образцом для создания очередей
с трафиком идущим на каждый отдельный ip нашей сети, а очередь 11
- соответственно примером для исходящего трафика с каждого нашего ip.
Эти четыре записи будут соответствовать тому как если бы мы
создали количество очередей соответствующее количеству IP адресов в нашей
сети и создали бы такое же количество правил для прохождения трафика и
разделили бы каждую запись на входящий и исходящий трафик.
Если Вам необходимо выделить еще несколько разных приоритетов,
для сильно вредных или сильно важных пользователей, то это можно сделать так:
#важным
ipfw add queue 3 ip from any to 192.168.0.233
ipfw add queue 31 ip from 192.168.0.233 to any
#вредным
ipfw add queue 2 ip from any to 192.168.0.154
ipfw add queue 21 ip from 192.168.0.154 to any
ipfw add queue 2 ip from any to 192.168.0.102
ipfw add queue 21 ip from 192.168.0.102 to any
#всем остальным
ipfw add queue 1 ip from any to 192.168.0.0/24
ipfw add queue 11 ip from 192.168.0.0/24 to any
Вот что мы получим в итоге.
Например работают три пользователя 192.168.0.1, 2, 3
Наша pipe будет выглядеть следующим образом:
pipe 1
> очередь queue 1 для трафика с любого интернет адреса на 192.168.0.1
_____________________________________________________________
> очередь queue 1 для трафика с любого интернет адреса на 192.168.0.2
_____________________________________________________________
> очередь queue 1 для трафика с любого интернет адреса на 192.168.0.3
____________________________________________________________________
____________________________________________________________________
< очередь queue 11 для трафика с адреса 192.168.0.1 на любой адрес интернет
_____________________________________________________________________
< очередь queue 11 для трафика с адреса 192.168.0.2 на любой адрес интернет
_____________________________________________________________________
< очередь queue 11 для трафика с адреса 192.168.0.3 на любой адрес интернет
Итак, запускаем скрипт, исправляем ошибки и смотрим что получилось