В моем маршрутизаторе Linux я использую следующую конфигурацию для ограничения скорости трафика к порту 44444 клиента в локальной сети (адрес клиента 192.168.10.2, подключенный через iface eth1 маршрутизатора):
tc qdisc add dev eth1 root handle 1: htb default 2
tc class add dev eth1 parent 1: classid 1:1 htb rate $RATE
tc class add dev eth1 parent 1: classid 1:2 htb rate 100mbit
tc filter add dev eth1 protocol ip parent 1: prio 1 u32 match ip dst 192.168.10.2 dport 44444 0xffff flowid 1:1
что я ожидаю от этой конфигурации, так это то, что трафик к 192.168.10.2:44444 будет формироваться в соответствии с параметром $ RATE, тогда как весь остальной трафик в основном останется нетронутым (поскольку скорость LAN составляет 100 Мбит / с).
Чтобы проверить эту конфигурацию, я отправляю UDP-пакеты на адрес 192.168.10.2:44444 с различной скоростью, отслеживая количество потерянных пакетов и варианты односторонней задержки. Во время тестов я заметил, что пакеты, превышающие скорость никогда быть отвергнутым. Скорее, пакеты помещаются в очередь в буфере, который продолжает расти, даже не достигнув (по-видимому) предельного размера.
Например:
Используя RATE = 30 кбит и отправляя пакеты со скоростью около 2 Мбит / с (полезная нагрузка пакета 1400 байт, пакет с интервалом 5 мс) в течение 10 секунд, я получаю следующую статистику от tc:
qdisc htb 1: root refcnt 2 r2q 10 default 2 direct_packets_stat 0 ver 3.17
Sent 104901 bytes 85 pkt (dropped 0, overlimits 185 requeues 0)
backlog 0b 0p requeues 0
(Статистика показана через tc -s -d qdisc show dev eth1
)
Фактически, пакеты принимаются 192.168.10.2 в течение более 26 секунд (т. Е. 16 секунд после того, как отправитель закончил).
Используя RATE = 5mbit и отправляя пакеты на 20mbit, я получаю следующую статистику:
qdisc htb 1: root refcnt 2 r2q 10 default 2 direct_packets_stat 0 ver 3.17
Sent 6310526 bytes 4331 pkt (dropped 0, overlimits 8667 requeues 0)
backlog 0b 0p requeues 0
хотя односторонняя задержка на этот раз не превышает 160 мс.
Я получил аналогичные результаты, указав burst
размер тоже, но я не заметил каких-либо значительных изменений, независимо от того, насколько низко я его установил (я уменьшил его до 1 кбит).
К сожалению, я не могу найти разумного объяснения этим результатам, несмотря на то, что я прочитал различные руководства и ссылки о Linux tc и htb. Я был бы рад, если бы кто-нибудь помог мне разобраться в этом.
Спасибо
Обновить. Я нашел очень полезное и ясное описание внутреннего устройства контроллера трафика Linux. Вы можете найти это Вот. Еще один полезный ресурс - это OpenWRT вики. На самом деле я уже знал о предыдущей статье, но, очевидно, пропустил важные моменты.
Короче говоря, буфер, в который помещаются мои пакеты, - это, конечно, исходящая очередь сетевого интерфейса. Пакеты в выходной очереди выбираются для передачи в соответствии с дисциплиной очередности, установленной через tc
команда. Интересно, что очередь на выходе измеряется не в байтах, а в пакетах (независимо от размера пакетов). Отчасти это причина того, что в моих экспериментах мне никогда не удавалось достичь предела размера очереди.
Размер исходящей очереди отображается через ifconfig
команда (txqueue
поле). В моем Linux-боксе размер исходящего трафика по умолчанию составляет 1000 пакетов, но вы можете легко изменить его через ifconfig DEV txqueuelen SIZE
. Уменьшив размер очереди до 1 пакета, мне, наконец, удалось принудительно отбросить сформированные пакеты (никогда не доходя до клиента). Так что я думаю, что в основном это все.
Еще один интересный факт, который я заметил, заключается в том, что фильтр корзины токенов (tbf
) в отличие от иерархического фильтра корзины делает предоставить дополнительный буфер, в котором пакеты ставятся в очередь перед передачей. Я предполагаю, что, используя этот фильтр с достаточно маленькой очередью, вы можете принудительно отбрасывать пакеты независимо от того, насколько велика исходящая очередь. Однако я не экспериментировал с этим.
Надеюсь это поможет.