Skip to content

[v3.33] [BPF] Keep pre-existing forwarded flows alive when switching to eBPF - #13885

Open
tomastigera wants to merge 1 commit into
projectcalico:release-v3.33from
tomastigera:auto-pick-of-#13778-upstream-release-v3.33
Open

[v3.33] [BPF] Keep pre-existing forwarded flows alive when switching to eBPF#13885
tomastigera wants to merge 1 commit into
projectcalico:release-v3.33from
tomastigera:auto-pick-of-#13778-upstream-release-v3.33

Conversation

@tomastigera

Copy link
Copy Markdown
Contributor

Switching the dataplane to eBPF drops pre-existing connections that arrive at a node port and are served by a backend on another node. The connection is silently lost on any node whose filter FORWARD policy is DROP.

A flow that pre-dates eBPF mode is kept alive by the mid-flow fallthrough: the ingress BPF program marks the packet FALLTHROUGH and lets it into the stack, Linux conntrack applies the translation it already holds, and the next BPF program allows it on the CT_ESTABLISHED mark. In eBPF mode Felix's FORWARD chain accepts bypass-marked traffic, traffic in from cali+, and traffic from bpfout.cali, and jumps to the workload dispatch chain for traffic out to cali+. A node port flow with a remote backend enters and leaves on the same host interface, so it matches none of them, collects the CT_ESTABLISHED mark, falls off the end of the chain and hits the DROP policy. Until the switch it was carried by kube-proxy's own -j KUBE-FORWARD accept, which Felix deletes as part of its kube-proxy cleanup.

INPUT has carried an accept for exactly this since the mechanism was written — the fallthrough was built for host-terminated flows such as the connection to the API server, and FORWARD only ever got the rule that sets the mark for the next program. This adds the matching accept to FORWARD, placed after the to-workload jumps so that workload destinations keep going through the dispatch chain.

FORWARD needs only the accept, not the reject and deny that follow it in INPUT. INPUT is the last word for host-terminated traffic, so it has to decide the unknown-flow case itself. A forwarded packet always meets a further BPF program on the egress interface, and that program already drops a mid-flow packet Linux conntrack does not know: tc.c sets CALI_ST_SUPPRESS_CT_STATE on the egress miss and calico_tc_skb_accepted_entrypoint returns TC_ACT_SHOT for it even when policy allowed. Denying in FORWARD would pre-empt that decision with less information.

Four functional verification specs cover the switch for service traffic, which nothing covered before: a ClusterIP with a local and a remote backend, and a node port with a local and a remote backend. kube-proxy does not run in the FV, so they install the rules it would have written, in the chains Felix deletes on the switch. The node-port-with-remote-backend spec fails without the fix and passes with it.

Release note:

Fixed a bug where pre-existing connections to a node port with a backend on another node were dropped when the dataplane was switched to eBPF mode.

AI assistance: Claude Code wrote the test code, found the root cause, and drafted the fix.

…-migration-fv

[BPF] Keep pre-existing forwarded flows alive when switching to eBPF

(cherry picked from commit d803bb9)
Copilot AI lite review requested due to automatic review settings September 11, 2026 16:24
@tomastigera
tomastigera requested a review from a team as a code owner September 11, 2026 16:24
@marvin-tigera marvin-tigera added this to the Calico v3.33.0 milestone Sep 11, 2026
@marvin-tigera marvin-tigera added release-note-required Change has user-facing impact (no matter how small) docs-pr-required Change is not yet documented labels Sep 11, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@tomastigera tomastigera added docs-not-required Docs not required for this change and removed docs-pr-required Change is not yet documented labels Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs-not-required Docs not required for this change release-note-required Change has user-facing impact (no matter how small)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants