QoS в Linux

Материал из Xgu.ru

Перейти к: навигация, поиск
stub.png
Данная страница находится в разработке.
Эта страница ещё не закончена. Информация, представленная здесь, может оказаться неполной или неверной.

Если вы считаете, что её стоило бы доработать как можно быстрее, пожалуйста, скажите об этом.


Содержание

[править] Терминология

Не для всех терминов, использующихся в этой статье, существует общепринятый русский перевод. При описании основных терминов указывается английская версия и альтернативные русские переводы, если они существуют. Другие термины со спорным переводом перечислены в списке ниже. Если вы считаете, что какой-то термин может быть переведён лучше, пожалуйста, напишите об этом на странице обсуждения.

Действия, применяемые по отношению к трафику:

shaping
(шейпинг) Контроль скорости передачи. Трафик сглаживается. Шейпинг применяется для исходящего трафика.
scheduling
(шедулинг) Контроль очерёдности отправки пакетов. За счёт изменения очерёдности пакетов, стоящих в очереди на отправку можно повысить качество обслуживания интерактивного трафика без ущерба для передачи пакетного(bulk) трафика, нечувствительного к задержкам. Также применяются термины: Изменение порядка пакетов (reordering) и приоритезацией (prioritizing). Применяется для исходящего трафика.
policing
Ограничение трафика. Фактически выражается в уничтожении трафика, превышающего заданную величину. Разница между ограничением и шейпингом трафика приблизительно такая же как между тем как срезать или размазать масло по бутерброду перед тем как просунуть его в узкую щель под дверью. Применяется для входящего трафика.
dropping
Уничтожение трафика, превышающего указанную величину. Может выполняться как на входе, так и на выходе.
marking
Маркировка пакетов.
classification
Классификация пакетов.

Механизмы, на которых базируется QoS:

qdiscs
Дисциплины обслуживания.
classes
Классы обслуживания.
filters
Фильтры. Применяются для классификации трафика. Вновь прибывший трафик не относится ни к одному из классов, и его классификация выполняется с помощью фильтров. Существуют ряд различных фильтров трафика, отличающихся возможностями и принципом работы.


[править] Перевод терминов

Термины, перевод которых на русский язык пока не является общепринятым (или я об этом не знаю):

  • leaf-class — класс-лист;

[править] Дисциплины обслуживания

Существуют классовые (classful) и бесклассовые (classless) дисциплины обслуживания. Бесклассовые дисциплины могут быть прикреплены только к корню устройства. Классовые дисциплины могут прикрепляться не только к корню, но и к классам.

Бесклассовые дисциплины обслуживания.

fifo
First In First Out — .
fifo_fast
First In First Out Fast — .
RED
Random Early Detection — .
SFQ
Stohastic Fairness Queueing — .
TBF
Token Bucket Filter — .

Классовые дисциплины обслуживания.

CBQ
Class Based Queueing — .
HTB
Hierarchy Token Bucket — .
PRIO
PRIO — .

[править] Принцип работы

Классы трафика организованы в дерево — у каждого класса есть не более одного родителя; класс может иметь множество потомков. Классы, которые не имеют родителей, называются корневыми. Классы, которые не имеют потомков, называются классами-ветками.

[править] QoS в Linux

Нам понадобится ядро с поддержкой QoS и (опционально) netfilter, а так же userspace инструменты iproute2 и iptables.

[править] Конфигурация ядра

Собираем ядро отвечая на вопросы y (или m, где возможно).

 TCP/IP networking (CONFIG_INET) [Y/n/?]y
  IP: advanced router (CONFIG_IP_ADVANCED_ROUTER) [N/y/?] y
    IP: policy routing (CONFIG_IP_MULTIPLE_TABLES) [N/y/?] (NEW) y
    IP: use TOS value as routing key (CONFIG_IP_ROUTE_TOS) [N/y/?] (NEW) y
    IP: large routing tables (CONFIG_IP_ROUTE_LARGE_TABLES) [N/y/?] (NEW) y

 QoS and/or fair queueing (CONFIG_NET_SCHED) [N/y/?] y
  CBQ packet scheduler (CONFIG_NET_SCH_CBQ) [N/y/m/?] (NEW) y
  HTB packet scheduler (CONFIG_NET_SCH_HTB) [N/y/m/?] (NEW) y
  The simplest PRIO pseudoscheduler (CONFIG_NET_SCH_PRIO) [N/y/m/?] (NEW) y
  RED queue (CONFIG_NET_SCH_RED) [N/y/m/?] (NEW) y
  SFQ queue (CONFIG_NET_SCH_SFQ) [N/y/m/?] (NEW) y
  TBF queue (CONFIG_NET_SCH_TBF) [N/y/m/?] (NEW) y
 QoS support (CONFIG_NET_QOS) [N/y/?] (NEW) y
   Rate estimator (CONFIG_NET_ESTIMATOR) [N/y/?] (NEW) y
   Packet classifier API (CONFIG_NET_CLS) [N/y/?] (NEW) y
   TC index classifier (CONFIG_NET_CLS_TCINDEX) [N/y/m/?] (NEW) y
   Routing table based classifier (CONFIG_NET_CLS_ROUTE4) [N/y/m/?] (NEW) y
   Firewall based classifier (CONFIG_NET_CLS_FW) [N/y/m/?] (NEW) y
   U32 classifier (CONFIG_NET_CLS_U32) [N/y/m/?] (NEW) y

[править] Программа tc

СИНТАКСИС

tc qdisc [ add | change | replace | link ] dev УСТРОЙСТВО [ parent qdisc-id | root ] [ handle qdisc-id ] qdisc [ параметры qdisc ]
tc class [ add | change | replace ] dev УСТРОЙСТВО parent qdisc-id [ classid class-id ] qdisc [ параметры qdisc ]
tc filter [ add | change | replace ] dev УСТРОЙСТВО [ parent qdisc-id | root ] protocol protocol prio priority filtertype [ параметры filtertype ] flowid flow-id
tc [-s | -d ] qdisc show [ dev УСТРОЙСТВО ]
tc [-s | -d ] class show dev УСТРОЙСТВО
tc filter show dev УСТРОЙСТВО

[править] Скрипты

[править] Pulsar QoS HOWTO

В этом HOW-TO я вкратце попытаюсь разъяснить, как в GNU/Linux системах управлять трафиком.


О включении поддержки netfilter и процедуре компиляции ядра читайте соответствующие HOWTO.


Я (и не только) придерживаюсь мнения, что для построения иерархии классов для управления полосой пропускания лучше использовать HTB, нежели CBQ. CBQ содержит ряд параметров, которые необходимо эмпирически получать для каждого конкретного случая.

