Quality of Service
- verteilt Bandbreite auf mehrere Beduerftige
verbessert die Reaktionsfaehigkeit von ssh & co waehrend eines Downloads
anscheinend verbessert es auch die Download-Geschwindigkeit waehrend eines Uploads, da die ack-Pakete mit hoeherer Prioritaet rausgeschickt werden koennen
!=Begriffstutzig
- Ethernet kennt kein "Quality-of-Service" (im Gegensatz zu z.B. ATM)
- aber: in Headern der versch. Protokollebenen lassen sich gezielt Bits setzen (zur Priorisierung)
- IP auf Ethernet kann Resourcen reservieren und Pakete priorisieren, dies wird meist "Class-of-Service" gennant
- Hardware muss damit allerdings umgehen koennen (spezielle Switches, Router)
Linuxrechner als Router kann das (wie dieses QoSHowTo (eigentlich <nowiki>CoS</nowiki>) gut beschreibt)
- WLAN-AP kann das eher nicht
Notwendigkeiten
- mindestens 2.4er-Kernel
<nowiki>QoS</nowiki> und die anhaengigen Verfahren fest oder modular einbauen
unter IP: Netfilter sollte tos-, mark- und length-matching, sowie das MARK-Target drin sein
- das iproute-Paket (debian-testing!)
- iptables
Grundgedanken
- das Engpass-Device in Richtung Freiheit wird von mehreren Warteschlangen gefuettert
- die Warteschlangen erhalten unterschiedliche Prioritaeten oder Transfer-Limits
- anhand sinnvoller Kriterien werden die Pakete, die hinaus wollen, der passenden Warteschlange zugeordnet
- diese Zuordnung erfolgt in zwei Schritten:
zuerst werden alle relevanten Pakete per iptables mit einer Prioritaetskennzahl markiert (--mark X)
wenn sie nun das Ausgangs-Interface erreichen, schiebt iproute (also tc) die Pakete einfach entsprechend dieser Markierung in die jeweilige Warteschlange
Umsetzung
Pakete Sortieren
- eigentlich werden sie erstmal nur entsprechend ihrer Bedeutung markiert ...
iptables -t mangle -A OUTPUT -m length --length 0:500 -j MARK --set-mark 1 iptables -t mangle -A OUTPUT -m length --length 500:1500 -j MARK --set-mark 2
- diese Regel gilt fuer Verkehr, der im qos-Rechner erzeugt wurde
- bei der Weiterleitung durch einen Router saehe es so aus:
iptables -t mangle -A FORWARD -o $DEV -m length --length 0:500 -j MARK --set-mark 1 iptables -t mangle -A FORWARD -o $DEV -m length --length 500:1500 -j MARK --set-mark 2
- zusaetzlich zur Paketlaenge (kleine ssh- und ack-Pakete) koennen natuerlich auch andere Kriterien verwendet werden
iptables -t mangle -A FORWARD -o $DEV -m tos --tos 0x10 -j MARK --set-mark 1
tos 0x10 steht fuer minimize delay - also wahrscheinlich irgendwelche Streams
- oder die Herkunft eines Pakets kann wichtig sein:
iptables -t mangle -A FORWARD -o $DEV -s PRIVILEG_IP -j MARK --set-mark 1
- um einen Download bei gleichzeitigem Upload zu beschleunigen, sollten die ack-Pakete vorgeschickt werden:
iptables -t mangle -A FORWARD -o $DEV -p tcp --tcp-flags ACK ACK -j MARK --set-mark 1
- zum Testen und weil es gut aussieht - schnelles icmp:
iptables -t mangle -A FORWARD -o $DEV -p icmp -j MARK --set-mark 1
- anhand der Markierungen werden die Pakete dann auf die Warteschlangen verteilt
Warteschlangen konfigurieren
- ein Warteschlangensystem an das Device haengen
tc qdisc add dev $DEV root handle 1: htb default 20
die default-Warteschlage ist die 20
- diese erste Warteschlange legt die oberste Grenze fest - sie sollte ein wenig unterhalb der theoretischen Bandbreite liegen, damit die Warteschlange beim ISP nicht voll wird (sonst werden die von uns muehsam beschleunigten Pakete dort wieder ausgebremst)
tc class add dev $DEV parent 1: classid 1:1 htb rate ${UPLINK}kbit burst 6k
- nun werden Warteschlagen mit verschiedenen Prioritaeten und Bandbreitengrenzen angelegt
tc class add dev $DEV parent 1:1 classid 1:10 htb rate ${UPLINK}kbit burst 6k prio 1 tc class add dev $DEV parent 1:1 classid 1:20 htb rate ${UPLINK}kbit burst 6k prio 2
- beide erhalten stochastische Fairness - das heisst, dass gelegentlich die Warteschlange neu gemischt wird, damit keine der Sitzungen, die durch diese Schlange muessen, zu lange warten muss
tc qdisc add dev $DEV parent 1:10 handle 10: sfq perturb 10 tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10
- nun wird das Kriterium fuer die Zuteilung der Pakete festgelegt
tc filter add dev $DEV parent 1: protocol ip handle 1 fw flowid 1:10 tc filter add dev $DEV parent 1: protocol ip handle 2 fw flowid 1:20
ip handle X fw bezieht sich auf die Markierung, die vorher durch iptables an die Pakete gehaengt wurde
kurz & fertig
- erstmal die Warteschlangen erzeugen
!/bin/sh UPLINK=120 DOWNLINK=980 OUTDEV=eth0
- bisherige Warteschlangen loeschen
tc qdisc del dev $OUTDEV root &>/dev/null tc qdisc del dev $OUTDEV ingress &>/dev/null
- neu anlegen
tc qdisc add dev $OUTDEV root handle 1: htb default 14
- die Gesamtwarteschlange verhindert, dass die Queue des ISP voll wird
tc class add dev $OUTDEV parent 1: classid 1:1 htb rate ${UPLINK}kbit burst 6k
- Warteschlangen erzeugen
tc class add dev $OUTDEV parent 1:1 classid 1:11 htb rate ${UPLINK}kbit burst 6k prio 1
- fuer die wichtigen Pakete (ssh und ack)
tc class add dev $OUTDEV parent 1:1 classid 1:12 htb rate ${UPLINK}kbit burst 6k prio 2
- das Labor-Netz
tc class add dev $OUTDEV parent 1:1 classid 1:13 htb rate ${UPLINK}kbit burst 6k prio 3
- das WG-Netz
tc class add dev $OUTDEV parent 1:1 classid 1:14 htb rate ${UPLINK}kbit burst 6k prio 4
- alle anderen da draussen
- stochastische Fairness aktivieren, damit alle Sitzungen in einer Schlange "gut" durchkommen
tc qdisc add dev $OUTDEV parent 1:11 handle 11: sfq perturb 10 tc qdisc add dev $OUTDEV parent 1:12 handle 12: sfq perturb 10 tc qdisc add dev $OUTDEV parent 1:13 handle 13: sfq perturb 10 tc qdisc add dev $OUTDEV parent 1:14 handle 14: sfq perturb 10
- die iptables-Markierungen zum Filtern verwenden
tc filter add dev $OUTDEV parent 1: protocol ip handle 1 fw flowid 1:11 tc filter add dev $OUTDEV parent 1: protocol ip handle 2 fw flowid 1:12 tc filter add dev $OUTDEV parent 1: protocol ip handle 3 fw flowid 1:13 tc filter add dev $OUTDEV parent 1: protocol ip handle 4 fw flowid 1:14
- etwas verlangsamen, um die Queue beim ISP nicht zu fuellen
tc qdisc add dev $OUTDEV handle ffff: ingress tc filter add dev $OUTDEV parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate $[DOWNLINK/2]kbit burst 1 0k drop flowid :1
- und dann die Pakete mit den Markierungen versehen:
- die drei Quellen mit Prioritaten versehen
iptables -t mangle -A FORWARD -i $WLAN_LABOR -o $WORLD -s ! $THORAX -j MARK --set-mark 4 iptables -t mangle -A FORWARD -i $WG_NETZ -o $WORLD -j MARK --set-mark 3 iptables -t mangle -A FORWARD -i $WLAN_LABOR -o $WORLD -s $THORAX -j MARK --set-mark 2
- die schnellen Pakete nach vorn schicken (vorherige Markierungen werden ueberschrieben)
iptables -t mangle -A FORWARD -o $WORLD -m length --length 0:500 -j MARK --set-mark 1 iptables -t mangle -A FORWARD -o $WORLD -m tos --tos 0x10 -j MARK --set-mark 1 iptables -t mangle -A FORWARD -o $WORLD -p icmp -j MARK --set-mark 1 iptables -t mangle -A FORWARD -o $WORLD -p tcp --tcp-flags ACK ACK -j MARK --set-mark 1
- der Rest (nur um zu gucken, ob was uebrigbleibt)
iptables -t mangle -A FORWARD -o $WORLD -m mark --mark 0 -j MARK --set-mark 5
- die drei Quellen mit Prioritaten versehen