Configurer PPPoE
09/02/2005
 Christian CALECA 
Liste des cours

MTU, MSS etc...

Accueil ] [ IP sur quoi ? ] [ Et les tunnels ? ] [ PPPoE et le câble ] [ PPPoE Installation ] [ Reniflons un peu... ] [ Les détails ] [ MTU, MSS etc... ]


Coupons les cheveux en quatre

PPPoE présente un inconvénient considérable, du au fait qu'il encapsule de l'IP avant de le faire transporter sur Ethernet. Cette couche supplémentaire apporte quelques octets de plus dans la trame Ethernet, ce qui est très lourd de conséquences.

Sans précautions particulières, l'internaute risque de rencontrer le fameux problème du "gel de la connexion". Nous allons maintenant analyser dans le détail cet inconvénient et, peut-être, trouver les solutions qui permettraient de supprimer ce désagrément.

Circulation des données

Une fois encore, nous devrons nous reporter au modèle OSI ou DOD. Rappelez-vous qu'entre l'applications qui émettent et reçoivent les données, il y a quelques couches à traverser pour arriver jusqu'au support physique du transport. Lorsqu'une donnée est émise par une application, elle descend les couches une à une, chaque couche ajoutant des informations supplémentaires aux données initiales. Le paquet grossit donc chaque fois qu'il descend d'une couche.

Le problème va venir ici de la couche supplémentaire introduite par PPPoE. Celle-ci ajoute 8 octets supplémentaires, 8 octets de trop dans bien des cas.

L'IP facile sur Ethernet

Nous le savons, IP est fait pour être transporté par Ethernet. L'Internet a été réalisé à partir de cet axiome.

IP

Comme nous le voyons sur l'illustration, une trame Ethernet fait un maximum de 1518 octets, ce qui laisse à IP 1500 octets maximum. Tout l'Internet est basé sur ce postulat. Je rappelle qu'il s'agit bien ici d'IP sur Ethernet ! Pas de PPPoE dans l'histoire.

PPPoE, l'intrus

intrus

Que se passe-t-il lorsque PPPoE s'installe ? Il ajoute, nous l'avons dit, une couche supplémentaire entre IP qu'il transporte et Ethernet qui le transporte. PPPoE ajoute au total 8 octets supplémentaires. Vous voulez le détail ?

 Si l'on part du principe que la trame Ethernet ne peut dépasser 1518 octets (si vous préférez, que la taille maximum du payload Ethernet ne doit pas dépasser 1500 octets), ça veut dire que la trame IP "utile"  doit être réduite à 1492 octets.

Compliqué ?

Lorsque les données arrivent sur la couche IP, il se passe le phénomène suivant. IP ne sait pas qu'en dessous de lui il y a PPP et non Ethernet. IP va donc considérer que sa longueur de trame peut atteindre 1500 octets (Maximum Transfert Unit), puisque normalement Ethernet sait transporter un volume de données de cette taille.

Le MTU est fixé, en principe, selon la nature du réseau situé en dessous de IP.

Normalement, lorsque le MTU est le même partout sur les divers composants de l'inter réseau, tout se passe bien.

Mais où est le problème ?

Dans une configuration comme celle qui suit. Forcément, quelque part, il va y avoir des configurations comme celle-ci, un routeur avec de l'IP sur Ethernet d'un côté et de l'IP sur PPP sur Ethernet de l'autre. Le paquet jaune représente le datagramme IP. Le point délicat est cerclé de rouge.

Ce paquet, cerclé de rouge, ne doit pas dépasser 1500 octets, à cause des limites d'Ethernet. De ce côté là du routeur, on le sait, mais pas de l'autre.

Si, sur l'entrée (à gauche) le datagramme IP fait 1500 octets, il n'a pas de problèmes pour être véhiculé par Ethernet. Il remonte les couches de gauche et au niveau IP, redescend les couches (à droite). là, il passe par PPPoE qui lui ajoute ses 8 octets. Le paquet devient trop gros pour Ethernet.

PPPoE

Dans ce cas, plusieurs éventualités apparaissent.

Finalement, dans un cas concret : 

