Na poli přepínaných sítí představuje pojem QoS (Quality of Service, kvalita služby) pravděpododobnost naplnění přenosového kontraktu, neformálně pak pravděpodobnost, že paket úspěšně překoná trasu mezi dvěma body na síti. Když vznikl internet, nebyla tu žádná vnímaná potřeba po QoS, takže internet fungoval na principu "best effort". Po síti proplouvaly pakety s nevyužitými bity určujícími typ služby a prioritu. Nicméně paketům jdoucím po síti se může na cestě přihodit mnoho nepěkného. Z hlediska vysílajícího a přijímajícího může dojít k následujícím poruchám:
Aplikace vyžadující QoS:
Míra QoS je obvykle stanovena na základě smlouvy mezi poskytovatelem a zákazníkem označované jako SLA (Service Level Agreement), která specifikuje parametry vybraným protokolům. Mezi hlavní parametry QoS patří míra propustnosti a zpoždění.
Fronty slouží jako algortimus k určování, která data se mají odeslat první. Je důležité s uvědomit, že můžeme ovlivnit pouze data, která vysíláme. Díky způsobem, jakým funguje Internet, nemáme žádnou přímou kontrolu nad tím, co k nám proudí za data.
Příchozí provoz na síťovém rozhraní se označuje ingress a jeho tvarování (přeuspořádání, zpomalení, či zahození paketu) se nazývá policing. V Linuxu lze na ingress uplatnit pouze omezení šířky pásma pomocí zahazování paketu. Žádné pokročilé způsoby klasifikace provozu nelze použít. Odchozí provoz se označuje jako egress a jeho tvarování se nazývá shaping. Pomocí shapingu lze pakety zpomalovat, preuspořádávat i zahazovat za použití různě složitých algoritmů.
Classless fronty jsou ty, které příjímají data a zpožďují, zahazují nebo mění pořadí paketů. Používají se na shapování provozu pro rozhraní jako celek. Narozdíl od classful nemohou obsahovat další qdisc.
Když provoz dosáhne classful qdisc, je poslán na nějakou z vnořených tříd - musí být "zatříděn". K určení, co se má s roztříděnými pakety dělat, slouží tzv. filtry. Filtry jsou volány prostřednictvím qdisc.
1: root qdisc | 1:1 child class / | \ / | \ / | \ / | \ 1:10 1:11 1:12 child classes | | | | 11: | leaf class | | 10: 12: qdisc / \ / \ 10:1 10:2 12:1 12:2 leaf classes
Filtry napojené k příslušnému qdiscu vrací o paketu "rozhodnutí", které je použito k zařazení paketu do jedné z vnořených tříd. Každá podtřída může znova zkusit připojený filtr. Pokud žádný není k dispozici, zařadí paket do qdisc, který je v ní obsažen. Kromě toho, že classful qdisc obsahují další qdisc, většina z nich také provádí shaping, což je dobré k omezování propustnosti a plánování (scheduling, např. pomocí SFQ).
Pro naše účely budeme potřebovat:
[Networking/Networking options/QoS and|or fair queueing/*]
Program tc je součástí balíku iproute (na některých distribucích iproute2). Debian:
# apt-get install iproute
# cd /usr/src/ # wget http://www.linuximq.net/patchs/linux-2.6.16-imq2.diff # cd linux-2.6.16 # patch -Np1 -i ../linux-2.6.16-imq2.diff # make menuconfig ... důležité je CONFIG_IP_NF_TARGET_IMQ=m [Network device support/IMQ (intermediate queueing device) support] CONFIG_IMQ=m [Networking options/IP: Netfilter Configuration/IMQ target support] # make ...
Kvůli podpoře IMQ je potřeba patchovat i iptables patchem z linuximq.net/patches
$ wget http://www.netfilter.org/projects/iptables/files/iptables-1.3.5.tar.bz2 $ wget http://www.linuximq.net/patchs/iptables-1.3.0-imq1.diff $ tar jxf iptables-1.3.5.tar.bz2 $ cd iptables-1.3.5 $ patch -Np1 -i ../iptables-1.3.0-imq1.diff $ make PREFIX=/opt/iptables-imq KERNEL_DIR=/usr/src/linux-'uname -r' install # make PREFIX=/opt/iptables-imq KERNEL_DIR=/usr/src/linux-'uname -r' install
K nastavení shapingu slouží program tc(1).
Popisy parametrů k jednotlivým algoritmům se nacházejí v manuálových stránkách tc-htb(8), tc-pfifo(8), apod..tc qdisc del dev eth0 root tc qdisc add dev eth0 root handle 1: htb default 11 tc class add dev eth0 parent 1:0 classid 1:1 rate 128kbit tc class add dev eth0 parent 1:1 classid 1:11 rate 64kbit ceil 128kbit tc class add dev eth0 parent 1:1 classid 1:12 rate 32kbit tc qdisc add dev eth0 parent 1:11 handle 11:0 sfq perturb 5 tc qdisc add dev eth0 parent 1:12 handle 12:0 sfq perturb 10
iptables -t mangle -A POSTROUTING -d 192.168.0.1 -j MARK --set-mark 1 tc filter add dev eth0 parent 1:0 protocol ip handle 1 fw flowid 1:10
tc filter add dev eth1 protocol ip parent 1:0 u32 match ip sport 22 0xffff flowid 1:10 tc filter add dev eth1 protocol ip parent 1:0 u32 match ip dport 22 0xffff flowid 1:10Pomocí těchto dvou pravidel jsme řekli, že pakety s cílovým portem 22 patří do třídy 1:10.
Popis příkazu:
tc qdisc add dev eth1 handle 1: root cbq bandwidth 100Mbit avpkt 1000 mpu 64 ------------ -------- --------- ---- --- ----------------------------------- 1 2 3 4 5 6
Další užitečné příkazy:
[root@icharyd:~]# tc qdisc show qdisc htb 1: dev eth0 r2q 10 default 30 direct_packets_stat 0 qdisc sfq 10: dev eth0 parent 1:10 limit 128p quantum 1514b perturb 10sec qdisc sfq 20: dev eth0 parent 1:20 limit 128p quantum 1514b perturb 10sec qdisc sfq 30: dev eth0 parent 1:30 limit 128p quantum 1514b perturb 10sec [root@icharyd:~]# tc class show dev eth0 class htb 1:1 root rate 6000Kbit ceil 6000Kbit burst 15Kb cburst 4599b class htb 1:10 parent 1:1 leaf 10: prio 0 rate 5000Kbit ceil 5000Kbit burst 15Kb cburst 4Kb class htb 1:20 parent 1:1 leaf 20: prio 0 rate 3000Kbit ceil 6000Kbit burst 15Kb cburst 4599b class htb 1:30 parent 1:1 leaf 30: prio 0 rate 1000bit ceil 6000Kbit burst 15Kb cburst 4599b [root@icharyd:~]# tc filter show dev eth0 filter parent 1: protocol ip pref 1 u32 filter parent 1: protocol ip pref 1 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 1 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:30 match 00000050/0000ffff at 20
modprobe IMQ # Musíme přesměrovat příchozí provoz na naše virtuální IMQ zařízení ješte # před jeho jakýmkoliv zpracováním. iptables -t mangle -A PREROUTING -j IMQ # Nyní můžeme vytvořit strom stejně jako v předchozím případě. tc qdisc del dev imq0 root tc class add ...
Dosáhneme toho pomocí metody zv. bonding, neboli sloučení více fyzických rozhraní do jednoho logického, která má musí mít podporu v jádře [Device drivers/Network device support/Bonding driver support]. Příklad zprovoznění:
[root@real-server root]# modprobe bonding [root@real-server root]# ip addr add 192.168.100.33/24 brd + dev bond0 [root@real-server root]# ip link set dev bond0 up [root@real-server root]# ifenslave bond0 eth2 eth3 master has no hw address assigned; getting one from slave! The interface eth2 is up, shutting it down it to enslave it. The interface eth3 is up, shutting it down it to enslave it. [root@real-server root]# ifenslave bond0 eth2 eth3 [root@real-server root]# cat /proc/net/bond0/info Bonding Mode: load balancing (round-robin) MII Status: up MII Polling Interval (ms): 0 Up Delay (ms): 0 Down Delay (ms): 0 Slave Interface: eth2 MII Status: up Link Failure Count: 0 Slave Interface: eth3 MII Status: up Link Failure Count: 0
Vyčerpávající dokumentaci k této technice najdete v dokumentaci kernelu ($kernel_src/Documentation/networking/bonding.txt).
K měření průtoku dat můžeme použít program iptraf(http://cebu.mozcom.com/riker/iptraf/). Jedná se o intuitivní ncurses program. Instalace na Debianu:
# apt-get install iptraf