From 32a70b1c194c715de24dab95c380cabb165b2c87 Mon Sep 17 00:00:00 2001 From: Martin Mares <mj@ucw.cz> Date: Sat, 29 Apr 2023 15:13:58 +0200 Subject: [PATCH] =?UTF-8?q?Pozn=C3=A1mky=20k=20traffic=20control?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tc.md | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 tc.md diff --git a/tc.md b/tc.md new file mode 100644 index 0000000..934bcda --- /dev/null +++ b/tc.md @@ -0,0 +1,142 @@ +# Traffic Control (náhodné poznámky) + +## Queueing Disciplines + +- ingress qdisc: může jenom klasifikovat a zahazovat pakety + - lze obejít přeposíláním paketů do imq (Intermediate Queueing Device) +- egress qdisc: může i zpožďovat pakety + +- číslování major:minor + - root je obvykle 1:0 (lze zkrátit na 1:) + - vstup do qdisc je major:0, třídy uvnitř mohou mít různé minors + +- pfifo_fast + - classless + - 3 bands (priority) + - tabulka překládající 4 bity TOS na band +- tbf (Token Bucket Filter) + - classless + - účtuje se v bytech + - limit (maximální množství dat ve frontě na tokeny) + - též jde zadat jako maximální latence + - burst (velikost kyblíku) + - mpu (minimální velikost paketu) + - rate +- prio + - classful + - bands (priority) + - filtry přidělují band + - pro každý band další qdisc + - příklad: + # tc qdisc add dev eth0 root handle 1: prio + ## This *instantly* creates classes 1:1, 1:2, 1:3 + # tc qdisc add dev eth0 parent 1:1 handle 10: sfq + # tc qdisc add dev eth0 parent 1:2 handle 20: tbf rate 20kbit buffer 1600 limit 3000 + # tc qdisc add dev eth0 parent 1:3 handle 30: sfq + ## CAVEAT: kbit = k bits/second, kbps = k bytes/second + ## Let us see what we created: + # tc -s qdisc ls dev eth0 +- htb (Hierarchical Token Bucket) + - classful +- multiq (mq) + - pro karty s více HW frontami + - classful, každá HW fronta má svou qdisc (typicky pfifo_fast) +- mqprio + - jako mqueue, ale navíc umí priority + - až 16 traffic classes, každé přiřadíme interval HW front + - překlad sbk->priority na traffic class, priorita se získá z: + - setsockopt + - iptables + - net_prio cgroup + - umí HW-offloaded shaper pro každou třídu + +## Filtry + + # tc filter add dev eth0 protocol ip parent 10: prio 1 u32 match ip dport 22 0xffff flowid 10:1 + # tc filter add dev eth0 protocol ip parent 10: prio 1 u32 match ip sport 80 0xffff flowid 10:1 + # tc filter add dev eth0 protocol ip parent 10: prio 2 flowid 10:2 + +Nebo: + + # tc filter add dev eth0 parent 10:0 protocol ip prio 1 u32 match ip dst 4.3.2.1/32 flowid 10:1 + # tc filter add dev eth0 parent 10:0 protocol ip prio 1 u32 match ip src 1.2.3.4/32 flowid 10:1 + # tc filter add dev eth0 protocol ip parent 10: prio 2 flowid 10:2 + +Nebo kombinace: + + # tc filter add dev eth0 parent 10:0 protocol ip prio 1 u32 match ip src 4.3.2.1/32 match ip sport 80 0xffff flowid 10:1 + +- u32 + - umí HW offloading +- též jde klasifikovat podle fwmarků nebo routing realms (i pro zdrojové adresy!) +- policing filter: umí pakety nad/pod nějakou mez průtoku/velikosti + - zahazovat + - reklasifikovat na best-effort + - pipe: předat další akci v pořadí +- ht: hash table +- xt: zavolá chain v xtables +- ematch + +- akce: + - drop + - mirred (mirror nebo redirect na jiné zařízení) + - lze definovat uživatelské (tc action) + - vlan (změna VLAN tagu) + +## Advanced Queue Management + +- RED (1993) +- good queue / bad queue +- korelace mezi flows +- měnící se podmínky + +## ECN = Explicit Congestion Notification + +- 2 bity v hlavičce IP (ukradeny z TOS): + - 00 = ECN not requested + - 01 / 10 = ECN requested + - 01 a 10 jsou ekvivalentní, ale dají se používat + po experimentální ověřování toho, jak routery + po cestě původně rezervované bity ovlivňují + - 11 = congestion experienced +- TCP posílá notifikaci odesílateli + - 2 bity v hlavičce: ECE a CWR + - při SYN a SYN+ACK se posílají oba (tím zapneme podporu ECN) + - kdykoliv mi přijde paket s IP ECN, nastavím si flag + - dokud mám flag nastavený, posílám protistraně TCP ECE + - až mi od protistrany přijde CWR, shodím flag + - Linux má 3 režimy: off / on / jen odpovídat + - také umí tcp_ecn_fallback +- modifikace RED, aby pří malé pravděpodobnosti posílal ECN + +## CoDel + +- https://www.bufferbloat.net/projects/ +- https://www.rfc-editor.org/rfc/rfc8289.html +- měří dobu, kterou paket strávil ve frontě + - počítá minimum z této doby přes časové okno + (doporučených 100 ms funguje dobře skoro vždy, ale při použití + jen uvnitř serverovny se může hodit řádově menší hodnota) + - snaží se udržet ho pod 5% šířky okna + - proto mu nevadí změny rychlosti, ani více front krmících + tutéž linku => fq_codel + - může nastavovat ECN + +## Flow Queue CoDel + +- https://www.rfc-editor.org/rfc/rfc8290 +- pakety se hešují podle flow ID (protocol, src IP+port, dest IP+port), defaultně 1K kyblíků + - uvnitř každého kyblíku CoDel + - něco-jako-round-robin střídá fronty pro odesílání + (snaží se odebírat stejné množství dat i při různě velkých paketech) +- pozor na interakci s offloadingem + +## CAKE + +- https://www.bufferbloat.net/projects/codel/wiki/CakeTechnical/ +- kombinuje fq_codel se shaperem +- hešování flows je 8-cestně množinově asociativní (omezuje efekt kolizí) +- traffic classes (priority): defaultně 4, automatická klasifikace +- umí započítat overhead linkové vrstvy (třeba i ATM) +- umí rozebrat superpakety pro GSO/GRO, pokud je potřeba +- tc qdisc add dev eth2 root cake bandwidth 50mbit -- GitLab