Le goulot d'étranglement de routage dans les passerelles VPN chiffrées

Sur les concentrateurs VPN à très haut débit, les routeurs NAT d'opérateurs et les passerelles de sécurité mutualisées, les administrateurs système se heurtent fréquemment à un plafond de performance processeur. Même sur des serveurs dotés de plusieurs dizaines de cœurs CPU et de cartes réseau PCIe 4.0, la cadence de traitement des paquets par seconde (PPS) sature souvent la capacité d'interruption logicielle d'un cœur bien avant d'avoir saturé la bande passante physique de l'interface.

Dans une pile de routage Linux classique, chaque paquet transféré doit traverser l'ensemble des points d'ancrage (hooks) du pare-feu Netfilter :

[ Câble réseau physique ] 
           |
           v
[ Anneau RX du pilote / NAPI Poll ]
           |
           v
[ Étape PREROUTING (conntrack, mangle, raw, dnat) ]
           |
           v
[ Décision de routage (fib_lookup) ]
           |
           v
[ Étape FORWARD (filtrage, limitation de débit) ]
           |
           v
[ Étape POSTROUTING (snat, masquerade, mangle) ]
           |
           v
[ Résolution de voisinage (ARP/NDP) / Egress Qdisc ]
           |
           v
[ Anneau TX du pilote ] ---> [ Câble réseau physique ]

Chaque maillon nécessite des compteurs atomiques, des verrous rotatifs sur les tables de suivi de connexion (nf_conntrack_lock), l'allocation de métadonnées pour les tampons de paquets (sk_buff), et de multiples requêtes dans la table de routage FIB. Lorsque la passerelle gère des milliers de tunnels simultanés (comme WireGuard, RiceGuard ou IPsec), cette surcharge devient colossale :

  1. Évaluations répétitives des flux établis : Les paquets appartenant à des connexions TCP ou des flux UDP de longue durée doivent subir à nouveau la totalité des règles de filtrage et la machine à états conntrack.
  2. Contention du cache inter-cœurs : La table de hachage conntrack est partagée entre les cœurs CPU. Un débit élevé de petits paquets provoque une invalidation continuelle des lignes de mémoire cache L3 (cache line bouncing).
  3. Latence de double encapsulation : Le renvoi des paquets déchiffrés vers l'extérieur ou le routage des datagrammes externes encapsulés impose une seconde traversée intégrale des hooks Netfilter.

Pour éliminer ce verrou sans sacrifier la sécurité du filtrage d'état (Stateful Packet Inspection), le noyau Linux intègre l'infrastructure Netfilter Flowtable (développée par Pablo Neira Ayuso et fusionnée à partir de Linux 4.16).

Architecture Ingress Fastpath de Netfilter Flowtable

Netfilter Flowtable est un mécanisme de mise en cache de raccourcis réseau directement au sein du noyau pour les flux bidirectionnels établis. Au lieu d'imposer à chaque paquet le long cheminement Netfilter, Flowtable enregistre la session dès la fin de la phase d'initialisation (ct state established) et installe un raccourci direct au niveau du hook de réception (ingress hook) du pilote réseau.

                      [ Paquet entrant sur la carte NIC ]
                                      |
                                      v
                        +---------------------------+
                        |   Flowtable Ingress Hook  |
                        +---------------------------+
                                     / \
                     Flux trouvé ?  /   \   Nouveau flux ?
                                   /     \
                                 OUI     NON
                                 /         \
                                v           v
          +-----------------------+     +-------------------------------+
          | Transfert Fastpath :  |     | Chemin Netfilter classique :  |
          | - Mise à jour TCP     |     | - PREROUTING                  |
          | - Application NAT     |     | - Analyse conntrack           |
          | - Décrément TTL / MAC |     | - Décision fib_lookup         |
          | - Envoi direct au TX  |     | - FORWARD et POSTROUTING      |
          +-----------------------+     +-------------------------------+
                      |                                |
                      |                    Connexion établie ?
                      |                                |
                      |                                v
                      |                    [ Ajout dans Flowtable ]
                      \                                /
                       \                              /
                        v                            v
                      +--------------------------------+
                      |   dev_queue_xmit (Sortie NIC)  |
                      +--------------------------------+

