
Guide pratique de la gestion de la bande passante d'une ligne ADSL

Version franaise du _ADSL Bandwidth Management HOWTO_

Dan Singletary

   <dvsing@sonicspike.net>

   _Franois Romieu - _Traduction franaise

   _Guillaume Lelarge - _Relecture de la version franaise
   1.2.fr.1.0

   2003-03-01
   _Historique des versions_
   Version 1.2.fr.1.0 01-03-2003 Revu par : fr
   Version franaise.
   Version 1.2        26-09-2002 Revu par : ds
   Ajout d'un lien vers la nouvelle liste de diffusion. Ajout d'une
   petite information dans la section d'avertissement concernant la
   nouvelle QoS amliore pour Linux, cre spcifiquement pour l'ADSL et
   bientt disponible.
   Version 1.1        26-08-2002 Revu par : ds
   Quelques corrections (Merci au nombreuses personnes m'ayant montr les
   problmes!). Ajout d'une information dans la section d'implmentation.
   Version 1.0        21-08-2002 Revu par : ds
   Meilleur contrle au niveau de la bande passante, plus de thorie,
   mise  jour pour les noyaux 2.4.
   Version 0.1        06-08-2002 Revu par : ds
   Premire publication

   Ce document dcrit la configuration d'un routeur Linux pour grer
   efficacement le trafic sortant  destination d'un modem ADSL ou de
   tout autre quipement de bande passante similaire (modem cble, RNIS,
   etc). Un accent particulier est apport  la diminution de latence
   pour le trafic de type interactif et ce mme durant les priodes de
   congestion.
     _________________________________________________________________

   _Table des matires_
   1. Introduction

        1.1. Mises  jour du document
        1.2. Liste de diffusion
        1.3. Avertissement
        1.4. Disclaimer
        1.5. Droits d'utilisation
        1.6. Copyright
        1.7. Retours d'exprience et corrections

   2. Cadre d'utilisation

        2.1. Prrequis
        2.2. Organisation
        2.3. Files d'attente des paquets

   3. Fonctionnement

        3.1. Limitation du trafic sortant avec HTB Linux
        3.2. Gestion des files de priorit avec HTB
        3.3. Classification des paquets sortant avec iptables
        3.4. Des rglages supplmentaires ...
        3.5. Une tentative de limitation du trafic entrant

   4. Ralisation

        4.1. Avertissements
        4.2. Script : mon_limiteur

   5. Test
   6. a fonctionne. Et maintenant ?

1. Introduction

   Ce document suggre une mthode de gestion de la bande passante pour
   le trafic sortant avec une connexion ADSL (ou modem cble)  Internet.
   Le problme provient du fait que de nombreuses lignes ADSL sont
   brides aux environs de 128 kbps pour le trafic montant. La situation
   s'aggrave lorsque la file d'attente du modem ADSL demande de 2  3
   secondes pour se librer quand elle est pleine. Lorsque la bande
   passante dans le sens montant est sature, une trame peut mettre
   jusqu' trois secondes pour atteindre Internet. Les applications
   interactives comme telnet et les jeux en rseau sont dgrades.
     _________________________________________________________________

1.1. Mises  jour du document

   La dernire version de ce document se trouve sur l'Internet 
   l'adresse : http://www.tldp.org.

   Les mises  jours seront reproduites dans divers sites web et ftp
   Linux tels que le LDP : http://www.tldp.org.

   La dernire version franaise de ce guide pratique est disponible sur
   le site traduc.org
     _________________________________________________________________

1.2. Liste de diffusion

   Souscrivez  la liste de diffusion de gestion de la bande passante
   pour l'ADSL http://jared.sonicspike.net/mailman/listinfo/adsl-qos afin
   de poser des questions ou de recevoir des informations de mise  jour.
     _________________________________________________________________

1.3. Avertissement

   Ni l'auteur, ni les diteurs, ni tout autre personne ayant contribu 
   ce guide pratique ne sont d'une quelconque faon responsables des
   dommages physiques, financiers, moraux ou d'un quelconque type
   survenus suite  l'utilisation des suggestions qu'il contient.
     _________________________________________________________________

1.4. Disclaimer

   Note

   La licence de ce document nous oblige  inclure une copie en anglais
   de ce texte, qui fait foi. La version franaise de ce texte se trouve
    la section prcdente.

   Neither the author nor the distributors, or any other contributor of
   this HOWTO are in any way responsible for physical, financial, moral
   or any other type of damage incurred by following the suggestions in
   this text.
     _________________________________________________________________

1.5. Droits d'utilisation

   Note

   Le texte ci-dessous est la version franaise de la licence de ce
   document. Seule la version originale, prsente dans la section
   suivante, de cette licence fait foi.

   L'auteur de ce document est Dan Singletary. La version originale de ce
   guide pratique est publie en accord avec les termes de la licence de
   documentation libre GNU GFDL, qui est ci-incluse par rfrence.

   La version franaise de document a t ralise par Franois Romieu et
   Guillaume Lelarge. La publication de ce document a t prpare par
   Jean-Philippe Gurard. La version franaise de ce guide pratique est
   publie en accord avec les termes de la licence de documentation libre
   GNU GFDL, qui est ci-incluse par rfrence.
     _________________________________________________________________

