Skip to content

fix(cnibgp): share BGPVRFInstance and Argument per (VPC, node) - #312

Open
privateip wants to merge 1 commit into
fix/vrf-shared-per-vpc-1-corefrom
fix/vrf-shared-per-vpc-2-cnibgp
Open

fix(cnibgp): share BGPVRFInstance and Argument per (VPC, node)#312
privateip wants to merge 1 commit into
fix/vrf-shared-per-vpc-1-corefrom
fix/vrf-shared-per-vpc-2-cnibgp

Conversation

@privateip

@privateip privateip commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

The BGPVRFInstance CRD and its SRv6 Argument were still allocated per attachment instead of per VPC per node, wasting an Argument slot for every extra attachment sharing a VPC. This makes every attachment on the same VPC/node converge on one CRD and Argument, and fixes rollback so a failed attachment's cleanup can no longer delete a live sibling's shared state.

Test plan

  • task ci passes (lint, build, unit tests)
  • A failed ADD's rollback never deletes a still-live sibling attachment's BGPVRFInstance
  • Two different VPCs' first attachment landing on the same node at the same time no longer wedges permanently on an argument collision

Stack (merge bottom to top):

🤖 Generated with Claude Code

Rebased onto the updated fix/vrf-shared-per-vpc-1-core (which picked
up my own rebase-and-reconcile of that branch after PR #307 moved
out from under it) after that branch's history moved out from under
this one -- same ripple as #306 -> #307 -> #311 -> #312.

Conflicts resolved: this PR drops the eBPF vrf_table
rollback path (registerEBPFDatapath no longer returns a block to
track, unregisterEBPFDatapath is deleted entirely, publishResult
loses ebpfRegistered/ebpfBlock/ebpfArgument) since the vrf_table
entry is now shared per (VPC, node) same as the BGPVRFInstance CRD,
so a failed ADD must never unregister it. The current tree had
independently refactored resourceTracker to embed publishResult
(rather than copying its fields one-by-one) between this PR's
original base and now, so I kept that embedding -- it still holds
exactly this PR's two surviving fields (advertisementCreated,
vrfInstanceCreated) once the eBPF fields are gone -- and added this
PR's own vrfInstanceCreated-conditioned-on-OperationResultCreated
behavior and nodeName field on top of it, along with this PR's fuller
cleanup() doc comment (it explains the shared-VRF reasoning more
completely than what was already there). Also kept ebpfPinDir (the
package-level var #305's own fix added for test injection) over the
attach.PinDir literal this PR's diff predates, matching the same
resolution #311 needed one level up.

internal/cnibgp/resource_test.go needed a full rewrite rather than a
per-hunk merge: it didn't exist yet at this PR's original base either
(same gap #311 hit) -- it was added by #305's own fix commit -- so
this PR's diff shows the file as "new," and the version already in
the tree still tested the old unconditional-vrfInstanceCreated/
ebpfRegistered design this PR removes. Took this PR's four tests
wholesale (they're purpose-built for the new design) and adjusted
their resourceTracker literals for the embedded-publishResult shape
(publishResult: publishResult{vrfInstanceCreated: true} instead of a
bare vrfInstanceCreated: true field, which the embedding makes
illegal in a keyed literal).

Verification: task lint, task build (all 8 binaries), task test:unit
all pass on the rebased tree. tests/e2e 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>
@privateip
privateip force-pushed the fix/vrf-shared-per-vpc-2-cnibgp branch from 7e9f4f6 to 8dd8bef Compare August 9, 2026 21:02
privateip added a commit that referenced this pull request Aug 9, 2026
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>
privateip added a commit that referenced this pull request Aug 9, 2026
…nimaster

Rebased onto the updated fix/cni-review-followups-doc-placement
(which picked up my own rebase-and-reconcile of that branch after PR
#307 moved out from under it) after that branch's history moved out
from under this one -- same ripple as #306 -> #307 -> #315 -> #316.

Conflicts resolved: internal/cni/resource.go and internal/cnitap/
resource.go each had two independent changes touching the same
resourceTracker/cleanup() region -- this PR's own extraction of the
shared k8s-client-construction (newK8sClient/cniScheme) and interface+
VRF rollback (veth.Delete/tap.Delete + vrf.Delete) into
internal/cnimaster's NewK8sClient/CleanupAttachment, and PR #305/#306's
unrelated addition of ipamDelegated/ipamType/ipamStdin fields plus an
IPAM-release rollback step (this PR's diff predates that feature
entirely, same gap #311/#312/#315 each hit one level up). Kept both:
call cnimaster.CleanupAttachment for the interface+VRF half (this PR's
whole point), and kept the IPAM release step ahead of it, unchanged.
internal/cnitap/ops_check.go had one similar import-only conflict
(this PR drops the netlink/rest/ctrl/vrf imports cnimaster.
CheckNodeLevelState/ProbeAPIServer/RunStatus now cover internally) --
its own IPAM CHECK delegation step (ipam.ExecCheck, same predates-this-
PR gap) sat entirely outside the conflicted hunk and needed no
resolution beyond keeping the "github.com/containernetworking/plugins/
pkg/ipam" import alive.

Verification: task lint, task build (all 8 binaries), task test:unit
all pass on the rebased tree, including the new internal/cnimaster
package. tests/e2e 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant