= 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 CoS) gut beschreibt) * WLAN-AP kann das eher nicht == Notwendigkeiten == * mindestens 2.4er-Kernel * QoS 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 1. {{{ !/bin/sh UPLINK=120 DOWNLINK=980 OUTDEV=eth0 }}} 1. bisherige Warteschlangen loeschen {{{ tc qdisc del dev $OUTDEV root &>/dev/null tc qdisc del dev $OUTDEV ingress &>/dev/null }}} 1. neu anlegen {{{ tc qdisc add dev $OUTDEV root handle 1: htb default 14 }}} 1. 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 }}} 1. Warteschlangen erzeugen {{{ tc class add dev $OUTDEV parent 1:1 classid 1:11 htb rate ${UPLINK}kbit burst 6k prio 1 }}} 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 }}} 1. das Labor-Netz {{{ tc class add dev $OUTDEV parent 1:1 classid 1:13 htb rate ${UPLINK}kbit burst 6k prio 3 }}} 1. das WG-Netz {{{ tc class add dev $OUTDEV parent 1:1 classid 1:14 htb rate ${UPLINK}kbit burst 6k prio 4 }}} 1. alle anderen da draussen 1. 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 }}} 1. 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 }}} 1. 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: 1. 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 }}} 1. 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 }}} 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 }}} = Quellen = * http://lartc.org/howto/lartc.cookbook.ultimate-tc.html * http://www.prout.be/qos/QoS-connection-tuning-HOWTO-4.html