1.6. Copyright

   Note

   Le texte ci-dessous est la licence de ce document. Ce texte fait foi.
   Il est compos de la licence en anglais du document orignal, suivi de
   la licence en franais de sa traduction.

   This document is copyright 2002 by Dan Singletary, and is released
   under the terms of the GNU Free Documentation License, which is hereby
   incorporated by reference.

   La version franaise de document a t ralise par Franois Romieu et
   Guillaume Lelarge. La publication de ce document a t prpare par
   Jean-Philippe Gurard. La version franaise de ce guide pratique est
   publie en accord avec les termes de la licence de documentation libre
   GNU GFDL, qui est ci-incluse par rfrence.
     _________________________________________________________________

1.7. Retours d'exprience et corrections

   Merci de faire parvenir en anglais  l'auteur vos questions et
   commentaires relatifs  ce document  <dvsing@sonicspike.net>.
   N'hsitez pas  faire parvenir tout commentaire relatif  la version
   franaise de ce document  <commentaires@traduc.org>.
     _________________________________________________________________

2. Cadre d'utilisation

2.1. Prrequis

   La mthode dcrite dans ce document devrait s'appliquer  n'importe
   quelle configuration Linux. Toutefois, elle n'a pour l'instant t
   teste que dans la configuration suivante :

     * Red Hat Linux 7.3
     * Un noyau 2.4.18-5 avec une prise en charge de la QoS
       (ventuellement sous forme de module) qui inclut les correctifs
       suivants :
          + file d'attente HTB - http://luxik.cdi.cz/~devik/qos/htb/
            Remarque : on signale que les noyaux Mandrake au del de la
            version 2.4.18-3 (versions 8.1 et 8.2 de la distribution
            Mandrake) incluent le correctif HTB.
          + priphrique IMQ - http://luxik.cdi.cz/~patrick/imq/
       Ces correctifs se retrouveront probablement intgrs en standard
       dans des versions ultrieures du noyau.
     * iptables v1.2.6a ou suivantes. Le module length est absent de la
       version d'iptables distribue avec la Red Hat 7.3

   Note : les versions antrieures de ce document impliquaient une
   mthode de contrle de la bande passante qui passait par l'application
   d'un correctif  la queue sch_prio existante. Il s'est avr que ce
   correctif tait inutile. De surcrot, l'approche retenue dans ce texte
   donne de meilleurs rsultats (quoiqu' la date de rdaction de ce
   document, l'application de _2_ correctifs au noyau soit ncessaire :o)
   ).
     _________________________________________________________________

2.2. Organisation

   Toutes les mentions de priphriques rseau et de configuration dans
   ce guide pratique se rapportent au schma suivant :
              <-- 128 kbit/s      +------------+   <-- 10 Mbit/s -->
  Internet <--------------------> | Modem ADSL | <-------------------+
                1.5 Mbit/s -->    +------------+                     |
                                                                     | eth0
                                                                     V
                                                         +---------------+
                                                         |               |
                                                         | Routeur Linux |
                                                         |               |
                                                         +---------------+
                                                          | .. | eth1..ethN
                                                          |    |
                                                          V    V

                                                       Rseau local
     _________________________________________________________________

2.3. Files d'attente des paquets

   Les files d'attente contiennent les donnes destines  un
   priphrique rseau quand celles-ci ne peuvent pas tre expdies
   immdiatement. La plupart des files d'attente sont du type premier
   entr/premier sorti (FIFO/first in, first out) sauf lorsqu'elles sont
   explicitement configures pour appliquer une autre stratgie. Cela
   signifie que lorsqu'une file d'attente est remplie, le paquet qui y a
   t plac en dernier n'est mis qu'aprs tous ceux qui taient dj
   prsents dans la file.
     _________________________________________________________________

2.3.1. Le lien montant

   La bande passante d'un modem ADSL est asymtrique avec des valeurs
   typiques de 1.5 Mbit/s en descente et 128kbit/s en trafic montant. Par
   rapport au dbit de cette ligne, le routeur Linux et le modem ADSL
   sont gnralement associs par un lien  10 Mb/s ou plus. Si
   l'interface du routeur avec le rseau local est galement  10 Mb/s il
   n'y a aucune mise en attente au niveau du routeur lorsque les paquets
   transitent  destination d'Internet. Les paquets sont transmis via
   eth0 aussi rapidement qu'ils sont reus du rseau local. Les paquets
   sjournent dans la file d'attente du modem ADSL puisqu'ils arrivent 
   10 Mb/s et sont renvoys  128kb/s. Une fois la file d'atttente du
   modem sature, les nouveaux paquets sont jets. TCP s'adapte  ce
   phnomne et ajuste la taille de sa fentre de transmission pour
   employer toute la bande passante disponible.

   Si les files d'attente et TCP s'accordent pour utiliser toute la bande
   passante, des tailles de FIFO importantes augmentent la latence du
   trafic  vocation interactive.

   Les files d'attente  n voies sont similaires aux files d'attente de
   type FIFO  cette diffrence prs qu'elles comprennent plusieurs
   files. Les paquets sont placs dans l'une des n files en fonction de
   leurs caractristiques. Chaque file se voit attribuer une priorit et
   les paquets sont mis  partir de la file de plus haute priorit qui
   n'est pas vide. Avec cette stratgie, les paquets FTP peuvent tre mis
   dans une file de priorit plus basse que les paquets destins  telnet
   de telle sorte qu'un simple paquet telnet est capable de franchir la
   file d'attente immdiatement mme lors d'un transfert FTP.

   Ce document a t repris pour faire usage d'une nouvelle file
   d'attente dans Linux, dite de type HTB (Hierarchical Token Bucket). La
   file HTB ressemble  la file  n voies dcrite prcdemment mais elle
   rend possible la limitation de trafic dans chaque classe. En outre,
   elle autorise la cration d'une hirarchie de classes de trafic. Une
   description complte d'HTB dpasse le cadre de ce document. Davantage
   d'informations sont disponibles sur le site http://www.lartc.org
     _________________________________________________________________

