Ограничение трафика: Linux TC и интерфейсный уровень
ToS
Поле IP-пакета. 4 бита (+3+1резервный) таблица отсюда:
TOS |
Bits |
Means |
Linux Priority |
Band |
0x0 |
0 |
Normal Service |
0 Best Effort |
1 |
0x2 |
1 |
Minimize Monetary Cost |
1 Filler |
2 |
0x4 |
2 |
Maximize Reliability |
0 Best Effort |
1 |
0x6 |
3 |
mmc+mr |
0 Best Effort |
1 |
0x8 |
4 |
Maximize Throughput |
2 Bulk |
2 |
0xa |
5 |
mmc+mt |
2 Bulk |
2 |
0xc |
6 |
mr+mt |
2 Bulk |
2 |
0xe |
7 |
mmc+mr+mt |
2 Bulk |
2 |
0x10 |
8 |
Minimize Delay |
6 Interactive |
0 |
0x12 |
9 |
mmc+md |
6 Interactive |
0 |
0x14 |
10 |
mr+md |
6 Interactive |
0 |
0x16 |
11 |
mmc+mr+md |
6 Interactive |
0 |
0x18 |
12 |
mt+md |
4 Int. Bulk |
1 |
0x1a |
13 |
mmc+mt+md |
4 Int. Bulk |
1 |
0x1c |
14 |
mr+mt+md |
4 Int. Bulk |
1 |
0x1e |
15 |
mmc+mr+mt+md |
4 Int. Bulk |
1 |
|
TC
Базовые статьи:
Userspace + поддержка в ядре + модули.
Отдельная подсистема (≠netfilter).
Работа с очередями пакетов («дисциплина обработки»):
- приоритизация (жесткое упорядочивание)
- переупорядочивание
- ограничение пропускной способности
Термины:
дисциплина — очередь (или иная динамическая структура) пакетов и правила её обработки
класс — поток пакетов; на конце этого потока либо очередь (по умолчанию fifo), либо родительский класс (тогда классы иерархические)
фильтр — сканирование пакетов на предмет записывания их в классы
Бесклассовые очереди
Prioritized FIFO (pfifo_fast)
Чистая приоритизация. Три приоритетных очереди в зависимости от ToS.
Token Bucket Filter (TBF)
Чистое ограничение трафика: очередь пакетов иррегулярная (то густо, то пусто), очередь жетонов равномерно прибывающая; выйти из системы пакет может только получив жетон.
- ⇒ средняя скорость отсылки пакетов не превышает скорость прибытия жетонов
- ⇒ т. н. burst: если очередь пакетов пуста, а очередь из N жетонов полна, и внезапно™ прибывает много пакетов, первые N пакетов отошлются быстрее
Пример:
# tc qdisc add dev ppp0 root tbf rate 220kbit latency 50ms burst 1540
Идея в том, чтобы очередь обрабатывалась со стороны Linux, а не на ADSL-модеме (где очередь может быть очень длинная и в ней потеряются интерактивные пакеты). В идеале неплохо бы использовать приоритетную очередь, но даже так лучше.
Stochastic Fairness Queueing (SFQ)
Чистое переупорядочивание.
Трафик классифицируется по «потокам» (грубо говоря, TCP-соединениям), каждый поток направляется в отдельную FIFO-очередь, а отсылка пакетов происходит по одному из каждой очереди.
Классовые очереди
Классы — потоки пакетов с определёнными свойствами (например, скорость отсылки или пропускная способность). Иерархические подклассы должны соответствовать этим свойствам (например, скорость отсылки или пропускная способность не выше, чем у родительского класса).
Классы и дисциплины (=очереди) в дереве обработки пакетов:
10:1 10:2 12:1 12:2 концевые классы \ / \ / 10: 12: дисциплины | | | 11: | концевой класс | | | 1:10 1:11 1:12 классы \ | / \ | / \ | / \ | / 1:1 класс | 1: корневая дисциплина
Идентификатор очереди всегда заканчивается на «:0» (или, что то же самое, на «:»).
Процесс:
- Постановка пакета в классовую очередь:
- Постановка пакета в корневую очередь
- Классификация пакета
Постановка пакета в очередь уровня k>0
- Классификация пакета
Постановка пакета в очередь уровня l>k
- …
- Отсылка пакета из классовой очереди:
- Прохождение очереди уровня N и передача в очередь уровня N-1
- …
- Прохождение корневой очереди и отсылка пакета
Пример:
1: → 1:1 → 1:12 → 12: → 12:2
12: → 1:
CBQ
Классы на основании времени ожидания отсылки пакета.
Считается малопонятной и устаревшей.
PRIO
Приоритетная классификация по ToS (как в pfifo), но пакеты помещаются в класс, который можно обработать дальше в графе. Класс :1 наиболее приоритетный.
Пример:
полоса 0 1 2 sfq tbf sfq 10: 20: 30: дисциплины | | | 1:1 1:2 1:3 классы \ | / \ | / \|/ 1: корневая дисциплина
Задание с помощью tc:
# tc qdisc add dev eth0 parent 1:1 handle 10: sfq # tc qdisc add dev eth0 parent 1:2 handle 20: tbf rate 20kbit buffer 1600 limit 3000 # tc qdisc add dev eth0 parent 1:3 handle 30: sfq
Hierarchical Token Bucket (HTB)
Классы на основании пропускной способности (по алгоритму TBF).
Пример:
10: 20: 30: sfq-очереди | | | 1:10 1:20 1:30 подклассы 5Mbit 3Mbit 1Kbit \ | / \ | / \ | / 1:1 класс | 1: корневая дисциплина (htb)
Описание классов:
# tc class add dev eth0 parent 1: classid 1:1 htb rate 6mbit burst 15k # tc class add dev eth0 parent 1:1 classid 1:10 htb rate 5mbit burst 15k # tc class add dev eth0 parent 1:1 classid 1:20 htb rate 3mbit ceil 6mbit burst 15k # tc class add dev eth0 parent 1:1 classid 1:30 htb rate 1kbit ceil 6mbit burst 15k
Задание очередей:
# tc qdisc add dev eth0 root handle 1: htb default 30 # tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10 # tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10 # tc qdisc add dev eth0 parent 1:30 handle 30: sfq perturb 10
Классификация с помощью фильтра u32 (класс 30: по умолчанию) — разброс по 25 и 80 порту.
# U32="tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32" # $U32 match ip dport 80 0xffff flowid 1:10 # $U32 match ip sport 25 0xffff flowid 1:20
Примеры экзотических дисциплин
CoDel — пакеты выбрасываются, если и так слишком долго задерживаются в очереди
choke — вариант RED: если очередной пакет заходит за LO-mark и принадлежит тому же потоку данных, что и случайно выбранный из очереди пакет, выбрасыватся оба (⇒ чем толще поток, тем выше вероятность)
drr — (deficit round robin), вариант SFQ с ручным разбиением на потоки (классы)
- …
Фильтры
(Again: работает не на уровне iptables)
Базовая статья: Advanced filters for (re-)classifying packets
- u32 — поля IP (и TCP/UDP)
В примере выше 0xffff — это битовая маска
- fw — пакеты, помеченные iptables
- route — куда направлен пакет
- hfsc — реализация HFSC для linux
- stab — подстановка других размеров пакетов при обработке их очередями
- …