Рассмотрим пример, в котором одному клиенту отводится гарантированная полоса пропускания в 1mbit/s, другому полоса пропускания 4mbit/s и выше, всем остальным 2mbit/s и выше. Для начала создадим с помощью HTB классы :

$TC qdisc add dev $DEVB root handle 1: htb default 30
$TC class add dev $DEVB parent 1: classid 1:1 htb \
  rate 100mbit ceil 100mbit burst 15k
$TC class add dev $DEVB parent 1:1 classid 1:10 htb \
  rate 64kbit ceil 64kbit  burst 15k
$TC class add dev $DEVB parent 1:1 classid 1:20 htb \
  rate 4mbit ceil 100mbit burst 15k
$TC class add dev $DEVB parent 1:1 classid 1:30 htb \
  rate 2mbit ceil 100mbit burst 15k

Немного о параметре burst. Дело в том, что "железо" в каждый момент времени может посылать только один пакет и только с определенной скоростью (100Mbit/s в случае fast ethernet). HTB эмулирует несколько потоков (flow) посредством переключения между классами. Таким образом параметр burst задает максимальный объем данных данного класса, который может быть пропущен через "железо" без переключения на другие классы. Отсюда логически следует, что нельзя ставить параметр burst у дочерних классов больше чем у родительских.

Далее мы должны присоединить дисциплины для трафика

$TC qdisc add dev $DEVB parent 1:10 red \
  min 1600 max 3210 burst 2 limit 32100 avpkt 1000
$TC qdisc add dev $DEVB parent 1:20  sfq perturb 10
$TC qdisc add dev $DEVB parent 1:30  sfq perturb 10


Этим мы сказали что "резать" трафик в классе 1:10 будем по алгоритму RED(Random Early Detection), в остальных — по алгоритму SFQ. Параметры для RED вычисляются следующим образом : min = (задержка)*bandwidt(bits/s), burst= (2*min+max)/(3*avpkt)), limit= 10*max, max > 2*min, avpkt 1000 для MTU 1500.

Несколько слов об алгоритмах управления трафиком. TBF алгоритм пропускает пакеты с определенной заданной скоростью, хороший выбор если вам просто нужно ограничить скорость на интерфейсе. Используемые параметры rate - нужная нам скорость, latency — максимальное время, которое пакет может проводить в очереди, burst размер "ведра" для токенов в байтах, естественно чем больше вы задаете rate, тем больше должно быть значение burst. Пример, ограничение скорости на eth0 к которому подключен dsl модем :

$TC qdisc add dev eth0 root tbf rate 128kbit latency 50ms burst 1500

Основным понятием SFQ является поток (flow), трафик разбивается на достаточно большое количество FIFO очередей, которые переключаются по кругу, таким образом не давая доминировать ни одной из них. Параметры perturb время реконфигурации (???) и quantum — обьем данных "выпускаемых" из потока за один раз (по умолчанию MTU, но!! ни в коем случае не ставьте меньше). Пример - псевдосправедливая раздача исходящего трафика с определенного интерфейса:

$TC qdisc add dev eth0 root sfq perturb 10

Параметры для RED вычисляются следующим образом min = (задержка)*bandwidth(bits/s), burst= (2*min+max)/(3*avpkt)), limit= 10*max, max > 2*min, avpkt 1000 для MTU 1500.


Дальше надо распределить трафик по классам, с помощью tc filter, например так :

$TC filter add dev $DEVB protocol ip parent 1:0 prio 1 u32 \
match ip dst 192.168.15.132 flowid 1:10

отправляем весь трафик у которого получатель 192.168.15.132 в класс 1:10. Можно распределить по классам предварительно помеченные с помощью iptables пакеты следующим образом:

$iptables -A OUTPUT -t mangle  -d 192.168.15.129 -j MARK --set-mark 20
$tc filter add dev $DEVB protocol ip parent 1:0 prio 2 handle 20 fw classid 1:20

Можно использовать более сложные правила для пометки трафика, например :

$iptables -A OUTPUT -t mangle -p tcp  -d 192.168.15.129 \
  --sport 80 -j MARK --set-mark 20

Обязательно проверьте с помощью $iptables -L -n -v -t mangle как маркируются пакеты, возможно происходит не то, что вы ожидали.


Резюмируем  
1. Cначала создаем иерархию классов #tc class add ...
2. Добавляем дисциплины #tc qdisc add ... 
3. Распределяем трафик по классам #tc filter add ...


(c), Sheshka Alexey, 2002 sheshka@yahoo.com Перепечатка в бумажных изданиях без согласия автора запрещена.

[править] HTB Linux queuing discipline manual - user guide

Martin Devera aka devik (devik@cdi.cz) Manual: devik and Don Cohen Last updated: 5.5.2002

New text is in red color. Coloring is removed on new text after 3 months. Currently they depicts HTB3 changes

   * 1. Introduction
   * 2. Link sharing
   * 3. Sharing hierarchy
   * 4. Rate ceiling
   * 5. Burst
   * 6. Priorizing bandwidth share
   * 7. Understanding statistics
   * 8. Making, debugging and sending error reports 

1. Introduction HTB is meant as a more understandable, intuitive and faster replacement for the CBQ qdisc in Linux. Both CBQ and HTB help you to control the use of the outbound bandwidth on a given link. Both allow you to use one physical link to simulate several slower links and to send different kinds of traffic on different simulated links. In both cases, you have to specify how to divide the physical link into simulated links and how to decide which simulated link to use for a given packet to be sent.

This document shows you how to use HTB. Most sections have examples, charts (with measured data) and discussion of particular problems.

This release of HTB should be also much more scalable. See comparison at HTB home page.

Please read: tc tool (not only HTB) uses shortcuts to denote units of rate. kbps means kilobytes and kbit means kilobits ! This is the most FAQ about tc in linux.

2. Link sharing Problem: We have two customers, A and B, both connected to the internet via eth0. We want to allocate 60 kbps to B and 40 kbps to A. Next we want to subdivide A's bandwidth 30kbps for WWW and 10kbps for everything else. Any unused bandwidth can be used by any class which needs it (in proportion of its allocated share).

HTB ensures that the amount of service provided to each class is at least the minimum of the amount it requests and the amount assigned to it. When a class requests less than the amount assigned, the remaining (excess) bandwidth is distributed to other classes which request service.

Also see document about HTB internals - it describes goal above in greater details.

Note: In the literature this is called "borrowing" the excess bandwidth. We use that term below to conform with the literature. We mention, however, that this seems like a bad term since there is no obligation to repay the resource that was "borrowed".

The different kinds of traffic above are represented by classes in HTB. The simplest approach is shown in the picture at the right. Let's see what commands to use:

tc qdisc add dev eth0 root handle 1: htb default 12

