Donner la priorité aux ACKS TCP vides avec pf et ALTQ

Introduction

ALTQ est une plateforme destinée à gérer les règles de mise en queue sur les interfaces réseau. Elle manipule des queues de sortie pour imposer les limites de bande passante et donner des priorités au trafic grâce à la classification.

Si ALTQ était intégrée à OpenBSD et a été activée par défaut depuis plusieurs release, la dernière d'entre elles confond les configurations de ALTQ et pf en un seul fichier et permet à pf d'assigner les paquets dans des queues. Ceci simplifie la configuration et réduit de manière importante le coût d'assignation dans une queue.

Cet article présente un exemple simple mais efficace de l'utilisation du couple pf/ALTQ. Cela tend à illustrer la nouvelle syntaxe de configuration ainsi que la mise en queue. Le code utilisé dans cet exemple est d'ores et déjà disponible dans la branche -current des sources de OpenBSD.

Problème

J'utilise une connexion DSL asymétrique avec un débit nominal de 512Kb descendant et 128Kb montant (overhead PPPoE minimum). Quand je télécharge, j'obtiens des taux de transfert d'environ 50Kb/s. Mais dès que je démarre un envoi concurrent, le taux de téléchargement chutte significativement, à environ 7Kb/s.

Explication

Même lorsque une connexion TCP est utilisée pour envoyer des données dans une seule direction (comme quand on télécharge un fichier via ftp), les acquittements TCP (ACKs) doivent être envoyés dans la direction inverse, ou le client croira que ses paquets ont été perdus et il les transmettra à nouveau. Pour permettre au client d'envoyer les données à un taux maximal, il est important de retourner les ACKs rapidement.

Quand le lien montant est saturé par d'autres connexions (comme un envoi concurrent), tous les paquets sortant bénéficient du même délai d'attente par défaut. Par conséquent, un envoi concurrent saturant le lien montant cause la mise en attente des ACKs du téléchargement ce qui cause le rejet dans le sens de la sortie.

Solution

Les ACKs sortant liés au téléchargement sont petits, vu qu'ils ne contiennent aucune donnée. Même si un téléchargement rapide sature les 512 kbps, le téléchargement n'a pas besoin de plus d'une fraction de la bande passante montante pour les ACKs mis en attente.

Ainsi, l'idée est de donner la priorité aux ACKs qui n'ont pas de charge. L' extrait de pf.conf suivant illustre comment configurer les déclarations de queues et d'assigner des paquets à ces dernières :

ext_if="kue0"

altq on $ext_if priq bandwidth 100Kb queue { q_pri, q_def }
queue q_pri priority 7
queue q_def priority 1 priq(default)

pass out on $ext_if proto tcp from $ext_if to any flags S/SA \
        keep state queue (q_def, q_pri)

pass in  on $ext_if proto tcp from any to $ext_if flags S/SA \
        keep state queue (q_def, q_pri)

Premièrement, une macro est définie pour l'interface externe. Ceci facilite les mises à jour de règles quand l'interface change.

Ensuite, altq est mise en service sur l'interface en utilisant l'algorithme priq, et la bande passante montante est spécifiée. J'utilise 100 kbps plutôt que 128 kbps car c'est le taux maximal que je peux atteindre (à cause des effets de l'encapsulation PPPoE). Des essais seront certainement nécessaires pour déterminer la meilleure valeur. Si elle est trop élevée, la priorité de la queue n'est pas efficace, et si elle est trop basse, la bande passante disponible n'est pas pleinement utilisée. Ensuite, deux queues sont définies avec les noms (arbitraires) q_pri et q_def. La queue avec la plus petite priorité est la queue par défaut.

Enfin, les règles de filtrage concernant les connexions (avec états) sont étendues afin de spécifier dans quelle queue assigner les paquets acceptés. La première queue spécifiée entre parenthèses est utilisée pour tous les paquets par défaut, alors que la seconde (et optionnelle) queue est utilisée pour les paquets avec le ToS (type de service) 'lowdelay' (par exemple, les sessions ssh interactives) et les ACKs TCP sans charge.

Les connexions entrantes et sortantes passeront par ces deux règles, créant un état, et tous les paquets en rapport à ces connexions seront assignés à l'une ou l'autre des queues q_def et q_pri. Les paquets assignés à la queue q_pri auront la priorité et seront envoyés avant tous les paquets en attente dans la queue q_def.

Résultat

Le test suivant fut réalisé tout d'abord sans, puis avec les règles ALTQ expliquées ci-dessus :

  • -10 to -8 minutes : inactif
  • -8 to -6 minutes : réception seule
  • -6 to -4 minutes : envoi et réception concurrents
  • -4 to -2 minutes : envoi seul
  • -2 to 0 minutes : inactif

Le premier graphique montre les résultats du test sans ALTQ, et le second avec ALTQ :

L'amélioration est relativement significative, le lien montant saturé ne met plus en attente les ACKs vides sortant, et le taux de téléchargement ne s'effondre plus.

Cet effet n'est pas limité aux liens asymétriques, cela joue chaque fois qu'un sens du lien est en saturation. Cela se produit évidemment plus souvent avec un lien asymétrique.

Liens

Crédits

Tutorial Original
Rédaction : Daniel Hartmeier
Traduction : Alexandre Anriot
Mis Sur Le Wiki : Azwaw OUSADOU
Version D'OpenBSD : 3.3

documentations/reseau/pf_altq.txt · Dernière modification: 2009/12/31 22:36 par bsdmaniak
OpenBSD Apache Driven by DokuWiki
CC Attribution-Noncommercial-Share Alike 3.0 Unported