Skip to content

datapath: Fix update to NodeAddress table and prioritize Node IP#33629

Merged
aanm merged 3 commits intocilium:mainfrom
joamaki:pr/joamaki/fix-node-address-update
Jul 15, 2024
Merged

datapath: Fix update to NodeAddress table and prioritize Node IP#33629
aanm merged 3 commits intocilium:mainfrom
joamaki:pr/joamaki/fix-node-address-update

Conversation

@joamaki
Copy link
Copy Markdown
Contributor

@joamaki joamaki commented Jul 8, 2024

When new node addresses were added after Cilium had started the update to the internal table of node addresses accidentally removed existing addresses due to wrong kind of comparison operation.

As part of fixing this issue a similar type of problem was found with update to the fallback addresses (used as backup when selecting BPF masquerading address). This commit also fixes this issue.

This only impacts users running v1.15 with the runtime device detection enabled.

The second commit adds in the prioritization of the K8s Node IP when selecting the NodeAddress. This was a semantic
difference between the old and new code and should have been retained.

Fixes: #33234

Fix an issue in updates to node addresses which may have caused missing NodePort frontend IP addresses. May have affected NodePort/LoadBalancer services for users running with runtime device detection enabled when node's IP addresses were changed after Cilium had started.
Node IP as defined in the Kubernetes Node is now preferred when selecting the NodePort frontend IPs.

@joamaki joamaki added release-note/bug This PR fixes an issue in a previous release of Cilium. release-blocker/1.16 This issue will prevent the release of the next version of Cilium. needs-backport/1.15 labels Jul 8, 2024
@joamaki joamaki changed the title datapath: Fix update to NodeAddress table datapath: Fix update to NodeAddress table and prioritize Node IP Jul 8, 2024
@joamaki joamaki force-pushed the pr/joamaki/fix-node-address-update branch from dd13590 to d5e1f5f Compare July 8, 2024 14:54
@joamaki joamaki requested review from brb and dylandreimerink July 8, 2024 14:55
@joamaki joamaki force-pushed the pr/joamaki/fix-node-address-update branch 2 times, most recently from ec14b8c to a1f83af Compare July 8, 2024 15:01
@joamaki joamaki added the backport/author The backport will be carried out by the author of the PR. label Jul 8, 2024
@joamaki
Copy link
Copy Markdown
Contributor Author

joamaki commented Jul 9, 2024

/test

@joamaki joamaki marked this pull request as ready for review July 9, 2024 08:20
@joamaki joamaki requested a review from a team as a code owner July 9, 2024 08:20
@joamaki joamaki force-pushed the pr/joamaki/fix-node-address-update branch 2 times, most recently from 2566813 to 4c886f2 Compare July 9, 2024 09:37
Copy link
Copy Markdown
Member

@dylandreimerink dylandreimerink left a comment

Choose a reason for hiding this comment

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

Just a small nit

@joamaki
Copy link
Copy Markdown
Contributor Author

joamaki commented Jul 9, 2024

/test

Copy link
Copy Markdown
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.

As discussed offline, let's split the first commit into two, and then update the commit msg to include more info on the first fix.

@joamaki joamaki force-pushed the pr/joamaki/fix-node-address-update branch 2 times, most recently from ae29acc to 2af1d78 Compare July 10, 2024 14:46
@joamaki
Copy link
Copy Markdown
Contributor Author

joamaki commented Jul 10, 2024

As discussed offline, let's split the first commit into two, and then update the commit msg to include more info on the first fix.

Done!

@joestringer joestringer added this to the 1.16 milestone Jul 10, 2024
Copy link
Copy Markdown
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!

@brb
Copy link
Copy Markdown
Member

brb commented Jul 11, 2024

/test

@joamaki joamaki force-pushed the pr/joamaki/fix-node-address-update branch from 2af1d78 to a12e94d Compare July 12, 2024 10:58
@joamaki
Copy link
Copy Markdown
Contributor Author

joamaki commented Jul 12, 2024

/test

@aanm aanm enabled auto-merge July 12, 2024 14:21
joamaki added 3 commits July 15, 2024 10:20
The fallback addresses in Table[NodeAddress] were not properly updated
when the address was removed. Fix this by clearing the addresses first
when updating the fallbacks.

Signed-off-by: Jussi Maki <jussi@isovalent.com>
When new node addresses were added after Cilium had started the
update to the internal table of node addresses accidentally removed
existing addresses due to comparing the NodeAddress instead of netip.Addr
which caused change in e.g. the NodePort flag to indicate that the address
should be removed.

As an example:
  Before:
    NodeAddress{Device: "eth0", Addr: "10.0.0.5", NodePort: true}

  After (expected):
    NodeAddress{Device: "eth0", Addr: "10.0.0.1", NodePort: true}
    NodeAddress{Device: "eth0", Addr: "10.0.0.5", NodePort: false}

  After (actual):
    NodeAddress{Device: "eth0", Addr: "10.0.0.1", NodePort: true}

