#!/bin/bash # # Moritz Orbach 2009 # http://apfelboymchen.net/gnu/configstuff/ # # http://luxik.cdi.cz/~devik/qos/htb/manual/userg.htm # test -f /etc/meins/mqosrc && . /etc/meins/mqosrc || { echo config? exit 1 } # kb/s -> kbit ((max *= 8000)) ((small_min *= 8000)) ((interactive_min *= 8000)) ((acks_min *= 8000)) ((bulk_max *= 8000)) ((bulk_public_min *= 8000)) ((bulk_local_p2p_min *= 8000)) ((bulk_local_p2p_max *= 8000)) ## ((bulk_min = bulk_local_maybe_interactive_min + bulk_local_p2p_min + bulk_public_min)) logger "MQOS!" ############################## # aufraeumen tc qdisc del dev $IF root 2>/dev/null test "$1" = "stop" && exit ########### # und los # ########### # root (1:0 HTB default 1:13) # | # HTB (1:1) # //// # (1:10) interactive -'/// # (1:11) ACKS -'// # (1:12) small -'/ # (1:13) bulk -' # `- public (1:21) # `- local (1:22) # `- maybe_interactive (1:30) # `- p2p (1:31) # # queue # attaches HTB (hierarchical Token Bucket) to $IF and gives it the "handle" 1: # default class: bulk (1:n). 30 geht noch, 40 net. tc qdisc add dev $IF root handle 1: htb default 31 # root class # maximale bandbreite fuer die root class. TODO burst tc class add dev $IF parent 1: classid 1:1 htb rate $max # # (1:10) interactive -'/// # (1:11) ACKS -'// # (1:12) small -'/ # (1:13) bulk -' # tc class add dev $IF parent 1:1 classid 1:10 htb rate $interactive_min ceil $max prio 1 quantum 1500 tc class add dev $IF parent 1:1 classid 1:11 htb rate $acks_min ceil $max prio 2 quantum 1500 tc class add dev $IF parent 1:1 classid 1:12 htb rate $small_min ceil $max prio 3 quantum 1500 #tc class add dev $IF parent 1:1 classid 1:13 htb rate $bulk_min ceil $max prio 4 quantum 1500 # queuing disciplines innerhalb der klassen FIXME limit 5 ? tc qdisc add dev $IF parent 1:10 handle 40: pfifo limit 5 tc qdisc add dev $IF parent 1:11 handle 41: pfifo limit 5 tc qdisc add dev $IF parent 1:12 handle 42: pfifo limit 5 # # `- public (1:21) # `- local (1:22) # tc class add dev $IF parent 1:1 classid 1:21 htb rate $bulk_public_min ceil $max prio 10 quantum 1500 tc qdisc add dev $IF parent 1:21 handle 43: pfifo limit 5 #tc filter add dev $IF parent 1:13 protocol ip prio 1 u32 match ip protocol 6 0xff flowid 1:21 # # `- maybe_interactive (1:30) # `- p2p (1:31) # tc class add dev $IF parent 1:1 classid 1:30 htb rate $bulk_local_maybe_interactive_min ceil $max prio 20 quantum 1500 tc class add dev $IF parent 1:1 classid 1:31 htb rate $bulk_local_p2p_min ceil $bulk_local_p2p_max prio 30 quantum 1500 tc qdisc add dev $IF parent 1:30 handle 44: pfifo limit 5 # PRIO fuer verteilung innerhalb maybe_interactive. 50:[123] werden mit der PRIO erstellt. #tc qdisc add dev $IF parent 1:50 handle 50 prio #tc qdisc add dev $IF parent 50:1 handle 51: sfq #tc qdisc add dev $IF parent 50:2 handle 52: tbf rate $(($bulk_max - $bulk_local)) buffer 1600 limit 3000 # XXX magic #tc qdisc add dev $IF parent 50:3 handle 53: sfq # # regeln (pakete verteilen) # # laenge des mach-patterns # u8 0xff # u16 0xffff # # 1000 = 0x8 # 1100 = 0xC # 1110 = 0xE # # at n bestimmt die startposition in *byte* # neue rules kommen an den *anfang* # matched eine rule werden keine weiteren mehr durchlaufen # # BEISPIELE # http://tldp.org/HOWTO/Adv-Routing-HOWTO/lartc.adv-filter.u32.html # http://mike.passwall.com/networking/ippacket.html#TOS # http://ace-host.stuart.id.au/russell/files/tc/doc/cls_u32.txt # http://www-net.cs.umass.edu/kurose/transport/ (TODO) # # match u8 0x05 0x0f at 0 # - 8 bit matchen (u8) # - in byte 1 gucken ob (at 0, "version" und "hdr len") # - in den letzten 4 bit (0x0F ist 0000 FFFF ist 00001111) # - der wert 5 steht (0x05/5/0101 = 5) # -> paket ohne options (der header ist 20 bytes lang) # header length ist * 32bit, was einer zeile in der ueblichen darstellung entspricht. # Ab zeile 5 kommen die daten (i.e. keine optionen) # - options sind selten, und man muss ja wissen wo der TCP-segment beginnt # # match u16 0x0000 0xffc0 at 2 # - 16 bit matchen (u16) # - in byte 3 gucken ob (at 2, "total length") # - in den ersten 10 bit (1111 1111 1100 0000) # - der wert 0 steht (0x0000) # -> trifft nur zu, wenn das paket kleiner 64 byte ist (11 1111 ist 63) # # match u8 0x10 0xff at 33 # # maybe_interactive-ports for port in 80 443 22 21 873; do tc filter add dev $IF protocol ip parent 1: prio 3 u32 \ match ip protocol 6 0xff \ match ip dport $port 0xffff \ flowid 1:30 done # public for port in 80 443; do tc filter add dev $IF protocol ip parent 1: prio 3 u32 \ match ip protocol 6 0xff \ match ip sport $port 0xffff \ flowid 1:21 done # ESP tc filter add dev $IF protocol ip parent 1: prio 3 u32 \ match ip protocol 32 0xff \ flowid 1:10 ## small #tc filter add dev $IF protocol ip prio 1 u32 \ # match ip protocol 6 0xff \ # match u8 0x05 0x0f at 0 \ # match u16 0x0000 0xff80 at 2 \ # flowid 1:12 # interactive dports UDP (17/0x11) for port in 53 5060; do tc filter add dev $IF protocol ip parent 1: prio 1 u32 \ match ip protocol 11 0xff \ match ip dport $port 0xffff \ flowid 1:10 done # interactive sports UDP (17/0x11) # match ip protocol 11 0xff \ for port in 5060 1000{0..4}; do tc filter add dev $IF protocol ip parent 1: prio 1 u32 \ match ip sport $port 0xffff \ flowid 1:10 done # ICMP tc filter add dev $IF protocol ip parent 1: prio 1 u32 \ match ip protocol 1 0xff \ flowid 1:12 # ACK < 64 byte (ACK bit set, and no further payload) # the ACK bit is second older bit (0x10) in the 14-th byte of the TCP header (at nexthdr+13) # # IP protocol 6, # IP header length 0x5 (header length ist in 32bit angegeben). # IP Total length 0x34 (ACK + 12 bytes of TCP options) # TCP ack set (bit 5, offset 33) tc filter add dev $IF parent 1:0 protocol ip prio 1 u32 \ match ip protocol 6 0xff \ match u8 0x05 0x0f at 0 \ match u16 0x0000 0xffc0 at 2 \ match u8 0x10 0xff at 33 \ flowid 1:11 # TOS # 8765xxxx # 5. bit ( 16/0x10): minimize delay # 6. bit ( 32/0x20): Maximize throughput # 7. bit ( 64/0x40): Maximize reliability # 8. bit (128/0x80): Minimize monetary costs tc filter add dev $IF protocol ip parent 1: prio 2 u32 \ match ip tos 0x10 0xff \ flowid 1:10 # interactive ports TCP. Ohne ssh wegen SCP, stattdessen TOS. for port in 21 5222 5190; do tc filter add dev $IF protocol ip parent 1: prio 2 u32 \ match ip protocol 6 0xff \ match ip dport $port 0xffff \ flowid 1:10 done # vim:ts=2