← Tous les articles

La vérité saut par saut

Votre outil de chemin dessine un couloir. Les routeurs acheminent saut par saut. Voici la mesure de l'écart sur 4 032 paires.

Michel Wijnberg

Presque tous les outils de chemin réseau que j’ai utilisés (y compris le mien, jusqu’à récemment) fonctionnent ainsi :

  1. Prendre le routeur source.
  2. Faire tourner Dijkstra sur la topologie.
  3. Dessiner le plus court chemin obtenu.

C’est un couloir enraciné à la source, et c’est un modèle subtilement faux de l’acheminement IP. L’acheminement réel n’a pas de couloir. Chaque routeur compare indépendamment l’adresse de destination à sa propre table de routage et choisit un saut suivant. Les deux réponses ne coïncident que tant que la règle de décision et le jeu d’entrées de chaque routeur intermédiaire correspondent à ceux de la source.

En OSPF, ce n’est régulièrement pas le cas.


Un paquet qui n’arrive jamais

Voici un cas de mon laboratoire, mesuré sur chaque routeur concerné avec show ip route, non pas modélisé mais relevé sur les équipements :

RouteurDit de la destinationAchemine vers
dfw1-gw2metric 20031, type inter areadfw1-cr1
dfw1-cr1metric 30001, type intra areaord1-cr1pas dfw2-cr1
ord1-cr1metric 20001, type intra areajfk1-cr1
jfk1-cr1metric 10001, type intra arealhr1-cr1
lhr1-cr1metric 1, connectedlivré

Le couloir enraciné à la source dessinait ceci :

dfw1-gw2 → dfw1-cr1 → dfw2-cr1 → iad2-cr1 → ams1-cr1 → lhr1-cr1

Le paquet n’atteint jamais dfw2-cr1. Le couloir est un chemin moins cher. Ce n’est simplement pas un chemin qu’un routeur construira. Deux règles indépendantes de la RFC 2328 font que dfw1-cr1 le refuse :

§16 étape (3) / §16.2 ¶1 : la porte du backbone. Un routeur rattaché à plusieurs areas n’examine que les summary-LSA du backbone. Le summary moins cher de dfw2-cr1 à 20011 est bel et bien dans la base de l’area 4.6.23.0 de dfw1-cr1 (je l’ai confirmé avec show ip ospf database summary), mais il n’est pas candidat, parce que dfw1-cr1 est un ABR et que ce summary n’est pas arrivé par l’area 0. La RFC 3509 §2.1/§2.2 (le comportement ABR de Cisco qui tourne réellement sur ces équipements) conditionne cela à une connexion backbone active, que dfw1-cr1 possède.

§16.2 étape (6) : intra bat inter, point final. “If the paths present in the table are intra-area paths, do nothing with the LSA (intra-area paths are always preferred).” dfw1-cr1 détient déjà un chemin intra-area à la métrique 30001. Le summary à 20011 perd face à lui. La métrique n’y est pour rien : c’est une règle sur le type de chemin, et aucune comparaison de coût n’a lieu.

Chacune des deux règles à elle seule tue le couloir. Un outil qui fait tourner un seul SPF depuis la source ne peut voir ni l’une ni l’autre, parce qu’il ne demande jamais à dfw1-cr1 ce que dfw1-cr1 en pense.


À quelle fréquence cela compte-t-il vraiment ?

C’est la partie qui m’intéresse, parce que « votre modèle est théoriquement imprécis » est une affirmation bien plus faible qu’un nombre.

J’ai donc relevé la table de routage OSPF complète des 64 routeurs de l’AS 200 et comparé chacune des 4 032 paires source/destination ordonnées :

MesureRésultat
Paires inter-area où le couloir dessinait ≥1 saut qu’aucun routeur ne prendrait360 sur 2 839 (12,68 %)
Paires intra-area avec le même défaut0 sur 1 193
Total360 sur 4 032 (8,93 %)

Le zéro en intra-area est le contrôle de cohérence. À l’intérieur d’une seule area, chaque routeur fait tourner SPF sur une LSDB identique, et un plus court chemin reste le plus court depuis n’importe quel point de celui-ci : les deux modèles ont donc toutes les raisons de coïncider. Ce qui compte, c’est que la coïncidence a été mesurée et non supposée : 1 193 paires, aucun désaccord. Dès qu’un ABR et un summary-LSA entrent en scène, un chemin sur huit est de la fiction.

Pas « légèrement sous-optimal ». De la fiction, contenant un routeur que le paquet ne visite manifestement jamais. Si vous vous servez de ce chemin pour planifier une fenêtre de maintenance ou expliquer un incident, vous raisonnez sur une route qui n’existe pas.


Le correctif : demander à chaque routeur

Osprey parcourt désormais la chaîne. À chaque saut, il évalue la route propre de ce routeur vers l’adresse de destination, en utilisant sa propre LSDB, ses propres appartenances d’area, son propre statut d’ABR et son propre mélange de distances administratives, puis suit le saut suivant qu’il sélectionne réellement, et recommence.

Validé face aux mêmes 4 032 paires :

ContrôleRésultat
Métrique propre du routeur reproduite exactement4 032 / 4 032
Type de chemin (intra / inter / externe) exact4 032 / 4 032
Ensemble complet des sauts suivants ECMP installés identique4 032 / 4 032
La chaîne se termine par delivered à la destination demandée4 032 / 4 032

Pas « proche ». Identique, sur chaque paire, y compris l’ensemble complet des sauts suivants à coût égal plutôt qu’un membre choisi arbitrairement.

Voici à quoi cela ressemble sur le canvas : aller en orange, retour en bleu, tout ce qui n’est pas sur le chemin atténué en couloir :

Un chemin OSPF tracé sur la topologie avec les couches aller et retour et quatre chemins à coût égal
Un chemin OSPF tracé sur la topologie avec les couches aller et retour et quatre chemins à coût égal

Notez le sélecteur 4 equal-cost paths et l’étiquette per-flow hash. Osprey énumère l’ensemble ECMP complet plutôt que de prendre un membre et de le présenter comme le chemin, parce que votre trafic est réparti par hachage sur les quatre, et qu’une session de dépannage qui n’en examine qu’un ne trouvera rien trois fois sur quatre.

Et voici le même chemin, déplié :

Un chemin OSPF de 10 sauts avec tableau par saut, badges ABR, ports d'entrée et de sortie et explication numérotée
Un chemin OSPF de 10 sauts avec tableau par saut, badges ABR, ports d'entrée et de sortie et explication numérotée

Chaque saut porte le routeur qui a pris la décision, l’area dans laquelle il l’a prise, les interfaces physiques d’entrée et de sortie avec leurs adresses, et le coût. Les badges ABR sont dérivés des LSDB, pas des noms d’hôte. Le ruban d’areas en dessous montre le chemin traversant 12.1.24.00.0.0.06.18.1.0, c’est-à-dire le transit par le backbone que la RFC 2328 exige pour le trafic inter-area.

Et le coût total affiché, 30061, est la métrique installée par la source elle-même. C’est littéralement le nombre que show ip route imprime sur lax1-gw1, coût du stub compris, et non une somme qu’Osprey aurait calculée en additionnant les liens qui lui plaisaient.

L’explication est générée, pas décorative :

  1. Route type: O IA (inter-area): Source 172.16.2.33 and destination 172.16.5.23 have no shared area, routing via backbone (area 0.0.0.0)
  2. Path traverses: area 12.1.24.0 (cost 10) → area 0.0.0.0 (cost 30040) → area 6.18.1.0 (cost 10)
  3. Total cost: 30061 via 10 hops
  4. ECMP: 4 equal-cost paths available

Au-delà de la frontière d’AS

À l’intérieur d’un IGP la chaîne est calculable parce que la LSDB est complète. Au-delà d’une frontière d’AS, rien ne l’est. Il n’y a ni base commune, ni espace de métriques commun, ni politique de distance administrative commune.

La réponse honnête n’est pas d’abandonner, et certainement pas de prétendre que les métriques se composent. C’est d’assembler des preuves.

Un chemin de 15 sauts passant de l'AS 200 à l'AS 300, avec coûts par segment et une transition eBGP
Un chemin de 15 sauts passant de l'AS 200 à l'AS 300, avec coûts par segment et une transition eBGP

Quinze sauts de lax1-gw1 dans l’AS 200 (locataire Harrier-Broadband, OSPF) à i-sin1-gw1 dans l’AS 300 (locataire Merlin-Carrier, IS-IS). Lisez ce qu’il fait :

  • Saut 8 jfk1-gw1 porte un badge BGP : c’est là que l’IGP s’arrête et que la décision BGP prend le relais.
  • Saut 9 i-jfk1-gw1 porte un badge IS-IS : un protocole complètement différent, un autre plan d’adressage, un autre locataire.
  • Le pied de page dit “Per-segment costs (never summed) | 15 hops”. Un coût OSPF de 20051 et un coût IS-IS de 1320 sont des nombres dans des espaces de métriques sans rapport. Les additionner produirait 21371, qui n’est pas une quantité existante. Osprey refuse de l’imprimer.

L’explication générée nomme ses preuves à chaque étape :

  1. BGP border selection: jfk1-gw1 holds 10.66.0.0/15 for 10.66.15.3 (AS path: 300)
  2. AS 200: IGP segment: lax1-gw1jfk1-gw1, cost 20051
  3. eBGP transition 200 → 300: jfk1-gw1 Et1/1 → i-jfk1-gw1 Et1/2 (bmp-peer+l2; ip-bound)
  4. AS 300: IGP segment: i-jfk1-gw1i-sin1-gw1, cost 1320

L’étape 3 est ma ligne préférée du produit. Elle ne dit pas « ces deux routeurs sont probablement reliés d’une manière ou d’une autre ». Elle nomme les ports physiques des deux côtés, puis elle montre son travail entre parenthèses :

  • bmp-peer : une session eBGP établie entre eux, vue via BMP
  • +l2 : le côté distant a été apparié via l’adjacence LLDP/CDP des routeurs de bordure
  • ip-bound : les deux adresses de session se résolvent sur ces ports précis via les liaisons IP-MIB des équipements

Trois preuves indépendantes qui concordent. Quand elles ne concordent pas, le produit le dit à la place, et c’est tout le sujet du billet suivant.


Pourquoi cela me tient plus à cœur que les fonctionnalités

Un tracé de chemin est une affirmation sur ce que votre réseau fera d’un paquet. Si l’affirmation est fausse une fois sur huit et que rien à l’écran ne distingue les fausses des vraies, le tracé est pire qu’inutile. Il est confiant et inutile, et on le croira exactement au moment où se tromper coûte cher.

Passer de « plausible » à « reproduit exactement les 64 tables de routage, 4 032 sur 4 032 » a demandé un banc de validation, un laboratoire dont je peux lire la vérité de terrain, et la volonté de découvrir que mon propre outil avait dessiné de la fiction 360 fois.

C’est à cela que sert le laboratoire.


Ensuite, l’autre face de la même pièce : les endroits où Osprey ne peut pas calculer la réponse, et le dit : Ce qu’Osprey refuse de deviner.