Standartní komunikace v sítích typu IP probíha způsobem best effort. To znamená, že sýstém odesílá data bez záruky doručení. Při velkém vytížení sítě může být paket po cestě zahozen a musí být znovu vysílán. Mnohdy se stává, že později odeslaný paket dorazí dříve než ten, který byl odeslán jako první. IP protokol verze 4 nerozezná pakety, jejichž včasné doručení je pro nás důležité, a proto je potřeba definovat kvalitu služby (QoS). Cílem QoS je klasifikovat síťový provoz podle stanovených pravidel do tříd s rozdílnou prioritou. Pakety jsou následně z jednotlivých tříd postupně odesílány v požadovaném pořadí. Klasifikaci je možné s úspěchem použít i pro dělení šírky pásma mezi více uživatelů.
Vyžaduje záruku QoS po celé trase mezi zdrojovou a cílovou stanicí. Všechny uzly na trase musí mít informace o parametrech datoveho toku a rezervované odpovídající zdroje. IntServ používá následující dvě třídy:
Oproti svému předchůdci se jedná o jednodušší model. DiffServ disponuje lepší škalovatelností, což umožnuje garantovat kvalitu služby datového toku na větší vzdálenosti bez zbytečné zátěže výpočetního výkonu jednotlivých uzlů. V modelu DiffServ se rozlišují tři typy routerů:
Jednotlivé pakety se před vysíláním nebo po příjetí řádí do fronty. Pakety čekající ve frontě je možné ovlivňovat pomocí disciplín qdisc (queue discipline), což jsou vlastně implementace různých QoS algoritmů. Pakety je možné zahazovat, zpomalovat nebo měnit jejich pořadí. Jelikož není možné ovlivnit pakety, které přichází na vstup síťového adaptéru, je problematické uplatňovat QoS pro příchozí traffic. Jediný způsob jak regulovat rychlost příchozích dat, je prostým zahazováním paketů. Zahazování paketů je však účinné pouze u protokolu TCP, kde vyšší ztrátovost paketů způsobí snížení vysílací rychlosti.
Existují dva základní typy disciplín:
Pro podporu QoS v Linuxu je nutné do konfigurace jádra přidat volby pro QoS.
CONFIG_NET_SCHED=y CONFIG_NET_SCH_CLK_JIFFIES=yJednotlivé disciplíny (qdisc)
CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m CONFIG_NET_SCH_PRIO=m CONFIG_NET_SCH_RED=m CONFIG_NET_SCH_SFQ=m CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_TEQL=m CONFIG_NET_SCH_DSMARK=mZpůsob klasifikace, značení paketů
CONFIG_NET_CLS=y CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=m CONFIG_CLS_U32_MARK=yPokud je potřeba i virtuální rozhraní IMQ, je nutné jádro opatchovat pomocí patche http://www.linuximq.net/patches.html
cd /usr/src/linux patch -p1 < /usr/src/imq/linux-2.6.16-imq2.diffDále do konfigurace jádra přidat volby CONFIG_IMQ a CONFIG_IP_NF_TARGET_IMQ.
Kolekce programů pro řízení provozu je poskytována pod souhrným názvem iproute.
Balíček je ke stažení na domácí stránce projektu
http://linux-net.osdl.org/index.php/Iproute2.
V debianu iproute nainstalujeme následovně:
apt-get install iproute
Pro používání IMQ je nutné patchnout iptables, jelikož standartně IMQ není podporován.
Zdrojové kódy iptablas http://www.netfilter.org,
patch pro IMQ
http://www.linuximq.net/patches.html
cd /usr/src/iptables-x.x.x patch -p1 < iptables-x.x.x-imqx.diff
Konfigurace se provádí pomocí utility tc (traffic control) z baličku iproute. Jednotlivé diciplíny se označují ve tvaru číslo:číslo, kde číslo před dvojtečkou udává číslo qdisku a číslo za dvojtečkou číslo třídy. Čísla mohou být libovolné, ale je dobré zachovat v číslování určitou logiku (pro přehlednost). Čísla slouží pro indentifikaci a proto musí být jedinečné.
Při tvoření stromové struktury je důležité dbát na to, aby součet průtoku dat listů nepřesáhl šířku pásma rodičovského uzlu. Stejně tak není dobré vytvářet velké množství listů s mnohonásobně nížší garantovanou propustností než propustností celkovou. Algoritmus pak špatně počítá a celé řízení toku dat se jeví jako nefunkční.
Představme si situaci, že máme k dispozici linku s downloadem 384kbps a chceme ji nasdílet třem uživatelům tak, aby každý uživatel měl garantováno minimálně 128kbps. Pokud nebude některý uživatel využívat svůj díl celý, bude jeho volná část pásma rozdělena mezi ostatní. Uživatelé mají IP adresy 10.0.0.10 - 10.0.0.12.
Nejprve připravíme jednotlivé třídy. Parametr rate udává garantovanou propustnost a ceil je maximální strop.
tc qdisc del dev eth0 root tc qdisc add dev eth0 root handle 1: htb default 1 tc class add dev eth0 parent 1: classid 1:1 htb rate 384kbit tc class add dev eth0 parent 1:1 classid 1:11 htb rate 128Kbit ceil 384kbit tc class add dev eth0 parent 1:1 classid 1:12 htb rate 128Kbit ceil 384kbit tc class add dev eth0 parent 1:1 classid 1:13 htb rate 128Kbit ceil 384kbit
Standartně se na classful qdisc přidává fronta typu FIFO, která není moc spravedlivá a proto FIFO nahradíme disciplínou SFQ.
tc qdisc add dev eth0 parent 1:11 handle 11: sfq perturb 10 tc qdisc add dev eth0 parent 1:12 handle 12: sfq perturb 10 tc qdisc add dev eth0 parent 1:13 handle 13: sfq perturb 10
Nyní už jen stačí rozhodit pakety do správných tříd. Provádí se to přídáním filtrů. Filtr pakety pro danou třídu může indentifikovat více způsoby. Může číst značku v TOS oktetu hlavičky paketu, filtrovat pomocí zdrojové/cílové IP adresy, zdrojového/cílového portu nebo využít značky vytvořené přes mangle tabulku v iptables.
Příklad klasifikace na základě cílové IP adresy
tc filter add dev eth0 parent 1:1 protocol ip u32 match ip dst 10.0.0.10 flowid 1:11 tc filter add dev eth0 parent 1:1 protocol ip u32 match ip dst 10.0.0.11 flowid 1:12 tc filter add dev eth0 parent 1:1 protocol ip u32 match ip dst 10.0.0.12 flowid 1:13
Příklad klasifikace na základě označení přes iptables
iptables -t mangle -A FORWARD -d 10.0.0.10 -j MARK --set-mark 10 iptables -t mangle -A FORWARD -d 10.0.0.11 -j MARK --set-mark 11 iptables -t mangle -A FORWARD -d 10.0.0.12 -j MARK --set-mark 12 tc filter add dev eth0 parent 1:1 protocol ip handle 10 fw flowid 1:11 tc filter add dev eth0 parent 1:1 protocol ip handle 11 fw flowid 1:12 tc filter add dev eth0 parent 1:1 protocol ip handle 12 fw flowid 1:13
Použití značkování paketů přes iptables je výhodné tehdy, pokud je potřeba vytvořit složité pravidla jako na které nám samotný filtr nestačí. Příkladem může být klasifikace na základě MAC adres. Na druhou stranu je používání tabulky mangle o trochu pomalejší a někdy zbytečné.
Máme obdobnou situaci jako v předcházejícím příkladě s tím rozdílem, že uživatelé se rozhodnou přikoupit další linku. Předpokládejme, že v routeru je připojení k internetu realizováno přes adaptéry wlan0, wlan1 a síťové rozhraní pro místní síť má označení eth0. Potřebujeme rodělit provoz mezi dvě linky.
vytvoříme virtuální rozhraní, které spojí naše dvě fyzické
iptables -t mangle -A POSTROUTING -o wlan0 -j IMQ --todev 0 iptables -t mangle -A POSTROUTING -o wlan1 -j IMQ --todev 0 ifconfig imq0 up
Aplikujeme obdobné QoS pravidla jako v předchozím příkladě
tc qdisc del dev imq0 root tc qdisc add dev imq0 root handle 1: htb default 1 tc class add dev imq0 parent 1: classid 1:1 htb rate 768kbit tc class add dev imq0 parent 1:1 classid 1:11 htb rate 256Kbit ceil 768kbit tc class add dev imq0 parent 1:1 classid 1:12 htb rate 256Kbit ceil 768kbit tc class add dev imq0 parent 1:1 classid 1:13 htb rate 256Kbit ceil 768kbit tc qdisc add dev imq0 parent 1:11 handle 11: sfq perturb 10 tc qdisc add dev imq0 parent 1:12 handle 12: sfq perturb 10 tc qdisc add dev imq0 parent 1:13 handle 13: sfq perturb 10 tc filter add dev imq0 parent 1:1 protocol ip u32 match ip dst 10.0.0.10 flowid 1:11 tc filter add dev imq0 parent 1:1 protocol ip u32 match ip dst 10.0.0.11 flowid 1:12 tc filter add dev imq0 parent 1:1 protocol ip u32 match ip dst 10.0.0.12 flowid 1:13
Rozdělení zátěže mezi více síťových rozhraní se uplatňuje u routerů, které mají k dispozici více datových linek. Provoz můžeme triviálně rozdělit například pomocí routovací tabulky tak, že napevno nadefinujeme destinace a rozhraní, přes které budou pakety posílány. Není to však moc efektivní řešení v případě, kdy používání datových proudů není rovnoměrné, mění se v čase nebo když potřebujeme datové proudy detailněji třídit. V praxi je tedy toto řešení téměř nepoužitelné a proto je vhodné využít nějaký silnější nástroj.
Jednou z možností je použít qdisc TEQL (Trivial Link EQualizer). Celý mechanismus se chová trochu jako qdisc a trochu jako virtuální rozhraní. Utilitkou tc určíme fyzická rozhraní, která budou spojena do virtuálního rozhraní teql0. Qdisc TEQL pak rozděluje provoz mezi spojená rozhraní algoritmem round robin.
O zařazení paketů do správné třídy (klasifikaci) se stará filter.
Na obou strojích tedy spojíme fyzická rozhraní (řekněme wlan0 a wlan1).
tc qdisc add dev wlan0 root teql0 tc qdisc add dev wlan1 root teql0 ip link set dev teql0 up
Po nastavení pravidel kvality služby je dobré chování sytému otestovat. K tomu je možné použit některé z následujících programů pro monitorování okamžitého průtoku dat.
Linux Advanced Routing & Traffic Control HOWTO
IPROUTE2 Utility Suite Howto
Differentiated Service on Linux HOWTO
Seriál o HTB na serveru root.cz
Referát o QoS z podzimu2005