@@ -8,25 +8,29 @@ remain.**
88## Architecture & control plane
99
1010### D1 — Overlay scope is per-fabric
11+
1112- ** Decision** : A Tenant and its VRFs/Segments belong to exactly one Fabric; each Fabric is an independent
1213 EVPN domain with its own ASN and VNI/RT space.
1314- ** Rationale** : Two independent Clos fabrics; fabric-local numbering is simplest and collision-free.
1415- ** Alternatives** : Cross-fabric tenants (rejected — requires DCI: inter-fabric gateways, RT stitching).
1516
1617### D2 — Standalone OverlayGenerator beside the physical cascade
18+
1719- ** Decision** : Tenant is a first-class design object with a dedicated OverlayGenerator (triggered by
1820 ` NetworkTenant ` checksum); physical generators get only small device-attribute extensions.
1921- ** Rationale** : Tenancy is orthogonal to the physical hierarchy and has its own lifecycle; preserves
2022 "one generator owns one concern" and a scoped day-two workflow (symmetric with add-rack).
2123- ** Alternatives** : Fold overlay into the Rack generator (rejected — conflates lifecycles, forces rebuilds).
2224
2325### D3 — Hierarchical route reflection, leaf-only VTEPs
26+
2427- ** Decision** : leafs = RR clients of their spines; spines = RR for leafs ** and** clients of super-spines;
2528 super-spines = top RR. Only leafs are VTEPs.
2629- ** Rationale** : Canonical 5-stage design; sessions follow topology; low per-leaf session count.
2730- ** Alternatives** : Super-spines-only RR (rejected — more sessions/leaf, spine tier carries no EVPN).
2831
2932### D8 — ASN from a global NumberPool, stamped to devices
33+
3034- ** Decision** : A global ` CoreNumberPool ` → ` NetworkFabric.overlay_asn ` ; FabricGenerator stamps
3135 ` device.asn = overlay_asn ` . Template renders ` router bgp {{ device.asn }} ` .
3236- ** Rationale** : ASN-as-allocated-resource fits the Resource Manager showcase; control-plane-agnostic value
@@ -37,24 +41,28 @@ remain.**
3741## Services & data model
3842
3943### D5 — Anycast gateway optional on Segment
44+
4045- ** Decision** : Segment is always an L2VNI bridge; subnet + anycast gateway are optional (present ⇒ IRB,
4146 absent ⇒ L2-only). Segment always nests under a VRF.
4247- ** Rationale** : Near-free flexibility; reflects real tenants with mixed routed/bridge-only segments.
4348- ** Alternatives** : Always-IRB (rejected — no L2-only support).
4449
4550### D7 — VLAN-based service model, fabric-global VLANs
51+
4652- ** Decision** : 1 VLAN ↔ 1 L2VNI ↔ 1 Segment; NX-OS ` feature vn-segment-vlan-based ` ; VLAN ID is a
4753 fabric-consistent handle, L2VNI is the global id.
4854- ** Alternatives** : VLAN-aware bundle / multi-VLAN EVI (rejected — unnecessary complexity for the demo).
4955
5056### D13 — Schema shape & simplifications
57+
5158- ** Decision** : Tenant/VRF/Segment are plain ` Network ` -namespace nodes with ` kind: Parent ` relationships
5259 (not ` NetworkBuildingBlock ` ). ** No ` route_reflector ` boolean** (derived from tier ordering in the template).
5360 Materialize ** only ` Device↔Segment ` ** (VRF presence derived via ` segment.vrf ` ).
5461- ** Rationale** : Different kinds → plain parent rels; tier ordering is the cleaner RR source and also right
5562 for eBGP-future; one materialized relationship is enough.
5663
5764### D14 — L3VNI transit VLAN + two VLAN pools
65+
5866- ** Decision** : Add ` NetworkVrf.l3_vlan_id ` for the L3VNI transit/core SVI. Two VLAN pools over disjoint
5967 ranges: L2 ` 100–3899 ` → ` Segment.vlan_id ` , L3 ` 3900–4094 ` → ` Vrf.l3_vlan_id ` .
6068- ** Rationale** : Symmetric IRB needs a transit VLAN per VRF on each carrying leaf; a NumberPool binds to one
@@ -64,31 +72,36 @@ remain.**
6472## Allocation, addressing, placement, triggering
6573
6674### D6 — VLAN/L2VNI/L3VNI from per-fabric NumberPools
75+
6776- ** Decision** : NumberPools (Resource Manager), not deterministic compute. Ranges: VLAN-L2 100–3899,
6877 VLAN-L3 3900–4094, L2VNI 10000–19999, L3VNI 50000–59999.
6978- ** Rationale** : On-brand with the solution's RM teaching point; queryable, collision-free.
7079- ** Alternatives** : ` VNI = base + VLAN ` (noted as the simpler documented alternative).
7180
7281### D9 — RT stored (generator-set, queryable); RD template-rendered
82+
7383- ** Decision** : OverlayGenerator stores ` route_target = "<asn>:<vni>" ` on VRF/Segment; RD is per-device →
7484 rendered in template ` <loopback0>:<id> ` . Optional ` import_rt ` /` export_rt ` overrides reserved.
7585- ** Rationale** : Queryable source of truth without computed-attr relationship-traversal risk; RD has no
7686 single home object.
7787- ** Alternatives** : Computed-attribute RT (traversal uncertain); NX-OS ` auto ` (hides RD/RT from Infrahub).
7888
7989### D10 — Separate overlay supernet; default IP namespace first
90+
8091- ** Decision** : New IPPrefix roles ` overlay_supernet ` + ` tenant_subnet ` ; segment subnets from an overlay
8192 supernet distinct from underlay ` 10.0.0.0/8 ` . Anycast GW = ` .1 ` , distributed; fabric-wide
8293 ` anycast-gateway-mac ` (template constant + optional Fabric override). Default namespace initially;
8394 optional ` ip_namespace ` on VRF/Tenant reserved for overlapping tenant space.
8495- ** Alternatives** : Per-VRF namespaces now (deferred — heavier generator bookkeeping for a phase-2 toggle).
8596
8697### D4 — Dedicated VTEP loopback1 on leafs
98+
8799- ** Decision** : Leaf loopback1 (role ` vtep ` ) as NVE source; advertised in OSPF; allocated from a per-pod
88100 VTEP pool (role ` pod_vtep_loopback ` ). loopback0 stays router-id/iBGP source. Spines/super-spines: none.
89101- ** Rationale** : Standard best practice; keeps anycast-VTEP/MLAG open; role-based IPAM consistency.
90102
91103### D11/D12 — Placement (advertise-all default) via materialized relationship (Design Y)
104+
92105- ** Decision** : Optional ` Segment↔Rack ` placement intent (empty ⇒ every leaf in fabric). OverlayGenerator
93106 materializes ` Device↔Segment ` onto carrying leafs; leaf-device change rides the existing
94107 device→artifact regeneration path.
0 commit comments