Как-то давным давно, когда я только начинал изучать FreeBSD, я набрёл на статью про распределение приоритетов пакетов посредством QoS и сохранил её себе локально для регулярного просмотра и повышения своего уровня в данной сфере, так как она меня в тот момент вдохновила по уровню подачи информации. Хоть я уже и писал об этом, но всё же я думаю что вам тоже будет полезна и эта информация. Поэтому я выложил оригинальную копию данной статьи с соблюдением всех формальностей: копия один в один, указание прямой ссылки и т.д.
Итак, оригинал статьи:

FreeBSD QoS.

Автор статьи — Эдуард Афонцев

В связи с развитием интерактивных сервисов задача обеспечения качества обслуживания (QoS) в сетях передачи данных становится все более актуальной. Операционная система FreeBSD в базовой поставке содержит встроенный механизм поддержки QoS – DUMMYNET.

DUMMYNET.

В общем случае DUMMYNET можно рассматривать как средство ограничения полосы пропускания (Bandwidth limiting – Shaper), обеспечения очередей (Queuing) и эмуляции канала (Delay, Packet loss, Multipath).

Основными элементами DUMMYNET являются каналы (pipes) и очереди (queues):

Канал (pipe) является базовым элементом, эмулирующим линк с заданными параметрами (Bandwidth, Delay, Packet loss rate). На практике pipe используется для жесткого ограничения полосы пропускания (Bandwidth).

Очереди (queues) используются для распределения полосы пропускания. В DUMMYNET реализован механизм Weighted Fair Queuing (WFQ).

Общая схема использования DUMMYNET.

1. Конфигурируется ядро с поддержкой DUMMYNET

options IPFIREWALL
options DUMMYNET
options HZ=1000

Замечание:

DUMMYNET неразрывно связан с файерволлом (IPFW), поэтому опция IPFIREWALL обязательна.

2. Устанавливаются системные переменные

sysctl net.inet.ip.fw.one_pass — данный параметр определяет прохождение пакета, выходящего из pipe: пакет будет обрабатываться следующим правилом файерволла (sysctl net.inet.ip.fw.one_pass=0) или игнорироваться всеми дальнейшими правилами (sysctl net.inet.ip.fw.one_pass=1).

net.inet.ip.dummynet.hash_size — число динамических объектов (pipes или queues).

3. В зависимости от задачи конфигурируются каналы и очереди с заданными свойствами

На практике для жесткого ограничения полосы пропускания (Bandwidth) используется pipe, а для распределения полосы пропускания (WFQ) – queue.

4. Средствами файерволла (Ipfw) производится классификация трафика на потоки (flows), которые направляются к соответствующим объектам (каналам или очередям).

Замечание:

Пакеты, посланные к конкретному pipe или queue далее могут классифицироваться на несколько потоков, каждый из которых далее посылается к отдельному dynamic pipe или queue. В данном случае flow идентификатор конструируется с помощью параметра mask. Для каждого отличающегося flow (разделение с помощью mask) создается новый pipe или queue с параметрами оригинального объекта и пакеты посылаются к новому pipe или queue.

Если есть много хостов и нужно ограничение для каждого, то: или много pipes (или queues) или используем masks (т.е. masks используется для отделения независимых pipes (или queues)) и получаем несколко pipes (или queues) с параметрами описанного с mask объекта.

5. Потоки (Flows) проходят через объекты (каналы или очереди), претерпевая заданные свойствами объектов изменения.

Ограничение полосы пропускания (Shaping).

1. Определение трубы (канала)

# ipfw pipe PIPE_NUMBER config bw BANDWIDTH queue QUEUE_SIZE

Замечание:

Следует отметить, что pipe использует очередь внутри себя, причем ее параметры можно менять (queue QUEUE_SIZE), но это очередь внутри pipe, она отличается от объекта queue!

2. Классификация трафика

# ipfw add IPFW_NUMBER pipe PIPE_NUMBER tcp from IP_ADDR to IP_ADDR

Замечание:

Классификатор является стандартным правилом файерволла (ipfw) и направляет пакеты в pipe.

3. Просмотр текущей конфигурации

# ipfw pipe show
# ipfw pipe list

4. Удаление

# ipfw pipe PIPE_NUMBER delete
# ipfw pipe flush

Распределение полосы пропускания (WFQ).

1. Определение общей трубы (канала)