This command attaches queue discipline HTB to eth0 and gives it the "handle" 1:. This is just a name or identifier with which to refer to it below. The default 12 means that any traffic that is not otherwise classified will be assigned to class 1:12.

Note: In general (not just for HTB but for all qdiscs and classes in tc), handles are written x:y where x is an integer identifying a qdisc and y is an integer identifying a class belonging to that qdisc. The handle for a qdisc must have zero for its y value and the handle for a class must have a non-zero value for its y value. The "1:" above is treated as "1:0".

tc class add dev eth0 parent 1: classid 1:1 htb rate 100kbps ceil 100kbps 
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 30kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 10kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 60kbps ceil 100kbps

The first line creates a "root" class, 1:1 under the qdisc 1:. The definition of a root class is one with the htb qdisc as its parent. A root class, like other classes under an htb qdisc allows its children to borrow from each other, but one root class cannot borrow from another. We could have created the other three classes directly under the htb qdisc, but then the excess bandwidth from one would not be available to the others. In this case we do want to allow borrowing, so we have to create an extra class to serve as the root and put the classes that will carry the real data under that. These are defined by the next three lines. The ceil parameter is described below.

Note: Sometimes people ask me why they have to repeat dev eth0 when they have already used handle or parent. The reason is that handles are local to an interface, e.g., eth0 and eth1 could each have classes with handle 1:1.

We also have to describe which packets belong in which class. This is really not related to the HTB qdisc. See the tc filter documentation for details. The commands will look something like this:

tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
   match ip src 1.2.3.4 match ip dport 80 0xffff flowid 1:10
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
   match ip src 1.2.3.4 flowid 1:11

(We identify A by its IP address which we imagine here to be 1.2.3.4.)

Note: The U32 classifier has an undocumented design bug which causes duplicate entries to be listed by "tc filter show" when you use U32 classifiers with different prio values.

You may notice that we didn't create a filter for the 1:12 class. It might be more clear to do so, but this illustrates the use of the default. Any packet not classified by the two rules above (any packet not from source address 1.2.3.4) will be put in class 1:12.

Now we can optionally attach queuing disciplines to the leaf classes. If none is specified the default is pfifo.

tc qdisc add dev eth0 parent 1:10 handle 20: pfifo limit 5
tc qdisc add dev eth0 parent 1:11 handle 30: pfifo limit 5
tc qdisc add dev eth0 parent 1:12 handle 40: sfq perturb 10

That's all the commands we need. Let's see what happens if we send packets of each class at 90kbps and then stop sending packets of one class at a time. Along the bottom of the graph are annotations like "0:90k". The horizontal position at the center of the label (in this case near the 9, also marked with a red "1") indicates the time at which the rate of some traffic class changes. Before the colon is an identifier for the class (0 for class 1:10, 1 for class 1:11, 2 for class 1:12) and after the colon is the new rate starting at the time where the annotation appears. For example, the rate of class 0 is changed to 90k at time 0, 0 (= 0k) at time 3, and back to 90k at time 6.

