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 :
- Prendre le routeur source.
- Faire tourner Dijkstra sur la topologie.
- 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 :
| Routeur | Dit de la destination | Achemine vers |
|---|---|---|
dfw1-gw2 | metric 20031, type inter area | dfw1-cr1 |
dfw1-cr1 | metric 30001, type intra area | ord1-cr1 ← pas dfw2-cr1 |
ord1-cr1 | metric 20001, type intra area | jfk1-cr1 |
jfk1-cr1 | metric 10001, type intra area | lhr1-cr1 |
lhr1-cr1 | metric 1, connected | livré |
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 :
| Mesure | Résultat |
|---|---|
| Paires inter-area où le couloir dessinait ≥1 saut qu’aucun routeur ne prendrait | 360 sur 2 839 (12,68 %) |
| Paires intra-area avec le même défaut | 0 sur 1 193 |
| Total | 360 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ôle | Résultat |
|---|---|
| Métrique propre du routeur reproduite exactement | 4 032 / 4 032 |
| Type de chemin (intra / inter / externe) exact | 4 032 / 4 032 |
| Ensemble complet des sauts suivants ECMP installés identique | 4 032 / 4 032 |
La chaîne se termine par delivered à la destination demandée | 4 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 :
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é :
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.0 → 0.0.0.0 → 6.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 :
- 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)
- Path traverses: area 12.1.24.0 (cost 10) → area 0.0.0.0 (cost 30040) → area 6.18.1.0 (cost 10)
- Total cost: 30061 via 10 hops
- 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.
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-gw1porte un badgeBGP: c’est là que l’IGP s’arrête et que la décision BGP prend le relais. - Saut 9
i-jfk1-gw1porte un badgeIS-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 :
- BGP border selection:
jfk1-gw1holds 10.66.0.0/15 for 10.66.15.3 (AS path: 300)- AS 200: IGP segment:
lax1-gw1→jfk1-gw1, cost 20051- eBGP transition 200 → 300:
jfk1-gw1 Et1/1 → i-jfk1-gw1 Et1/2(bmp-peer+l2; ip-bound)- AS 300: IGP segment:
i-jfk1-gw1→i-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 bordureip-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.