2.3.2. Le lien descendant

   Le trafic entrant dans le modem ADSL en provenance d'Internet est mis
   en file d'attente de la mme faon que le trafic sortant  ceci prs
   que la file d'attente se situe chez le FAI. Il n'est donc gure
   possible de contrler les priorits relatives des flux ou d'appliquer
   un traitement prfrentiel  certains. La seule faon de maintenir une
   latence dcente consiste  s'assurer que les interlocuteurs n'envoient
   pas les donnes trop vite. Il n'y a malheureusement pas de mthode
   directe. Comme une bonne partie du trafic est de type TCP, il est
   toutefois possible de ralentir les metteurs :

     * Jeter volontairement les paquets entrants. TCP est conu pour
       employer la bande passante disponible tout en vitant la
       congestion du lien. Durant un change TCP, les donnes sont mises
       jusqu' ce qu'un paquet soit perdu. TCP remarque la perte et
       diminue sa fentre de transmission. Le cycle reprend, avec un
       rythme de progression des envois plus faible au cours du transfert
       et garantit une transmission aussi rapide que possible.
     * Jouer avec les annonces de fentre de rception. Au cours d'un
       transfert TCP, le rcepteur envoie un flux permanent de paquets
       d'acquittements (ACK). Les paquets ACK incluent une annonce de
       taille de fentre qui prcise la quantit maximale de donnes
       non-acquittes qui peut tre reue. Ceci permet de ralentir le
       rythme d'mission. Il n'existe  ce jour pas de mise en oeuvre
       libre de ce type de contrle de flux pour Linux (quoique je puisse
       tre en train d'y travailler).
     _________________________________________________________________

3. Fonctionnement

   L'optimisation de la bande passante montante s'effectue en deux
   tapes. Tout d'abord il faut viter que le modem ADSL ne mette les
   paquets en attente car on ne peut pas contrler la faon dont il gre
   sa file. Ceci s'effectue en limitant la quantit de donnes mise par
   le routeur via eth0 un peu en dessous de la bande passante disponible.
   Le routeur met en file les paquets qui arrivent du rseau local plus
   vite qu'il ne les met.

   La seconde tape consiste  mettre en oeuvre une stratgie de file
   d'attente au niveau du routeur. On examinera une file d'attente qui
   peut tre configure pour donner la priorit au trafic interactif tel
   que telnet ou les jeux  plusieurs participants en rseau.

   Les files HTB permettent  la fois la limitation de trafic et l'envoi
   prioritaire tout en assurant qu'aucune classe de priorit n'touffe
   les autres. Ce dernier point n'tait pas possible avec la mthode
   prconise par la version 0.1 de ce document.

   La dernire tape porte sur le marquage des paquets au niveau du
   pare-feu pour affecter des priorits aux paquets avec fwmark.
     _________________________________________________________________

3.1. Limitation du trafic sortant avec HTB Linux

   Bien que le lien entre le routeur et le modem soit  10 Mb/s, voire
   plus, le modem n'met au mieux les donnes qu' 128kbit/s. Au del de
   cette vitesse, les donnes sont mise en attente dans la file du modem.
   Un paquet de ping peut atteindre le modem immdiatement mais devoir
   attendre quelques secondes avant de rejoindre Internet si la file
   d'attente du modem est remplie. La plupart des modems ADSL ne
   permettent pas de contrler la faon dont les paquets sont retirs de
   la file d'attente ni quelle est la taille de cette dernire. Le
   premier objectif consiste donc  dplacer le point de congestion des
   paquets sortants  un endroit o on peut exercer suffisamment de
   contrle.

   La file HTB limite le rythme d'envoi des paquets au modem ADSL. Bien
   que le rythme montant puisse atteindre 128kb/s, on doit le brider 
   une valeur lgrement infrieure. Pour limiter la latence, il faut
   tre certain du fait qu'aucun paquet n'est mis en attente au niveau du
   modem. L'exprience m'a indiqu qu'une limitation  90kb/s du trafic
   sortant me donne 95% de la bande passante atteinte en l'absence de
   HTB. L'activation de HTB  ce rythme prvient la mise en file
   d'attente par le modem ADSL.
     _________________________________________________________________

3.2. Gestion des files de priorit avec HTB

   Remarque : les affirmations antrieures de cette section (concernant
   la mise en file d'attente  N voies) se sont avres errones. En
   l'occurrence, il tait possible de classer les paquets dans les
   lments de la file de priorit juste au moyen du champ fwmark. Cette
   fonctionnalit n'tait toutefois gure documente lors de la rdaction
   de la version 0.1 de ce guide pratique.

   Pour l'instant, les performances n'ont pas t modifies. La file de
   type FIFO des paquets a simplement t dplace du modem ADSL au
   routeur. Comme Linux a une longueur de file gale  100 paquets par
   dfaut, la situation s'est probablement aggrave (mais pas pour
   longtemps).

   Chaque classe adjacente dans une file HTB peut se voir attribuer une
   priorit. En plaant diffrents types de trafic dans des classes
   distinctes et en affectant  ces classes des priorits spcifiques,
   l'ordre dans lequel les paquets sont extraits de la file puis mis est
   contrlable. HTB le permet tout en vitant qu'une classe ne soit
   teinte puisqu'une bande passante minimale pour chaque classe peut
   tre garantie. En outre, HTB autorise une classe  utiliser jusqu' un
   certain niveau la bande passante laisse libre par les autres classes.

   Une fois les classes en place, on installe des filtres qui
   rpartissent le trafic dans les classes. Plusieurs approches sont
   envisageables mais le document s'appuie sur les utilitaires courants
   ipchains/iptables pour marquer les paquets avec un indicateur fwmark.
   Les filtres dirigent le trafic dans les classes de la file HTB selon
   leur indice fwmark. De cette faon, les rgles de reconnaissance
   d'iptables aiguillent certains trafics suivant leur classe.
     _________________________________________________________________

3.3. Classification des paquets sortant avec iptables

   Remarque : cette documentation reposait  l'origine sur ipchains pour
   trier les paquets. iptables est  prsent utilis.

   La dernire tape de configuration du routeur pour augmenter la
   priorit du trafic interactif consiste  spcifier au filtre comment
   identifier le trafic. Ceci s'effectue avec le champ fwmark des
   paquets.

   Sans trop rentrer dans les dtails, voici une description simplifie
   du cheminement des paquets entre quatre classes dont celle d'indice
   0x00 a la priorit la plus leve :

    1. On marque tous les paquets avec l'indice 0x03. Ceci les place tous
       dans la file de priorit la plus basse.
    2. On marque les paquets ICMP avec l'indice 0x00 afin que ping
       fournisse la latence des paquets de priorit la plus leve.
    3. On marque tous les paquets dont le port destination est infrieur
        1024 comme 0x01. Les services systme tels telnet et ssh voient
       leur priorit augmenter. Le port de contrle de ftp rentre dans
       cette catgorie. Toutefois, les transferts de donnes ftp ont lieu
       avec des ports situs plus haut et ils restent donc dans la
       catgorie 0x03.
    4. On marque tous les paquets  destination du port 25 (SMTP) avec un
       indice 0x03 afin d'viter que l'envoi d'un courrier muni d'un
       attachement volumineux n'empite sur le trafic interactif.
    5. On marque tous les paquets en direction d'un serveur de jeu avec
       un indice 0x02. Les joueurs fous auront une bonne latence sans
       craser les applications systme qui demandent une latence faible.
       On marque tous les paquets de petite taille avec un indice 0x02.
       Les paquets de type ACK des tlchargements doivent tre retourns
       rapidement afin d'assurer des transferts efficaces. Ceci est
       possible grce au module adquat (i.e. length) d'iptables.

   Tout ce qui prcde est bien sr personnalisable en fonction des
   besoins.
     _________________________________________________________________

3.4. Des rglages supplmentaires ...

   Deux choses sont encore susceptibles d'amliorer la latence. La MTU
   peut tre positionne en dessous de la valeur par dfaut de 1500
   octets. Sa diminution se rpercute sur le temps moyen d'attente lors
   de l'envoi d'un paquet prioritaire lorsqu'un paquet de faible priorit
   est dj en cours de transmission. La bande passante en souffre
   puisque le poids relatif des informations d'en-tte augmente (40
   octets pour le couple TCP et IP).

   La longueur de queue de 100 paquets par dfaut, qui demande jusqu' 10
   secondes pour se vider avec une ligne ADSL et une MTU de 1500 octets,
   peut galement tre abaisse.
     _________________________________________________________________