Initially all classes generate 90kb. Since this is higher than any of the rates specified, each class is limited to its specified rate. At time 3 when we stop sending class 0 packets, the rate allocated to class 0 is reallocated to the other two classes in proportion to their allocations, 1 part class 1 to 6 parts class 2. (The increase in class 1 is hard to see because it's only 4 kbps.) Similarly at time 9 when class 1 traffic stops its bandwidth is reallocated to the other two (and the increase in class 0 is similarly hard to see.) At time 15 it's easier to see that the allocation to class 2 is divided 3 parts for class 0 to 1 part for class 1. At time 18 both class 1 and class 2 stop so class 0 gets all 90 kbps it requests.

It might be good time to touch concept of quantums now. In fact when more classes want to borrow bandwidth they are each given some number of bytes before serving other competing class. This number is called quantum. You should see that if several classes are competing for parent's bandwidth then they get it in proportion of their quantums. It is important to know that for precise operation quantums need to be as small as possible and larger than MTU. Normaly you don't need to specify quantums manualy as HTB chooses precomputed values. It computes classe's quantum (when you add or change it) as its rate divided by r2q global parameter. Its default value is 10 and because typical MTU is 1500 the default is good for rates from 15 kBps (120 kbit). For smaller minimal rates specify r2q 1 when creating qdisc - it is good from 12 kbit which should be enough. If you will need you can specify quantum manualy when adding or changing the class. You can avoid warnings in log if precomputed value would be bad. When you specify quantum on command line the r2q is ignored for that class.

This might seem like a good solution if A and B were not different customers. However, if A is paying for 40kbps then he would probably prefer his unused WWW bandwidth to go to his own other service rather than to B. This requirement is represented in HTB by the class hierarchy. 3. Sharing hierarchy The problem from the previous chapter is solved by the class hierarchy in this picture. Customer A is now explicitly represented by its own class. Recall from above that the amount of service provided to each class is at least the minimum of the amount it requests and the amount assigned to it. This applies to htb classes that are not parents of other htb classes. We call these leaf classes. For htb classes that are parents of other htb classes, which we call interior classes, the rule is that the amount of service is at least the minumum of the amount assigned to it and the sum of the amount requested by its children. In this case we assign 40kbps to customer A. That means that if A requests less than the allocated rate for WWW, the excess will be used for A's other traffic (if there is demand for it), at least until the sum is 40kbps.

Notes: Packet classification rules can assign to inner nodes too. Then you have to attach other filter list to inner node. Finally you should reach leaf or special 1:0 class. The rate supplied for a parent should be the sum of the rates of its children.

The commands are now as follows:

tc class add dev eth0 parent 1: classid 1:1 htb rate 100kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:2 htb rate 40kbps ceil 100kbps
tc class add dev eth0 parent 1:2 classid 1:10 htb rate 30kbps ceil 100kbps
tc class add dev eth0 parent 1:2 classid 1:11 htb rate 10kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 60kbps ceil 100kbps

We now turn to the graph showing the results of the hierarchical solution. When A's WWW traffic stops, its assigned bandwidth is reallocated to A's other traffic so that A's total bandwidth is still the assigned 40kbps. If A were to request less than 40kbs in total then the excess would be given to B. 4. Rate ceiling The ceil argument specifies the maximum bandwidth that a class can use. This limits how much bandwidth that class can borrow. The default ceil is the same as the rate. (That's why we had to specify it in the examples above to show borrowing.) We now change the ceil 100kbps for classes 1:2 (A) and 1:11 (A's other) from the previous chapter to ceil 60kbps and ceil 20kbps.

The graph at right differs from the previous one at time 3 (when WWW traffic stops) because A/other is limited to 20kbps. Therefore customer A gets only 20kbps in total and the unused 20kbps is allocated to B. The second difference is at time 15 when B stops. Without the ceil, all of its bandwidth was given to A, but now A is only allowed to use 60kbps, so the remaining 40kbps goes unused.

This feature should be useful for ISPs because they probably want to limit the amount of service a given customer gets even when other customers are not requesting service. (ISPs probably want customers to pay more money for better service.) Note that root classes are not allowed to borrow, so there's really no point in specifying a ceil for them.

Notes: The ceil for a class should always be at least as high as the rate. Also, the ceil for a class should always be at least as high as the ceil of any of its children. 5. Burst Networking hardware can only send one packet at a time and only at a hardware dependent rate. Link sharing software can only use this ability to approximate the effects of multiple links running at different (lower) speeds. Therefore the rate and ceil are not really instantaneous measures but averages over the time that it takes to send many packets. What really happens is that the traffic from one class is sent a few packets at a time at the maximum speed and then other classes are served for a while. The burst and cburst parameters control the amount of data that can be sent at the maximum (hardware) speed without trying to serve another class.

If cburst is smaller (ideally one packet size) it shapes bursts to not exceed ceil rate in the same way as TBF's peakrate does.

When you set burst for parent class smaller than for some child then you should expect the parent class to get stuck sometimes (because child will drain more than parent can handle). HTB will remember these negative bursts up to 1 minute.

You can ask why I want bursts. Well it is cheap and simple way how to improve response times on congested link. For example www traffic is bursty. You ask for page, get it in burst and then read it. During that idle period burst will "charge" again.

Note: The burst and cburst of a class should always be at least as high as that of any of it children.

On graph you can see case from previous chapter where I changed burst for red and yellow (agency A) class to 20kb but cburst remained default (cca 2 kb). Green hill is at time 13 due to burst setting on SMTP class. A class. It has underlimit since time 9 and accumulated 20 kb of burst. The hill is high up to 20 kbps (limited by ceil because it has cburst near packet size). Clever reader can think why there is not red and yellow hill at time 7. It is because yellow is already at ceil limit so it has no space for furtner bursts. There is at least one unwanted artifact - magenta crater at time 4. It is because I intentionaly "forgot" to add burst to root link (1:1) class. It remembered hill from time 1 and when at time 4 blue class wanted to borrow yellow's rate it denied it and compensated itself.

Limitation: when you operate with high rates on computer with low resolution timer you need some minimal burst and cburst to be set for all classes. Timer resolution on i386 systems is 10ms and 1ms on Alphas. The minimal burst can be computed as max_rate*timer_resolution. So that for 10Mbit on plain i386 you needs burst 12kb.

If you set too small burst you will encounter smaller rate than you set. Latest tc tool will compute and set the smallest possible burst when it is not specified. 6. Priorizing bandwidth share Priorizing traffic has two sides. First it affects how the excess bandwidth is distributed among siblings. Up to now we have seen that excess bandwidth was distibuted according to rate ratios. Now I used basic configuration from chapter 3 (hierarchy without ceiling and bursts) and changed priority of all classes to 1 except SMTP (green) which I set to 0 (higher). From sharing view you see that the class got all the excess bandwidth. The rule is that classes with higher priority are offered excess bandwidth first. But rules about guaranted rate and ceil are still met.

There is also second face of problem. It is total delay of packet. It is relatively hard to measure on ethernet which is too fast (delay is so neligible). But there is simple help. We can add simple HTB with one class rate limiting to less then 100 kbps and add second HTB (the one we are measuring) as child. Then we can simulate slower link with larger delays. For simplicity sake I use simple two class scenario:

# qdisc for delay simulation
tc qdisc add dev eth0 root handle 100: htb
tc class add dev eth0 parent 100: classid 100:1 htb rate 90kbps

# real measured qdisc
tc qdisc add dev eth0 parent 100:1 handle 1: htb
AC="tc class add dev eth0 parent"
$AC 1: classid 1:1 htb rate 100kbps
$AC 1:2 classid 1:10 htb rate 50kbps ceil 100kbps prio 1
$AC 1:2 classid 1:11 htb rate 50kbps ceil 100kbps prio 1
tc qdisc add dev eth0 parent 1:10 handle 20: pfifo limit 2
tc qdisc add dev eth0 parent 1:11 handle 21: pfifo limit 2

Note: HTB as child of another HTB is NOT the same as class under another class within the same HTB. It is because when class in HTB can send it will send as soon as hardware equipment can. So that delay of underlimit class is limited only by equipment and not by ancestors. In HTB under HTB case the outer HTB simulates new hardware equipment with all consequences (larger delay)

Simulator is set to generate 50 kbps for both classes and at time 3s it executes command:

tc class change dev eth0 parent 1:2 classid 1:10 htb \

rate 50kbps ceil 100kbps burst 2k prio 0

As you see the delay of WWW class dropped nearly to the zero while SMTP's delay increased. When you priorize to get better delay it always makes other class delays worse. Later (time 7s) the simulator starts to generate WWW at 60 kbps and SMTP at 40 kbps. There you can observe next interesting behaviour. When class is overlimit (WWW) then HTB priorizes underlimit part of bandwidth first.

What class should you priorize ? Generaly those classes where you really need low delays. The example could be video or audio traffic (and you will really need to use correct rate here to prevent traffic to kill other ones) or interactive (telnet, SSH) traffic which is bursty in nature and will not negatively affect other flows. Common trick is to priorize ICMP to get nice ping delays even on fully utilized links (but from technical point of view it is not what you want when measuring connectivity). 7. Understanding statistics The tc tool allows you to gather statistics of queuing disciplines in Linux. Unfortunately statistic results are not explained by authors so that you often can't use them. Here I try to help you to understand HTB's stats. First whole HTB stats. The snippet bellow is taken during simulation from chapter 3.

  1. tc -s -d qdisc show dev eth0
qdisc pfifo 22: limit 5p
Sent 0 bytes 0 pkts (dropped 0, overlimits 0) 
qdisc pfifo 21: limit 5p
Sent 2891500 bytes 5783 pkts (dropped 820, overlimits 0) 
qdisc pfifo 20: limit 5p
Sent 1760000 bytes 3520 pkts (dropped 3320, overlimits 0) 
qdisc htb 1: r2q 10 default 1 direct_packets_stat 0
Sent 4651500 bytes 9303 pkts (dropped 4140, overlimits 34251) 

First three disciplines are HTB's children. Let's ignore them as PFIFO stats are self explanatory. overlimits tells you how many times the discipline delayed a packet. direct_packets_stat tells you how many packets was sent thru direct queue. Other stats are sefl explanatory. Let's look at class' stats:

tc -s -d class show dev eth0 class htb 1:1 root prio 0 rate 800Kbit ceil 800Kbit burst 2Kb/8 mpu 0b

   cburst 2Kb/8 mpu 0b quantum 10240 level 3 
Sent 5914000 bytes 11828 pkts (dropped 0, overlimits 0) 
rate 70196bps 141pps 
lended: 6872 borrowed: 0 giants: 0

class htb 1:2 parent 1:1 prio 0 rate 320Kbit ceil 4000Kbit burst 2Kb/8 mpu 0b

   cburst 2Kb/8 mpu 0b quantum 4096 level 2 
Sent 5914000 bytes 11828 pkts (dropped 0, overlimits 0) 
rate 70196bps 141pps 
lended: 1017 borrowed: 6872 giants: 0

class htb 1:10 parent 1:2 leaf 20: prio 1 rate 224Kbit ceil 800Kbit burst 2Kb/8 mpu 0b

   cburst 2Kb/8 mpu 0b quantum 2867 level 0 
Sent 2269000 bytes 4538 pkts (dropped 4400, overlimits 36358) 
rate 14635bps 29pps 
lended: 2939 borrowed: 1599 giants: 0

I deleted 1:11 and 1:12 class to make output shorter. As you see there are parameters we set. Also there are level and DRR quantum informations. overlimits shows how many times class was asked to send packet but he can't due to rate/ceil constraints (currently counted for leaves only). rate, pps tells you actual (10 sec averaged) rate going thru class. It is the same rate as used by gating. lended is # of packets donated by this class (from its rate) and borrowed are packets for whose we borrowed from parent. Lends are always computed class-local while borrows are transitive (when 1:10 borrows from 1:2 which in turn borrows from 1:1 both 1:10 and 1:2 borrow counters are incremented). giants is number of packets larger than mtu set in tc command. HTB will work with these but rates will not be accurate at all. Add mtu to your tc (defaults to 1600 bytes). 8. Making, debugging and sending error reports If you have kernel 2.4.20 or newer you don't need to patch it - all is in vanilla tarball. The only thing you need is tc tool. Download HTB 3.6 tarball and use tc from it.

You have to patch to make it work with older kernels. Download kernel source and use patch -p1 -i htb3_2.X.X.diff to apply the patch. Then use make menuconfig;make bzImage as before. Don't forget to enable QoS and HTB. Also you will have to use patched tc tool. The patch is also in downloads or you can download precompiled binary.

If you think that you found an error I will appreciate error report. For oopses I need ksymoops output. For weird qdisc behaviour add parameter debug 3333333 to your tc qdisc add .... htb. It will log many megabytes to syslog facility kern level debug. You will probably want to add line like: kern.debug -/var/log/debug to your /etc/syslog.conf. Then bzip and send me the log via email (up to 10MB after bzipping) along with description of problem and its time.

[править] tc - Linux man page

NAME tc - show / manipulate traffic control settings

SYNOPSIS tc qdisc [ add | change | replace | link ] dev DEV [ parent qdisc-id | root ] [ handle qdisc-id ] qdisc [ qdisc specific parameters ]

tc class [ add | change | replace ] dev DEV parent qdisc-id [ classid class-id ] qdisc [ qdisc specific parameters ]

tc filter [ add | change | replace ] dev DEV [ parent qdisc-id | root ] protocol protocol prio priority filtertype [ filtertype specific parameters ] flowid flow-id

tc [-s | -d ] qdisc show [ dev DEV ] tc [-s | -d ] class show dev DEV tc filter show dev DEV

[править] DESCRIPTION

Tc is used to configure Traffic Control in the Linux kernel. Traffic Control consists of the following:

SHAPING
When traffic is shaped, its rate of transmission is under control. Shaping may be more than lowering the available bandwidth - it is also used to smooth out bursts in traffic for better network behaviour. Shaping occurs on egress.
SCHEDULING
By scheduling the transmission of packets it is possible to improve interactivity for traffic that needs it while still guaranteeing bandwidth to bulk transfers. Reordering is also called prioritizing, and happens only on egress.
POLICING
Where shaping deals with transmission of traffic, policing pertains to traffic arriving. Policing thus occurs on ingress.
DROPPING
Traffic exceeding a set bandwidth may also be dropped forthwith, both on ingress and on egress. Processing of traffic is controlled by three kinds of objects: qdiscs, classes and filters.
QDISCS
qdisc is short for 'queueing discipline' and it is elementary to understanding traffic control. Whenever the kernel needs to send a packet to an interface, it is enqueued to the qdisc configured for that interface. Immediately afterwards, the kernel tries to get as many packets as possible from the qdisc, for giving them to the network adaptor driver. A simple QDISC is the 'pfifo' one, which does no processing at all and is a pure First In, First Out queue. It does however store traffic when the network interface can't handle it momentarily.
CLASSES
Some qdiscs can contain classes, which contain further qdiscs - traffic may then be enqueued in any of the inner qdiscs, which are within the classes. When the kernel tries to dequeue a packet from such a classful qdisc it can come from any of the classes. A qdisc may for example prioritize certain kinds of traffic by trying to dequeue from certain classes before others.
FILTERS
A filter is used by a classful qdisc to determine in which class a packet will be enqueued. Whenever traffic arrives at a class with subclasses, it needs to be classified. Various methods may be employed to do so, one of these are the filters. All filters attached to the class are called, until one of them returns with a verdict. If no verdict was made, other criteria may be available. This differs per qdisc. It is important to notice that filters reside within qdiscs - they are not masters of what happens.

[править] CLASSLESS QDISCS

The classless qdiscs are:

[p|b]fifo
Simplest usable qdisc, pure First In, First Out behaviour. Limited in packets or in bytes.
pfifo_fast
Standard qdisc for 'Advanced Router' enabled kernels. Consists of a three-band queue which honors Type of Service flags, as well as the priority that may be assigned to a packet.
red
Random Early Detection simulates physical congestion by randomly dropping packets when nearing configured bandwidth allocation. Well suited to very large bandwidth applications.
sfq
Stochastic Fairness Queueing reorders queued traffic so each 'session' gets to send a packet in turn.
tbf
The Token Bucket Filter is suited for slowing traffic down to a precisely configured rate. Scales well to large bandwidths.

CONFIGURING CLASSLESS QDISCS In the absence of classful qdiscs, classless qdiscs can only be attached at the root of a device. Full syntax: tc qdisc add dev DEV root QDISC QDISC-PARAMETERS

To remove, issue tc qdisc del dev DEV root

The pfifo_fast qdisc is the automatic default in the absence of a configured qdisc.

[править] CLASSFUL QDISCS

The classful qdiscs are:

CBQ
Class Based Queueing implements a rich linksharing hierarchy of classes. It contains shaping elements as well as prioritizing capabilities. Shaping is performed using link idle time calculations based on average packet size and underlying link bandwidth. The latter may be ill-defined for some interfaces.
HTB
The Hierarchy Token Bucket implements a rich linksharing hierarchy of classes with an emphasis on conforming to existing practices. HTB facilitates guaranteeing bandwidth to classes, while also allowing specification of upper limits to inter-class sharing. It contains shaping elements, based on TBF and can prioritize classes.
PRIO
The PRIO qdisc is a non-shaping container for a configurable number of classes which are dequeued in order. This allows for easy prioritization of traffic, where lower classes are only able to send if higher ones have no packets available. To facilitate configuration, Type Of Service bits are honored by default.

[править] THEORY OF OPERATION

Classes form a tree, where each class has a single parent. A class may have multiple children. Some qdiscs allow for runtime addition of classes (CBQ, HTB) while others (PRIO) are created with a static number of children.

Qdiscs which allow dynamic addition of classes can have zero or more subclasses to which traffic may be enqueued.

Furthermore, each class contains a leaf qdisc which by default has pfifo behaviour though another qdisc can be attached in place. This qdisc may again contain classes, but each class can have only one leaf qdisc.

When a packet enters a classful qdisc it can be classified to one of the classes within. Three criteria are available, although not all qdiscs will use all three:

tc filters
If tc filters are attached to a class, they are consulted first for relevant instructions. Filters can match on all fields of a packet header, as well as on the firewall mark applied by ipchains or iptables. See tc-filters(8).
Type of Service
Some qdiscs have built in rules for classifying packets based on the TOS field.
skb->priority
Userspace programs can encode a class-id in the 'skb->priority' field using the SO_PRIORITY option. Each node within the tree can have its own filters but higher level filters may also point directly to lower classes. If classification did not succeed, packets are enqueued to the leaf qdisc attached to that class. Check qdisc specific manpages for details, however.

[править] NAMING

All qdiscs, classes and filters have IDs, which can either be specified or be automatically assigned.

IDs consist of a major number and a minor number, separated by a colon.

QDISCS
A qdisc, which potentially can have children, gets assigned a major number, called a 'handle', leaving the minor number namespace available for classes. The handle is expressed as '10:'. It is customary to explicitly assign a handle to qdiscs expected to have children.
CLASSES
Classes residing under a qdisc share their qdisc major number, but each have a separate minor number called a 'classid' that has no relation to their parent classes, only to their parent qdisc. The same naming custom as for qdiscs applies.
FILTERS
Filters have a three part ID, which is only needed when using a hashed filter hierarchy, for which see tc-filters(8).

[править] UNITS

All parameters accept a floating point number, possibly followed by a unit. Bandwidths or rates can be specified in:

kbps 
Kilobytes per second
mbps 
Megabytes per second
kbit
Kilobits per second
mbit
Megabits per second
bps or a bare number
Bytes per second Amounts of data can be specified in:
kb or k
Kilobytes
mb or m
Megabytes
mbit
Megabits
kbit
Kilobits
b or a bare number
Bytes. Lengths of time can be specified in:
s, sec or secs
Whole seconds
ms, msec or msecs
Milliseconds
us, usec, usecs or a bare number
Microseconds.

[править] TC COMMANDS

The following commands are available for qdiscs, classes and filter:

add 
Add a qdisc, class or filter to a node. For all entities, a parent must be passed, either by passing its ID or by attaching directly to the root of a device. When creating a qdisc or a filter, it can be named with the handle parameter. A class is named with the classid parameter.
remove 
A qdisc can be removed by specifying its handle, which may also be 'root'. All subclasses and their leaf qdiscs are automatically deleted, as well as any filters attached to them.
change 
Some entities can be modified 'in place'. Shares the syntax of 'add', with the exception that the handle cannot be changed and neither can the parent. In other words, change cannot move a node.
replace 
Performs a nearly atomic remove/add on an existing node id. If the node does not exist yet it is created.
link 
Only available for qdiscs and performs a replace where the node must exist already.

[править] HISTORY

tc was written by Alexey N. Kuznetsov and added in Linux 2.2.


[править] Сага по Hierarchical Token Bucket

В статье Advanced Routing & QoS (http://www.atmsk.ru/index.php?option=articles&task=viewarticle&artid=27) я упоминал полноклассовую дисциплину HTB. Так как она в последнее время набирает обороты, хочу поделиться некоторой информацией, которая может оказаться полезной при ее использовании.

Начну с краткого описания HTB. Я думаю, есть хотя-бы приблизительное представление о том, как работает classfull шэйпинг, поэтому в описание терминологии вдаваться не нужно. Кроме того, все заинтересованные прочитали статью про QoS.

Итак, что дает нам HTB:

  1. Последняя реализация так-же быстра, как CBQ и гораздо точнее ее.
  2. Это более понятно и легко конфигурируемо, чем CBQ.
  3. HTB работает похоже на CBQ, но не расчитывает на временнЫе параметры в канале в момент простоев (idle time) для разграничения полос. Вместо этого, он работает как полноклассовый Token Bucket Filter. У НТВ небольшое число параметров, которые неплохо документированы.
  4. Вытекает из предыдущего — классы уже работают как TBF-шэйперы и мы можем выбирать qdisc, который будет не резать, а распределять трафик. У CBQ.init в листьях был только TBF.
  5. Решение на основе НТВ более расширяемо. Нужно мало действий, чтобы создать минимальную конфигурацию. Про CBQ так не скажешь.
  6. HTB может наследовать неиспользуемую полосу пропускания как по горизонтали, так и по вертикали в дереве классов.
  7. Наследование происходит на основе приоритетов классов и фильтров, а так-же установленного rate.
  8. Вводится понятие CIR(знакомое по frame-relay), т.е. минимально-допустимой полосы пропускания.
  9. В HTB работают все настройки, в отличие от параметров bounded совместно с isolated в CBQ.
  10. Разработка этого добра продолжается, тогда как про CBQ Кузнецов почему-то забыл. Приходится даже патчить его утилиту tc на предмет совместимости с HTB. В ядре HTB начиная с 2.4.20.
  11. Наконец существует довольно оживленный список рассылки по вопросам конфигурирования и функционирования HTB.
  12. И последнее — при описании дерева классов, не обязательно точно описывать родительский RATE.

Несколько генеральных ссылок по HTB:

  1. http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm
  2. http://www.docum.org/stef.coene/qos/faq/cache/
  3. http://tldp.org/HOWTO/ADSL-Bandwidth-Management-HOWTO/index.html

Краткие правила при использовании HTB:

  1. Напоминаю, что управлять можно только исходящим трафиком.
  2. kbps = kilobyte/s; kb = kilobyte; kbit = kilobit/s or kilobit - это нужно для понимания вывода статистики по сконфигурированным классам и дальнейших рассуждений.
  3. Не нужно добавлять htb/cbq/tbf qdiscs в классы - это вносит задержки и жрет CPU. Мы будем использовать sfq и pbfifo.
  4. Чем больше prio в классе, тем ниже приоритет при наследовании полосы. Допустимый диапазон - 0-7.
  5. rate <= ceil в классе.
  6. sum (rate of childs) <= parent rate & ceil; в идеальном случае sum (rate of childs) = parent rate. Если правило не соблюдается, то на parent параметры HTB кладет (см. п.12 выше). Это допустимо но не желательно. Реальный пример — имеем около 80 классов, которые имеют rate=32kbit. При их суммировании, имеем почти в три раза большее значение, чем имеющийся у нас мегабит исходящего канала, который описан как rate родительского класса. Таким образом HTB сохраняет свою целостность (в отличие от CBQ, у которого съезжает крыша, и он начинает ошибаться и врать в статистике). В случае, если предположить, что все классы будут забиты трафиком (почти невероятно), то никто не получит свой CIR, но будет очень близок к нему тот класс, у которого выше prio и больше quantum.
  7. Если ceil не указан, то он = rate.
  8. Если класс промежуточный (не leaf и не root), в него _не_ нужно вводить qdisc и фильтры(rules) соответственно. Приоритеты в таких классах так-же не работают, они нужны только для leafs.
  9. Приоритет класса описывает то, какие классы в каком порядке наследуют полосу. Приоритет фильтра описывает порядок просмотра списка фильтров при классификации.
  10. HTB обычно подразумевается как класс, но так-же существует и как qdisc, который присоединяется _только_ непосредственно к интерфейсу (до root-class)
  11. Численное значение любого класса лежит в пределах 2-ffff и должно быть уникально в пределах интерфейса.

Теперь сообщу приятную новость. Есть-таки скрипт htb.init, который был переписан с cbq.init и работает очень похоже. Найти его можно по адресу http://freshmeat.net/projects/htb.init Ниже я расскажу о нюансах в примерной реализации дерева классов на его основе. А сейчас рассмотрим параметры НТВ, которые, кстати, вместе с примером описаны в этом скрипте. Все слова написанные ЗАГЛАВНЫМИ буквами распознаются htb.init как параметры. Однако, никто не запрещает писать plain-script с вызовами tc, и для него эти параметры такие-же.

  1. Для HTB qdisc устройства мы описываем DEFAULT класс по умолчанию, в который попадает трафик не подпавший ни под одно rule, обычно это самый низко-приоритетный трафик. Если DEFAULT не указывать, то весь не склассифицированный трафик пойдет напрямую с наивысшим 0 приоритетом.
  2. Второй параметр R2Q используется для квантования трафика в классах. В случае малых скоростей рекомендуется значение = 1, что позволяет шейпать с точностью до 4kbit. Если не указан, то =10, что для скоростей >120Kbit.
  3. В скриптах допустим параметр QUANTUM, но он используется только как параметр для sfq, а не htb. При использовании htb.init для htb-классов вычисляется автоматически, исходя из глобального параметра R2Q и rate класса. На что влияет quantum в HTB, можно попробовать понять из [1]. На что влияет QUANTUM(как параметр в скриптах) для sfq - читать [2].
  4. CEIL используется для ограничения полосы в leaf(оконечном) классе, точно как RATE в cbq.init. RATE в HTB используется для управления тем, как полоса разбивается между дочерними классами, и гарантирует минимальную полосу, если есть у кого наследовать. То есть своего рода CIR.
  5. Про PRIO я уже писал. Обычно у классов хостов он где-то в середине, у интерактивного трафика - повыше, у остального (или по умолчанию) - пониже.
  6. Классификация трафика происходит так-же как и в cbq.init с помощью параметра RULE, которых допустимо несколько. Пакет попавший под любое rule будет отправлен в этот класс. Обращать внимание на запятые! rule=addres, - это source; rule=addres - это destination. Допустимы звездочки, при описании портов. При введении rules, классификация происходит с использованием u32 классификатора, про который читать [3]
  7. Классификация например в интерактивный класс может происходить так-же при помощи параметра MARK. Тут в дело вступает классификатор fw, который выбирает fwmarked пакеты. Отмечаем пакеты в фаерволе. Приоритет при просмотре фильтров у fw в скрипте ниже, что IMHO не правильно. Для того, чтобы ловить сначала мелкие пакеты (ACKs), а только потом по адресам-портам, надо подправить приоритеты фильтрам прямо в htb.init. При генерации plain-script-а, htb.init назначит всем фильтрам один приоритет, который отличается численно для u32, fw и route классификаторов.
  8. Параметры листьев: для sfq - QUANTUM и PERTURB, можно оставить по умолчанию. Для pfifo - LIMIT. О смысле расскажу ниже в реализации. Других qdiscs, кроме как еще bfifo, для HTB не предусмотрено (RED не рассматриваем, да он и не поддерживается скриптом).
  9. BURST и CBURST можно не описывать, они вычисляются автоматически. Смысл - как и PEAK в CBQ (который вы тоже скорее всего не описывали).

Наконец примерная реализация.

В двух словах, htb.init парсит каталог /etc/sysconfig/htb, генерит plain-script, состоящий из множества вызовов tc и запускает его. Точно также как и cbq.init. Одно из существенных изменений - именование файлов классов. Оно детально расписано внутри самого скрипта, так-что приведу только пример:

eth0-2:20:0101:A101.client_out

  1. Здесь до минуса - интерфейс, в его соответствующем файле описываем

параметры htb qdisc (R2Q и DEFAULT).

  1. Далее id корнвого класса, в его файле только rate, для eth = 10/100Mbit.
  2. Далее id=20 Это класс, объединяющий всех клиентов. Про него ниже.
  3. Далее 0101 - parent класс клиента (только в случае запроса на prio, и соответственно разделение трафика по подклассам), обычно

это просто листовой класс клиента. Чтобы разобраться, зачем это нужно, смотрите [4]

  1. A101 - leaf класс клиента, в котором описывается qdisc.
  2. Все, что после точки - смысловое описание класса.

В нашей примерной реализации я создал три класса сразу под корневым - 10: 20: и 30: Их функции таковы:

1) 10: - интерактивный трафик. Сюда попадает ssh трафик, SMB в офисе, http на превилегированный хост - чтобы интранет работал без ограничений. С помощью марки в таблице mangle в этот-же класс завернуты пакеты < 64 байт, в основном это ACK-и. Нужно для обеспечения клиентам upload-а во время download-а. А так-же завернуты udp запросы к DNS - они маленькие, а пользы прибавят. ICMP в этот класс не попадает, для возможности актуальной проверки канала на загрузку. Вы конечно можете это делать по своему.

Подчеркну, что клиентский трафик, попавший в этот класс, не шейпается его классом (если не забыли сделать fw фильтру бОльший приоритет, чем u32 в htb.init, см. п.7 параметров), и более приоритетен, чем его остальной трафик. Правда он достаточно мал, чтобы слишком выбиваться на картинках клинтского трафика. Служит для того, чтобы клиент не "убивал" одной закачкой весь свой канал.

К классу прикреплена дисциплина sfq, так как в него попадают пакеты с разных адресов. SFQ работает по принципу русской рулетки и не дает одному tcp виртуальному каналу все время владеть полосой. Подробнее я писал в статье по QoS. (http://www.atmsk.ru/index.php?option=articles&task=viewarticle&artid=27) Параметр QUANTUM оставлен по умолчанию, параметр PERTURB, так-же по умолчанию и равен 10 сек. Это время перестройки хэша "русской рулетки", т.е. частота рандомизации хэша. Подробно про SFQ читать - см. п.3 в параметрах HTB. Полоса класса например 10Мбит, ceil = 100Mbit.

2) 20: - клиентский трафик. Ниже лежат все классы-листья клиентов. Ничего особого - rate(который может быть overlimit) согласно нашему внешнему каналу, ceil = 100Mbit(как-раз для таких случаев).

Особо остановлюсь на клиентских классах. В общем ничего мудреного, все согласно правилам выше. Про прио я уже упоминал. В качестве qdisc в листьях используется pfifo (packet фифо), который еще проще, чем pfifo_fast, используемый в случае отсутствия какого-либо qdisc. Напомню, что pfifo_fast трехполосный, и распределение по полосам плохенько, но производилось с помощью TOS. TOS умеют выставлять некоторые "умные" приложения, типа openssh.

Используемый pfifo имеет одну полосу, поэтому весь трафик в ней эквивалентен, однако в отличие от pfifo_fast имеет механизм статистики. Единственный параметр LIMIT указывает на размер очереди для pfifo в пакетах, для bfifo в байтах. Стандартная очередь pfifo{_fast} = 100. Чем больше очередь, тем беспрерывнее и "быстрее" работает одна tcp сессия, например закачка. Но и не дает никому другому кислорода, поэтому больше задержка в канале. При значениях по умолчанию qlen*MTU/sec=100*1500=150kbps, то есть к примеру на идеально забитом канале в 128kbit мы можем ожидать ответа например на пинг теоретически 150/16kbps больше 9 секунд!

Исходя из этих соображений выбирайте значения поменьше, если хотите обеспечить интерактив.

3) 30: - класс по умолчанию, он же "опущенный". Сюда попадает весь не описанный фильтрами в классах трафик. Qdisc = SFQ, т.к. разномастный трафик от разных адресов.

