devis switch : le SDN prend le routage tenant, le devis se vide
Trois décisions appliquées : une zone EVPN par tenant, routage ET filtrage inter-zone à ce niveau, inter-tenant obligatoirement par l'OPNsense. `underlay.routage_tenants` (`switch` par défaut, `sdn`) : en SDN le devis cesse d'émettre VLAN tenants, SVI et ACL, et les retire des trunks. Chez Chezlepro les trunks passent de quinze VLAN à deux — seul du VXLAN circule, que le commutateur transporte sans le lire. Le MTU devient une garde : `make underlay` refuse un transport sous 1550 en mode SDN, en disant pourquoi — sous ce seuil le ping passe et les transferts échouent. Le partage des responsabilités est écrit dans docs/sdn-evpn.md : qui route, qui filtre, pour chaque nature de trafic. Deux conséquences nommées — l'inter-tenant ne peut plus être oublié (il traverse une bordure en block par défaut), et le commutateur ne voit plus rien du trafic tenant. Point ouvert : le registre des flux n'a aucun mot-clé pour un flux inter-tenant. Défaut sûr, mais on ne peut pas déclarer d'exception légitime. Preuves : 24 OK, 0 échec. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
c8b43f1a70
commit
e5ce2b93b1
5 changed files with 184 additions and 68 deletions
32
CHANGELOG.md
32
CHANGELOG.md
|
|
@ -1,5 +1,37 @@
|
|||
# CHANGELOG — Set-OPS
|
||||
|
||||
## 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
|
||||
**et le filtrage** entre les zones d'un même tenant à ce niveau ; **l'inter-tenant
|
||||
obligatoirement par l'OPNsense**.
|
||||
|
||||
### `underlay.routage_tenants` — `switch` (défaut) ou `sdn`
|
||||
En `sdn`, le devis switch cesse d'émettre VLAN tenants, SVI de zone et ACL, et les retire des
|
||||
trunks. Chez Chezlepro, les trunks ne portent plus que **deux VLAN d'underlay** au lieu de
|
||||
quinze : aucun VLAN de tenant ne circule sur le fil, seulement du VXLAN que le commutateur
|
||||
transporte sans le lire.
|
||||
|
||||
Les sections 1 à 3 sont remplacées par la raison, dont celle-ci : les passerelles `.1` n'ont
|
||||
pas changé d'adresse, elles ont changé de **porteur** — passerelle anycast du VNet, présente
|
||||
sur chaque hyperviseur.
|
||||
|
||||
### Le MTU devient une garde, pas un conseil
|
||||
VXLAN ajoute 50 octets. `make underlay` **refuse** un réseau de transport sous 1550 dès que
|
||||
`routage_tenants: sdn`, en disant pourquoi : sous ce seuil, le ping passe et les transferts
|
||||
échouent — la panne la plus coûteuse à diagnostiquer. Les deux réseaux de la fabric principale
|
||||
passent à 9000.
|
||||
|
||||
### Le partage des responsabilités, écrit
|
||||
Une table dans `docs/sdn-evpn.md` dit qui route et qui filtre pour chaque nature de trafic.
|
||||
Deux conséquences y sont nommées : **l'inter-tenant ne peut plus être oublié** — il doit sortir
|
||||
du VRF, donc traverser une bordure en `block` par défaut ; et **le commutateur ne voit plus
|
||||
rien du trafic tenant**, donc y chercher la trace d'un problème applicatif est une perte de
|
||||
temps.
|
||||
|
||||
Point ouvert ajouté : le registre des flux n'a **aucun mot-clé pour un flux inter-tenant**.
|
||||
Défaut sûr aujourd'hui, mais il rend impossible de *déclarer* une exception légitime.
|
||||
|
||||
## 2026-08-02 (suite 20) — décision : le routage passe aux hyperviseurs (SDN EVPN)
|
||||
|
||||
`docs/sdn-evpn.md`. Les commutateurs ne savent pas lier une ACL à une interface de routage ;
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
> commutateurs L3 par des zones EVPN de Proxmox SDN. Complète `docs/frontiere-opnsense.md`
|
||||
> (la bordure, inchangée) et `underlay.yml.example` (la fabric, très allégée).
|
||||
>
|
||||
> **Rien n'est encore éprouvé.** Ce document fixe la cible et la projection du modèle ; le
|
||||
> spike vient avant toute génération.
|
||||
> **Décidé le 2026-08-03** : une zone EVPN **par tenant** ; le routage **et le filtrage**
|
||||
> entre les VLAN d'un même tenant se font à ce niveau ; le trafic **inter-tenant passe
|
||||
> obligatoirement par l'OPNsense**.
|
||||
|
||||
## 1. Ce que la décision résout
|
||||
|
||||
|
|
@ -42,9 +43,29 @@ Effet de bord favorable : un VNI est codé sur 24 bits là où un VLAN plafonne
|
|||
du nombre de tenants n'est plus l'espace de VLAN mais le second octet IPv4 du supernet — le
|
||||
plafond de 245 tenants reste, sa cause change.
|
||||
|
||||
## 3. Ce que le devis switch devient
|
||||
## 3. Le partage des responsabilités
|
||||
|
||||
Il maigrit beaucoup. Disparaissent : les VLAN tenants, les SVI de zone, les ACL d'isolation,
|
||||
| Trafic | Où il est routé | Où il est filtré |
|
||||
|---|---|---|
|
||||
| **entre zones d'un même tenant** | zone EVPN du tenant (VRF, sur les hyperviseurs) | **au même endroit** |
|
||||
| **entre tenants** | sort du VRF → nœud de sortie → **OPNsense** | la frontière, et elle seule |
|
||||
| **vers l'extérieur** | idem | la frontière |
|
||||
| **de service à service, sur un hôte** | — | nftables d'hôte, `policy drop` |
|
||||
|
||||
Deux conséquences qui méritent d'être dites.
|
||||
|
||||
**L'inter-tenant ne peut plus être « oublié ».** Il ne circule pas latéralement : il doit
|
||||
sortir du VRF, donc traverser la bordure, qui est en `block` par défaut. Un flux inter-tenant
|
||||
légitime devra être **déclaré** pour exister — le registre des flux n'a pas encore de mot-clé
|
||||
pour ça, c'est un point ouvert.
|
||||
|
||||
**Le commutateur ne voit plus rien du trafic tenant.** Il transporte du VXLAN qu'il ne lit
|
||||
pas. Y chercher une trace d'un problème applicatif serait perdre son temps : le miroir utile
|
||||
est sur l'hyperviseur.
|
||||
|
||||
## 4. Ce que le devis switch devient
|
||||
|
||||
C'est fait, et piloté par `underlay.routage_tenants: sdn`. Disparaissent : les VLAN tenants, les SVI de zone, les ACL d'isolation,
|
||||
et les VLAN tenants dans les trunks. En EVPN, **aucun VLAN de tenant ne circule sur le fil** —
|
||||
seulement du VXLAN encapsulé dans de l'IP.
|
||||
|
||||
|
|
@ -55,22 +76,23 @@ IP**.
|
|||
`underlay.routeur` garde son sens, mais son rôle se réduit : il route l'underlay, plus les
|
||||
tenants.
|
||||
|
||||
## 4. Ce que ça change ailleurs
|
||||
## 5. Ce que ça change ailleurs
|
||||
|
||||
**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
|
||||
comme voisins. `underlay.passerelle_sortie` changera de nature : il désignera l'entrée du
|
||||
tenant vers la bordure, côté hyperviseur.
|
||||
|
||||
**Le MTU devient un prérequis, pas un détail.** VXLAN ajoute 50 octets. Le transport doit
|
||||
passer à 1550 au minimum, jumbo de préférence. C'est le premier mur, et le plus déroutant : il
|
||||
ne casse pas franchement, il casse **partiellement** — le ping passe, les transferts échouent.
|
||||
**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
|
||||
mur, et le plus déroutant : il ne casse pas franchement, il casse **partiellement** — le ping
|
||||
passe, les transferts échouent.
|
||||
|
||||
**Ce qui ne change pas** : le plan, le registre des flux, les nftables d'hôte, la frontière
|
||||
OPNsense et ses règles dérivées, la voûte, les preuves. La cible d'émission change ; le modèle
|
||||
non.
|
||||
|
||||
## 5. Ce qui reste à éprouver — avant toute génération
|
||||
## 6. Ce qui reste à éprouver — avant toute génération
|
||||
|
||||
Le principe du dépôt s'applique : **éprouver l'outil avant d'écrire le rôle.** L'EVPN est la
|
||||
partie la plus jeune de Proxmox SDN, et c'est là que vivent les bogues.
|
||||
|
|
@ -86,13 +108,16 @@ Un tenant de labo, une zone EVPN, deux VNet, une VM dans chacun — et vérifier
|
|||
|
||||
Ce n'est qu'après que la question « comment générer cette configuration » se pose.
|
||||
|
||||
## 6. Ce qui reste à trancher
|
||||
## 7. Ce qui reste à trancher
|
||||
|
||||
- **Où vit la configuration SDN.** Elle est *par cluster*, donc propriété de l'hébergeur —
|
||||
comme `underlay.yml`, et par le même raisonnement.
|
||||
- **Le contrôleur EVPN** : ASN, voisins, et si l'on fait du BGP avec la bordure ou des routes
|
||||
statiques comme aujourd'hui.
|
||||
- **Le nombre de nœuds de sortie** et leur redondance.
|
||||
- **Le mot-clé d'un flux inter-tenant** dans le registre. Aujourd'hui aucun ne l'exprime, donc
|
||||
tout inter-tenant tombe dans le `block` de la bordure — un défaut sûr, mais qui rend
|
||||
impossible de *déclarer* une exception légitime.
|
||||
- **La migration depuis l'existant** : le tenant Chezlepro tourne déjà sur des VLAN. Passer à
|
||||
EVPN est un changement de plan de transport pour des VM en service — la recette de
|
||||
`docs/migration-tenant.md` s'applique-t-elle, ou faut-il un chemin plus court ?
|
||||
|
|
|
|||
|
|
@ -469,68 +469,83 @@ def generer(tenants: list[tuple[str, str, dict]], dialecte: str | None = None) -
|
|||
"!",
|
||||
]
|
||||
out += section_underlay(underlay)
|
||||
out += ["! ----- 1. VLANs (tenants) -----"]
|
||||
for nom, pfx, n in tenants:
|
||||
out.append(f"! {nom} (index {n['index']})")
|
||||
for zone in sorted(n["categories"]):
|
||||
c = n["categories"][zone]
|
||||
out.append(f"vlan {vlan_de(n['index'], zone)}")
|
||||
out.append(f" name {pfx}{n['index']}-{c['libelle']}")
|
||||
acl = underlay_mod.acl_inter_tenant(underlay)
|
||||
out += ["!", "! ----- 2. Interfaces de routage (SVI = passerelle des hotes) -----"]
|
||||
for nom, pfx, n in tenants:
|
||||
m = masque(int(n.get("cidr_hote", 24)))
|
||||
for zone in sorted(n["categories"]):
|
||||
c = n["categories"][zone]
|
||||
out.append(f"interface Vlan{vlan_de(n['index'], zone)}")
|
||||
out.append(f" description {nom}-{c['libelle']}")
|
||||
out.append(f" ip address {passerelle_de(n['index'], zone)} {m}")
|
||||
if acl:
|
||||
out.append(f" ip access-group {pfx}{n['index']}-ISOLATION in")
|
||||
out.append(" no shutdown")
|
||||
if not acl:
|
||||
out += ["!", "! ----- 3. Isolation inter-tenant — PAS D'ACL SUR CETTE FABRIC -----",
|
||||
"! `underlay.acl_inter_tenant: false` : le materiel ne sait pas lier une ACL",
|
||||
"! a une interface de routage. Emettre des ACL qu'on ne peut pas lier serait",
|
||||
"! pire que rien — elles auraient l'air d'isoler sans jamais filtrer.",
|
||||
if underlay_mod.routage_tenants(underlay) == "sdn":
|
||||
out += ["! ----- 1 a 3. VLANs, SVI et ACL des tenants — PORTES PAR LE SDN -----",
|
||||
"! `underlay.routage_tenants: sdn` : une zone EVPN par tenant porte son VRF.",
|
||||
"! Le routage ET le filtrage entre les zones d'un meme tenant vivent sur les",
|
||||
"! hyperviseurs. AUCUN VLAN DE TENANT NE CIRCULE SUR CE FIL — seulement du",
|
||||
"! VXLAN encapsule dans de l'IP, que ce commutateur transporte sans le lire.",
|
||||
"!",
|
||||
"! L'isolation repose donc ENTIEREMENT sur les nftables de chaque hote",
|
||||
"! (`make flux`), en `policy drop`, au moindre privilege par IP source.",
|
||||
"! Ce commutateur ne porte donc ni VLAN tenant, ni SVI de zone, ni ACL. Les",
|
||||
"! passerelles `.1` n'ont pas change d'adresse, elles ont change de porteur :",
|
||||
"! passerelle anycast du VNet, presente sur chaque hyperviseur.",
|
||||
"!",
|
||||
"! /!\\ CE QUI N'EST PLUS PROTEGE AU NIVEAU RESEAU : le plan de gestion de la",
|
||||
"! fabric. Une VM qui emet vers l'underlay voit son paquet ROUTE localement par",
|
||||
"! ce commutateur — mgmt des switches, mgmt Proxmox, OOB/IPMI. Les nftables des",
|
||||
"! VM n'y peuvent rien (politique `output` permissive), et l'IPMI n'est pas un",
|
||||
"! hote gere. Seule parade structurelle : sortir le management de la fabric",
|
||||
"! routee des tenants, comme l'est deja le stockage.",
|
||||
"! L'inter-tenant sort du VRF et passe par la FRONTIERE, qui le police",
|
||||
"! (`make devis-opnsense`). Il n'est pas filtre ici : il ne passe pas ici.",
|
||||
"!"]
|
||||
else:
|
||||
out += ["!", "! ----- 3. ACL d'isolation tenant (default-deny inter-tenant) -----"]
|
||||
out += ["! ----- 1. VLANs (tenants) -----"]
|
||||
for nom, pfx, n in tenants:
|
||||
reseau, m = masque_acl(supernet_de(n["index"]), dialecte)
|
||||
out.append(f"ip access-list extended {pfx}{n['index']}-ISOLATION")
|
||||
out += remarque(dialecte, f"Intra-tenant {nom} : routage local autorise")
|
||||
out.append(f" permit ip {reseau} {m} {reseau} {m}")
|
||||
for autre_nom, _, autre in tenants:
|
||||
if autre_nom == nom:
|
||||
continue
|
||||
a_reseau, a_m = masque_acl(supernet_de(autre["index"]), dialecte)
|
||||
out += remarque(dialecte, f"Bloquer le tenant {autre_nom}")
|
||||
out.append(f" deny ip {reseau} {m} {a_reseau} {a_m}")
|
||||
# L'underlay est la fabric physique : mgmt des switches, mgmt Proxmox, OOB/IPMI,
|
||||
# iSCSI, Ceph. Le trafic d'un tenant vers ces reseaux est route LOCALEMENT par le
|
||||
# switch : il ne passe jamais par la frontiere, donc il n'est jamais filtre. Sans
|
||||
# ce deny, le `permit any` final l'autorise — une VM atteindrait la console
|
||||
# physique des hyperviseurs. Aucun flux du registre ne vise l'underlay.
|
||||
# TOUTES les fabrics y passent, meme celles portees par d'autres switches : la
|
||||
# regle porte sur l'adresse de DESTINATION, pas sur le cablage. Si un jour un
|
||||
# chemin s'ouvre vers le stockage, il est deja ferme.
|
||||
for r in underlay_mod.reseaux(underlay):
|
||||
u_reseau, u_m = masque_acl(r["sous_reseau"], dialecte)
|
||||
out += remarque(dialecte, f"Bloquer l'underlay {r['nom']} (fabric physique)")
|
||||
out.append(f" deny ip {reseau} {m} {u_reseau} {u_m}")
|
||||
out += remarque(dialecte, "Reste (Internet / inter-tenant controle) -> passerelle OPNsense")
|
||||
out.append(f" permit ip {reseau} {m} any")
|
||||
out.append(f"! {nom} (index {n['index']})")
|
||||
for zone in sorted(n["categories"]):
|
||||
c = n["categories"][zone]
|
||||
out.append(f"vlan {vlan_de(n['index'], zone)}")
|
||||
out.append(f" name {pfx}{n['index']}-{c['libelle']}")
|
||||
acl = underlay_mod.acl_inter_tenant(underlay)
|
||||
out += ["!", "! ----- 2. Interfaces de routage (SVI = passerelle des hotes) -----"]
|
||||
for nom, pfx, n in tenants:
|
||||
m = masque(int(n.get("cidr_hote", 24)))
|
||||
for zone in sorted(n["categories"]):
|
||||
c = n["categories"][zone]
|
||||
out.append(f"interface Vlan{vlan_de(n['index'], zone)}")
|
||||
out.append(f" description {nom}-{c['libelle']}")
|
||||
out.append(f" ip address {passerelle_de(n['index'], zone)} {m}")
|
||||
if acl:
|
||||
out.append(f" ip access-group {pfx}{n['index']}-ISOLATION in")
|
||||
out.append(" no shutdown")
|
||||
if not acl:
|
||||
out += ["!", "! ----- 3. Isolation inter-tenant — PAS D'ACL SUR CETTE FABRIC -----",
|
||||
"! `underlay.acl_inter_tenant: false` : le materiel ne sait pas lier une ACL",
|
||||
"! a une interface de routage. Emettre des ACL qu'on ne peut pas lier serait",
|
||||
"! pire que rien — elles auraient l'air d'isoler sans jamais filtrer.",
|
||||
"!",
|
||||
"! L'isolation repose donc ENTIEREMENT sur les nftables de chaque hote",
|
||||
"! (`make flux`), en `policy drop`, au moindre privilege par IP source.",
|
||||
"!",
|
||||
"! /!\\ CE QUI N'EST PLUS PROTEGE AU NIVEAU RESEAU : le plan de gestion de la",
|
||||
"! fabric. Une VM qui emet vers l'underlay voit son paquet ROUTE localement par",
|
||||
"! ce commutateur — mgmt des switches, mgmt Proxmox, OOB/IPMI. Les nftables des",
|
||||
"! VM n'y peuvent rien (politique `output` permissive), et l'IPMI n'est pas un",
|
||||
"! hote gere. Seule parade structurelle : sortir le management de la fabric",
|
||||
"! routee des tenants, comme l'est deja le stockage.",
|
||||
"!"]
|
||||
else:
|
||||
out += ["!", "! ----- 3. ACL d'isolation tenant (default-deny inter-tenant) -----"]
|
||||
for nom, pfx, n in tenants:
|
||||
reseau, m = masque_acl(supernet_de(n["index"]), dialecte)
|
||||
out.append(f"ip access-list extended {pfx}{n['index']}-ISOLATION")
|
||||
out += remarque(dialecte, f"Intra-tenant {nom} : routage local autorise")
|
||||
out.append(f" permit ip {reseau} {m} {reseau} {m}")
|
||||
for autre_nom, _, autre in tenants:
|
||||
if autre_nom == nom:
|
||||
continue
|
||||
a_reseau, a_m = masque_acl(supernet_de(autre["index"]), dialecte)
|
||||
out += remarque(dialecte, f"Bloquer le tenant {autre_nom}")
|
||||
out.append(f" deny ip {reseau} {m} {a_reseau} {a_m}")
|
||||
# L'underlay est la fabric physique : mgmt des switches, mgmt Proxmox, OOB/IPMI,
|
||||
# iSCSI, Ceph. Le trafic d'un tenant vers ces reseaux est route LOCALEMENT par le
|
||||
# switch : il ne passe jamais par la frontiere, donc il n'est jamais filtre. Sans
|
||||
# ce deny, le `permit any` final l'autorise — une VM atteindrait la console
|
||||
# physique des hyperviseurs. Aucun flux du registre ne vise l'underlay.
|
||||
# TOUTES les fabrics y passent, meme celles portees par d'autres switches : la
|
||||
# regle porte sur l'adresse de DESTINATION, pas sur le cablage. Si un jour un
|
||||
# chemin s'ouvre vers le stockage, il est deja ferme.
|
||||
for r in underlay_mod.reseaux(underlay):
|
||||
u_reseau, u_m = masque_acl(r["sous_reseau"], dialecte)
|
||||
out += remarque(dialecte, f"Bloquer l'underlay {r['nom']} (fabric physique)")
|
||||
out.append(f" deny ip {reseau} {m} {u_reseau} {u_m}")
|
||||
out += remarque(dialecte, "Reste (Internet / inter-tenant controle) -> passerelle OPNsense")
|
||||
out.append(f" permit ip {reseau} {m} any")
|
||||
out += ["!", "! ----- 4. Trunk vers les hyperviseurs -----",
|
||||
"! Ports TERMINAUX : rien derriere eux ne participe au spanning-tree.",
|
||||
"! Les liens vers les autres switches sont en section 4c, pas ici."]
|
||||
|
|
@ -541,7 +556,9 @@ def generer(tenants: list[tuple[str, str, dict]], dialecte: str | None = None) -
|
|||
for r in underlay_mod.reseaux_de_fabric(
|
||||
underlay, underlay_mod.fabric_du_routeur(underlay))
|
||||
if not (transit and r["vlan"] == transit["vlan"])]
|
||||
vlans_tenants = [
|
||||
# En SDN, les VLAN tenants n'existent pas sur le fil : le trunk ne porte que
|
||||
# l'underlay, qui transporte le VXLAN.
|
||||
vlans_tenants = [] if underlay_mod.routage_tenants(underlay) == "sdn" else [
|
||||
str(vlan_de(n["index"], zone))
|
||||
for _, _, n in tenants
|
||||
for zone in sorted(n["categories"])
|
||||
|
|
|
|||
|
|
@ -81,6 +81,27 @@ STP_MODES = ("rstp", "mstp", "pvst")
|
|||
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
|
||||
|
||||
|
||||
def routage_tenants(underlay: dict | None) -> str:
|
||||
"""Qui route entre les zones d'un tenant : `switch` (SVI) ou `sdn` (EVPN).
|
||||
|
||||
En `sdn`, une zone EVPN par tenant porte le VRF : le routage ET le filtrage
|
||||
inter-zone d'un meme tenant vivent sur les hyperviseurs. Aucun VLAN de tenant ne
|
||||
circule alors sur le fil — seulement du VXLAN encapsule dans de l'IP — et le devis
|
||||
switch cesse d'emettre VLAN tenants, SVI et ACL.
|
||||
|
||||
L'inter-tenant, lui, sort du VRF et passe par la frontiere, qui le police.
|
||||
"""
|
||||
v = str((underlay or {}).get("routage_tenants") or "switch")
|
||||
return v if v in ROUTAGE_TENANTS else "switch"
|
||||
|
||||
|
||||
def acl_inter_tenant(underlay: dict | None) -> bool:
|
||||
"""La fabric porte-t-elle l'isolation inter-tenant par ACL ? Vrai par defaut.
|
||||
|
||||
|
|
@ -339,6 +360,20 @@ def valider(underlay: dict | None,
|
|||
if v is not None and not isinstance(v, bool):
|
||||
erreurs.append(f"acl_inter_tenant doit etre un booleen (recu : {v!r})")
|
||||
|
||||
rt = (underlay or {}).get("routage_tenants")
|
||||
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.
|
||||
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:
|
||||
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")
|
||||
|
||||
d = dialecte(underlay)
|
||||
if d and d not in DIALECTES:
|
||||
erreurs.append(f"dialecte '{d}' inconnu (attendu : {', '.join(DIALECTES)})")
|
||||
|
|
|
|||
|
|
@ -28,6 +28,13 @@ underlay:
|
|||
# d'adresses qu'il y a de zones. Doit nommer un hote declare dans `hotes:`.
|
||||
routeur: switch-01
|
||||
|
||||
# Qui route entre les zones d'un tenant : `switch` (SVI sur le commutateur, defaut)
|
||||
# ou `sdn` (une zone EVPN par tenant, portant son VRF sur les hyperviseurs).
|
||||
# En `sdn` : aucun VLAN de tenant ne circule sur le fil, le devis switch cesse
|
||||
# d'emettre VLAN tenants / SVI / ACL, et les reseaux de transport doivent avoir un
|
||||
# MTU >= 1550 (VXLAN ajoute 50 octets) — `make underlay` le refuse sinon.
|
||||
#routage_tenants: switch
|
||||
|
||||
# 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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue