You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(containerlab): give ns30/ns40 two attachments, not one shared
Rebased onto the updated fix/vrf-shared-per-vpc-2-cnibgp (which
picked up my own rebase-and-reconcile of that branch after
fix/vrf-shared-per-vpc-1-core moved out from under it) after that
branch's history moved out from under this one -- same ripple as
#306 -> #307 -> #311 -> #312 -> #313.
No conflicts: this PR only touches containerlab docs/scripts/
manifests, none of which overlapped with the Go source changes further
up the stack. Applied cleanly.
Verification: task lint, task build (all 8 binaries) pass on the
rebased tree. No Go source changed in this PR, so task test:unit is
unaffected. tests/e2e and the containerlab lab itself not run in this
sandbox (no Kind cluster / root), same caveat as every PR in this
stack.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|`ns50`| dfw, sjc, iad (3-site) | IPv4 + public IPv6 ptp |`G000000050050V`| Also defines a `public` NAD with an IPv6 IPAM pool for external-connectivity testing. |
25
-
|`ns10`| dfw, sjc, iad (3-site) | IPv6-only (fd20 ULA) |`G000000010010V`| No `ipv4_subnet` at all. |
26
-
|`ns20`| dfw, sjc, iad (3-site) | Dual-stack (fd20 ULA + IPv4) |`G000000020020V`| Both families active; exercises the dual-stack IPAM path. |
27
-
|`ns30`| dfw only, 2 replicas | IPv6-only (fd20 ULA) |`G000000030030V`| Both pods land on `dfw-worker` and share one VRF — same-node connectivity, no cross-site hop. |
28
-
|`ns40`| iad only, 2 replicas | IPv4-only |`G000000040040V`| Both pods land on `iad-worker` (not `iad-worker-control`, which is tainted for the route-reflector role) and share one VRF. |
29
-
30
-
The VRF interface name follows `G<vpc, zero-padded to 9><vpcattachment,
31
-
zero-padded to 3>V` on every worker — e.g. `ns20` (`vpc="20"`,
|`ns50`| dfw, sjc, iad (3-site) | IPv4 + public IPv6 ptp |`G000000050V`| Also defines a `public` NAD with an IPv6 IPAM pool for external-connectivity testing. |
25
+
|`ns10`| dfw, sjc, iad (3-site) | IPv6-only (fd20 ULA) |`G000000010V`| No `ipv4_subnet` at all. |
26
+
|`ns20`| dfw, sjc, iad (3-site) | Dual-stack (fd20 ULA + IPv4) |`G000000020V`| Both families active; exercises the dual-stack IPAM path. |
27
+
|`ns30`| dfw only, 2 attachments | IPv6-only (fd20 ULA) |`G000000030V`| Two distinct attachments (`private`/`private-b`, distinct `vpcattachment` values, same `vpc`), each its own single-replica Deployment, both land on `dfw-worker` and share one VRF — same-node connectivity, no cross-site hop. |
28
+
|`ns40`| iad only, 2 attachments | IPv4-only |`G000000040V`| Two distinct attachments (`private`/`private-b`), each its own single-replica Deployment, both land on `iad-worker` (not `iad-worker-control`, which is tainted for the route-reflector role) and share one VRF. |
29
+
30
+
The VRF interface name follows `G<vpc, zero-padded to 9>V` on every worker —
31
+
e.g. `ns20` (`vpc="20"`) is `G000000020V`. Unlike the host/guest veth
32
+
interface names (`G<vpc><vpcattachment>H`/`G<vpc><vpcattachment>G`, still
33
+
per-attachment), the VRF carries no `vpcattachment` segment: it's shared by
34
+
every attachment on that VPC on a given node, not created fresh per
35
+
attachment — see [ns30's `vpcattachment` note](#ns30ns40-use-two-distinct-vpcattachment-values)
36
+
below for why `ns30`/`ns40` deliberately use two attachments instead of one.
37
+
38
+
### `ns30`/`ns40` use two distinct `vpcattachment` values
39
+
40
+
`ns30` and `ns40` each define **two** NADs (`private` and `private-b`) with
41
+
the same `vpc` but different `vpcattachment` values, each backing its own
42
+
single-replica Deployment — not one NAD scaled to `replicas: 2`. This is
43
+
required, not a style choice: `galactic-cni` derives its host/guest veth
44
+
interface names from `(vpc, vpcAttachment)` alone, so two pods sharing one
45
+
`vpcattachment` on the same node would collide on that name, and
46
+
`internal/cni/veth`'s "stale veth" self-heal would delete whichever pod's
47
+
veth got there second — silently breaking it without either pod's own CNI
48
+
ADD ever reporting a failure. Two distinct `vpcattachment` values avoid the
49
+
collision while still landing both pods in the one shared VRF their common
50
+
`vpc` gets on this node (see the VRF interface table above).
33
51
34
52
### SRv6 USID Argument allocation
35
53
36
54
Each site's tenant node advertises its own `/56` SRv6 locator block into the
37
55
fabric. The low hextet of a pod's USID is `(Function << 12) | Argument`
38
56
(`uFMT 48+16`, `internal/plumbing/ebpf/uformat`): `Function` is the constant
39
57
`0xE` (`FunctionEndDT46`) for every plain L3 VRF attachment, and `Argument` is
40
-
a 12-bit value `galactic-router` allocates per-node as the lowest unused slot
41
-
in `[0x001, 0xFFF]` among that node's existing `BGPVRFInstance` CRDs
42
-
(`allocateArgument`, `internal/cnibgp/bgp.go`) — **not** a decode of the NAD's
43
-
`vpc`/`vpcattachment` values. Concretely, expect hextets in the
44
-
`0xe001`–`0xefff` range; the exact value depends on allocation order (`ns50`
45
-
is provisioned first in `task deploy`, then `ns10`, `ns20`, `ns30`, `ns40` in
46
-
that order, each consuming the next free slot on each node it lands on).
47
-
Always confirm the live value rather than trusting a table:
58
+
a 12-bit value `galactic-router` allocates per **(VPC, node)** — not per
59
+
attachment — as the lowest unused slot in `[0x001, 0xFFF]` among that node's
0 commit comments