frontière : le devis rattrape la bascule SDN, et deux devis se contredisaient
Le prochain saut des routes tenants pointait le SVI du commutateur. En EVPN il ne route plus les tenants : la route arriverait sur un équipement sans chemin vers le tenant — configuration qui s'applique sans erreur et ne fonctionne pas. Le devis émet `<NOEUD-DE-SORTIE-EVPN>` et dit pourquoi. `underlay.passerelle_sortie` garde son sens : adresse du pare-feu sur le lien de transit, donc sortie de l'UNDERLAY. Deux choses distinctes. Corrigé aussi une contradiction antérieure au SDN : la section 0 demandait de router l'administration vers 10.0.4.6, le SVI du commutateur lui-même, alors que `devis-reseau` émet 10.0.4.1, l'adresse du pare-feu — tout en affirmant que l'autre devis « émet déjà ces routes ». Elles coïncident maintenant, vérifié ligne à ligne. Et deux commentaires qui affirmaient l'inverse de la décision se dérivent du mode de routage. Preuves : 24 OK, 0 échec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
87697597fb
commit
58fdaa5540
3 changed files with 62 additions and 5 deletions
25
CHANGELOG.md
25
CHANGELOG.md
|
|
@ -1,5 +1,30 @@
|
||||||
# CHANGELOG — Set-OPS
|
# CHANGELOG — Set-OPS
|
||||||
|
|
||||||
|
## 2026-08-03 (suite) — le devis frontière rattrape la bascule SDN
|
||||||
|
|
||||||
|
Trois affirmations du devis frontière étaient devenues fausses, dont une qui cassait le
|
||||||
|
routage.
|
||||||
|
|
||||||
|
### Corrigé — le prochain saut des routes tenants
|
||||||
|
Elles pointaient le SVI du commutateur (`10.0.4.6`). En EVPN, il ne route plus les tenants :
|
||||||
|
une route pointée là arriverait sur un équipement **sans chemin vers le tenant**. Configuration
|
||||||
|
qui s'applique sans erreur et ne fonctionne pas — la signature qu'on traque depuis deux jours.
|
||||||
|
|
||||||
|
Le devis émet désormais `<NOEUD-DE-SORTIE-EVPN>` et dit pourquoi, à figer après le spike.
|
||||||
|
|
||||||
|
`underlay.passerelle_sortie` **garde** son sens : c'est l'adresse du pare-feu sur le lien de
|
||||||
|
transit, donc la sortie de l'**underlay**. Deux choses distinctes qu'il ne faut pas confondre.
|
||||||
|
|
||||||
|
### Corrigé — une contradiction entre les deux devis, antérieure au SDN
|
||||||
|
La section 0 du devis frontière demandait de router les réseaux d'administration **vers
|
||||||
|
`10.0.4.6`** — le SVI du commutateur lui-même. `make devis-reseau` émet `10.0.4.1`, l'adresse
|
||||||
|
du pare-feu. Les deux devis se contredisaient, alors que l'un affirmait que l'autre « émet déjà
|
||||||
|
ces routes ». Elles coïncident maintenant, vérifié ligne à ligne.
|
||||||
|
|
||||||
|
### Corrigé — deux commentaires qui affirmaient l'inverse de la décision
|
||||||
|
L'en-tête (« les passerelles de zone restent sur les switches L3 ») et la description des
|
||||||
|
routes (« routage inter-zone sur les switches L3 ») se dérivent maintenant du mode de routage.
|
||||||
|
|
||||||
## 2026-08-03 — le SDN prend le routage tenant, le devis switch se vide
|
## 2026-08-03 — le SDN prend le routage tenant, le devis switch se vide
|
||||||
|
|
||||||
Trois décisions, et le devis les applique déjà : **une zone EVPN par tenant** ; le routage
|
Trois décisions, et le devis les applique déjà : **une zone EVPN par tenant** ; le routage
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,16 @@ tenants.
|
||||||
|
|
||||||
**Le nœud de sortie remplace le prochain saut.** En EVPN, le trafic quitte le VRF par un ou
|
**Le nœud de sortie remplace le prochain saut.** En EVPN, le trafic quitte le VRF par un ou
|
||||||
plusieurs *exit nodes* désignés. Ce sont eux, et non plus le commutateur, que l'OPNsense voit
|
plusieurs *exit nodes* désignés. Ce sont eux, et non plus le commutateur, que l'OPNsense voit
|
||||||
comme voisins. `underlay.passerelle_sortie` changera de nature : il désignera l'entrée du
|
comme voisins.
|
||||||
tenant vers la bordure, côté hyperviseur.
|
|
||||||
|
C'est **appliqué** : en mode `sdn`, le devis frontière n'émet plus le SVI du commutateur comme
|
||||||
|
prochain saut des routes tenants — il émet le marqueur `<NOEUD-DE-SORTIE-EVPN>` et dit
|
||||||
|
pourquoi. Une route pointée vers le SVI arriverait sur un équipement qui n'a aucun chemin vers
|
||||||
|
le tenant : c'est le genre de configuration qui s'applique sans erreur et ne fonctionne pas.
|
||||||
|
|
||||||
|
À noter : `underlay.passerelle_sortie` **garde** son sens — c'est l'adresse du pare-feu sur le
|
||||||
|
lien de transit, donc la sortie de l'**underlay**, indépendante du routage tenant. Ce sont
|
||||||
|
deux choses distinctes qu'il ne faut pas confondre.
|
||||||
|
|
||||||
**Le MTU est un prérequis vérifié, pas un conseil.** VXLAN ajoute 50 octets ; `make underlay`
|
**Le MTU est un prérequis vérifié, pas un conseil.** VXLAN ajoute 50 octets ; `make underlay`
|
||||||
**refuse** un réseau de transport sous 1550 dès que `routage_tenants: sdn`. C'est le premier
|
**refuse** un réseau de transport sous 1550 dès que `routage_tenants: sdn`. C'est le premier
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ import underlay as underlay_mod # noqa: E402
|
||||||
# (meme idiome que devis_reseau). Le panneau « Intrants de base » du GUI les ecrit
|
# (meme idiome que devis_reseau). Le panneau « Intrants de base » du GUI les ecrit
|
||||||
# dans group_vars/opnsense.yml : le devis se complete tout seul ensuite.
|
# dans group_vars/opnsense.yml : le devis se complete tout seul ensuite.
|
||||||
PROCHAIN_SAUT = "<PROCHAIN-SAUT-SWITCH>"
|
PROCHAIN_SAUT = "<PROCHAIN-SAUT-SWITCH>"
|
||||||
|
NOEUD_SORTIE = "<NOEUD-DE-SORTIE-EVPN>"
|
||||||
IF_TRANSIT = "<IF-TRANSIT>"
|
IF_TRANSIT = "<IF-TRANSIT>"
|
||||||
IF_WAN = "<IF-WAN>"
|
IF_WAN = "<IF-WAN>"
|
||||||
|
|
||||||
|
|
@ -122,6 +123,11 @@ def prochain_saut(transit: dict | None) -> str:
|
||||||
fois dans l'underlay) ouvrirait la porte a deux valeurs contradictoires — c'est
|
fois dans l'underlay) ouvrirait la porte a deux valeurs contradictoires — c'est
|
||||||
exactement le mode de panne qu'on ferme. Marqueur tant qu'aucun transit n'existe.
|
exactement le mode de panne qu'on ferme. Marqueur tant qu'aucun transit n'existe.
|
||||||
"""
|
"""
|
||||||
|
if underlay_mod.routage_tenants(underlay_mod.charger()) == "sdn":
|
||||||
|
# En EVPN, le commutateur ne route plus les tenants : le voisin de la frontiere
|
||||||
|
# est un NOEUD DE SORTIE (hyperviseur), pas le SVI. Emettre le SVI produirait
|
||||||
|
# des routes vers un equipement qui n'a aucun chemin vers le tenant.
|
||||||
|
return NOEUD_SORTIE
|
||||||
return str((transit or {}).get("passerelle") or "").strip() or PROCHAIN_SAUT
|
return str((transit or {}).get("passerelle") or "").strip() or PROCHAIN_SAUT
|
||||||
|
|
||||||
# Le socle est porte par TOUS les hotes : sa destination n'est pas une poignee
|
# Le socle est porte par TOUS les hotes : sa destination n'est pas une poignee
|
||||||
|
|
@ -286,7 +292,10 @@ def construire(tenants: list[tuple[str, str, dict]]) -> dict:
|
||||||
{
|
{
|
||||||
"reseau": supernet_de(n["index"]),
|
"reseau": supernet_de(n["index"]),
|
||||||
"prochain_saut": saut,
|
"prochain_saut": saut,
|
||||||
"description": f"{nom} (index {n['index']}) — routage inter-zone sur les switches L3",
|
"description": f"{nom} (index {n['index']}) — routage inter-zone "
|
||||||
|
+ ("dans la zone EVPN du tenant"
|
||||||
|
if underlay_mod.routage_tenants(underlay_mod.charger()) == "sdn"
|
||||||
|
else "sur les switches L3"),
|
||||||
}
|
}
|
||||||
for nom, _pfx, n in tenants
|
for nom, _pfx, n in tenants
|
||||||
]
|
]
|
||||||
|
|
@ -314,8 +323,12 @@ def construire(tenants: list[tuple[str, str, dict]]) -> dict:
|
||||||
"adresse_frontiere": (transit or {}).get("passerelle_sortie"),
|
"adresse_frontiere": (transit or {}).get("passerelle_sortie"),
|
||||||
"nom_frontiere": nom_frontiere(transit),
|
"nom_frontiere": nom_frontiere(transit),
|
||||||
} if transit else None,
|
} if transit else None,
|
||||||
|
# Le switch route vers l'ADRESSE DU PARE-FEU sur le lien de transit
|
||||||
|
# (`passerelle_sortie`), pas vers son propre SVI ni vers un noeud de sortie :
|
||||||
|
# c'est la sortie de l'underlay. `devis_reseau` emet exactement ces lignes.
|
||||||
"reciproque_switch": [
|
"reciproque_switch": [
|
||||||
f"ip route {cidr} -> {saut} (retour vers l'administration)"
|
f"ip route {cidr} -> {(transit or {}).get('passerelle_sortie') or PROCHAIN_SAUT}"
|
||||||
|
f" (retour vers l'administration)"
|
||||||
for cidr in admin
|
for cidr in admin
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
@ -327,7 +340,9 @@ def rendre(devis: dict) -> str:
|
||||||
"# DEVIS OPNSENSE — frontiere nord/sud (Set-OPS)",
|
"# DEVIS OPNSENSE — frontiere nord/sud (Set-OPS)",
|
||||||
"# Genere par scripts/devis_opnsense.py. NE PAS EDITER A LA MAIN.",
|
"# Genere par scripts/devis_opnsense.py. NE PAS EDITER A LA MAIN.",
|
||||||
"# Derive du registre des flux (pair: externe) + des nomenclatures.",
|
"# Derive du registre des flux (pair: externe) + des nomenclatures.",
|
||||||
"# Les passerelles de zone restent sur les switches L3 : aucun SVI ici.",
|
("# Les passerelles de zone sont anycast sur les hyperviseurs (SDN EVPN) : aucun SVI ici."
|
||||||
|
if underlay_mod.routage_tenants(underlay_mod.charger()) == "sdn"
|
||||||
|
else "# Les passerelles de zone restent sur les switches L3 : aucun SVI ici."),
|
||||||
"# ============================================================",
|
"# ============================================================",
|
||||||
"",
|
"",
|
||||||
"## 0. Prerequis reciproques — COTE SWITCHES",
|
"## 0. Prerequis reciproques — COTE SWITCHES",
|
||||||
|
|
@ -373,6 +388,15 @@ def rendre(devis: dict) -> str:
|
||||||
out += [
|
out += [
|
||||||
"## 2. Routes statiques (vers les supernets tenants)",
|
"## 2. Routes statiques (vers les supernets tenants)",
|
||||||
]
|
]
|
||||||
|
if devis["routes"] and devis["routes"][0]["prochain_saut"] == NOEUD_SORTIE:
|
||||||
|
out += [
|
||||||
|
"# /!\\ LE PROCHAIN SAUT N'EST PAS LE COMMUTATEUR. En SDN EVPN, il ne route plus",
|
||||||
|
"# les tenants : une route pointee vers son SVI arriverait sur un equipement sans",
|
||||||
|
"# chemin vers le tenant. Le voisin de la frontiere est un NOEUD DE SORTIE — un",
|
||||||
|
"# hyperviseur qui porte la sortie du VRF. A figer apres le spike EVPN.",
|
||||||
|
]
|
||||||
|
out += [
|
||||||
|
]
|
||||||
for r in devis["routes"]:
|
for r in devis["routes"]:
|
||||||
out.append(f"route add {r['reseau']} via {r['prochain_saut']} # {r['description']}")
|
out.append(f"route add {r['reseau']} via {r['prochain_saut']} # {r['description']}")
|
||||||
out += ["", "## 3. Alias"]
|
out += ["", "## 3. Alias"]
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue