Skip to content

fix: Remove tenant taps that outlived their VPCAttachment - #1331

Merged
privateip merged 1 commit into
mainfrom
fix/issue-1330
Nov 3, 2026
Merged

privateip merged 1 commit into
mainfrom
fix/issue-1330

Conversation

@privateip

Copy link
Copy Markdown
Collaborator

Summary

A tenant tap whose CNI DEL never ran stayed on the node forever once its BGP advertisement was gone, with a dead route, a traffic policy row counted as unattributed drops, and its map rows.

The CNI daemon now removes such a tap when no VM holds it open and no advertisement or VPC attachment names it, after two consecutive passes agree. It first clears the same per-interface datapath rows that DEL clears, then deletes the tap, and the kernel takes its routes with it.

The daemon gains read access to VPC attachments, and the tap's firewall accept rules are left behind because the production image has no iptables.

Test plan

  • A detached tap with no advertisement and no attachment is removed on the second pass, along with its route and datapath rows, on a real kernel
  • A tap a VM holds, a tap a live attachment or advertisement names, and a tap restamped by a new container are all kept
  • Build, lint, unit, root and end-to-end checks pass
  • After deploy, the unattributed traffic policy counter stays flat in audit on a node that had leaked taps

Fixes #1330

A tap is removed by its sandbox's CNI DEL, or by galactic-router's GC while the attachment's BGPAdvertisement still records the tap's dead container. When the DEL never ran and the advertisement was deleted first, nothing looked at the tap again. It stayed enslaved to its VPC's VRF with a linkdown route for a prefix no live attachment owns, kept a traffic policy row with no binding so every decision on it counted as an unattributed policy_unavailable drop, and held its ifindex and map rows for the node's lifetime. On a node whose workloads are recreated on a schedule these taps accumulated with every cycle.

galactic-cni's eBPF GC tick now runs a stale tap reclaim. A candidate is a stamped tenant tap that no file descriptor holds, read from the tun queue counts so an attached but administratively down tap still counts as in use, whose (VPC, attachment) identity no BGPAdvertisement on any node and no VPCAttachment in the cluster carries. Only veths share the host link name, and a veth's host end goes with its peer's namespace, so only a tap can be left behind.

A candidate is removed only when the previous pass read every input and found it too, with the same ifindex and owner stamp, which covers an ADD that creates its tap between this pass's reads and before its VMM opens it. The removal checks again under the node's VRF lock, removes the tap's ifindex-keyed eBPF rows, then deletes the tap through tap.Delete, and the kernel removes its routes. A failed list removes nothing and restarts the confirmation, and so does a cluster that lists no VPCAttachment carrying an identity, since that says more about where attachments are read from than about the taps. A tap whose rows or link could not be removed is kept for the next pass.

The rows are removed through attachreg.UnregisterInterface, which both CNI DEL paths now share, so the reclaim and DEL clear the same traffic policy, ifindex_vrf_table, egress kind, gateway and host-only port rows. galactic-cni gains list on vpcattachments, and galactic_cni_stale_taps_pending, galactic_cni_stale_taps_reclaimed_total and galactic_cni_stale_tap_reclaim_failures_total report the passes.

The production image has no iptables, so a leaked tap's FORWARD accept rules stay behind. Which path deleted the advertisements before their taps went is still unidentified; the reclaim does not depend on it.

Fixes #1330
@privateip privateip self-assigned this Nov 3, 2026
@privateip privateip changed the title fix: Remove tenant taps that outlived their VPC attachment fix: Remove tenant taps that outlived their VPCAttachment Nov 3, 2026
@privateip
privateip marked this pull request as ready for review November 3, 2026 14:15
@privateip
privateip requested a review from a team as a code owner November 3, 2026 14:15
@privateip
privateip enabled auto-merge November 3, 2026 14:15
@privateip

Copy link
Copy Markdown
Collaborator Author

Both reviewers returned a merge verdict on the first pass. The only finding applied was a nit, so the fix phase went straight to the ready path with no second pass.

Adversary review: VERDICT: merge. No correctness defects found; the live-tap safeguards hold.

Conventions review: VERDICT: merge. Nothing above nit; galactic main deploys to staging first, galactic-cni RBAC addition is list-only, body/test plan/commit meet conventions.

Applied: the PR title now matches the commit subject. No commit was added. The reviewers' RAN lists were not in the reports the fixer received, so they are not repeated here.

CI: every check passed on head fd6aea7. The ci / Build and test job failed once in the fabric routing topology envtest (TestConflictsAndOwnership), passed on rerun, and passed locally at this head.

Auto-merge is enabled with the merge method. The main ruleset requires an approving review, code owner review, approval of the last push, and dismisses stale reviews on push, so auto-merge waits for a human approval.

@privateip
privateip merged commit 1a4bed5 into main Nov 3, 2026
27 of 28 checks passed
@privateip
privateip deleted the fix/issue-1330 branch November 3, 2026 14:21
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.

Tenant taps outlive their VPCAttachment once its BGPAdvertisement is gone

2 participants