Как-то давным давно, когда я только начинал изучать 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/?p=801


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

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

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

Add your comment now

You must be logged in to post a comment.