FPAC 4.2 : étude des routes ROSE échangées dans les deux sens
Étude du 02/11/2026. Le code est écrit et publié dans le dépôt, rien n'est encore installé sur les nœuds : les essais diront si les choix tiennent. Voir aussi la spécification des routes dynamiques.
1. Objectif
Faciliter l'installation d'un nouveau nœud FPAC avec le minimum de
configuration, en évitant le plus possible les routes fixes dans
fpac.routes.
Dans un réseau maillé, cela demande que chaque voisin annonce ce qu'il sait joindre et apprenne ce que les autres savent joindre : les routes circulent dans les deux sens.
Aujourd'hui, seul f6bvp-8 annonce ; les sept autres nœuds apprennent seulement.
2. Ce qui existe déjà dans fpacrtd
En relisant le code (route/fpacrtd.c, 4c32d18),
l'échange dans les deux sens est déjà prévu par le protocole :
- chaque nœud garde, pour chaque destination, le coût annoncé par
CHACUN de ses voisins (
cost[voisin]), pas seulement le meilleur ; - il installe le meilleur voisin ouvert, et se rabat seul sur un autre si le meilleur disparaît ;
- il relaie ce qu'il a appris, au coût reçu plus 1 ;
- horizon coupé : une destination n'est jamais annoncée au voisin par lequel le nœud la joint ;
- retrait (
W) envoyé environ 10 s après une perte ; - plafond de 6 sauts ;
- vieillissement : 3 tables complètes sans la route, ou 90 minutes sans table, et la route est retirée.
Passer « dans les deux sens » est donc d'abord un RÉGLAGE : mettre
RouteAnnounce = yes et RouteLearn = all sur
chaque nœud qui participe. C'est l'étape 2 du plan d'essai de la
spécification, jamais activée.
Ce qui manque, ce sont des protections adaptées à un réseau maillé (section 4) et une façon d'annoncer les nœuds qui ne font pas tourner fpacrtd (section 5.2).
3. Notre réseau est maillé
Voisins ROSE déclarés dans fpac.nodes, relevés le
02/11/2026 :
| Nœud | Ses voisins (indicatif L3) |
|---|---|
| f6bvp-8 | 16 voisins, dont tous les nôtres et l'étranger |
| f6bvp-12 | F6BVP-7, F6BVP-11, F6BVP-9, F4KLO-9 |
| f6bvp-6 | F6BVP-9, -11, -13, F3KT-11, F4KLO-9 |
| f6bvp-10 | F6BVP-7, -9, -13, F6KKR-9, F4KLO-9, F6CNB-11, |
| F5ZHO-9 | |
| F4KLO | F6BVP-7, -9, -11, -13, F6CNB-11, F6KKR-9 |
| F6CNB | F6BVP-9, -11, F5KTR-11, F3KT-11, F6KKR-9, F4KLO-9 |
| F6KKR | F6CNB-11, F6BVP-9, F6BVP-11, F3KT-11, SV2HRT-9 |
| F3KT | F6BVP-9, F6BVP-11, F6CNB-11, F5ZHO-9, |
| et ses nœuds F3KT-5, -9, -13 |
Il y a des triangles partout : f6bvp-8 / f6bvp-12 / f6bvp-10, f6bvp-8 / F6CNB / F6KKR, f6bvp-8 / F3KT / F6CNB, etc.
C'est exactement le cas où l'horizon coupé ne suffit plus.
4. Le risque : des boucles passagères à trois nœuds
4.1 Le scénario
Prenons le DNIC 5050 (VK7HDM), dont f6bvp-8 est la sortie, et le triangle f6bvp-8 / f6bvp-12 / f6bvp-10, tous dans les deux sens.
En régime normal :
- f6bvp-12 joint 5050 par f6bvp-8 (coût 1) ; il connaît aussi le chemin par f6bvp-10 (coût 2) ;
- f6bvp-10 de même : par f6bvp-8 (1), ou par f6bvp-12 (2).
Le lien vers l'Australie tombe ; f6bvp-8 envoie W 5050 à
tous :
- f6bvp-12 reçoit le
Wle premier et se rabat sur son second choix : f6bvp-10, coût 2. Mais f6bvp-10 n'a pas encore reçu leW, et son chemin passe... par f6bvp-8. - f6bvp-10 reçoit à son tour le
Wet se rabat sur f6bvp-12, coût 2, qui passe maintenant par f6bvp-10. - f6bvp-12 et f6bvp-10 se désignent l'un l'autre : c'est une boucle. Elle se défait en se renvoyant des coûts croissants (3, 4, 5, 6), une dizaine de secondes par tour, jusqu'au plafond de 6 : de 30 secondes à une minute environ.
4.2 Pourquoi c'est grave en ROSE
Un appel lancé pendant ce temps vers 5050 part dans la boucle. À ma
connaissance, rien dans un CALL REQUEST ROSE ne compte les sauts :
chaque passage crée un circuit de transit de plus. C'est le mécanisme
des tempêtes déjà vues sur le réseau (contrôle des boucles par
rose-controle).
Le plafond de 6 limite la durée de la boucle, pas son existence.
4.3 Les autres cas
Le même enchaînement vaut pour toute destination apprise (adresse de nœud ou DNIC) dès que trois nœuds qui annoncent sont reliés en triangle. Il se produit à chaque perte : coupure d'un lien, arrêt d'un fpacrtd, redémarrage de nuit d'un nœud.
5. Propositions
5.1 Une « condition de faisabilité » contre les boucles
C'est la protection des protocoles modernes à vecteur de distances (EIGRP, Babel), sans changer le protocole entre nœuds.
Règle : pour chaque destination, le nœud retient la meilleure distance qu'il a eue (distance de référence). Il n'accepte un voisin que si le coût ANNONCÉ par ce voisin (avant le +1) est strictement inférieur à cette distance de référence.
Sur le scénario 4.1 :
- la distance de référence de f6bvp-12 vers 5050 est 1 ;
- f6bvp-10 annonce 5050 au coût 1 (son chemin par f6bvp-8) ;
- 1 n'est pas inférieur à 1 : f6bvp-12 refuse ce second choix, retire
5050 et envoie son propre
W. Même chose de l'autre côté. - Plus de boucle : la route disparaît proprement en quelques secondes.
Un vrai chemin de secours reste accepté : un voisin qui annonce un coût plus petit que notre distance de référence ne peut pas passer par nous.
La distance de référence est remise à zéro quand la destination n'a
plus aucune route depuis 2 minutes (le temps que les W
aient fait le tour). La route peut alors revenir par n'importe quel
voisin.
Coût : une quarantaine de lignes dans fpacrtd.c, aucun
changement du protocole. Un nœud non mis à jour reste compatible, mais
n'est pas protégé : la règle doit être en service sur tous les nœuds qui
annoncent AVANT de passer dans les deux sens.
5.2 Annoncer les voisins directs (origine par voisinage)
Aujourd'hui, un nœud n'est l'origine que de ses propres adresses
(coût 0) et des DNIC de RouteOrigin. Une route de
fpac.routes n'est jamais annoncée par elle-même.
Conséquence : un nœud qui ne fait pas tourner fpacrtd (F5ZHO, VK7HDM, les nœuds étrangers) n'est connu des autres que par une route fixe ou par les White Pages.
Proposition : un nœud annonce aussi, au coût 1, l'adresse d'un voisin direct, à trois conditions vérifiées ensemble :
- ce voisin est déclaré dans un bloc
Nodedefpac.nodes, avec son adresse complète (masque 10) ; - le nœud a une route vers cette adresse par ce voisin dans le noyau ;
- le lien vers ce voisin est ouvert (
rose_neigh).
Exemple réel : F3KT a 817501 = ZHO dans
fpac.routes, F5ZHO-9 dans fpac.nodes, et le
lien est ouvert. F3KT annoncerait 2080817501 au coût 1, et
f6bvp-8 joindrait F5ZHO-8 sans route fixe.
À noter : f6bvp-10 déclare aussi F5ZHO-9 dans son
fpac.nodes, mais n'a ni route ni lien vers lui. La
condition 2 l'empêche d'annoncer F5ZHO-8 : c'est voulu.
Un voisin qui fait tourner fpacrtd s'annonce lui-même au coût 0 ; son annonce l'emporte sur celle du voisinage (coût 1).
C'est un changement de principe de la spécification (« une route de
fpac.routes ne donne jamais lieu à une annonce »), mais
limité aux voisins directs dont le lien est vérifié ouvert. À
décider.
5.3 Le réglage dans les deux sens
Sur chaque nœud qui participe :
RouteAnnounce = yes
RouteLearn = all
RouteOrigin reste réservé au nœud qui a le lien réel
vers un pays (aujourd'hui f6bvp-8).
Avec 5.1 et 5.2, un nœud feuille apprend les adresses précises de
tous les nœuds. Ses routes larges du type 2080 = F6BVP-9 ne
servent plus qu'en dernier recours, et peuvent disparaître peu à peu de
fpac.routes.
5.4 Moins de configuration pour un nouveau nœud
Ce qu'un nouveau nœud doit écrire aujourd'hui, et ce qui resterait :
| Fichier | Aujourd'hui | Visé |
|---|---|---|
| fpac.conf | indicatifs, adresse | idem |
| fpac.nodes | ses voisins | idem |
| fpac.routes | toutes ses routes | presque vide |
| Route = yes | des deux côtés | des deux côtés (1) |
| chez voisins | bloc Node + routes | bloc Node seulement |
Route = yesreste nécessaire tant qu'un nœud sans fpacrtd prend un appel versFPACRTpour un appel d'utilisateur (spécification, section 3). Piste pour plus tard : quefpadrefuse poliment un appel versFPACRTquand fpacrtd ne tourne pas.Route = yespourrait alors devenir automatique entre nœuds récents. Pas pour la première étape.
5.5 Ce que devient RouteWp
Dans les deux sens, tous les voisins qui participent deviennent des «
apprenants » : la règle anti-boucle de RouteWp ignorerait presque toutes
les fiches qu'ils relaient (sauf les blocs d'adresses propres à un
voisin, in_neigh_block()).
Avec 5.2, les nœuds sans fpacrtd sont annoncés par leurs voisins directs : RouteWp ne sert plus qu'en dernier recours.
Proposition : garder RouteWp seulement sur f6bvp-8 pendant les essais, puis décider s'il faut le garder.
6. Ce qui ne change pas
fpac.routesgarde toujours le dernier mot.- Le protocole entre nœuds reste en version 1 : 5.1 et 5.2 sont des règles locales à chaque nœud.
- Le noyau et les White Pages ne sont pas touchés.
- Un nœud sans les nouveaux réglages se comporte comme aujourd'hui.
7. Plan d'essai proposé
- Coder 5.1 (et 5.2 si accepté). Avant tout déploiement, vérifier sur une simulation de notre topologie réelle (section 3) que la perte d'un lien ne crée aucune boucle, avec et sans 5.1.
- Installer le nouveau fpacrtd sur les 8 nœuds, réglages inchangés : aucun effet attendu.
- Paire f6bvp-8 / f6bvp-12 dans les deux sens : f6bvp-12 annonce, f6bvp-8 apprend. f6bvp-8 doit apprendre l'adresse de f6bvp-12.
- Triangle f6bvp-8 / f6bvp-12 / f6bvp-10 dans les deux sens. Essai de
perte provoquée : arrêter fpacrtd sur f6bvp-8 ; vérifier que les routes
disparaissent chez les deux autres sans boucle
(
rose-controle, journaux), puis reviennent. - Tous nos nœuds dans les deux sens, F3KT compris avec 5.2 : f6bvp-8 doit joindre F5ZHO-8 sans route fixe.
- Une semaine d'observation, puis retrait progressif des routes fixes devenues inutiles, nœud par nœud, avec l'accord de chaque sysop.
8. Questions à trancher
- Coder la condition de faisabilité (5.1) avant toute activation dans les deux sens ? (recommandé : oui, c'est la protection indispensable dans un réseau maillé)
- Accepter l'annonce des voisins directs (5.2), qui règle F5ZHO-8 et les nœuds sans fpacrtd ?
- Faire la simulation de l'étape 0 avant les essais réels ?
- RouteWp : le garder sur f6bvp-8 seulement pendant les essais ?
- Le refus poli de
FPACRTparfpad(5.4) : pour une version suivante ?
9. Décisions et résultats (02/11/2026, suite)
Décisions de Bernard : suivre les recommandations, y compris l'assouplissement 5.2 (annonce des voisins directs). Les essais valideront ou non.
9.1 Simulation (étape 0)
Programme de simulation en Python : un modèle des règles de fpacrtd sur nos 8 nœuds et les liens déclarés des deux côtés. Cinq pannes, 100 tirages de latences.
| Protection | Boucles après une panne |
|---|---|
| aucune (code actuel) | de 1,5 à 10 minutes |
| aucune + correctif (b) | environ 55 s |
| « inférieur ou égal » | environ 12 s |
| stricte, oubli 5 à 10 s | jusqu'à 44 s |
| stricte, oubli ≥ 20 s | aucune |
Deux découvertes :
- La version « inférieur ou égal » ne suffit pas : retenue, la version stricte.
- Défaut du code actuel : quand le coût change par le voisin déjà choisi, rien ne part avant la table complète suivante (30 min). Dans les deux sens, c'est ce qui faisait durer les boucles. Corrigé.
Prix de la version stricte : quand un vrai chemin de secours existe au même coût, le nœud attend la fin de l'oubli avant de le prendre. Retenu : oubli de 60 s (trois fois le seuil de 20 s), soit environ une minute de coupure dans ces cas-là.
9.2 Code (commit c375006 sur fpac-4.2, poussé le 02/11, non installé)
- condition de faisabilité stricte, oubli 60 s contrôlé toutes les 5 s ;
- correctif (b) ;
- annonce des voisins directs, derrière un mot-clé
RouteNeighbours = yes, inactif par défaut, pour que l'étape 1 du plan (installer sur les 8 nœuds) reste sans effet ; - en contrepartie de 5.2 : un nœud n'installe jamais de route apprise vers l'adresse d'un de ses propres voisins directs tant que ce lien est ouvert (sinon f6bvp-10, par exemple, aurait joint F6CNB par f6bvp-8 au lieu du lien direct).
Spécification : nouvelle section 20 (anglais et français).