What happened was that the code was removing anything old that wasn't in
the new set of addresses, leading it to essentially this comparison:
    NodeAddress{"eth0", "10.0.0.5", true} !=
	  NodeAddress{"eth0", "10.0.0.5", false}

The result of which was that the address "10.0.0.5" was updated and then
subsequently deleted.

Fix this by reworking the code to keep the old set of addresses as netip.Addr
and reducing that set down when inserting the new entries and then finally
cleaning up what remains.

The prefix match comment on the device name and the prefix length check was
removed as this issue had been fixed in StateDB.

As far as we can tell, the only production impact this could have had would
have been to users of v1.16 pre-releases or users running v1.15 with the
experimental runtime device detection enabled (only then would have changes
to Table[NodeAddress] mattered).

Fixes: cilium#33234
Signed-off-by: Jussi Maki <jussi@isovalent.com>
The K8s Node IP address should be preferred when choosing the NodePort and
Primary (BPF masquerade) addresses.

Signed-off-by: Jussi Maki <jussi@isovalent.com>
@joamaki joamaki force-pushed the pr/joamaki/fix-node-address-update branch from a12e94d to 899ff3a Compare July 15, 2024 08:20
@joamaki
Copy link
Copy Markdown
Contributor Author

joamaki commented Jul 15, 2024

/test

@aanm aanm added this pull request to the merge queue Jul 15, 2024
@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 Jul 15, 2024
Merged via the queue into cilium:main with commit f8eba9a Jul 15, 2024
@joestringer joestringer added backport-done/1.16 The backport for Cilium 1.16.x for this PR is done. and removed backport-pending/1.16 labels Jul 16, 2024
@github-actions github-actions bot added backport-done/1.15 The backport for Cilium 1.15.x for this PR is done. and removed backport-pending/1.15 labels Jul 16, 2024
usiegj00 added a commit to buildio/cilium that referenced this pull request Jan 25, 2026
…face

When a network device has multiple IP addresses (both public and
private), BPF masquerading was incorrectly selecting the Kubernetes
Node IP even when it was a private address and a public address was
available on the same interface.

The issue was introduced in PR cilium#33629 which added K8s Node IP
prioritization. The code was setting both ipv4PublicIndex and
ipv4PrivateIndex to the K8s Node IP index, effectively forcing
it to be selected regardless of public/private status. This broke
the documented "prefer public over private" logic for Primary
address selection used by BPF masquerading.

The fix ensures that K8s Node IP prioritization only applies within
its own category (public or private):
- If K8s Node IP is public, it takes precedence over other public IPs
- If K8s Node IP is private, it takes precedence over other private IPs
- But public IPs still take precedence over private IPs for masquerading

This restores the correct behavior where egress traffic is masqueraded
using the public IP address when available, which is required for
proper routing in environments with both public and private IPs on
the same interface.

Fixes: cilium#41866
usiegj00 added a commit to buildio/cilium that referenced this pull request Jan 25, 2026
…face

When a network device has multiple IP addresses (both public and
private), BPF masquerading was incorrectly selecting the Kubernetes
Node IP even when it was a private address and a public address was
available on the same interface.

The issue was introduced in PR cilium#33629 which added K8s Node IP
prioritization. The code was setting both ipv4PublicIndex and
ipv4PrivateIndex to the K8s Node IP index, effectively forcing
it to be selected regardless of public/private status. This broke
the documented "prefer public over private" logic for Primary
address selection used by BPF masquerading.

The fix ensures that K8s Node IP prioritization only applies within
its own category (public or private):
- If K8s Node IP is public, it takes precedence over other public IPs
- If K8s Node IP is private, it takes precedence over other private IPs
- But public IPs still take precedence over private IPs for masquerading

This restores the correct behavior where egress traffic is masqueraded
using the public IP address when available, which is required for
proper routing in environments with both public and private IPs on
the same interface.

Fixes: cilium#41866
usiegj00 added a commit to buildio/cilium that referenced this pull request Jan 25, 2026
…face

When a network device has multiple IP addresses (both public and
private), BPF masquerading was incorrectly selecting the Kubernetes
Node IP even when it was a private address and a public address was
available on the same interface.

The issue was introduced in PR cilium#33629 which added K8s Node IP
prioritization. The code was setting both ipv4PublicIndex and
ipv4PrivateIndex to the K8s Node IP index, effectively forcing
it to be selected regardless of public/private status. This broke
the documented "prefer public over private" logic for Primary
address selection used by BPF masquerading.

The fix ensures that K8s Node IP prioritization only applies within
its own category (public or private):
- If K8s Node IP is public, it takes precedence over other public IPs
- If K8s Node IP is private, it takes precedence over other private IPs
- But public IPs still take precedence over private IPs for masquerading

This restores the correct behavior where egress traffic is masqueraded
using the public IP address when available, which is required for
proper routing in environments with both public and private IPs on
the same interface.

Fixes: cilium#41866
Signed-off-by: Jonathan Siegel <248302+usiegj00@users.noreply.github.com>
usiegj00 added a commit to buildio/cilium that referenced this pull request Jan 25, 2026
…face

