За начинаещи относно управлението на честотната лента в Linux

Преди известно време ме помолиха да настроя просто балансиране на трафика в отдалечен клон. Те работят, горките, чрез ADSL и изпращането на големи имейли (сканиране на документи) задръства целия канал за връщане с тях, което води до проблеми при работата с офис онлайн програми чрез VPN. Те използват Linux (Fedora) като свой шлюз. Преди това видях няколко пъти как такова балансиране се конфигурира чрез ipfw на FreeBSD и тъй като познавам механизма на iptables доста добре, не очаквах никакви специални проблеми. Но след търсене в интернет бях неприятно изненадан, че iptables изобщо не ми беше помощник тук. А знанията за реда на преминаване на пакетите през неговите таблици и правила едва ли ще са ми полезни. Трябва да научите tc от пакета iproute2.

Безкласови дисциплини

И така, в Linux, за управление на трафика, на всеки мрежов интерфейс се присвоявадисциплина (qdisc). Именно от дисциплините се изгражда цялата система за управление на трафика. Но не трябва да се страхувате, всъщност дисциплината е само алгоритъм за обработка на опашка от мрежови пакети. В един интерфейс може да има няколко дисциплини и така нареченатаосновна дисциплина (root qdisc)е прикрепена директно към интерфейса. Всеки интерфейс обаче има своя собствена основна дисциплина.

По подразбиране, след зареждане на системата, root qdisc задава алгоритъма за обработка на пакети катоpfifo_fast.

лента

qdisc pfifo_fast 0: dev eth0 коренни ленти 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1

pfifo_fastе обичайният алгоритъм "Първо въвеждане - първи изход", но с известно приоритизиране на трафика. Дисциплина от този тип съдържа в себе си три FIFO опашки с различни приоритети за обработка на пакети. Пакетите се разлагат на тях въз основа на флага ToS (Тип науслуга) във всеки IP пакет. Пакет във FIFO0 има най-висок приоритет за обработка, във FIFO2 е с най-нисък. Самите ToS изискват отделна дискусия, така че предлагам да се ограничим до факта, че самата операционна система знае кои ToS да присвои на изпратения IP пакет. Например в telnet и ping пакетите ToS ще има различни стойности.

0:— манипулатор на основната дисциплина. Дескрипторите трябва да бъдат във форматаосновно_число: второстепенно_число, но за дисциплини второстепенното число винаги трябва да бъде 0 и следователно може да бъде пропуснато.

Параметърpriomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1просто задава побитовото съответствие на полето ToS на всяка вътрешна опашка (лента). Например, с ToS=4, пакетът се обработва в опашка 1, с ToS=7, в опашка 0.

Редица източници показват, че параметрите на дисциплината pfifo_fast не могат да бъдат променяни, повярвайте ми.

Сега нека да разгледаме как можете да ограничите скоростта на общия изходящ трафик. За да направите това, нека присвоим дисциплина от типTBF (Token Bucket Filter)като основна дисциплина на интерфейса.

# tc qdisc add dev eth0 root tbf rate 180kbit латентност 20ms буфер 1540

rate 180kbit- задава прага за скоростта на трансфер на интерфейса.

латентност 20ms- задава максималното време, през което пакетът данни чака токен.

буфер 1540— задайте размера на буфера на токена в байтове. В примерите пишат, че буфер от 10Kbytes е достатъчен за лимит от 10Mbit/s. Основното нещо е да не го правите твърде малък, възможно е повече. Приблизителна формула за изчисление: rate_in_Bytes/100.

относно

Дисциплината TBF използва механизма на токените за своята работа. Токените се генерират от системата с постоянна скорост и се поставят в буфер (кофа). За всеки токен, който напуска буфера, един IP пакет напуска интерфейса. Ако скоростта на предаване на пакети и скоростта на генериране на токени съвпадат, процесът на прехвърляне на данни продължава без забавяне. Ако скоростта на пакетите е по-малка от скоростта на токена, токените започват да се натрупват в буфера и след това могат да се използват за краткосрочно предаване на данни със скорост над прага. Ако скоростта на пренос на пакети е по-висока, ще има недостиг на токени. Пакетите с данни чакат нови токени за известно време и след това започват да се изпускат.

