Etcnet QoS

Материал из ALT Linux Wiki
42px-Wikitext-ru.svg.png
Эту статью следует викифицировать.


Настройка QoS в /etc/net (редакция 3)

Общая теория

QoS — quality of service (качество обслуживания) — общий термин, обозначающий технологии управления скоростными и временными характеристиками пропускаемого трафика. Конфигурация выполняется для каждого интерфейса отдельно. Для этого создаётся древовидная структура, состоящая из дисциплин очередей и классов. Корень этой структуры — так называемая корневая дисциплина очереди, которая является обязательным атрибутом интерфейса. Увидеть её можно так:

$ /sbin/ip ad sh dev eth0
3: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 4c:00:10:3b:3e:f0 brd ff:ff:ff:ff:ff:ff
    inet 10.1.1.175/23 brd 10.1.1.255 scope global eth0

В данном случае корневая дисциплина очереди — pfifo_fast (она назначается по умолчанию). Иерархия очередей и классов определяет, как именно будут обрабатываться исходящие с интерфейса пакеты: номинальная скорость, параметры допустимых кратковременных всплесков, правила переупорядочивания пакетов внутри очередей, условия взаимного заимствования полосы пропускания между объектами на одном уровне иерархии и прочие параметры, зависящие от конкретной используемой структуры. «Перпендикулярно» этому дереву существует набор фильтров, которые описывают прохождение пакетов по структуре. Наиболее популярными являются дисциплины очередей CBQ (class based queueing) и HTB (hierarchical token bucket). Дерево CBQ формируется по довольно простым принципам:

  • пропускная способность корневой дисциплины очереди интерфейса равна физической пропускной способности интерфейса
  • классы могут иметь своим родителем только дисциплину очереди
  • решение о направлении пакета в класс принимается в дисциплине очереди с помощью фильтров
  • если вам необходимо разделить класс на подклассы, то создайте вложенную дисциплину очереди, а далее делите её

Дерево HTB строится ещё проще:

  • классы могут содержать другие классы напрямую, без промежуточных дисциплин очередей

Описание реализации

Общая идея реализации в /etc/net заключается в том, что иерархия объектов QoS представляется в виде дерева каталогов и файлов. Конфигурация начинается с каталога qos, располагающегося в каталоге конфигурации интерфейса. Далее в нём могут содержаться другие каталоги, которые представляют либо дисциплины очереди, либо классы. В каталогах дисциплин присутствуют файлы с названием qdisc, а в каталогах с классами — файлы class. Эти файлы содержат параметры дисциплин и классов. Фильтры располагаются в файлах с названием filter.

Пример 1

Рассмотрим пример конфигурации HTB, поставляемый с /etc/net: http://etcnet.org/examples/QoS-HTB-user-guide/1/qdisc Так как дерево начинается с корневой дисциплины, то в каталоге qos будет содержаться только один каталог qos/1, а в нём будет содержаться файл qdisc:

[DIR] 1/                                       22-Aug-2005 14:13      -  
[TXT] qdisc                                    18-Mar-2005 11:06     1k

Корневая дисциплина здесь имеет номер 1. Параметры корневой дисциплины простые: htb default 12. Корневая дисциплина кроме своих параметров содержит один класс в каталоге qos/1/1. Полным именем объекта будет 1:1. Левое число отсутствует в названии каталога, так как оно всегда равно идентификатору очереди. В файле qos/1/1/class содержатся параметры класса: htb rate 100kbps ceil 100kbps. Кроме этого, в каталогах qos/1/1/2 и qos/1/1/12 определено ещё два класса: 1:2 и 1:12. В файле qos/1/1/extra содержатся параметры, общие для классов 1:2 и 1:12: htb ceil 100kbps. Это необязательный файл, можно было бы поместить эти параметры в файлы qos/1/1/2/class и qos/1/1/12/class. Если у вас много классов на одном уровне, то файл extra поможет вынести общую часть «за скобки». Класс 1:12 пуст, а класс 1:2 содержит 1:10 и 1:11. В файлах qos/1/1/2/10/filter и qos/1/1/2/11/filter содержатся описания фильтров по одному в каждой строке. Местоположение файла filter определяет, куда будут направлены пакеты, которые ему удовлетворяют. Для класса 1:10 будет использован один фильтр protocol ip prio 1 u32 match ip src 1.2.3.4 match ip dport 80 0xffff, что соответствует исходящему HTTP-трафику с адреса 1.2.3.4, а для класса 1:11 будет использован фильтр protocol ip prio 1 u32 match ip src 1.2.3.4, что соответствует всему исходящему трафику с адреса 1.2.3.4. Файлы class классов 1:10 и 1:11 содержат соответственно rate 30kbps и rate 10kbps.

Пример 2

1. Я советую, поставив пакет etcnet, сначала спрятать куда-нибудь все каталоги интерфейсов из /etc/net/ifaces (кроме lo, default и unknown) и запустить /etc/net/scripts/initconf. Его выдачу сохранить и на основании этой выдачи организовать файл /etc/net/iftab, который определит логические имена интерфейсов. Например, одну сетевую карту можно из eth0 переименовать в соответствии с её макадресом в wan, другую — в lan. Я для себя использовал вместо wan имя провайдера (comcast), а вместо lan — придуманное самим имя локального домена своей сети 192.168.10.0/24 (menlo). Ну и дальше буду их использовать, чтобы не ошибиться где-нибудь заменяя их на более нейтральные типа wan и lan. Далее создайте каталоги с именами определёнными в таблице /etc/net/iftab, внутри /etc/ifaces. Я создал /etc/net/ifaces/comcast и /etc/net/ifaces/menlo. И положил туда нужные мне файлы options. Для внешней сети comcast достаточно определить TYPE и BOOTPROTO, я добавил строчку MODULE как того рекомендовал initconf:

