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 :

  • CBQ
  • “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

  • HTB
  • “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
  • PRIO qdisc n’effectue pas de traffic shapping en tant que tel, il permet juste de fixer des priorités entre les différents type de protocoles transitant dans le lien.
    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


    BinaireDécimalSignification
    10008Minimise le Délai (Minimize delay) (md)
    01004Maximalise le Débit (Maximize throughput) (mt)
    00102Maximalise la Fiabilité (Maximize reliability) (mr)
    00011Minimalise le Coût Monétaire (Minimize monetary cost) (mmc)
    00000Service Normal

    TOSBinaireDécimalSignificationPriorité LinuxBande
    0x000000Service Normal0 Best Effort1
    0x200011Minimise le Coût Monétaire (mmc)1 Filler2
    0x400102http://fr.wikipedia.org/wiki/Mod%C3%A8le_OSI0 Best Effort1
    0x600113mmc+mr0 Best Effort1
    0x801004Maximalise le Débit (mt)2 Masse2
    0xa01015mmc+mt2 Masse2
    0xc01106mr+mt2 Masse2
    0xe01117mmc+mr+mt2 Masse2
    0x1010008Minimise le Délai (md)6 Interactive0
    0x1210019mmc+md6 Interactive0
    0x14101010mr+md6 Interactive0
    0x16101111mmc+mr+md6 Interactive0
    0x18110012mt+md4 Int. Masse1
    0x1a110113mmc+mt+md 4 Int. Masse 14 Int. Masse1
    0x1c111014mr+mt+md4 Int. Masse1
    0x1e111115mmc+mr+mt+md4 Int. Masse1

    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 🙂

    Vus : 809
    Publié par Geekfault : 45