Описаните две дисциплини спадат към така наречените безкласови дисциплини. Те имат редица функционални ограничения: те се свързват само с интерфейс (или клас край), плюс пакетни филтри не могат да бъдат приложени към тях. И съответно задачата ми за балансиране на пощенския трафик не може да бъде решена с тяхна помощ. Между другото, пълният набор от безкласови дисциплини е малко по-широк: pfifo, bfifo, sqf (осигурява същата скорост на пакети, получени от различни потоци), esqf и т.н.

класни дисциплини

Ако дисциплините могат да бъдат представени като сегменти от водопроводни тръби, тогава класовете са съединители (фитинги). Това може да бъде обикновен фитинг-адаптер или може да бъде сложен фитинг-разклонител с дузина завои.

Родител на клас може да бъде или дисциплина, или друг клас. Дъщерните класове могат да бъдат прикрепени към клас (съединяване на няколко фитинга).

Клас, който няма дъщерни класове, се наричалистов клас. Тук пакетите с данни, преминали през нашия „водопровод“, напускат системата за контрол на трафика и се изпращат от мрежовия интерфейс. По подразбиране всеки граничен клас има прикачена дисциплина от тип fifo и именно тази дисциплина определя реда, в който се предават пакетите за този клас. Но красотата е, че можем да променим тази дисциплина на всякадруг. Ако се добави дъщерен клас, дисциплината се премахва.

Нека се върнем към задачата за балансиране на пощенския трафик и да разгледаме дисциплината на класаprio. Много е подобен на вече описания pfifo_fast. Но тази дисциплина е специална с това, че когато се присвои, автоматично се създават три класа (броят може да се промени с параметъра bands).

Нека заменим основната дисциплина на интерфейса с prio.

# tc qdisc add dev eth0 root манипулатор 1: prio

ръкохватка 1:- задайте манипулатора на този основен qdisc. В класните дисциплини след това се уточнява при свързване на класове.

qdisc преди 1: dev eth0 ленти 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1

# tc -d -s class show dev eth0

клас прио 1:1 родител 1: Изпратени 734914 байта 7875 pkt (изпуснати 0, надхвърля 0 опашки 0) назад 0b 0p опашки 0 надхвърля 26443 опашки 0) назад 0b 0p опашки 0 клас преди 1:3 родител 1: Изпратени 57934378 байта 802213 pkt (изпуснати 70976, надхвърля 284608 опашки 0) назад 0b 0p опашки 0

Виждаме три класа с идентификатори 1:1, 1:2 и 1:3, свързани с родителската дисциплина 1: от тип prio (класовете трябва да имат общ идентификатор major_number със своя родител). Това означава, че поставяме тройник на „тръбния“ корен qdisc, който разделя потоците от данни точно както прави pfifo_fast. Ръководен от ToS, трафикът с висок приоритет попада в клас 1:1, редовният трафик преминава в клас 1:2, а абсолютният „боклук“ отива в клас 1:3.

Да кажем, че обратният канал ADSL издава скорост от 90Kb / s. Нека го разделим на 20Kb/s за поща и 70Kb/s за всичко останало.

Движението от класа 1:1 няма да бъде специално ограничавано. Пакетите му винаги могат да се взематвъпреки че цялата ширина на канала поради високия приоритет на ToS, но количеството трафик в този клас ще бъде незначително в сравнение с другите два класа. Затова не запазваме отделна лента за него.

Стандартният трафик по правило попада в класа 1:2. Свързваме тръба-дисциплина при 70Kbytes / s към втория изход на класа tee:

# tc qdisc add dev eth0 parent 1:2 манипулатор 10: tfb скорост 70kbps буфер 1500 латентност 50ms

На третия изход на тройника свързваме тръба-дисциплина при 20Kbytes / s:

# tc qdisc add dev eth0 parent 1:3 манипулатор 20: tfb скорост 20kbps буфер 1500 латентност 50ms

И трите от тези класове са гранични.