Et voilà le (sale) travail...

Ce problème peut également apparaître chez vous, si vous partagez votre connexion sur un réseau privé. Votre routeur, quel qu'il soit, sera confronté au même inconvénient. Vous risquez de devoir modifier le MTU de tous les hôtes de votre réseau privé. Nous verrons que si la passerelle est sous Linux et utilise rp-pppoe, le problème pourra être contourné.

Comment résoudre le problème en amont

Grâce à MSS (Maximum Segment Size).

Nous sommes ici au niveau TCP. TCP prépare les paquets de données à envoyer à IP. En agissant sur la taille de ces paquets, on peut éviter les problèmes au niveau du MTU.

Comme l'on sait que les couches inférieures vont ajouter jusqu'à 40 octets aux données, si l'on prend un MSS de 1460 octets, on est à peu près certain que la taille des données transportées au niveau Ethernet ne dépassera pas 1500. Le MSS est établi lors de l'initiation d'une connexion TCP. Le client annonce un MSS typiquement de 1460 dans son premier paquet SYN et le serveur répond dans le SYN/ACK. La trace qui suit est prise sur un poste Windows XP situé sur un LAN connecté à l'internet par une passerelle Sous Debian. Un client FTP (Filezilla), se connecte sur un serveur FTP de l'internet.

Frame 1 (62 bytes on wire, 62 bytes captured)
    Arrival Time: Jul 15, 2004 14:04:53.598297000
    Time delta from previous packet: 0.000000000 seconds
    Time since reference or first frame: 0.000000000 seconds
    Frame Number: 1
    Packet Length: 62 bytes
    Capture Length: 62 bytes
Ethernet II, Src: 00:05:5d:47:f5:c5, Dst: 00:90:27:71:43:c7
    Destination: 00:90:27:71:43:c7 (Intel_71:43:c7)
    Source: 00:05:5d:47:f5:c5 (D-Link_47:f5:c5)
    Type: IP (0x0800)