Fonctionnement interne au sein du noyau

Le code moteur se trouve dans le fichier net/netfilter/nf_flow_table_core.c. Lorsqu'un paquet arrive sur une interface associée à une Flowtable :

  1. Interception à l'Ingress : La fonction nf_flow_offload_ip_hook() traite le paquet brut au stade NF_INET_INGRESS, avant même ip_rcv() et la chaîne PREROUTING.
  2. Recherche sans verrou du 5-uplet : Une table de hachage protégée par le mécanisme RCU (Read-Copy-Update) sans verrou compare le 5-uplet : IP source, IP destination, port source, port destination et protocole de transport de niveau 4.
  3. Exécution du transfert accéléré :
    • Décrémentation TTL : La durée de vie (TTL) est décrémentée et la somme de contrôle IP recalculée.
    • Transformation NAT directe : Si la connexion utilise du SNAT ou DNAT, Flowtable réécrit immédiatement les adresses et ports dans l'en-tête du paquet.
    • Mise à jour de l'en-tête Ethernet : L'adresse MAC de destination du saut suivant (mise en mémoire lors de la résolution préalable) est inscrite dans la trame sans interrogation ARP.
    • Remise directe au pilote : Le paquet évite le sous-système de routage classique (ip_forward) et est transmis directement à la file d'émission de l'interface de sortie via dev_queue_xmit().

Lorsqu'un paquet présente un drapeau TCP FIN ou RST, ou en cas d'inactivité prolongée, l'entrée est retirée de la Flowtable. Les paquets suivants repassent normalement par le chemin standard de Netfilter, préservant la cohérence de fin de session.

Fastpath logiciel face au déchargement matériel SmartNIC

Le sous-système Flowtable propose deux degrés d'accélération selon le matériel hôte :

Critère Routage Linux conventionnel Fastpath logiciel Flowtable Déchargement matériel SmartNIC
Point d'ancrage Multiples hooks (Pre/Fwd/Post) NF_INET_INGRESS (Noyau) ASIC / TCAM sur la carte réseau
Traitement conntrack Chaque paquet Uniquement à l'initialisation Uniquement à l'initialisation
Consommation CPU Élevée (Cœurs saturés) Faible (Évite la pile IP) 0 % CPU sur les flux actifs
Latence de transfert 15 – 35 µs 4 – 8 µs < 1,5 µs
Débit en PPS par cœur 1,5 – 3,2 Mpps / cœur 6,5 – 12,0 Mpps / cœur Vitesse de ligne (100 Gbps+)
Prérequis matériel Toute carte réseau Ethernet Toute carte réseau Ethernet Carte supportant TC offload (Mellanox, E810)

Déchargement matériel sur SmartNIC

Sur les serveurs équipés de contrôleurs réseau avancés prenant en charge l'accélération matérielle (comme les cartes NVIDIA Mellanox ConnectX-5, ConnectX-6 Dx ou Intel E810), le noyau Linux peut programmer les entrées de la Flowtable directement dans les tables TCAM physiques de la carte.

En activant la directive flags { offload; } dans nftables, le noyau transmet les règles de flux et de réécriture NAT au composant matériel via l'interface switchdev. Dès lors, les paquets sont acheminés, modifiés et émis directement par le silicium de la carte réseau, sans aucune sollicitation des cœurs processeurs de la machine hôte.

Impact de Flowtable sur les passerelles VPN

Dans une architecture de passerelle VPN mutualisée, le trafic se partage en deux flux distincts :

  1. Trafic externe encapsulé UDP : Datagrammes arrivant par Internet à destination du module de chiffrement (wg0, riceguard0, tun0).
  2. Trafic interne déchiffré : Paquets en clair redistribués entre sous-réseaux, tables de routage virtuelles (VRF) ou liaison montante vers Internet via NAT.

L'apport de Flowtable sur ce chemin interne est considérable :

1. Préservation des cœurs pour RiceGuard