# ipfw pipe PIPE_NUMBER config bw BANDWIDTH queue QUEUE_SIZE

Замечание:

Размер очереди (queue QUEUE_SIZE) задается в так называемых слотах (пакетах) или байтах (по умолчанию 50 слотов). В некоторых случаях, например при небольшой ширине трубы BANDWIDTH, размер очереди по умолчанию может оказаться чрезмерно большим и приводить к неоправданным задержкам, что недопустимо.

Проиллюстрируем это на примере. Для Ethernetа размер очереди по умолчанию равен QUEUE_TOTAL=MTU*QUEUE_SIZE=1500(bytes)*50=12000(bit)*50=600(kbit). Если сделать BANDWIDTH=56 (kbit/s), то данная очередь заполнится за QUEUE_TOTAL/ BANDWIDTH ~10 (s), то есть возникнет большая задержка. Поэтому нужно указывать размер очереди отличный от размера по умолчанию. Например, pipe 10 config bw 56Kbit/s queue 5kbytes. Данная очередь заполнится за 5000*8/56000~0.7 (s).

2. Определение очередей (с весами) внутри канала (трубы)

# ipfw queue QUEUE_NUMBER config pipe PIPE_NUMBER weight WEIGHT

Queue ассоциирует с каждым потоком (flow) вес (WEIGHT) и соответствующий pipe (PIPE_NUMBER). Вес — это не приоритет, DUMMYNET queue предназначена только для WFQ. В соответствии с весом очереди выделяется часть пропускной способности.

Например:

# ipfw queue 1 config pipe 1 weight 50
# ipfw queue 2 config pipe 1 weight 30
# ipfw queue 3 config pipe 1 weight 20

3. Классифицируем трафик (направляем в соответствующие очереди)

# ipfw add IPFW_NUMBER queue QUEUE_NUMBER … from … to … via … in/out

Например:

Более приоритетный в очередь номер 1

# ipfw add 1000 queue 1 … from … to … via … in/out
# ipfw add 1000 queue 1 … from … to … via … in/out

Менее приоритетный в очередь номер 2

# ipfw add 2000 queue 2 … from … to …
# ipfw add 2000 queue 2 … from … to …

И так далее

# ipfw add 3000 queue 3 … from … to …
# ipfw add 3000 queue 3 … from … to …

Замечание:

Классификатор является стандартным правилом файерволла (ipfw) и направляет пакеты в queue.

4. Просмотр текущей конфигурации

# ipfw queue show
# ipfw queue list

5. Удаление

# ipfw queue QUEUE_NUMBER delete
# ipfw queue flush

Примеры ограничения трафика.

1. Ограничение для всех ftp клиентов bw в 64 Kbyte/s (64*8=512 Kbit/s).

# ipfw pipe 1 config bw 512Kbits queue 10
# ipfw add 1000 pipe 1 tcp from me 20 to any

Первый ftp клиент покажет скорость скачивания в 64 Kbyte/s. Следующий меньшую скорость, так как они поделят общую полосу в 64 Kbyte/s. И так далее.

2. Ограничение для каждого ftp клиента bw в 20 Kbyte/s (20*8=160 Kbit/s).

# ipfw pipe 1 config mask all bw 160Kbits queue 10
# ipfw add 1000 pipe 1 tcp from me 20 to any

Каждый клиент покажет скорость скачивания в 20 Kbyte/s (Пока хватит общей полосы).

3. Канал в котором все делят одну полосу на прием и другую на передачу.

# ipfw add pipe 1 ip from A to B out
# ipfw add pipe 2 ip from B to A in
# ipfw pipe 1 config bw 1Mbit/s delay 80ms queue 10
# ipfw pipe 2 config bw 128Kbit/s delay 300ms queue 10

Для симуляции full-duplex делается два объекта pipe — in и out.

4. Канал в котором ограничивается трафик для каждого адреса в 100Kbit/s.

# ipfw pipe 10 config mask src-ip 0x000000ff bw 100Kbit/s queue 10Kbytes
# ipfw pipe 20 config mask dst-ip 0x000000ff bw 100Kbit/s queue 10Kbytes
# ipfw add 1000 add pipe 10 all from 192.168.0.0/16 to any out via fxp0
# ipfw add 2000 add pipe 20 all from 192.168.0.0/16 to any in via fxp0