3.5. Une tentative de limitation du trafic entrant

   L'emploi d'un priphrique de file intermdiaire (IMQ ou Intermediate
   Queuing Device) place tous les paquets entrants dans une file d'une
   faon analogue au traitement des paquets sortants. La gestion de la
   priorit en est simplifie. On met tout le trafic hors TCP dans la
   classe 0x00, le trafic TCP tant quant  lui dans la classe 0x01. Les
   petits paquets vont galement dans la classe 0x00 car il s'agit
   vraisemblablement d'acquittements de donnes sortantes dj mises.
   Une file d'attente FIFO standard est applique  la classe 0x00 et une
   queue de rejet anticip alatoire (Random Early Drop/RED) traite la
   classe 0x01. RED est meilleur qu'une FIFO pour le contrle de TCP en
   ce qu'il rejette des paquets avant que la file ne dborde afin de
   ralentir le trafic qui semble sur le point de devenir incontrlable.
   Les deux classes sont galement bornes suprieurement  une valeur
   infrieure  la capacit maximale de la ligne ADSL.
     _________________________________________________________________

3.5.1. Problmes soulevs par la limitation de trafic entrant

   On souhaite limiter le trafic entrant afin de ne pas remplir la file
   d'mission du ct du FAI qui est susceptible de contenir jusqu' 5
   secondes de donnes. La seule faon de limiter le trafic entrant
   consiste  jeter des paquets tout  fait valables. Ces paquets ont
   dj consomm leur quote part de bande passante et le routeur Linux
   les jette afin de limiter le rythme d'arrive des paquets futurs. Ces
   paquets seront srement retransmis et consommeront davantage de bande
   passante. La limitation du trafic porte sur le rythme auquel les
   paquets vont tre accepts. Comme le taux _courant_ est bien suprieur
   en raison des paquets jets, la bande passante descendante doit tre
   _bien_ infrieure  la capacit de la ligne pour maintenir une latence
   faible. En pratique, j'ai d brider ma connexion ADSL descendante de
   1,5 Mb/s  700kb/s afin de conserver une bonne latence avec 5
   tlchargements simultans. Plus les sessions TCP sont nombreuses,
   plus la bande passante perdue dans les paquets jets est leve et
   plus il faut limiter le taux de transfert.

   Une meilleure mthode consisterait  jouer sur la fentre TCP mais je
   ne connais pas d'outil libre pour le faire sous Linux.
     _________________________________________________________________