И сега остава само да се насочи пощенският трафик не към класа 1:2, както се случи преди, а към класа 1:3. Това се прави с помощта на филтри за класова дисциплина.

# tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip dport 25 0xffff flowid 1:3

родител 1:— филтърът може да бъде прикачен само към дисциплина и извикан от нея. Въз основа на работата на филтъра дисциплината решава в кой клас ще продължи обработката на пакета.

протокол ip- определя типа на мрежовия протокол

prio 1- параметърът ме объркваше дълго време, тъй като се използва в класове и филтри, плюс това е името на дисциплината. Тук prio задава приоритета на работата на филтрите, филтрите с по-ниско prio се активират първи.

match ip dport 25 0xffff- настройва филтъра да работи, когато пакетите се изпращат към порт 25. 0xffff е битова маска за номера на порта.

flowid 1:3- посочете към кой клас пакети се прехвърлят, когато този филтър се задейства.

Грубо направено, но ще свърши работа.

Разглеждаме статистиката на преминаващите пакети:

# tc -s -d qdisq показва dev eth0 # tc -s -d клас показва dev eth0 # tc -s -d филтър показва dev eth0

Можете бързо да премахнете всички класове, филтри и да върнете основния qdisc на интерфейса в първоначалното му състояние с командата:

# tc qdisc del dev eth0 root

От друга страна, вече имаме твърде тънък обратен канал, за да запазим 20Kb/s само за изпращане на електронна поща. Следователно тук е по-добре да използвате дисциплината на класа HTB (Hierarchical Token Bucket). Той позволява на дъщерните класове да заемат честотна лента от родителя.

честотната

# tc qdics add dev eth0 root манипулатор 1: htb по подразбиране 20

по подразбиране 20- задайте клас по подразбиране. Той ще обработва пакети, които не попадат в други класове на htb дисциплината. Ако не е посочено, тогава ще бъде присвоено „по подразбиране 0“ и целият некласифициран (нефилтриран) трафик ще бъде изпратен със скоростта на интерфейса.

# tc class add dev eth0 parent 1: classid 1:1 htb rate 90kbps ceil 90kbps

прикачете клас с ID 1:1 към root qdisc. По този начин ограничаваме скоростта на интерфейса до 90Kb / s.

classid 1:1— идентификатор на клас.

скорост 90kbps- задайте долния праг на честотната лента за класа.

ceil 90kbps- задайте горния праг на честотната лента за класа.

# tc class add dev eth0 parent 1:1 classid 1:10 htb rate 20kbps ceil 70kbps

създаваме клас 1:10, дете на клас 1:1. След това изходящият пощенски трафик ще бъде изпратен към него от филтъра.

скорост 20kbps- задайте гарантирания долен праг на честотната лента за класа.

ceil 70kbps- задайте горния праг на честотната лента за класа. В случай, че родителятклас ще има свободна честотна лента (наличие на „допълнителни“ токени), клас 1:10 ще може временно да увеличи скоростта на трансфер на данни до определената граница от 70Kb / s.

# tc class add dev eth0 parent 1:1 classid 1:20 htb rate 70kbps ceil 90kbps

Нека създадем клас по подразбиране. Целият останал трафик ще попадне в него. По същия начин, с параметрите rate и ceil, задаваме разширяването на честотната лента, в случай че вече няма пощенски трафик.

# tc filter add dev eth0 parent 1: protocol ip prio 1 u32 match ip dport 25 0xffff flowid 1:10

базиран на u32 филтър, който насочва пакетите, изходящи към порт 25, към клас 1:10.

Между другото, в документацията се посочва, че всъщност в HTB оформянето на трафика се извършва само в крайните класове, в нашия случай 1:10 и 1:20. Указването на параметрите за ограничаване на честотната лента в останалите HTB класове е необходимо само за функционирането на системата за заемане между класовете.

При добавяне на клас е възможно също така да посочите параметъраprio. Той задава приоритета на класа (0 - макс. приоритет). Класове с по-нисък приоритет не се обработват, докато има данни в класове с по-висок приоритет.

Hardcore conf в C++. Каним само професионалисти.