Eeegw – part III – Quality Of Service aka QOS
La Quality Of Service (QOS) , qualité de service en français, intervient principalement au niveau 3 du modèle OSI.
Il faut donc placer ses scripts de QOS sur la passerelle de votre réseau, c’est la raison pour laquelle, mettre en place de la QOS sur la eeegw prend tout son sens.
N’hésitez pas à revenir sur les précédents articles sur la eeegw :
eeegw part I
eeegw part II
Si vous avez besoin d’un rafraîchissement sur le concept, je vous oriente vers la page Qualité de service de Wikipedia.
La partie qui clairement nous intéresse ici est décrite au chapitre Ordonnancement :
L’ordonnancement désigne l’ensemble des méthodes visant à modifier l’ordre de départ des paquets, en remplacement de la règle du « premier arrivé, premier servi ».
Une de ses applications les plus courantes consistera ainsi à donner priorité à certains types de trafic.
Grosso modo j’ai mis en place de la QOS sur ma eeegw car j’en avais marre que mes communications SIP (Téléphonie voir futur article :p) ne soient pas de bonne qualité, lors d’upload de pièces jointes via mon mailer ou lorsque j’avais besoin d’utiliser beaucoup d’upload en même temps qu’une communication téléphonique.
Voici mon tout premier script de QOS, ill date un peu et est loin de bien fonctionner
Je vous le montre afin que vous voyez un peu à quoi on s’attaque en parlant de QOS :
Script de QOS exemple1 basé sur HTB
#!/bin/bash #Constantes LOCALNET="213.41.xx.xx/255.255.255.255" MARKPRIO1="1" MARKPRIO2="2" MARKPRIO3="3" MARKPRIO4="4" MARKPRIO5="5" MARKPRIO6="6" MARKPRIO7="7" IFACE=eth0 UPRATE="8mbit" DOWNRATE="0.8mbit" PRIORATE1="5mbit" PRIORATE2="3mbit" PRIORATE3="2mbit" PRIORATE4="0.5mbit" QUANTUM1="12187" QUANTUM2="8625" QUANTUM3="5062" QUANTUM4="1500" BURST1="1000k" BURST2="400k" BURST3="200k" BURST4="10k" CBURST1="300k" CBURST2="200k" CBURST3="10k" CBURST4="1k" iptables -t mangle -F OUTPUT iptables -t mangle -F FORWARD iptables -t mangle -A FORWARD -p icmp -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A OUTPUT -p icmp -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A INPUT -p icmp -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A FORWARD -p tcp --dport 22 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A OUTPUT -p tcp --dport 22 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A INPUT -p tcp --dport 22 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A FORWARD -p tcp --dport 687 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A OUTPUT -p tcp --dport 687 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A INPUT -p tcp --dport 687 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A FORWARD -p udp --dport 687 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A OUTPUT -p udp --dport 687 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A INPUT -p udp --dport 687 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A FORWARD -p tcp --dport 5060 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A OUTPUT -p tcp --dport 5060 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A INPUT -p tcp --dport 5060 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A FORWARD -p udp --dport 5060 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A OUTPUT -p udp --dport 5060 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A INPUT -p udp --dport 5060 -j MARK --set-mark $MARKPRIO1 iptables -t mangle -A FORWARD -p tcp --dport 25 -j MARK --set-mark $MARKPRIO3 iptables -t mangle -A OUTPUT -p tcp --dport 25 -j MARK --set-mark $MARKPRIO3 iptables -t mangle -A FORWARD -p tcp --dport 143 -j MARK --set-mark $MARKPRIO3 iptables -t mangle -A OUTPUT -p tcp --dport 143 -j MARK --set-mark $MARKPRIO3 iptables -t mangle -A FORWARD -p tcp --dport 80 -j MARK --set-mark $MARKPRIO2 iptables -t mangle -A OUTPUT -p tcp --dport 80 -j MARK --set-mark $MARKPRIO2 iptables -t mangle -A INPUT -p tcp --dport 80 -j MARK --set-mark $MARKPRIO2 iptables -t mangle -A FORWARD -p tcp --dport 443 -j MARK --set-mark $MARKPRIO2 iptables -t mangle -A OUTPUT -p tcp --dport 443 -j MARK --set-mark $MARKPRIO2 iptables -t mangle -A INPUT -p tcp --dport 443 -j MARK --set-mark $MARKPRIO2 iptables -t mangle -A FORWARD -p tcp --dport 21 -j MARK --set-mark $MARKPRIO3 iptables -t mangle -A OUTPUT -p tcp --dport 21 -j MARK --set-mark $MARKPRIO3 iptables -t mangle -A INPUT -p tcp --dport 21 -j MARK --set-mark $MARKPRIO3 ifconfig $IFACE txqueuelen 128 tc qdisc add dev $IFACE root handle 1:0 htb default 103 r2q 1 tc class add dev $IFACE parent 1:0 classid 1:1 htb rate $UPRATE burst $BURST1 cburst $CBURST1 tc class add dev $IFACE parent 1:1 classid 1:101 htb rate $PRIORATE1 ceil $UPRATE quantum $QUANTUM1 burst $BURST1 cburst $CBURST1 prio 0 tc class add dev $IFACE parent 1:1 classid 1:102 htb rate $PRIORATE2 ceil $UPRATE quantum $QUANTUM2 burst $BURST2 cburst $CBURST2 prio 1 tc class add dev $IFACE parent 1:1 classid 1:103 htb rate $PRIORATE3 ceil $UPRATE quantum $QUANTUM3 burst $BURST3 cburst $CBURST3 prio 2 tc class add dev $IFACE parent 1:1 classid 1:104 htb rate $PRIORATE4 ceil $P2PRATE quantum $QUANTUM4 burst $BURST4 cburst $CBURST4 prio 3 tc filter add dev $IFACE parent 1:0 protocol ip prio 0 handle $MARKPRIO1 fw classid 1:101 tc filter add dev $IFACE parent 1:0 protocol ip prio 1 handle $MARKPRIO2 fw classid 1:102 tc filter add dev $IFACE parent 1:0 protocol ip prio 2 handle $MARKPRIO3 fw classid 1:103 tc filter add dev $IFACE parent 1:0 protocol ip prio 3 handle $MARKPRIO4 fw classid 1:104 tc qdisc add dev $IFACE parent 1:101 sfq perturb 16 quantum $QUANTUM1 tc qdisc add dev $IFACE parent 1:102 sfq perturb 16 quantum $QUANTUM2 tc qdisc add dev $IFACE parent 1:103 sfq perturb 16 quantum $QUANTUM3 tc qdisc add dev $IFACE parent 1:104 sfq perturb 16 quantum $QUANTUM4
Ce script est loin d’être optimisé.
Son but était de marquer via iptables certain type de flux, afin de les faire passer via des règles de tc/qdisc pour en limiter la bande passante. il utilise HTB (voir plus loin)
Ce script manque clairement de flexibilité.
Soyons clairs, la QOS sous GNU/Linux est un cauchemar à gérer.
Autre concept à bien avoir en tête, vous ne pouvez gérer la QOS que de votre lien sortant, en aucun cas vous ne pouvez gérer ce qui rentre via votre lien. Par analogie, vous ne pouvez pas contrôler la pluie qui tombe dans votre piscine, par contre vous pouvez contrôler l’eau que vous enlevez, et l’eau que vous décidez de rajouter.
Il existe quelques bidouilles afin de réussir tout de même à gérer ce trafic entrant, nous allons essayer de vous présenter ça un peu plus loin dans l’article.
Nous allons donc utiliser Mangle de iptables (pour qos.sh) ainsi que la fonction de mark des packets de iptables.
Il faut donc aller activer cela dans le noyau.
#
# QoS and/or fair queueing
#
CONFIG_NET_SCHED=y
CONFIG_NET_SCH_CBQ=m
CONFIG_NET_SCH_HTB=m
CONFIG_NET_SCH_CSZ=m
CONFIG_NET_SCH_PRIO=m
CONFIG_NET_SCH_RED=m
CONFIG_NET_SCH_SFQ=m
CONFIG_NET_SCH_TEQL=m
CONFIG_NET_SCH_TBF=m
CONFIG_NET_SCH_GRED=m
CONFIG_NET_SCH_DSMARK=m
CONFIG_NET_SCH_INGRESS=m
CONFIG_NET_QOS=y
CONFIG_NET_ESTIMATOR=y
CONFIG_NET_CLS=y
CONFIG_NET_CLS_TCINDEX=m
CONFIG_NET_CLS_ROUTE4=m
CONFIG_NET_CLS_ROUTE=y
CONFIG_NET_CLS_FW=m
CONFIG_NET_CLS_U32=m
CONFIG_NET_CLS_RSVP=m
CONFIG_NET_CLS_RSVP6=m
CONFIG_NET_CLS_POLICE=y
Scheduler / Ordonnanceur
Mise en place des outils
En tout premier lieu vous aurez besoin de iptables et de iproute2
iproute2 est une suite d’utilitaires en ligne de commande qui vous permettent de manipuler les structures kernel liées aux couches réseau de votre machine.
Gentoo :
emerge -av iproute2 iptables
Debian :
apt-get install iptables iproute2
Verifiez que vous avez bien l’utilitaire tc :
eeegw:~# tc
Usage: tc [ OPTIONS ] OBJECT { COMMAND | help }
tc [-force] -batch file
where OBJECT := { qdisc | class | filter | action | monitor }
OPTIONS := { -s[tatistics] | -d[etails] | -r[aw] | -p[retty] | -b[atch] [file] }
Traduction du manuel de tc
Les “classful qdiscs” sont :
“Class Based Queueing” implémente une hierarchie de classes. il contient des éléments de shaping comme des fonctions de prioritisations. Le shape est calculé à partir de latence et de taille de packets
“Hierarchy Token Bucket”
HTB permet de garantir de la bande passante a une classe, définir des limites entre les classes et de fixer des priorités entre elles.
PRIO permet de classifier les classes qui prennent en priorité de la bande passante, en ne laissant aux autres que ce qui reste de bande passante disponible.
Qu’est-ce qu’une classe
Une classe forme, en fait, un arbre avec des branches.
Le but est de former une classe root qui va permettre de faire rentrer tout le trafic et, en fonction des protocoles, on va faire passer le traffic dans différentes branches.
ici nous définissons nos classes root :
## On met en place la classe root pour la BP disponible. /sbin/tc qdisc add dev $EXTERNAL_IFACE root handle 1: cbq avpkt 1000 bandwidth $BNDWIDTH ## Match ici l'upload de la connexion /sbin/tc class add dev $EXTERNAL_IFACE parent 1: classid 1:1 cbq rate ${UPLINK}kbit allot 1500 prio 5 bounded isolated
Datagrame IPv4 et Type Of Service : TOS
Tableau des TOS possible dans un Datagram IPv4
Binaire | Décimal | Signification |
---|---|---|
1000 | 8 | Minimise le Délai (Minimize delay) (md) |
0100 | 4 | Maximalise le Débit (Maximize throughput) (mt) |
0010 | 2 | Maximalise la Fiabilité (Maximize reliability) (mr) |
0001 | 1 | Minimalise le Coût Monétaire (Minimize monetary cost) (mmc) |
0000 | 0 | Service Normal |
TOS | Binaire | Décimal | Signification | Priorité Linux | Bande |
---|---|---|---|---|---|
0x0 | 0000 | 0 | Service Normal | 0 Best Effort | 1 |
0x2 | 0001 | 1 | Minimise le Coût Monétaire (mmc) | 1 Filler | 2 |
0x4 | 0010 | 2 | http://fr.wikipedia.org/wiki/Mod%C3%A8le_OSI | 0 Best Effort | 1 |
0x6 | 0011 | 3 | mmc+mr | 0 Best Effort | 1 |
0x8 | 0100 | 4 | Maximalise le Débit (mt) | 2 Masse | 2 |
0xa | 0101 | 5 | mmc+mt | 2 Masse | 2 |
0xc | 0110 | 6 | mr+mt | 2 Masse | 2 |
0xe | 0111 | 7 | mmc+mr+mt | 2 Masse | 2 |
0x10 | 1000 | 8 | Minimise le Délai (md) | 6 Interactive | 0 |
0x12 | 1001 | 9 | mmc+md | 6 Interactive | 0 |
0x14 | 1010 | 10 | mr+md | 6 Interactive | 0 |
0x16 | 1011 | 11 | mmc+mr+md | 6 Interactive | 0 |
0x18 | 1100 | 12 | mt+md | 4 Int. Masse | 1 |
0x1a | 1101 | 13 | mmc+mt+md 4 Int. Masse 1 | 4 Int. Masse | 1 |
0x1c | 1110 | 14 | mr+mt+md | 4 Int. Masse | 1 |
0x1e | 1111 | 15 | mmc+mr+mt+md | 4 Int. Masse | 1 |
Exemple de ce qu’on peut faire avec TOS
L’intérêt de la QoS sous Linux est très souvent associé à la priorisation de flux interactifs via iptables.
Par exemple, vous ne souhaitez pas que votre session ssh lag à cause d’un utilisateur qui est en train de monopoliser la bande passante de votre réseau en téléchargeant une bande annonce sur internet ?
Nous allons ici, à titre d’exemple, optimiser les trafics courants avec iptables, à savoir ssh :
# Priorisation des connexions ftp et ssh iptables -A PREROUTING -t mangle -p tcp -sport ssh -j TOS -set-tos Minimize-Delay # On donne un maximum de débit aux transferts scp iptables -A PREROUTING -t mangle -p tcp -sport ssh -j TOS -set-tos Maximize-Throughput
Voici le script de QOS final basé sur CTB et PRIO (celui que j’utilise en production)
#!/bin/bash ### Script de reservation de bande passante par bragon ## On fixe quelques variables EXTERNAL_DOWNLINK_KBPS="6400" ## je sais downloader à ~800ko/s ma limite est donc a 6400 Kbps EXTERNAL_DL_IPSEC_KBPS="1024" EXTERNAL_DL_PPTP_KBPS="" EXTERNAL_DL_ICA_KBPS="" EXTERNAL_DL_TSE_KBPS="128" EXTERNAL_DL_SMTP_KBPS="512" EXTERNAL_DL_HTTP_KBPS="1024" EXTERNAL_DL_OTHERTCP_KBPS="2048" EXTERNAL_DL_OTHERTCP_PORT="2048" ## je sais uploader à environ 80Ko/s je fixe donc ma limite a 512 afin d'être sûr de ne pas engendrer de lag. EXTERNAL_UPLINK_KBPS="512" EXTERNAL_UL_IPSEC_KBPS="" EXTERNAL_UL_IPSEC_SHARE="" EXTERNAL_UL_PPTP_KBPS="" EXTERNAL_UL_PPTP_SHARE="" EXTERNAL_UL_ICA_KBPS="" EXTERNAL_UL_ICA_SHARE="" EXTERNAL_UL_TSE_KBPS="512" EXTERNAL_UL_TSE_SHARE="512" EXTERNAL_UL_SMTP_KBPS="256" EXTERNAL_UL_SMTP_SHARE="256" EXTERNAL_UL_HTTP_KBPS="32" EXTERNAL_UL_HTTP_SHARE="" EXTERNAL_UL_OTHERTCP_KBPS="" EXTERNAL_UL_OTHERTCP_SHARE="" EXTERNAL_UL_OTHERTCP_PORT="" EXTERNAL_UL_VOIP_KBPS="256" EXTERNAL_UL_VOIP_SHARE="isolated" EXTERNAL_DEV_BANDWIDTH="" ## CE script de QOS s'applique à toutes les interface dans MON cas cela convient. ## Je vous conseille de retirer votre interface LAN du match si vous avez plusieurs interfaces reseau. ## La commande va permettre de lister toutes les interfaces et d'appliquer les regles de QOS dessus. ## On match aussi les interfaces tap if [ -n "$EXTERNAL_DOWNLINK_KBPS" ] && [ -n "$EXTERNAL_UPLINK_KBPS" ] && echo $INTERFACE | egrep -q "(eth[023]|ppp[0-9]|ippp0|tap[0-3])" ; then #In kilobits DOWNLINK=$EXTERNAL_DOWNLINK_KBPS UPLINK=$EXTERNAL_UPLINK_KBPS BNDWIDTH=$EXTERNAL_DEV_BANDWIDTH if [ -z "$BNDWIDTH" ]; then BNDWIDTH="100mbit" fi ## on clean deja les parametres en tout premier lieu ## On vide toutes les regles pouvant deja etre en place. /sbin/tc qdisc del dev $EXTERNAL_IFACE root 2> /dev/null > /dev/null /sbin/tc qdisc del dev $EXTERNAL_IFACE ingress 2> /dev/null > /dev/null # install root CBQ # On met en place la policy root, les autres policies seront liées à celle-ci ## cbq avpkt : la taille moyenne des packets en bytes sont necessaire afin de calculer l'idle maximum ## bandwidth rate : pour determiner l'idle time cbq doit forcement connaitre la bande passante de l'interface physique. /sbin/tc qdisc add dev $EXTERNAL_IFACE root handle 1: cbq avpkt 1000 bandwidth $BNDWIDTH ## allot bytes : utile pour calculer le temps de transmission des packets entre tables, valeur liée à avpkt /sbin/tc class add dev $EXTERNAL_IFACE parent 1: classid 1:1 cbq rate ${UPLINK}kbit allot 1500 prio 5 bounded isolated # voip (udp sip 5060 et asterisk 4569) ## Tout ce qui match cette règle possede une reservation CBQ de $EXTERNAL_UL_VOIP_KBPS | priorité numéro 1 ! if [ -n "$EXTERNAL_UL_VOIP_KBPS" ]; then /sbin/tc class add dev $EXTERNAL_IFACE parent 1:1 classid 1:5 cbq rate ${EXTERNAL_UL_VOIP_KBPS}kbit allot 1600 prio 1 avpkt 1000 $EXTERNAL_UL_VOIP_SHARE ## pfifo : pure 'premier entré premier sortie' qdisc, évite la congestion de packet dans la classid 1:5 /sbin/tc qdisc add dev $EXTERNAL_IFACE parent 1:5 handle 5: pfifo limit 10 # sip prioritaire 5 ! ## filter: utile afin de savoir dans quel classfull qdisc, un packet va etre envoye. ## on peut filter les packets a partir de leur TOS : Type Of Service /sbin/tc filter add dev $EXTERNAL_IFACE parent 1:0 protocol ip prio 5 u32 match ip sport 5060 0xffff match ip protocol 17 0xff flowid 1:5 /sbin/tc filter add dev $EXTERNAL_IFACE parent 1:0 protocol ip prio 5 u32 match ip dport 5060 0xffff match ip protocol 17 0xff flowid 1:5 # rtp (tos 0x10 et udp) (voir le tableau recap de TOS) /sbin/tc filter add dev $EXTERNAL_IFACE parent 1:0 protocol ip prio 5 u32 match ip tos 0x10 0xff match ip protocol 17 0xff flowid 1:5 let UPLINK=UPLINK-EXTERNAL_UL_VOIP_KBPS fi # SMTP if [ -n "$EXTERNAL_UL_SMTP_KBPS" ]; then /sbin/tc class add dev $EXTERNAL_IFACE parent 1:1 classid 1:44 \\ cbq rate ${EXTERNAL_UL_SMTP_KBPS}kbit allot 1600 prio 1 avpkt 1000 $EXTERNAL_UL_SMTP_SHARE /sbin/tc qdisc add dev $EXTERNAL_IFACE parent 1:44 handle 44: sfq perturb 10 /sbin/tc filter add dev $EXTERNAL_IFACE parent 1:0 protocol ip prio 44 u32 \\ match ip dport 25 0xffff match ip protocol 6 0xFF match ip firstfrag flowid 1:44 /sbin/tc filter add dev $EXTERNAL_IFACE parent 1:0 protocol ip prio 44 u32 \\ match ip dport 2525 0xffff match ip protocol 6 0xFF match ip firstfrag flowid 1:44 /sbin/tc filter add dev $EXTERNAL_IFACE parent 1:0 protocol ip prio 44 u32 \\ match ip dport 587 0xffff match ip protocol 6 0xFF match ip firstfrag flowid 1:44 let UPLINK=UPLINK-EXTERNAL_UL_SMTP_KBPS fi # HTTP if [ -n "$EXTERNAL_UL_HTTP_KBPS" ]; then /sbin/tc class add dev $EXTERNAL_IFACE parent 1:1 classid 1:46 \\ cbq rate ${EXTERNAL_UL_HTTP_KBPS}kbit allot 1600 prio 1 avpkt 1000 $EXTERNAL_UL_HTTP_SHARE /sbin/tc qdisc add dev $EXTERNAL_IFACE parent 1:46 handle 46: sfq perturb 10 /sbin/tc filter add dev $EXTERNAL_IFACE parent 1:0 protocol ip prio 46 u32 \\ match ip dport 80 0xffff match ip protocol 6 0xFF match ip firstfrag flowid 1:46 let UPLINK=UPLINK-EXTERNAL_UL_HTTP_KBPS fi # OTHERTCP if [ -n "$EXTERNAL_UL_OTHERTCP_KBPS" ]; then /sbin/tc class add dev $EXTERNAL_IFACE parent 1:1 classid 1:48 \\ cbq rate ${EXTERNAL_UL_OTHERTCP_KBPS}kbit allot 1600 prio 1 avpkt 1000 $EXTERNAL_UL_OTHERTCP_SHARE /sbin/tc qdisc add dev $EXTERNAL_IFACE parent 1:48 handle 48: sfq perturb 10 /sbin/tc filter add dev $EXTERNAL_IFACE parent 1:0 protocol ip prio 48 u32 \\ match ip dport $EXTERNAL_UL_OTHERTCP_PORT 0xffff match ip protocol 6 0xFF match ip firstfrag \\ flowid 1:48 let UPLINK=UPLINK-EXTERNAL_UL_OTHERTCP_KBPS fi if [ $UPLINK -gt 0 ]; then # classe interactive /sbin/tc class add dev $EXTERNAL_IFACE parent 1:1 classid 1:10 cbq rate ${UPLINK}kbit allot 1600 prio 2 avpkt 1000 /sbin/tc qdisc add dev $EXTERNAL_IFACE parent 1:10 handle 10: sfq perturb 10 # TOS Minimum Delay (ssh, NOT scp) in 1:10: donc on lui donne un priorité de 1000 /sbin/tc filter add dev $EXTERNAL_IFACE parent 1:0 protocol ip prio 1000 u32 match ip tos 0x10 0xff flowid 1:10 # ICMP (ip protocol 1) dans la classe interactive 1:10 donc on lui donne un priorité de 1001 /sbin/tc filter add dev $EXTERNAL_IFACE parent 1:0 protocol ip prio 1001 u32 match ip protocol 1 0xff flowid 1:10 # Pour accélérer le downaload lorsqu'un upload est en court il faut bien faire les ACK dans la classe interactive. /sbin/tc filter add dev $EXTERNAL_IFACE parent 1: protocol ip prio 1002 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:10 # classe bulk /sbin/tc class add dev $EXTERNAL_IFACE parent 1:1 classid 1:20 cbq rate $[9*$UPLINK/10]kbit \\ allot 1600 prio 3 avpkt 1000 /sbin/tc qdisc add dev $EXTERNAL_IFACE parent 1:20 handle 20: sfq perturb 10 /sbin/tc filter add dev $EXTERNAL_IFACE parent 1: protocol ip prio 1003 u32 \\ match ip dst 0.0.0.0/0 flowid 1:20 else echo "Error: no bandwidth left for uplink on $EXTERNAL_IFACE: $UPLINK" 1>&2 /sbin/tc qdisc del dev $EXTERNAL_IFACE root 2> /dev/null > /dev/null fi # # Il faut ralentir les download afin d'éviter que l'ISP mette en queue ce qui engendre le lag # Les ISP ont tendance à avoir des queues énormes afin d'être sûrs que les downloads seront rapides. # # police ingress: /sbin/tc qdisc add dev $EXTERNAL_IFACE handle ffff: ingress # voip # tout ce qui est voip ne doit pas être limité, donc on fait un match simple # iax2 /sbin/tc filter add dev $EXTERNAL_IFACE parent ffff: protocol ip prio 5 u32 \\ match ip sport 4569 0xffff match ip protocol 17 0xff flowid :1 /sbin/tc filter add dev $EXTERNAL_IFACE parent ffff: protocol ip prio 5 u32 \\ match ip dport 4569 0xffff match ip protocol 17 0xff flowid :1 # sip # priorite 5 ! /sbin/tc filter add dev $EXTERNAL_IFACE parent ffff: protocol ip prio 5 u32 \\ match ip sport 5060 0xffff match ip protocol 17 0xff flowid :1 /sbin/tc filter add dev $EXTERNAL_IFACE parent ffff: protocol ip prio 5 u32 \\ match ip dport 5060 0xffff match ip protocol 17 0xff flowid :1 /sbin/tc filter add dev $EXTERNAL_IFACE parent ffff: protocol ip prio 5 u32 \\ match ip sport 5061 0xffff match ip protocol 17 0xff flowid :1 # rtp (tos 0x10 et udp) # priorte 5 ! /sbin/tc filter add dev $EXTERNAL_IFACE parent ffff: protocol ip prio 5 u32 \\ match ip tos 0x10 0xff match ip protocol 17 0xff flowid :1 # SMTP if [ -n "$EXTERNAL_DL_SMTP_KBPS" ]; then /sbin/tc filter add dev $EXTERNAL_IFACE parent ffff: protocol ip prio 44 u32 \\ match ip sport 25 0xffff match ip protocol 6 0xFF match ip firstfrag \\ police rate ${EXTERNAL_DL_SMTP_KBPS}kbit burst 10k drop flowid :1 let DOWNLINK=DOWNLINK-EXTERNAL_DL_SMTP_KBPS fi # HTTP if [ -n "$EXTERNAL_DL_HTTP_KBPS" ]; then /sbin/tc filter add dev $EXTERNAL_IFACE parent ffff: protocol ip prio 46 u32 \\ match ip sport 80 0xffff match ip protocol 6 0xFF match ip firstfrag \\ police rate ${EXTERNAL_DL_HTTP_KBPS}kbit burst 10k drop flowid :1 let DOWNLINK=DOWNLINK-EXTERNAL_DL_HTTP_KBPS fi # OTHERTCP qui ne matchent pas les règles précédentes if [ -n "$EXTERNAL_DL_OTHERTCP_KBPS" ]; then /sbin/tc filter add dev $EXTERNAL_IFACE parent ffff: protocol ip prio 48 u32 \\ match ip sport $EXTERNAL_DL_OTHERTCP_PORT 0xffff match ip protocol 6 0xFF match ip firstfrag \\ police rate ${EXTERNAL_DL_OTHERTCP_KBPS}kbit burst 10k drop flowid :1 let DOWNLINK=DOWNLINK-EXTERNAL_DL_OTHERTCP_KBPS fi ##règles de burst if [ $DOWNLINK -gt 0 ]; then /sbin/tc filter add dev $EXTERNAL_IFACE parent ffff: protocol ip prio 1000 u32 \\ match ip src 0.0.0.0/0 police rate ${DOWNLINK}kbit burst 10k drop flowid :1 else echo "Error: no bandwidth left for downlink on $EXTERNAL_IFACE: $DOWNLINK" 1>&2 /sbin/tc qdisc del dev $EXTERNAL_IFACE ingress 2> /dev/null > /dev/null fi # initial if (are the 2 required variables defined?) fi
N’hésitez pas à le tester, il déboite