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 :

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 :

Le lien vers l'Australie tombe ; f6bvp-8 envoie W 5050 à tous :

  1. f6bvp-12 reçoit le W le premier et se rabat sur son second choix : f6bvp-10, coût 2. Mais f6bvp-10 n'a pas encore reçu le W, et son chemin passe... par f6bvp-8.
  2. f6bvp-10 reçoit à son tour le W et se rabat sur f6bvp-12, coût 2, qui passe maintenant par f6bvp-10.
  3. 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 :

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 :

  1. ce voisin est déclaré dans un bloc Node de fpac.nodes, avec son adresse complète (masque 10) ;
  2. le nœud a une route vers cette adresse par ce voisin dans le noyau ;
  3. 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
  1. Route = yes reste nécessaire tant qu'un nœud sans fpacrtd prend un appel vers FPACRT pour un appel d'utilisateur (spécification, section 3). Piste pour plus tard : que fpad refuse poliment un appel vers FPACRT quand fpacrtd ne tourne pas. Route = yes pourrait 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

7. Plan d'essai proposé

  1. 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.
  2. Installer le nouveau fpacrtd sur les 8 nœuds, réglages inchangés : aucun effet attendu.
  3. Paire f6bvp-8 / f6bvp-12 dans les deux sens : f6bvp-12 annonce, f6bvp-8 apprend. f6bvp-8 doit apprendre l'adresse de f6bvp-12.
  4. 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.
  5. Tous nos nœuds dans les deux sens, F3KT compris avec 5.2 : f6bvp-8 doit joindre F5ZHO-8 sans route fixe.
  6. 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

  1. 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é)
  2. Accepter l'annonce des voisins directs (5.2), qui règle F5ZHO-8 et les nœuds sans fpacrtd ?
  3. Faire la simulation de l'étape 0 avant les essais réels ?
  4. RouteWp : le garder sur f6bvp-8 seulement pendant les essais ?
  5. Le refus poli de FPACRT par fpad (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 :

  1. La version « inférieur ou égal » ne suffit pas : retenue, la version stricte.
  2. 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é)

Spécification : nouvelle section 20 (anglais et français).