Skip to content

fix: Explicitly flush guest netns route/address on CNI DEL - #271

Merged
privateip merged 1 commit into
mainfrom
fix/hostnetwork-cni-del-route-flush
Jul 31, 2026
Merged

fix: Explicitly flush guest netns route/address on CNI DEL#271
privateip merged 1 commit into
mainfrom
fix/hostnetwork-cni-del-route-flush

Conversation

@privateip

Copy link
Copy Markdown
Contributor

Summary

Pods with a hostNetwork sandbox plus a Multus secondary VPC attachment got permanently wedged on ADD retry with configure IPAM: add default route ...: file exists. Their args.Netns resolves to the host's own root namespace rather than a distinct per-sandbox one, since the pod uses hostNetwork.

DEL relied on host-device DEL moving the guest veth end back out of the container netns to flush its address/route as a side effect of crossing a namespace boundary. For a hostNetwork pod that "move" is a no-op (source and destination netns are the same), so the kernel never triggers the flush, and the leftover default route survives indefinitely — there's no ephemeral sandbox netns to reclaim it. The prior ADD-side idempotency fix (#269's follow-up, 00382cf) didn't help here since it only checks for a matching route on the same link, not one left behind by an earlier attempt.

flushGuestNetnsConfig now removes the guest interface's default route(s) and non-link-local addresses directly, without deleting the link itself (it's a shared veth pair with host-side VRF wiring other pod instances may still depend on). cmdDel calls it unconditionally ahead of host-device DEL, so cleanup no longer depends on the move-triggered flush firing.

Test plan

  • task lint
  • task build
  • task test:unit (root-gated netns tests could not execute in this sandbox — its nested user namespace can't create veth/dummy links at all, confirmed identical on main; they follow the same requireRoot pattern as pre-existing passing tests)
  • task test:e2e (not run — needs a Kind cluster)
  • Verify against a real hostNetwork + Multus secondary-attachment pod retry in a live cluster

Pods with a hostNetwork sandbox plus a Multus secondary VPC attachment
got permanently wedged on ADD retry with "configure IPAM: add default
route ... file exists", because their args.Netns resolves to the
host's own root namespace rather than a distinct per-sandbox one.

DEL relied on host-device DEL moving the guest veth end back out of
the container netns to flush its address/route as a side effect of
crossing a namespace boundary. For a hostNetwork pod that "move" is a
no-op (source and destination netns are the same), so the kernel never
triggers the flush, and the leftover default route survives
indefinitely — there is no ephemeral sandbox netns to reclaim it. The
prior ADD-side idempotency fix (00382cf) didn't help here since it
only checks for a matching route on the same link, not one left behind
by an earlier attempt.

flushGuestNetnsConfig now removes the guest interface's default
route(s) and non-link-local addresses directly, without deleting the
link itself (it's a shared veth pair with host-side VRF wiring other
pod instances may still depend on). cmdDel calls it unconditionally
ahead of host-device DEL, so cleanup no longer depends on the
move-triggered flush firing.
@privateip
privateip requested a review from a team as a code owner July 31, 2026 14:55
@privateip
privateip requested review from 0xmc, savme and slindseysr July 31, 2026 14:55
@privateip
privateip merged commit 89b9a09 into main Jul 31, 2026
9 checks passed
@privateip
privateip deleted the fix/hostnetwork-cni-del-route-flush branch July 31, 2026 15:05
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.

2 participants