Так-как рулеса в скриптах работают только с tcp и портами, udp и мелкие ACK-и придется маркировать в iptables. Для этого создаем соответствующую цепочку в mangle. Любопытных милости просим сходить по треттей ссылке из генеральных.

Напоследок замечу, что это действительно работает :-)

[править] Настройка HTB на шлюзовом сервере PPPoE

Подробнее о htb можно узнать здесь: [5] Скрипт запуска htb можно скачать здесь: [6]

Копируем этот скрипт в /etc/init.d Создаем директорию /etc/sysconfig/htb Создаем там файлы:

ppp0
ppp0-2.root
ppp0-2:10.ppp

тут и прописывается ограничение пропускной способности для клиентов.

ppp0
    DEFAULT=30
    R2Q=10
ppp0-2.root
    RATE=96Kbit
    BURST=9k
ppp0-2:10.ppp
    RATE=96Kbit
    BURST=9k
    LEAF=sfq
    RULE=*,192.168.2.0/24

Эти файлы рассчитаны на пропуск примерно 11-12 kb\sec. Я не буду рассказывать про то, как настраивается htb. Про это отлично написано в статье, указанной выше.

Скрипт, который создаёт такие файлы для 255 интерфесов PPP, с 0 по 254. <sh/>

  1. !/bin/sh
  2. create.ppp.shapers

