Ограничение трафика: 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).

Работа с очередями пакетов («дисциплина обработки»):

Термины:

Бесклассовые очереди

Prioritized FIFO (pfifo_fast)

Чистая приоритизация. Три приоритетных очереди в зависимости от ToS.

Token Bucket Filter (TBF)

Чистое ограничение трафика: очередь пакетов иррегулярная (то густо, то пусто), очередь жетонов равномерно прибывающая; выйти из системы пакет может только получив жетон.

Пример:

# 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» (или, что то же самое, на «:»).

Процесс:

  1. Постановка пакета в классовую очередь:
    1. Постановка пакета в корневую очередь
    2. Классификация пакета
    3. Постановка пакета в очередь уровня k>0

    4. Классификация пакета
    5. Постановка пакета в очередь уровня l>k

  2. Отсылка пакета из классовой очереди:
    1. Прохождение очереди уровня N и передача в очередь уровня N-1
    2. Прохождение корневой очереди и отсылка пакета

Пример:

  1. 1: →  1:1 → 1:12 → 12: → 12:2

  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

Примеры экзотических дисциплин

Фильтры

(Again: работает не на уровне iptables)

Базовая статья: Advanced filters for (re-)classifying packets