When a network device has multiple IP addresses (both public and
private), BPF masquerading was incorrectly selecting the Kubernetes
Node IP even when it was a private address and a public address was
available on the same interface.

The issue was introduced in PR cilium#33629 which added K8s Node IP
prioritization. The code was setting both ipv4PublicIndex and
ipv4PrivateIndex to the K8s Node IP index, effectively forcing
it to be selected regardless of public/private status. This broke
the documented "prefer public over private" logic for Primary
address selection used by BPF masquerading.

The fix ensures that K8s Node IP prioritization only applies within
its own category (public or private):
- If K8s Node IP is public, it takes precedence over other public IPs
- If K8s Node IP is private, it takes precedence over other private IPs
- But public IPs still take precedence over private IPs for masquerading

This restores the correct behavior where egress traffic is masqueraded
using the public IP address when available, which is required for
proper routing in environments with both public and private IPs on
the same interface.

Fixes: cilium#41866
Signed-off-by: Jonathan Siegel <248302+usiegj00@users.noreply.github.com>
pull bot pushed a commit to bhardwajRahul/cilium that referenced this pull request Jan 29, 2026
…face

When a network device has multiple IP addresses (both public and
private), BPF masquerading was incorrectly selecting the Kubernetes
Node IP even when it was a private address and a public address was
available on the same interface.

The issue was introduced in PR cilium#33629 which added K8s Node IP
prioritization. The code was setting both ipv4PublicIndex and
ipv4PrivateIndex to the K8s Node IP index, effectively forcing
it to be selected regardless of public/private status. This broke
the documented "prefer public over private" logic for Primary
address selection used by BPF masquerading.

The fix ensures that K8s Node IP prioritization only applies within
its own category (public or private):
- If K8s Node IP is public, it takes precedence over other public IPs
- If K8s Node IP is private, it takes precedence over other private IPs
- But public IPs still take precedence over private IPs for masquerading

This restores the correct behavior where egress traffic is masqueraded
using the public IP address when available, which is required for
proper routing in environments with both public and private IPs on
the same interface.

Fixes: cilium#41866
Signed-off-by: Jonathan Siegel <248302+usiegj00@users.noreply.github.com>
rastislavs pushed a commit that referenced this pull request Feb 2, 2026
…face

[ upstream commit a598dfd ]

When a network device has multiple IP addresses (both public and
private), BPF masquerading was incorrectly selecting the Kubernetes
Node IP even when it was a private address and a public address was
available on the same interface.

The issue was introduced in PR #33629 which added K8s Node IP
prioritization. The code was setting both ipv4PublicIndex and
ipv4PrivateIndex to the K8s Node IP index, effectively forcing
it to be selected regardless of public/private status. This broke
the documented "prefer public over private" logic for Primary
address selection used by BPF masquerading.

The fix ensures that K8s Node IP prioritization only applies within
its own category (public or private):
- If K8s Node IP is public, it takes precedence over other public IPs
- If K8s Node IP is private, it takes precedence over other private IPs
- But public IPs still take precedence over private IPs for masquerading

This restores the correct behavior where egress traffic is masqueraded
using the public IP address when available, which is required for
proper routing in environments with both public and private IPs on
the same interface.

Fixes: #41866
Signed-off-by: Jonathan Siegel <248302+usiegj00@users.noreply.github.com>
Signed-off-by: Rastislav Szabo <rastislav.szabo@isovalent.com>
github-merge-queue bot pushed a commit that referenced this pull request Feb 2, 2026
…face

[ upstream commit a598dfd ]

When a network device has multiple IP addresses (both public and
private), BPF masquerading was incorrectly selecting the Kubernetes
Node IP even when it was a private address and a public address was
available on the same interface.

The issue was introduced in PR #33629 which added K8s Node IP
prioritization. The code was setting both ipv4PublicIndex and
ipv4PrivateIndex to the K8s Node IP index, effectively forcing
it to be selected regardless of public/private status. This broke
the documented "prefer public over private" logic for Primary
address selection used by BPF masquerading.

The fix ensures that K8s Node IP prioritization only applies within
its own category (public or private):
- If K8s Node IP is public, it takes precedence over other public IPs
- If K8s Node IP is private, it takes precedence over other private IPs
- But public IPs still take precedence over private IPs for masquerading

This restores the correct behavior where egress traffic is masqueraded
using the public IP address when available, which is required for
proper routing in environments with both public and private IPs on
the same interface.

Fixes: #41866
Signed-off-by: Jonathan Siegel <248302+usiegj00@users.noreply.github.com>
Signed-off-by: Rastislav Szabo <rastislav.szabo@isovalent.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport/author The backport will be carried out by the author of the PR. backport-done/1.15 The backport for Cilium 1.15.x for this PR is done. backport-done/1.16 The backport for Cilium 1.16.x for this PR is done. ready-to-merge This PR has passed all tests and received consensus from code owners to merge. release-blocker/1.16 This issue will prevent the release of the next version of Cilium. release-note/bug This PR fixes an issue in a previous release of Cilium.

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

NodeAddress controller can drop addresses on table update

5 participants