Repository navigation
fix: Remove tenant taps that outlived their VPCAttachment - #1331
Conversation
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
|
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. |
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
Fixes #1330