Dataplane
VPP : un graphe de nœuds de paquets
Le Vector Packet Processing achemine des lots de paquets à travers un graphe orienté — et c'est pour cela qu'il est rapide.
Router les paquets vite tient moins d’algorithmes astucieux que du respect de la machine. Les CPU modernes détestent les surprises : un cache d’instructions froid, un branchement imprévisible, un accès mémoire que le préchargeur n’avait pas vu venir — chacun bloque le pipeline pendant des dizaines ou des centaines de cycles. Au débit de ligne 10 GbE, cela fait 14,88 Mpps pour des trames de 64 octets, soit environ 67 nanosecondes par paquet. Vous n’avez pas de cycles à gaspiller en défauts de cache.
VPP (Vector Packet Processing) est le dataplane au cœur de SiHA, et toute sa conception est bâtie autour du fait de garder le CPU heureux. Deux idées font le gros du travail : les vecteurs et le graphe.
Des lots, pas des paquets
Un routeur naïf traite un paquet à la fois : tirer un paquet de la carte réseau, le faire passer par tout le chemin de forwarding — parser l’Ethernet, chercher la route, appliquer les ACL, réécrire les en-têtes, transmettre — puis recommencer. Chaque paquet reparcourt le même code, et chaque paquet paie le coût de ramener ce code dans le cache d’instructions.
VPP inverse cela. Il prend les paquets de DPDK en rafales et les traite comme un vecteur — un lot de jusqu’à 256 paquets qui voyagent ensemble à travers le chemin de forwarding. Au lieu d’exécuter tout le chemin pour un seul paquet, VPP exécute une étape du chemin pour le vecteur entier, puis remet le vecteur à l’étape suivante.
Le graphe
Ce chemin de forwarding est un graphe orienté de nœuds. Chaque nœud est un petit
morceau de code focalisé : ethernet-input parse les en-têtes L2, ip4-lookup
fait la recherche FIB, ip4-rewrite écrit les nouveaux en-têtes, et des nœuds de
fonctionnalité comme acl et nat44 font exactement ce que leur nom indique. Le
voyage d’un paquet est une marche à travers ce graphe, de nœud en nœud, et le
vecteur y circule d’un bloc.
Le nœud est l’unité de travail, et le vecteur est l’unité d’ordonnancement. La boucle interne d’un nœud ressemble à « pour chaque paquet de ce vecteur, fais mon unique tâche ».
Pourquoi les vecteurs sont rapides
C’est l’intuition centrale, et ce n’est pas de la magie — c’est de l’efficacité de cache.
- Cache d’instructions chaud. Le code d’un nœud est chargé dans le cache d’instructions une fois par vecteur, puis exécuté sur les N paquets. La boucle naïve un-paquet-à-la-fois recharge le code de tout le chemin de forwarding pour chaque paquet individuel. Amortir la récupération du code sur un lot est d’où provient l’essentiel du gain.
- Préchargeur efficace. Parce que le nœud sait qu’il a N paquets en file, il peut précharger les données du paquet i+1 pendant qu’il travaille sur le paquet i. La latence mémoire est masquée au lieu de bloquer le cœur.
- Coûts fixes amortis. Le surcoût d’appel de fonction, la mise en place de la boucle, la comptabilité par nœud — tout est divisé sur le vecteur au lieu d’être payé par paquet.
Le plus beau, c’est que cela s’améliore sous la charge. Une interface plus occupée délivre de plus grandes rafales, ce qui signifie de plus grands vecteurs, ce qui signifie un meilleur amortissement. L’efficacité de VPP monte précisément quand vous en avez le plus besoin.
Les plugins sont des nœuds du graphe
Les fonctionnalités dans VPP sont simplement des nœuds que vous insérez dans le
graphe. C’est ce qui en fait une plateforme plutôt qu’un pipeline figé.
dpdk_plugin injecte les paquets depuis la carte réseau ; acl_plugin, nat44 et
vrrp_plugin ajoutent des nœuds de filtrage, de translation et de haute
disponibilité ; linux_cp fait le pont avec le noyau de l’hôte. Activer une fonctionnalité
sur une interface, c’est, mécaniquement, câbler un nœud dans le chemin que ces
paquets empruntent.
Comment SiHA le pilote
VPP tourne entièrement en espace utilisateur en tant que processus unique — aucun module noyau sur le chemin rapide. Sur l’appliance SiHA, il est supervisé comme un enfant du superviseur PID 1, recyclé et contrôlé par la santé comme n’importe quel autre daemon.
Le plan de contrôle de SiHA programme VPP via son API binaire en utilisant
govpp. Chaque fonctionnalité a un fin wrapper Go — interfaces, ACL, NAT, LB — qui
traduit les ressources COSI déclaratives en les appels d’API binaire
correspondants. Ces wrappers sont aussi l’endroit où nous absorbons quelques
bizarreries amont de VPP pour que le reste du plan de contrôle n’ait pas à en avoir
connaissance ; les fichiers de wrapper documentent chaque contournement avec une
note Why:.
La configuration propre du dataplane — le startup.conf de VPP — est possédée
par le plan de contrôle, pas éditée à la main sur la machine. Lorsqu’un opérateur
pousse un DataplaneConfig, SiHA re-génère le fichier et redémarre VPP avec un
apply en deux phases à contrôle de santé : snapshot de la config actuelle comme
dernier état bon connu, écriture de la nouvelle, redémarrage, puis sondage. Si VPP
ne revient pas sain, SiHA restaure la config du dernier état bon connu et refuse de
réessayer la révision défaillante jusqu’à ce que l’opérateur l’édite. Le dataplane
ne se retrouve jamais coincé dans une boucle de crash parce que quelqu’un a fait une
faute de frappe dans une config.
Toute la conception est un pari : que la vitesse de forwarding vient de la discipline de cache, et que la sûreté vient d’un plan de contrôle déclaratif qui traite la config du dataplane comme du code — pas de tours de passe-passe sur le chemin rapide.
Vous voulez voir comment le plan de contrôle et le dataplane s’assemblent de bout en bout ? Lisez la vue d’ensemble de l’architecture.