diff --git a/CHANGELOG.md b/CHANGELOG.md index 724a6c2..d2a3ed9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,31 @@ # CHANGELOG — Set-OPS +## 2026-08-03 (suite 7) — le modèle déclarait un MTU que le matériel n'a pas + +En préparant le déplacement des adresses de VTEP, la lecture des interfaces a montré deux +choses que le modèle ignorait. + +### `underlay.yml` annonçait 9000, `vmbr3` est à 1500 +La garde P23 validait donc **une déclaration fausse** : elle exigeait ≥ 1550 et passait parce +que le fichier disait 9000. **Une garde qui valide une déclaration plutôt qu'une réalité donne +un faux confort** — c'est pire qu'une garde absente, qui au moins n'endort personne. + +Le seuil ne peut pas non plus être fixe : 1550 aurait rejeté à tort un transport à 1500 +portant un overlay à 1450, qui tient exactement. Il **dérive** désormais d'un +`mtu_overlay` déclaré (1450 par défaut) : transport ≥ overlay + 50. + +Le fichier dit maintenant la vérité — 1500 — et la garde passe pour la bonne raison. Exercé : +un overlay porté à 1500 sur ce transport est refusé. + +### `vmbr3` n'est pas *VLAN-aware* +Pas de `bridge_vlan_aware`, contrairement à `vmbr2`. L'adresse du VTEP y est **non +étiquetée** : elle vit dans le VLAN natif du port de commutateur. Déplacer le VTEP vers +l'underlay n'est donc pas un changement d'adresse — il faut soit un VLAN natif 10, soit une +interface étiquetée dédiée (`bond3.10`). + +C'est la raison pour laquelle le déplacement n'a **pas** été effectué : le geste demandé +suppose une décision de câblage qui n'est pas prise. + ## 2026-08-03 (suite 6) — les hyperviseurs entrent au modèle, à leur adresse cible Redresser les pairs EVPN vers l'underlay suppose d'abord que les hyperviseurs **existent dans diff --git a/docs/sdn-evpn.md b/docs/sdn-evpn.md index 8d4259c..bba990d 100644 --- a/docs/sdn-evpn.md +++ b/docs/sdn-evpn.md @@ -91,8 +91,8 @@ le tenant : c'est le genre de configuration qui s'applique sans erreur et ne fon 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. -**L'overlay est plafonné à 1450** (décision du 2026-08-03), donc le transport doit dépasser -1500. Conséquence à ne pas manquer : sous 1500, **tout ce qui traverse la frontière dépend de +**L'overlay est plafonné à 1450** (décision du 2026-08-03) parce que le transport réel — le +pont `vmbr3` des hyperviseurs — est à **1500** : 1450 + 50 de VXLAN y tient exactement. Conséquence à ne pas manquer : sous 1500, **tout ce qui traverse la frontière dépend de la découverte de MTU de chemin**, qui a besoin de l'ICMP « fragmentation nécessaire ». Or le registre des flux ne connaissait que TCP et UDP : ce message ne pouvait pas être @@ -154,6 +154,11 @@ garde détecte la faute avant qu'on ne la documente. dernier octet conservé comme sur `vmbr0`. Le déplacement réel de l'adresse sur les nœuds reste à faire : c'est une modification du réseau d'un hyperviseur en service. +**Le pont `vmbr3` n'est pas *VLAN-aware*** (pas de `bridge_vlan_aware`, contrairement à +`vmbr2`). L'adresse du VTEP y est donc **non étiquetée** : elle vit dans le VLAN natif du port +de commutateur. Déplacer le VTEP vers l'underlay suppose soit un VLAN natif 10, soit une +interface étiquetée dédiée (`bond3.10`) — ce n'est pas qu'un changement d'adresse. + **`vishnu` n'est pas câblé.** Son `vmbr3` n'a **aucun port physique** : le pont existe, porte une adresse, et ne mène nulle part. Un pair VXLAN pointé sur lui ne fonctionnera jamais. diff --git a/scripts/underlay.py b/scripts/underlay.py index abe2aa5..99a9eea 100644 --- a/scripts/underlay.py +++ b/scripts/underlay.py @@ -82,10 +82,18 @@ STP_TOPOLOGIES = ("etoile", "anneau", "maille") ROUTAGE_TENANTS = ("switch", "sdn") -# VXLAN ajoute 50 octets d'encapsulation. Sous ce seuil, le transport casse -# PARTIELLEMENT : le ping passe, les transferts echouent — la panne la plus couteuse -# a diagnostiquer. On refuse donc un underlay qui ne peut pas porter le SDN. -MTU_MINIMAL_VXLAN = 1550 +# VXLAN coute 50 octets d'encapsulation : le TRANSPORT doit valoir au moins l'overlay +# plus cette surcharge. Sous ce seuil, il casse PARTIELLEMENT — le ping passe, les +# transferts echouent — la panne la plus couteuse a diagnostiquer. +SURCOUT_VXLAN = 50 +MTU_OVERLAY_DEFAUT = 1450 # ce que voit une VM ; regle par zone dans Proxmox SDN + + +def mtu_overlay(underlay: dict | None) -> int: + """MTU annonce aux VM par les VNet. Declare, parce qu'il commande le minimum du + transport : un overlay a 1450 tient dans un transport a 1500, pas un overlay a 1500.""" + v = (underlay or {}).get("mtu_overlay") + return int(v) if isinstance(v, int) else MTU_OVERLAY_DEFAUT def routage_tenants(underlay: dict | None) -> str: @@ -386,15 +394,16 @@ def valider(underlay: dict | None, if rt is not None and str(rt) not in ROUTAGE_TENANTS: erreurs.append(f"routage_tenants '{rt}' inconnu (attendu : {', '.join(ROUTAGE_TENANTS)})") if routage_tenants(underlay) == "sdn": - # Le transport du VXLAN doit encaisser l'encapsulation, sinon panne partielle. + # Le transport doit valoir l'overlay DECLARE plus la surcharge d'encapsulation. + minimal = mtu_overlay(underlay) + SURCOUT_VXLAN fab = fabric_du_routeur(underlay) for r in reseaux_de_fabric(underlay, fab): mtu = int(r.get("mtu") or 1500) - if mtu < MTU_MINIMAL_VXLAN: + if mtu < minimal: erreurs.append( - f"reseau '{r.get('nom','?')}': MTU {mtu} < {MTU_MINIMAL_VXLAN} alors que " - f"`routage_tenants: sdn` — VXLAN ajoute 50 octets ; sous ce seuil le ping " - f"passe et les transferts echouent") + f"reseau '{r.get('nom','?')}': MTU {mtu} < {minimal} " + f"(overlay {mtu_overlay(underlay)} + {SURCOUT_VXLAN} de VXLAN) — sous ce " + f"seuil le ping passe et les transferts echouent") d = dialecte(underlay) if d and d not in DIALECTES: diff --git a/underlay.yml.example b/underlay.yml.example index 961df4e..84d3060 100644 --- a/underlay.yml.example +++ b/underlay.yml.example @@ -35,6 +35,11 @@ underlay: # MTU >= 1550 (VXLAN ajoute 50 octets) — `make underlay` le refuse sinon. #routage_tenants: switch + # MTU annonce aux VM par les VNet, en mode `sdn`. Il commande le minimum du TRANSPORT : + # `make underlay` refuse un reseau de fabric sous `mtu_overlay + 50` (surcout VXLAN). + # 1450 tient dans un transport a 1500 ; viser 1500 d'overlay exige du jumbo. + #mtu_overlay: 1450 + # Isolation inter-tenant par ACL de commutateur. `true` par defaut. # Mettre `false` quand le materiel ne sait pas lier une ACL a une interface de # routage : le devis cesse alors d'emettre des ACL qui ne seraient jamais liees.