4. Ralisation

   Aprs toutes ces explications, il est temps de passer  la mise en
   oeuvre sous Linux.
     _________________________________________________________________

4.1. Avertissements

   Brider le rythme d'mission des donnes vers le modem ADSL n'est pas
   aussi simple qu'il y parait. La plupart des modems DSL tablit juste
   un pont Ethernet entre le routeur Linux et la passerelle du ct du
   FAI. La couche de liaison de donnes s'appuie le plus souvent sur ATM
   qui envoie les donnes au moyen de cellules de 53 octets. 5 octets
   sont consomms pour l'en-tte ATM laissant ainsi 48 octets de donnes
   utiles. La transmission d'un simple octet de donnes isol ne peut
   donc pas demander moins de 53 octets au niveau du lien ATM. Dans le
   cas d'un acquittement TCP typique qui comprend 0 octet de donnes, 20
   octets d'en-tte TCP, autant d'en-tte IP et 18 de prambule Ethernet,
   les donnes utiles (40 octets) sont infrieures au minimum de 48
   octets requis par une trame Ethernet. Afin d'envoyer les 64 (48+16)
   octets via ATM, deux cellules ATM sont ncessaires, d'o une
   consommation de 106 octets de bande passante au niveau du lien ADSL.
   Chaque paquet TCP d'acquittement gaspille donc 42 octets de bande
   passante. Ceci ne serait pas gnant si Linux prenait en compte
   l'encapsulation due au modem ADSL. Il ne peut malheureusement pas le
   faire et se cantonne aux en-ttes TCP et IP ainsi qu'aux 14 octets
   d'adresse MAC (les 4 octets de CRC grs au niveau matriel sont
   ignors). Linux ne prend pas en compte la taille minimale de trame
   Ethernet ni la taille de cellule ATM.

   Tout ceci pour convaincre qu'il faut limiter le trafic sortant  une
   valeur sensiblement infrieure  la vritable capacit de la ligne
   (jusqu' ce qu'on dispose d'un ordonnanceur de paquets capable de
   prendre en compte les diffrentes encapsulations employes). Vous
   pouvez penser avoir trouv un bon rglage mais constater des sauts de
   latence au del de 3 secondes lors d'un tlchargements important.
   Ceci viendra probablement d'une mauvaise valuation de la bande
   passante consomme par les petits paquets d'acquittement.

   Je travaille depuis quelques mois sur une solution  ce problme et
   j'ai presque termin quelque chose qui sera publi afin que chacun
   puisse le tester. Ma solution repose sur une file en espace
   utilisateur  la place de la QoS de Linux pour limiter le rythme de
   transfert des paquets. Il s'agit d'une variante d'HTB en espace
   utilisateur. Pour l'instant cette solution a t capable de rguler le
   trafic sortant lors de tlchargements massifs (plusieurs flux) et de
   transferts point--point en volume (gnutella, sic) avec une telle
   efficacit que la latence dpasse au plus de 400ms la latence nominale
   de 15ms inhrente  mon lien ADSL. Pour davantage d'informations,
   abonnez-vous  la liste de diffusion ou surveillez les mises  jour de
   ce document.
     _________________________________________________________________

4.2. Script : mon_limiteur

   Ci-suit le source d'un script que j'emploie pour grer la bande
   passante de mon routeur Linux. Il s'appuie sur les concepts expliqus
   dans ce guide. Le trafic sortant est ventil entre une des 7 files
   disponibles en fonction de son type. Le trafic entrant est plac dans
   une file parmi deux, le trafic TCP tant jet en premier en cas de
   surcharge de la ligne. Les valeurs conviennent  mon installation mais
   les rsultats peuvent tre diffrents ailleurs.

   Ce script s'inspire du WonderShaper ADSL disponible sur le site du
   LARTC.

#!/bin/bash
#
# mon_limiteur - Limiteur et classificateur de trafic pour modem Cable ou ADSL.
#                 Inspir de WonderShaper (www.lartc.org)
#
# crit par Dan Singletary (7/8/02)
#
# Remarque - ce script suppose que le noyau a t patch avec les files
#             HTB et IMQ disponibles ici (les noyaux  venir ne demanderont
#             pas forcment l'application d'un correctif):
#       http://luxik.cdi.cz/~devik/qos/htb/
#       http://luxik.cdi.cz/~patrick/imq/
#
# Options de configuration pour mon_limiteur:
#  DEV    - correspond au priphrique ethX connect au modem
#  RATEUP -  positionner  une valeur infrieure  la bande
#            passante montante de la ligne.
#            Pour ma ligne ADSL en 1500/128, RATEUP=90 convient au rythme
#            montant de 128 kbps.  vous d'ajuster.
#  RATEDN -  positionner en dessous de la bande passante descendante de
#            la ligne.
#
#
#  Principe d'utilisation d'imq pour limiter le trafic entrant:
#
#    Il est impossible de limiter directement le rythme auquel les
#  donnes vous sont envoyes depuis l'Internet. Afin de limiter le
#  trafic entrant, on s'appuie sur les mcanismes anti-congestion de
#  TCP. Ceci signifie que SEUL LE TRAFIC TCP PEUT SE LIMITER. Le
#  trafic hors TCP est plac dans une queue prioritaire car le jeter
#  ne conduit vraisemblablement qu' une retransmission ultrieure
#  qui accrot la bande passante consomme.
#  On limite le trafic TCP en jetant les paquets lorsqu'ils dbordent
#  de la file HTB qui les limitera  un certain rythme (RATEDN)
#  lgrement infrieur  la capacit relle de la ligne. Jeter ces
#  paquets revient  en singer la perte par la file d'mission du
#  ct du FAI. Ceci a l'avantage d'viter la congestion de la file
#  d'mission chez le FAI puisque TCP ralentira avant qu'elle ne
#  se remplisse. L'usage d'une stratgie de mise en attente base sur
#  la classification des paquets par priorit permet de ne PAS jeter
#  certains types de paquets (ssh, telnet, etc). Les paquets ne sont
#  retirs des files d'attente de faible priorit qu'une fois que
#  chaque classe a atteint un seuil minimum (1/7 de la bande passante
#  dans ce script).
#
#  Rsum:
#   * La perte d'un paquet TCP diminue le rythme de rception de la
#     connexion associe via les mcanismes de contrle de congestion.
#   * Jeter des paquets TCP n'apporte rien. S'ils sont importants, ils
#     seront retransmis.
#   * Limiter le rythme des connexions TCP entrantes en dessous de la
#     capacit de la ligne DEVRAIT viter la mise en attente des paquets
#     du ct du FAI (DSLAM, concentrateur de cables, etc). L'exprience
#     indique que ces files contiennent 4 secondes de trafic  1500 kbps,
#     soit 6 Mb de donnes.  ce niveau, l'absence de mise en attente
#     diminue la latence.
#
#  Avertissements:
#   * Est-ce que la limitation de bande passante diminue l'efficacit de
#     transferts TCP massifs ?
#     - Apparemment non. L'augmentation de priorit des paquets
#       d'acquittement maximise le dbit en vitant de perdre de la bande
#       passante  retransmettre des paquets dj reus.
#

# NOTE: La configuration ci-dessous fonctionne avec ma connexion ADSL
# 1.5M/128K via Pacific Bell Internet (SBC Global Services)

DEV=eth0
RATEUP=90
RATEDN=700  # Nettement infrieur  la capacit de la ligne de 1500.
            # On n'a donc pas  limiter le trafic entrant jusqu' ce
            # qu'une meilleure ralisation telle que la modification
            # de fentre TCP soit disponible.

#
# Fin des options de configuration
#

if [ "$1" = "status" ]
then
        echo "[qdisc]"
        tc -s qdisc show dev $DEV
        tc -s qdisc show dev imq0
        echo "[class]"
        tc -s class show dev $DEV
        tc -s class show dev imq0
        echo "[filter]"
        tc -s filter show dev $DEV
        tc -s filter show dev imq0
        echo "[iptables]"
        iptables -t mangle -L MONLIMITEUR-OUT -v -x 2> /dev/null
        iptables -t mangle -L MONLIMITEUR-IN -v -x 2> /dev/null
        exit
fi

# Remise  zro
tc qdisc del dev $DEV root    2> /dev/null > /dev/null
tc qdisc del dev imq0 root 2> /dev/null > /dev/null
iptables -t mangle -D POSTROUTING -o $DEV -j MONLIMITEUR-OUT 2> /dev/null > /de
v/null
iptables -t mangle -F MONLIMITEUR-OUT 2> /dev/null > /dev/null
iptables -t mangle -X MONLIMITEUR-OUT 2> /dev/null > /dev/null
iptables -t mangle -D PREROUTING -i $DEV -j MONLIMITEUR-IN 2> /dev/null > /dev/
null
iptables -t mangle -F MONLIMITEUR-IN 2> /dev/null > /dev/null
iptables -t mangle -X MONLIMITEUR-IN 2> /dev/null > /dev/null
ip link set imq0 down 2> /dev/null > /dev/null
rmmod imq 2> /dev/null > /dev/null

if [ "$1" = "stop" ]
then
        echo "Limitation de dbit dsactive sur $DEV."
        exit
fi

###########################################################
#
# Limitation de trafic sortant (limite suprieure  RATEUP)