COUNTER=1 while [ "$COUNTER" -lt 254 ]; do

   echo Shaper for interface ppp$COUNTER created!
   rm -f /etc/sysconfig/htb/ppp$COUNTER
   rm -f /etc/sysconfig/htb/ppp$COUNTER-2.root
   rm -f /etc/sysconfig/htb/ppp$COUNTER-2:10.ppp
   cp /etc/sysconfig/htb/ppp0 /etc/sysconfig/htb/ppp$COUNTER
   cp /etc/sysconfig/htb/ppp0-2.root /etc/sysconfig/htb/ppp$COUNTER-2.root
   cp /etc/sysconfig/htb/ppp0-2:10.ppp /etc/sysconfig/htb/ppp$COUNTER-2:10.ppp
   let COUNTER=COUNTER+1

done /etc/init.d/htb.init restart

Т.е. для того чтобы изменить пропускную способность для всех, изменяем всё что относится к ppp0, а потом запускаем скрипт.

Для того чтобы правила применялись при подключении клиента, необходимо в каталоге /etc/ppp/ip-up.d создать скрипт shaper.start, а в каталоге /etc/ppp/ip-down.d скрипт shaper.stop.

Скрипт shaper.start <sh/>

  1. !/bin/sh

/etc/init.d/htb.init restart