Dans les passerelles déployant RiceGuard avec des dizaines de milliers de tunnels actifs, la réduction de 60 % des instructions de filtrage par paquet libère la puissance processeur au profit des algorithmes cryptographiques ChaCha20-Poly1305. Cela permet d'absorber les pics de trafic sans perte de paquets.

2. Réduction du jitter pour la voix et les jeux

Les flux interactifs tels que la VoIP (SIP/RTP) et les jeux réseau emploient des ports UDP constants. Avec Flowtable, 99,8 % des paquets empruntent la voie rapide. Le temps de traversée du noyau passe de 25 microsecondes à moins de 5 microsecondes, évitant tout désordre de paquets entre cœurs.

3. Synergie avec la gestion de qualité de service (QoS)

Lorsqu'un paquet quitte la voie rapide via dev_queue_xmit(), il rejoint la discipline de file d'attente (qdisc) de l'interface de sortie. Les administrateurs peuvent associer Flowtable à FQ-CoDel ou CAKE pour éliminer le bufferbloat tout en exploitant le plein potentiel du matériel.

Exemple de configuration nftables en production

Voici un modèle de configuration opérationnel pour activer Flowtable entre une interface externe reliée à Internet (eth0) et une interface locale ou un tunnel VPN (eth1 / wg0) :

#!/usr/sbin/nft -f

# Nettoyer les règles existantes
flush ruleset

table inet vpn_router {
    # 1. Définition de la Flowtable associée aux interfaces réseau
    flowtable ft_fastpath {
        hook ingress priority filter
        devices = { eth0, eth1 }
        # Pour activer le déchargement matériel sur SmartNIC compatible :
        # flags { offload; }
    }

    # 2. Chaîne de transfert (Forward chain)
    chain forward {
        type filter hook forward priority filter; policy drop;

        # Orienter les flux TCP et UDP établis vers la voie rapide
        meta l4proto { tcp, udp } flow add @ft_fastpath

        # Autoriser le trafic établi et lié sur le chemin standard
        ct state established,related accept

        # Écarter les paquets invalides
        ct state invalid drop

        # Autoriser les nouvelles connexions sortantes du réseau local
        iifname "eth1" oifname "eth0" accept
    }

    # 3. Translation d'adresses source (SNAT / Masquerade)
    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;

        # Masquage sur l'interface WAN externe
        oifname "eth0" masquerade
    }
}

Vérification et surveillance opérationnelle

Une fois la configuration appliquée, suivez l'activité des flux avec les commandes suivantes :

# Lister les flux actifs dans la Flowtable et les compteurs
nft list flowtable inet vpn_router ft_fastpath

# Consulter les statistiques matérielles dans sysfs
cat /sys/kernel/debug/netfilter/nf_flowtable/*

# Comparer les indicateurs conntrack entre voie normale et voie rapide
cat /proc/net/stat/nf_conntrack

Dans la liste renvoyée par nft list flowtable, chaque flux affiche son volume d'octets et de paquets. Si le déchargement matériel est actif, la mention [OFFLOAD] confirme que la carte réseau assure directement la transmission.

Bonnes pratiques de déploiement

  1. Fragmentation IP : Flowtable ne prend pas en charge le réassemblage des paquets IP fragmentés. Les fragments sans en-tête de niveau 4 complet retournent vers le conntrack standard. Veillez à activer le clamping TCP MSS ou la détection PMTUD sur les interfaces de tunnel.
  2. Renouvellement des clés (Re-keying) : Les protocoles comme WireGuard effectuent des échanges de clés réguliers. Ces paquets de contrôle empruntent le chemin de traitement habituel sans perturber les flux de données déjà présents dans la Flowtable.
  3. Adaptabilité virtuelle : Flowtable s'attache sans difficulté aux sous-interfaces VLAN (eth0.100) ou aux agrégations de liens (bond0), offrant une flexibilité idéale pour les infrastructures de centres de données modernes.

En transformant le suivi de flux en une validation unique à la connexion, Netfilter Flowtable permet aux passerelles VPN sous Linux d'offrir des débits maximaux avec une latence remarquablement faible.