Routage de politique IPv6 lorsque deux liaisons montantes partagent fe80::1
Deux liaisons montantes peuvent présenter le même saut suivant fe80::1 sur des liens différents. Choisissez une table par politique, assumez les durées de vie et vérifiez avec une recherche de route.
Vous avez deux liaisons montantes, et ip -6 route show affiche le même saut suivant sur les deux : default via fe80::1 dev uplink0 et default via fe80::1 dev uplink1. Ce n’est pas un conflit d’adresses en double, et copier le saut suivant nu fe80::1 dans une table de politique ne dit pas au noyau quel lien vous visiez. La vraie question est plus étroite que le symptôme ne le suggère : la seconde table a-t-elle besoin d’un lien ou des deux, et qu’est-ce qui garde ces routes vivantes après un redémarrage. Trois conditions, vérifiées dans l’ordre, en règlent l’essentiel.
Le même fe80::1, ce sont deux voisins différents
Les adresses lien-local sont limitées à un seul lien, donc fe80::1 n’est pas une adresse imprimée deux fois ; ce sont deux voisins qui partagent un suffixe par hasard. L’index de zone est la façon dont un hôte dit lequel il vise, donc fe80::1%uplink0 et fe80::1%uplink1 sont des destinations différentes pour le noyau, et ce suffixe ne voyage jamais jusqu’à un routeur distant. RFC 4007 décrit le modèle de zones qui sous-tend cela, et c’est pourquoi une table de politique doit porter un périphérique avec chaque saut suivant lien-local.
Un générateur de configuration VPN qui copie un ID de zone numérique d’un hôte dans un modèle traite le contexte local comme s’il faisait partie de l’adresse, et le fichier qu’il écrit est faux sur toute machine dont les noms ou les index d’interface diffèrent. Une table de politique ne fusionne pas non plus deux liens en un : un VPN routé fait passer des paquets entre réseaux, mais il ne transporte pas l’identité lien-local d’un voisin Ethernet distant à travers le tunnel, donc le trafic lien-local reste sur son propre lien.
Retirez le périphérique et la route devient non inscriptible. ip -6 route add default via fe80::1 table 200 ne peut pas résoudre la passerelle, et iproute2 la rejette avec Error: Nexthop has invalid gateway. Ajoutez dev uplink0 et la commande réussit, car c’est le périphérique qui épingle le saut suivant sur l’un de ces deux voisins. Ce que le périphérique ne peut pas vous dire, c’est si uplink0 est le bon lien pour cette table, et une route copiée depuis un autre hôte apporte les noms d’interface de cet hôte, et c’est de là que viennent les vraies erreurs.
Condition un : un lien ou deux dans la table
Commencez par à quoi sert la seconde liaison montante. Si les deux liens portent le même trafic et que l’un est en secours, la table alternative devrait contenir les deux passerelles avec des métriques distinctes : mêmes destinations, un chemin préféré, un second choix évident. Si les liaisons existent parce que des trafics différents doivent sortir par des fournisseurs différents, ou parce qu’il s’agit d’un tunnel divisé où une partie du trafic contourne le VPN tandis que le reste reste à l’intérieur, les deux liens n’appartiennent pas du tout à une seule table. Ils appartiennent à deux tables, choisies par une règle, et la règle choisit la table, pas le tunnel : le trafic qui contourne est marqué avant d’être routé, et la marque est ce qui l’envoie vers la seconde table.
Dans ce second cas, la règle décide quand une table est consultée, et la route décide où va le paquet ensuite :
ip -6 rule add fwmark 0x2 table 201
ip -6 route add default via fe80::1 dev uplink1 metric 100 table 201
ip -6 route add 2001:db8:100::/48 dev uplink1 metric 100 table 201
ip -6 route show table 201Aucun des deux objets ne remplace l’autre, et une table qui ne contient qu’une route par défaut peut encore échouer à résoudre sa passerelle. Si un ajout est rejeté, ou si la route est présente mais inutilisable, placez le préfixe connecté de cette interface dans la même table, ou marquez le saut onlink lorsque ce préfixe est routé ailleurs. Dans le bloc ci-dessus, 2001:db8:100::/48 représente justement ce préfixe connecté sur uplink1, pas une destination arbitraire. La règle fwmark ne consomme qu’une marque que quelque chose d’autre doit poser, depuis une règle nftables ou iptables sur le chemin de transfert ou depuis SO_MARK sur la socket, donc un bloc copié sans source de marque ne correspond à rien.
Condition deux : les métriques ne détectent pas un fournisseur mort
Une métrique est une préférence entre des routes qui existent, pas un contrôle de santé. Quand le porteur tombe, le noyau retire les routes sur ce périphérique et la seconde route par défaut prend le relais. Quand le câble reste connecté et que le fournisseur derrière meurt, rien ne change dans la table : la route préférée est installée, le voisin est joignable en couche 2, et les paquets partent dans un trou noir. Si cette distinction compte pour votre installation, le basculement doit venir de quelque chose qui sonde le chemin et retire la route, que ce soit un démon de routage ou un petit script qui supprime et réinstalle l’entrée.
Vérifiez le choix une fois la table construite, et vérifiez-le comme le noyau le verra. ip -6 route get 2001:db8:100::1 imprime la route qui serait utilisée, y compris le périphérique et l’adresse source sélectionnée, et il respecte les règles de politique. Une adresse source appartenant à la mauvaise liaison montante est le signe habituel qu’une règle a correspondu plus tôt que prévu.
Condition trois : décidez qui possède la persistance
Une route ajoutée avec ip -6 route add survit jusqu’à un redémarrage ou jusqu’à ce que quelque chose la purge. Une route par défaut apprise des annonces de routeur porte une durée de vie et peut être retirée par le routeur, tandis qu’une route par défaut ajoutée à la main n’expire jamais d’elle-même. Mélanger les deux dans une table, c’est ainsi qu’une route permanente obsolète finit par supplanter une route fraîchement annoncée, longtemps après que la liaison qu’elle décrivait a cessé d’exister.
Choisissez un propriétaire par table. Si un gestionnaire de réseau ou un démon de routage gère déjà l’interface, décrivez-y la route de politique et laissez le noyau tranquille. Si vous le scriptez, rendez le script idempotent et écrivez le démontage en même temps, car vous en aurez besoin lors du premier mauvais changement :
ip -6 route flush table 201
ip -6 rule del fwmark 0x2 table 201Sur un routeur qui transfère pour d’autres hôtes, vérifiez net.ipv6.conf.all.forwarding avant de blâmer la table. Transfert désactivé, les paquets adressés à un autre réseau sont abandonnés, aussi correcte que soit la table 201.
Consignez la conception pour que la personne suivante puisse l’auditer
Un inventaire qui ne stocke que fe80::1 jette les champs qui comptent. Consignez la destination, le saut suivant, le périphérique, la table et la métrique ensemble, plus l’origine de chaque route — annoncée, générée par le gestionnaire ou statique. Quand quelqu’un demandera plus tard si la seconde liaison montante porte réellement du trafic, cet enregistrement répondra sans conjectures.
Avant de déclarer la table terminée, confirmez le voisin avec ip -6 neigh show dev uplink0, relisez ip -6 rule show pour les accidents d’ordre, et testez avec un trafic qui correspond à la règle plutôt qu’avec un ping qui prend la route par défaut. Puis coupez volontairement une liaison montante et observez vers quelle route le noyau se replie ; la réponse devrait correspondre à celle que vous avez notée.