Skip to content

fix(ingress-sidecar): remove a redirect route only via its own VRF - #1384

Draft
scotwells wants to merge 1 commit into
mainfrom
fix/ingress-sidecar-cross-vpc-route
Draft

scotwells wants to merge 1 commit into
mainfrom
fix/ingress-sidecar-cross-vpc-route

Conversation

@scotwells

@scotwells scotwells commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Scot Schuchert-Wells · project thread

Summary

The ingress sidecar deleted a backend's main-table /128 redirect by destination alone. Two VPCs can carry the same backend address: IPAM hands a deleted Network's subnet to the next Network, which the production e2e runs do every time (fd20:0:1e::/64). When the new VPC's slice is applied before the deleted VPC's slice finishes its teardown grace, ensureRedirectRoute's RouteReplace points the route at the new VPC's VRF, and the deleted VPC's teardown then deletes it. Nothing reinstalls it until the slice or the eBPF datapath changes, so every connect from Envoy to the live backend fails while Envoy still lists it as a healthy endpoint.

This matches cause 2 of datum-cloud/engineering#467 (503 with upstream_cx_connect_fail through the us-central-1 edge, intermittent, only on runs whose backend reuses the previous run's address).

The store's shared-prefix guard (prefixClaimedElsewhereLocked) only covers slices of the same VPC, so it does not catch this case.

Change

  • removeRedirectRoute now takes the VRF table, resolves its VRF device and deletes with LinkIndex set. The kernel then removes the route only while it still leaves through this VPC's VRF; a route another VPC replaced it with is kept (ESRCH, already treated as success).
  • A missing VRF device returns nil: the kernel already dropped every route through it, and any route still held for the prefix belongs to another VPC.

Testing

  • New real-kernel test TestRemoveRedirectRoute_KeepsAnotherVPCsRoute: two VRFs, same backend address, old VPC's removal keeps the new VPC's route, removal for a table with no VRF keeps it, owner's removal deletes it. It fails without the change (redirect via ifindex 0, want live VPC's 3).
  • go test -race ./internal/ingresssidecar/ as root in a privileged Linux container with the vrf module: pass. golangci-lint run ./internal/ingresssidecar/...: 0 issues.
  • Not run locally: the full task ci (e2e).
  • Not yet confirmed on the production pods: reading their main-table routes during a failing run is pending access.

The main-table /128 redirect for a backend was deleted by destination
alone. When two VPCs carry the same backend address, as when IPAM hands a
deleted Network's subnet to the next one, the live VPC's RouteReplace takes
over the route and the deleted VPC's teardown then removes it. Nothing
reinstalls it, so connects to the live backend fail until the slice or
datapath changes.

Name the VRF device in the delete so the kernel removes the route only
while it still points at the tearing-down VPC, and treat a missing VRF as
nothing left to remove.

Refs datum-cloud/engineering#467
@scotwells scotwells self-assigned this Nov 12, 2026
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