Skip to content

Conversation

julianwiedmann
Copy link
Member

@julianwiedmann julianwiedmann commented Nov 14, 2023

With eff26cf ("datapath: Fix double SNAT") the outbound SNAT path now
sets ctx_snat_done_set() after checking whether a packet requires SNAT.
This was meant to avoid double-NATing when a packet passes through multiple
network interfaces with a to-netdev program.

But looking at the SNAT code in detail, some of its conditions only apply
on specific interfaces (see nodeport_has_nat_conflict_ipv4(), which
checks for `NATIVE_DEV_IFINDEX == DIRECT_ROUTING_DEV_IFINDEX`). So if a
packet passes through multiple interfaces which all have `to-netdev`
attached, the first `to-netdev` program might set SNAT_DONE even when some
subsequent program (attached to DIRECT_ROUTING_DEV_IFINDEX) would still
want to apply SNAT to the packet.

Therefore we should apply the SNAT checks on *each* interface, until we
have actually SNATed the packet. Only then set the SNAT_DONE marker.

Note that this also fixes an EgressGW bug in nodeport_snat_fwd_ipv4(),
where we would redirect the packet even if snat_v4_nat() reported an error.

Fixes: eff26cf ("datapath: Fix double SNAT")
When using stacked network interfaces (such as br0 -> eth0) in the egress path, ensure that BPF SNAT checks are applied on all interfaces.

@julianwiedmann julianwiedmann added area/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages. feature/egress-gateway Impacts the egress IP gateway feature. feature/snat Relates to SNAT or Masquerading of traffic labels Nov 14, 2023
@maintainer-s-little-helper maintainer-s-little-helper bot added the dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. label Nov 14, 2023
@julianwiedmann
Copy link
Member Author

/test

With eff26cf ("datapath: Fix double SNAT") the outbound SNAT path now
sets ctx_snat_done_set() after checking whether a packet requires SNAT.
This was meant to avoid double-NATing when a packet passes through multiple
network interfaces with a to-netdev program.

But looking at the SNAT code in detail, some of its conditions only apply
on specific interfaces (see nodeport_has_nat_conflict_ipv4(), which
checks for `NATIVE_DEV_IFINDEX == DIRECT_ROUTING_DEV_IFINDEX`). So if a
packet passes through multiple interfaces which all have `to-netdev`
attached, the first `to-netdev` program might set SNAT_DONE even when some
subsequent program (attached to DIRECT_ROUTING_DEV_IFINDEX) would still
want to apply SNAT to the packet.

Therefore we should apply the SNAT checks on *each* interface, until we
have actually SNATed the packet. Only then set the SNAT_DONE marker.

Note that this also fixes an EgressGW bug in nodeport_snat_fwd_ipv4(),
where we would redirect the packet even if snat_v4_nat() reported an error.

Fixes: eff26cf ("datapath: Fix double SNAT")
Signed-off-by: Julian Wiedmann <jwi@isovalent.com>
@julianwiedmann julianwiedmann added kind/bug This is a bug in the Cilium logic. release-note/bug This PR fixes an issue in a previous release of Cilium. needs-backport/1.12 and removed dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. labels Nov 20, 2023
@julianwiedmann julianwiedmann requested a review from brb November 20, 2023 09:57
@julianwiedmann julianwiedmann marked this pull request as ready for review November 20, 2023 09:57
@julianwiedmann julianwiedmann requested a review from a team as a code owner November 20, 2023 09:57
@julianwiedmann
Copy link
Member Author

/test

@julianwiedmann julianwiedmann changed the title bpf: fixes for SNAT_DONE bpf: nat: only set SNAT_DONE when packet was actually SNATed Nov 20, 2023
Copy link
Member

@brb brb left a comment

Choose a reason for hiding this comment

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

Thanks!

@maintainer-s-little-helper maintainer-s-little-helper bot added the ready-to-merge This PR has passed all tests and received consensus from code owners to merge. label Nov 22, 2023
@lmb lmb merged commit 2393707 into cilium:main Nov 22, 2023
@julianwiedmann julianwiedmann deleted the 1.15-bpf-snat-mark-fix branch November 22, 2023 13:42
@joamaki joamaki mentioned this pull request Nov 29, 2023
4 tasks
@joamaki joamaki mentioned this pull request Nov 29, 2023
4 tasks
@joamaki joamaki mentioned this pull request Nov 29, 2023
14 tasks
@joamaki joamaki added the backport-pending/1.14 The backport for Cilium 1.14.x for this PR is in progress. label Nov 29, 2023
@github-actions github-actions bot added backport-done/1.14 The backport for Cilium 1.14.x for this PR is done. backport-done/1.12 The backport for Cilium 1.12.x for this PR is done. backport-done/1.13 The backport for Cilium 1.13.x for this PR is done. and removed backport-pending/1.14 The backport for Cilium 1.14.x for this PR is in progress. backport-pending/1.12 labels Dec 1, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/datapath Impacts bpf/ or low-level forwarding details, including map management and monitor messages. backport-done/1.12 The backport for Cilium 1.12.x for this PR is done. backport-done/1.13 The backport for Cilium 1.13.x for this PR is done. backport-done/1.14 The backport for Cilium 1.14.x for this PR is done. feature/egress-gateway Impacts the egress IP gateway feature. feature/snat Relates to SNAT or Masquerading of traffic kind/bug This is a bug in the Cilium logic. ready-to-merge This PR has passed all tests and received consensus from code owners to merge. release-note/bug This PR fixes an issue in a previous release of Cilium.
Projects
No open projects
Status: Released
Status: Released
Status: Released
Development

Successfully merging this pull request may close these issues.

4 participants