Internet Protocol, Src Addr: 192.168.0.10 (192.168.0.10), Dst Addr: 195.83.118.1 (195.83.118.1)
    Version: 4
    Header length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
        0000 00.. = Differentiated Services Codepoint: Default (0x00)
        .... ..0. = ECN-Capable Transport (ECT): 0
        .... ...0 = ECN-CE: 0
    Total Length: 48
    Identification: 0x72da (29402)
    Flags: 0x04 (Don't Fragment)
        0... = Reserved bit: Not set
        .1.. = Don't fragment: Set
        ### Le "flag Don't fragment" est mis, ce qui permet éventuellement de découvrir
        ### le MTU, si tout se passe bien au niveau d'ICMP
        ..0. = More fragments: Not set
    Fragment offset: 0
    Time to live: 128
    Protocol: TCP (0x06)
    Header checksum: 0x8de6 (correct)
    Source: 192.168.0.10 (192.168.0.10)
    Destination: 195.83.118.1 (195.83.118.1)
Transmission Control Protocol, Src Port: kpop (1109), Dst Port: ftp (21), Seq: 1814706075, Ack: 0, Len: 0
    Source port: kpop (1109)
    Destination port: ftp (21)
    Sequence number: 1814706075
    Header length: 28 bytes
    Flags: 0x0002 (SYN)
        0... .... = Congestion Window Reduced (CWR): Not set
        .0.. .... = ECN-Echo: Not set
        ..0. .... = Urgent: Not set
        ...0 .... = Acknowledgment: Not set
        .... 0... = Push: Not set
        .... .0.. = Reset: Not set
        .... ..1. = Syn: Set
        .... ...0 = Fin: Not set
    Window size: 16384
    Checksum: 0xa0e8 (correct)
    Options: (8 bytes)
        Maximum segment size: 1460 bytes
        NOP
        NOP
        SACK permitted

Et le serveur répond :

Frame 2 (62 bytes on wire, 62 bytes captured)
    Arrival Time: Jul 15, 2004 14:04:53.638354000
    Time delta from previous packet: 0.040057000 seconds
    Time since reference or first frame: 0.040057000 seconds
    Frame Number: 2
    Packet Length: 62 bytes
    Capture Length: 62 bytes
Ethernet II, Src: 00:90:27:71:43:c7, Dst: 00:05:5d:47:f5:c5
    Destination: 00:05:5d:47:f5:c5 (D-Link_47:f5:c5)
    Source: 00:90:27:71:43:c7 (Intel_71:43:c7)
    Type: IP (0x0800)
Internet Protocol, Src Addr: 195.83.118.1 (195.83.118.1), Dst Addr: 192.168.0.10 (192.168.0.10)
    Version: 4
    Header length: 20 bytes
    Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00)
        0000 00.. = Differentiated Services Codepoint: Default (0x00)
        .... ..0. = ECN-Capable Transport (ECT): 0
        .... ...0 = ECN-CE: 0
    Total Length: 48
    Identification: 0x0000 (0)
    Flags: 0x04 (Don't Fragment)
        0... = Reserved bit: Not set
        .1.. = Don't fragment: Set
        ..0. = More fragments: Not set
    Fragment offset: 0
    Time to live: 49
    Protocol: TCP (0x06)
    Header checksum: 0x4fc1 (correct)
    Source: 195.83.118.1 (195.83.118.1)
    Destination: 192.168.0.10 (192.168.0.10)
Transmission Control Protocol, Src Port: ftp (21), Dst Port: kpop (1109), Seq: 5846264, Ack: 1814706076, Len: 0
    Source port: ftp (21)
    Destination port: kpop (1109)
    Sequence number: 5846264
    Acknowledgement number: 1814706076
    Header length: 28 bytes
    Flags: 0x0012 (SYN, ACK)
        0... .... = Congestion Window Reduced (CWR): Not set
        .0.. .... = ECN-Echo: Not set
        ..0. .... = Urgent: Not set
        ...1 .... = Acknowledgment: Set
        .... 0... = Push: Not set
        .... .0.. = Reset: Not set
        .... ..1. = Syn: Set
        .... ...0 = Fin: Not set
    Window size: 5840
    Checksum: 0x94be (correct)
    Options: (8 bytes)
        Maximum segment size: 1452 bytes
        NOP
        NOP
        SACK permitted

Donc nous serons d'accord sur un MSS de 1452 octets, ce qui donnera au sortir de la couche IP un paquet d'un maximum de 1492 octets. On est bon pour PPPoE.

Il est intelligent ce serveur, il a compris tout seul que je me connectais via PPPoE ?

Non, ce n'est pas de l'intelligence, mais un gros bricolage opéré en douce par le client PPPoE de la passerelle. Lorsque le paquet passe par ppp0, le client PPPoE substitue cette valeur de MSS à celle que le serveur a annoncé. Ainsi, le client du LAN agira en conséquence.

Le client PPPoE de Debian est une émanation de RP-PPPoE. La même manipulation est donc faite sur d'autres distributions, qui utilisent RP-PPPoE.

C'est pas très propre, ça ne plaira pas du tout à IPsec, qui trouvera un paquet falsifié et ne le laissera pas passer, mais dans le cas classique d'IP "normal" ça résout le problème sans qu'il soit nécessaire d'intervenir sur tous les postes du LAN, du moins pour TCP. Cette méthode permet de contourner le problème du "path to MTU" qui, comme nous l'avons vu plus haut, ne fonctionne correctement que si ICMP n'est pas bloqué quelque part sur le chemin.

Pour les utilisateurs de GNU/Linux, il existe dans les dernières versions d'IPtables, une cible particulière qui permet de réaliser ce genre de travail sur le MSS. Je ne résiste pas au plaisir de vous citer un extrait de ce HOWTO :

"Ce patch par Marc Boucher, ajoute une nouvelle "target" qui vous permet d'examiner et de changer le MSS dans les paquets TCP SYN, pour contrôler la taille maximum pour cette connexion.
Comme l'explique Marc lui même, c'est un hack, utilisé pour résoudre les problèmes engendrés par ces ISPs têtus comme des mules qui bloquent les paquets ICMP Fragmentation Needed à tort."


Précédente ] [ Accueil ]