# cat <<EOF >/etc/net/ifaces/comcast/options
TYPE=eth
BOOTPROTO=dhcp
MODULE=tulip
EOF

Для интерфейса локальной сети menlo адрес задан статически, так что там кроме файла options ещё нужен файл ipv4address:

# cat <<EOF >/etc/net/ifaces/menlo/options
TYPE=eth
BOOTPROTO=static
MODULE=natsemi
EOF
# echo "192.168.10.1/24" >/etc/net/ifaces/menlo/ipv4address

2. Дальше настраиваете ip-forwarding и nat masquarading. За первый отвечает строчка

net.ipv4.ip_forward = 1

в файле /etc/net/sysctl.conf, в то время как другое делается добавлением строки masquerade out-iface comcast в файл /etc/net/ifaces/default/fw/iptables/nat/POSTROUTING:

echo "masquerade out-iface comcast" >>/etc/net/ifaces/default/fw/iptables/nat/POSTROUTING

После этого ваш раутер после # service network restart уже должен начать выполнять свою функцию разделения доступа в интернет.

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

#cat <<EOF >/etc/net/ifaces/default/fw/iptables/mangle/POSTROUTING
mark 21 if from 192.168.10.21 from-iface menlo
mark 22 if from 192.168.10.5 from-iface menlo
EOF

Мысль для себя на будущее: наверно можно было маркировать по мак-адресу, и тем самым избежать необходимости настраивать статические адреса выдаваемые dhcpd.

4. Ну а теперь остаётся самое настроить qos htb для идущего наружу интерфейса comcast.

# # создаём дисциплину 1
# mkdir -p /etc/net/ifaces/comcast/qos/1

# # определяем что эта дисциплина - htb
# # и её дефолтный класс для неклассифицированного траффика 77.
# echo "htb default 77" >/etc/net/ifaces/comcast/qos/1/qdisc

# # создаём корневой класс 1 (1:1)
# mkdir /etc/net/ifaces/comcast/qos/1/1

# # определяем ширину пропускания интерфейса (upload)
# echo "htb rate 360kbit" >/etc/net/ifaces/comcast/qos/1/1/class

# # организуем фильтр, направляющий весь траффик в класс 1:1
# # !!!Этого фильтра нет в примерах пакета etcnet    !!!
# # !!!(по крайней мере для версии etcnet-0.9.3-alt3)!!!
# # !!!Но он действительно нужен, без него трафик    !!!
# # !!! не проходит по вложенным классам             !!!
# echo "proto ip prio 1 u32 match ip src 0.0.0.0/0"  >/etc/net/ifaces/comcast/qos/1/1/filter

# # создаём класс для первого телефонного адаптера
# mkdir /etc/net/ifaces/comcast/qos/1/1/21/

# # определяем для него ширину пропускания 80 килобит/сек.
# echo "htb rate 80kbit" >/etc/net/ifaces/comcast/qos/1/1/21/class

# # задаём фильтр этого класса, отбирающий для него пакеты с маркой "21"
# echo "protocol ip prio 1 handle 21 fw" >/etc/net/ifaces/comcast/qos/1/1/21/filter

# # создаём класс для второго телефонного адаптера
# mkdir /etc/net/ifaces/comcast/qos/1/1/22/

# # определяем для него ширину пропускания 80 килобит/сек.
# echo "htb rate 80kbit" >/etc/net/ifaces/comcast/qos/1/1/22/class

# # задаём фильтр этого класса, отбирающий для него пакеты с маркой "22"
# echo "protocol ip prio 1 handle 22 fw" >/etc/net/ifaces/comcast/qos/1/1/22/filter


# # создаём класс для дефолтного траффика:
# mkdir /etc/net/ifaces/comcast/qos/1/1/77/

# # определяем для него ширину пропускания 200 (= 360 - (80 + 80)) килобит/сек.
# # с возможностью заимствования неиспользуемого в данный момент траффика других классов
# # вплоть до 360kbit, то есть полной ширины исходящего канала
# echo "htb rate 200kbit ceil 360kbit" >/etc/net/ifaces/comcast/qos/1/1/77/class

Теперь телефонам будет предоставляться 80 килобит в секунду как только они того потребуют, а если они недоиспользуют эти 80kbit, всё оставшееся будет предоставляться другим соединениям.

P.S Большое спасибо Денису Овсиенко за то, что объяснил, как правильно организовать иерархию фильтров, чтобы эта конструкция заработала.

Утилиты

  • С 11/07/2006 в contrib находится скрипт eqos (по аналогии с efw), который предназначен для ручного управления qos и умеет следующее:
/etc/net QoS handler

Usage: ./eqos [iface] <action> [action options]

iface    - real interface name ('eth0' by default) or 'all' for all interfaces
action   - 'start','stop','restart','show|list','stat|stats'
start    - start QoS for given interface
stop     - stop QoS for given interface
restart  - equivalent to 'stop' then 'start'
show     - list qdiscs, classes or filters on given interface
list     - same as 'show'
stat     - print statistics for qdiscs, classes or filters on given interface
stats    - same as 'stat'

Options for actions 'show' or 'list' and 'stat' or 'stats':

- one of 'qdisc' (by default), 'class' or 'filter'

- component specific options (e.g. 'parent')