Скрипт shaper.stop <sh/>

  1. !/bin/sh

/etc/init.d/htb.init restart

[править] Примеры настройки

Зарезка 192.168.1.57 на 2Mbit/s:

%# tc qdisc  add dev eth0 root handle 1: htb default 30
%# tc class  add dev eth0 parent 1: classid 1:1 htb rate 100mbit ceil 100mbit burst 15k

#============= 192.168.1.57/2048Kbit ==================

%#tc class  add dev eth0 parent 1:1   classid 1:36 htb rate 2048kbit ceil 2048kbit  burst 150k
%#tc qdisc  add dev eth0 parent 1:36  sfq perturb 10
%#tc filter add dev eth0 protocol ip parent 1:0 prio 2 handle 36 fw classid 1:36
%#iptables -t mangle -A POSTROUTING -d 192.168.1.57 -s \! 192.168.0.0/16 -j MARK --set-mark 36


Как шейпить ssh и scp раздельно [7]:

iptables -t mangle -A MYSHAPER-OUT -p tcp -m length --length 1024: 
--dport ssh -j MARK --set-mark 26 # large ssh=scp!

[править] Программы для проверки и диагностики

  • ping-exp [8] — программа, которая позволяет отслеживать временные характеристики пингов, а затем выводить графическое представление этих характеристик. Подробнее: [9]

[править] Дополнительная информация


Ещё подборка материалов:

Источник — «http://xgu.ru/wiki/QoS_%D0%B2_Linux»