# positionnement de la taille de la file d'mission pour obtenir
# une latence d'environ 2 secondes pour les paquets de la file
# de faible priorit.
ip link set dev $DEV qlen 30

# modification de MTU du priphrique sortant.
# - Diminuer la MTU abaisse la latence mais dgrade le dbit en raison de
#   la surcharge IP et TCP.
ip link set dev $DEV mtu 1000

# ajout de la stratgie HTB
tc qdisc add dev $DEV root handle 1: htb default 26

# ajout de la classe de limitation principale
tc class add dev $DEV parent 1: classid 1:1 htb rate ${RATEUP}kbit

# ajout des classes filles:
# - chaque classe dispose AU MOINS de son quota de bande passante. Aucune
#   classe n'est donc touffe par les autres. Chaque classe peut galement
#   consommer toute la bande passante si aucune autre classe ne l'emploie.
tc class add dev $DEV parent 1:1 classid 1:20 htb rate $[$RATEUP/7]kbit \
        ceil ${RATEUP}kbit prio 0
tc class add dev $DEV parent 1:1 classid 1:21 htb rate $[$RATEUP/7]kbit \
        ceil ${RATEUP}kbit prio 1
tc class add dev $DEV parent 1:1 classid 1:22 htb rate $[$RATEUP/7]kbit \
        ceil ${RATEUP}kbit prio 2
tc class add dev $DEV parent 1:1 classid 1:23 htb rate $[$RATEUP/7]kbit \
        ceil ${RATEUP}kbit prio 3
tc class add dev $DEV parent 1:1 classid 1:24 htb rate $[$RATEUP/7]kbit \
        ceil ${RATEUP}kbit prio 4
tc class add dev $DEV parent 1:1 classid 1:25 htb rate $[$RATEUP/7]kbit \
        ceil ${RATEUP}kbit prio 5
tc class add dev $DEV parent 1:1 classid 1:26 htb rate $[$RATEUP/7]kbit \
        ceil ${RATEUP}kbit prio 6

# ajout de la stratgie aux classes filles
# - SFQ offre un traitement sensiblement quitable de chaque classe.
tc qdisc add dev $DEV parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev $DEV parent 1:21 handle 21: sfq perturb 10
tc qdisc add dev $DEV parent 1:22 handle 22: sfq perturb 10
tc qdisc add dev $DEV parent 1:23 handle 23: sfq perturb 10
tc qdisc add dev $DEV parent 1:24 handle 24: sfq perturb 10
tc qdisc add dev $DEV parent 1:25 handle 25: sfq perturb 10
tc qdisc add dev $DEV parent 1:26 handle 26: sfq perturb 10

# rpartition du trafic en classe via fwmark
# - le trafic est rparti en classes de priorit suivant l'indicateur
#   fwmark des paquets (ceux-ci sont positionns avec iptables un peu plus
#   loin). La classe de priorit par dfaut a t mise  1:26 de telle sorte
#   que les paquets qui ne sont pas marqus se retrouvent dans la classe de
#   priorit la plus faible.
tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20
tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 21 fw flowid 1:21
tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 22 fw flowid 1:22
tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 23 fw flowid 1:23
tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 24 fw flowid 1:24
tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 25 fw flowid 1:25
tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 26 fw flowid 1:26

# ajout de MONLIMITEUR-OUT  la table de modification des paquets d'iptables
# - ceci dclare la table employe pour filtrer et classer les paquets
iptables -t mangle -N MONLIMITEUR-OUT
iptables -t mangle -I POSTROUTING -o $DEV -j MONLIMITEUR-OUT

# ajout de fwmark pour classer les diffrents types de trafic
# - fwmark est positionn de 20  26 suivant la classe. 20 correspond  la
#   priorit la plus forte.

        # Trafic sur les ports bas
iptables -t mangle -A MONLIMITEUR-OUT -p tcp --sport 0:1024 -j MARK --set-mark
23

        # Trafic sur les ports bas
iptables -t mangle -A MONLIMITEUR-OUT -p tcp --dport 0:1024 -j MARK --set-mark
23

        # Port ftp-data, faible priorit
iptables -t mangle -A MONLIMITEUR-OUT -p tcp --dport 20 -j MARK --set-mark 26

        # Messagerie Immdiate AOL
iptables -t mangle -A MONLIMITEUR-OUT -p tcp --dport 5190 -j MARK --set-mark 23

        # ICMP (ping) - forte priorit (impressionnez vos amis)
iptables -t mangle -A MONLIMITEUR-OUT -p icmp -j MARK --set-mark 20

        # DNS (petits paquets)
iptables -t mangle -A MONLIMITEUR-OUT -p udp -j MARK --set-mark 21

        # shell scuris
iptables -t mangle -A MONLIMITEUR-OUT -p tcp --dport ssh -j MARK --set-mark 22

        # shell scuris
iptables -t mangle -A MONLIMITEUR-OUT -p tcp --sport ssh -j MARK --set-mark 22

        # telnet (hum ...)
iptables -t mangle -A MONLIMITEUR-OUT -p tcp --dport telnet -j MARK --set-mark
22

        # telnet (hum ...)
iptables -t mangle -A MONLIMITEUR-OUT -p tcp --sport telnet -j MARK --set-mark
22

        # IPSec - la surcharge n'est pas connue ...
iptables -t mangle -A MONLIMITEUR-OUT -p ipv6-crypt -j MARK --set-mark 24

        # Serveur WWW local