Внутри pipe несколько dynamic pipes (по одному 100Kbit/s на каждый хост в данном случае).

5. Ограничение нежелательного трафика.

Организуем следующую топологию: маршрутизатор ROUTER связывает CLIENT и SERVER, причем интерфейс fxp0 на ROUTERе имеет скорость 100 Mbit/s, а интерфейс fxp1 — 10 mbit/s. Таким образом организуется узкое место по пропускной способности в сети.

CLIENT—[fxp0 100mbit] ROUTER [fxp1 10mbit]—SERVER
Каким-либо образом загружаем канал CLIENT-SERVER udp пакетами, например, используя iperf:

SERVER# iperf -s -u

CLIENT# iperf -c SERVER_IP -N -P 20 -u -V -t 1000

Наблюдаем, что tcp пакеты от CLIENTа до SERVERа не проходят (ping, ssh). Это означает перегрузку канала по пропускной способности (участок 10 mbit).

Включаем на ROUTERе ограничение полосы для udp:

ROUTER# ipfw pipe 1 config bw 512Kbits queue 10
ROUTER# ipfw add 1000 pipe 1 udp from any to any

После этого tcp пакеты от CLIENTа до SERVERа успешно проходят, то есть ограничивается нежелательный трафик udp.

Примеры приоритезации трафика.

1. Общая полоса 512Kbits с приоритезацией (WFQ).

# ipfw pipe 1 config bw 512Kbits queue 10

# ipfw queue 1 config pipe 1 weight 50
# ipfw queue 2 config pipe 1 weight 30
# ipfw queue 3 config pipe 1 weight 20

# ipfw add 1000 queue 1 ip from … to …
# ipfw add 2000 queue 1 ip from … to …

# ipfw add 3000 queue 2 ip from … to …
# ipfw add 4000 queue 2 ip from … to …

# ipfw add 5000 queue 3 ip from … to …
# ipfw add 6000 queue 3 ip from … to …

В данном примере организуется канал шириной 512 Kbits в котором организуются очереди, обрабатывающиеся в соответствии с весом (из очереди с большим весом проходит больше пакетов в единицу времени). Это не Priority Queuing (PQ), а WFQ, то есть всем очередям гарантируется прохождение пакетов.

2. Предотвращение перегрузки канала.

Организуем следующую топологию: маршрутизатор ROUTER связывает CLIENT и SERVER, причем интерфейс fxp0 на ROUTERе имеет скорость 100 Mbit, а интерфейс fxp1 — 10 mbit. Таким образом организуется узкое место по пропускной способности в сети.

CLIENT—[fxp0 100mbit] ROUTER [fxp1 10mbit]—SERVER
Каким-либо образом загружаем канал CLIENT-SERVER udp пакетами, например, используя iperf:

SERVER# iperf -s -u

CLIENT# iperf -c SERVER_IP -N -P 20 -u -V -t 1000

Наблюдаем, что tcp пакеты от CLIENTа до SERVERа не проходят (ping, ssh). Это означает перегрузку канала по пропускной способности (участок 10 mbit).

Включаем на ROUTERе приоритезацию:

ROUTER# ipfw pipe 1 config bw 1Mbits queue 10
ROUTER# ipfw queue 1 config pipe 1 weight 80
ROUTER# ipfw queue 2 config pipe 1 weight 20

ROUTER# ipfw add 1000 queue 1 icmp from any to any
ROUTER# ipfw add 1000 queue 1 tcp from any to any
ROUTER# ipfw add 2000 queue 2 udp from any to any

После этого tcp пакеты от CLIENTа до SERVERа успешно проходят, то есть работает приоритезация (очереди).

Оригинальная статья находится по адресу: http://nag.ru/news/15524/.

Напоминаю всем копирующим мой контент о существовании закона "Об авторском праве".
В связи с этим, прошу во избежании конфликтов при копировании данного материала, ставить на него ссылку:

http://noted.org.ua/801


Также, вы можете отблагодарить меня переслав любую сумму на любой кошелек WebMoney, для поддержания данного ресурса. Или просто админу на пиво ;)

Кошельки для получения благодарности:
R386985788805
U234140473141
Z147712360455

На данной странице нет комментариев, возможно они закрыты. Если Вы хотите оставить свой комментарий, перейдите на специально созданный раздел

Add your comment now

Please note: JavaScript is required to post comments.