iptables -t mangle -A MONLIMITEUR-OUT -p tcp --sport http -j MARK --set-mark 25

        # Petits paquets (des ACK probablement)
iptables -t mangle -A MONLIMITEUR-OUT -p tcp -m length --length :64 -j MARK --s
et-mark 21

        # Rptition - on marque les paquets restants  26 (faible priorit)
iptables -t mangle -A MONLIMITEUR-OUT -m mark --mark 0 -j MARK --set-mark 26

# Fin de la limitation sortante
#
####################################################

echo "Limitation de trafic sortant activ sur $DEV.  Dbit: ${RATEUP}kbit/sec."

# Dcommenter la ligne suivante pour n'avoir que la limitation de trafic montan
t.
# exit

####################################################
#
# Limitation du trafic entrant (dbit maximal de RATEDN)

# on force le chargement du module imq

modprobe imq numdevs=1

ip link set imq0 up

# ajout de la stratgie de mise en file d'attente
# - par dfaut une classe 1:21  faible priorit

tc qdisc add dev imq0 handle 1: root htb default 21

# ajout de la classe de limitation principale
tc class add dev imq0 parent 1: classid 1:1 htb rate ${RATEDN}kbit

# ajout des classes filles
# - trafic TCP en 21, le reste en 20
#
tc class add dev imq0 parent 1:1 classid 1:20 htb rate $[$RATEDN/2]kbit \
        ceil ${RATEDN}kbit prio 0
tc class add dev imq0 parent 1:1 classid 1:21 htb rate $[$RATEDN/2]kbit \
        ceil ${RATEDN}kbit prio 1

# ajout de la stratgie de limitation aux classes filles
# - voir les remarques ci-dessus sur SFQ.
tc qdisc add dev imq0 parent 1:20 handle 20: sfq perturb 10
tc qdisc add dev imq0 parent 1:21 handle 21: red limit 1000000 \
        min 5000 max 100000 avpkt 1000 burst 50

# rpartition du trafic en classe via fwmark
# - le trafic est rparti en classes de priorit suivant l'indicateur
#   fwmark des paquets (ceux-ci sont positionns avec iptables un peu plus
#   loin). La classe de priorit par dfaut  t mise  1:26 de telle sorte
#   que les paquets qui ne sont pas marqus se retrouvent dans la classe de
#   priorit la plus faible.
tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 20 fw flowid 1:20
tc filter add dev imq0 parent 1:0 prio 0 protocol ip handle 21 fw flowid 1:21

# ajout de MONLIMITEUR-IN  la table de modification des paquets d'iptables
iptables -t mangle -N MONLIMITEUR-IN
iptables -t mangle -I PREROUTING -i $DEV -j MONLIMITEUR-IN

# ajout de fwmark pour classer les diffrents types de trafic
# - fwmark est positionn de 20  21 suivant la classe. 20 correspond  la
#   priorit la plus forte.

        # Forte priorit pour les paquets non TCP
iptables -t mangle -A MONLIMITEUR-IN -p ! tcp -j MARK --set-mark 20

        # Les petits paquets TCP sont probablement des ACK
iptables -t mangle -A MONLIMITEUR-IN -p tcp -m length --length :64 -j MARK --se
t-mark 20

        # shell scuris
iptables -t mangle -A MONLIMITEUR-IN -p tcp --dport ssh -j MARK --set-mark 20

        # shell scuris
iptables -t mangle -A MONLIMITEUR-IN -p tcp --sport ssh -j MARK --set-mark 20

        # telnet (hum ...)
iptables -t mangle -A MONLIMITEUR-IN -p tcp --dport telnet -j MARK --set-mark 2
0

        # telnet (hum ...)
iptables -t mangle -A MONLIMITEUR-IN -p tcp --sport telnet -j MARK --set-mark 2
0

        # Rptition - les paquets sans marque sont positionns  21 (faible pr
iorit)
iptables -t mangle -A MONLIMITEUR-IN -m mark --mark 0 -j MARK --set-mark 21

# on envoie les paquets prcdents  l'interface imq0.
iptables -t mangle -A MONLIMITEUR-IN -j IMQ

# Fin de la limitation de trafic entrant.
#
####################################################

echo "Limitation de trafic entrant active sur $DEV.  Dbit: ${RATEDN}kbit/sec.
"
     _________________________________________________________________

5. Test

   La mthode de test la plus facile consiste  saturer le lien montant
   avec du trafic  faible priorit. Si le trafic telnet et le ping ont
   une priorit leve par opposition aux transferts FTP, l'augmentation
   de dlai des pings lorsqu'un transfert FTP s'tablit devrait tre
   ngligeable par rapport  ce qu'elle devient en l'absence de file
   d'attente. Des pings en dessous de 100ms dpendent de la
   configuration. Des pings au dessus d'une ou deux secondes signalent
   une anomalie.
     _________________________________________________________________

6. a fonctionne. Et maintenant ?

   Maintenant que la bande passante est gre, il faut s'en servir. Aprs
   tout, elle a t paye !

     * Utilisez un client Gnutella et PARTAGEZ VOS FICHIERS sans dgrader
       les performances de votre rseau.
     * Hbergez un site web sans que la consultation ne ralentisse vos
       sessions Quake.
