Skip to content

wireguard: tracking only nodeIPs as AllowedIPs in tunneling mode#35895

Merged
julianwiedmann merged 5 commits intocilium:mainfrom
smagnani96:pr/allowed-ips
Jan 21, 2025
Merged

wireguard: tracking only nodeIPs as AllowedIPs in tunneling mode#35895
julianwiedmann merged 5 commits intocilium:mainfrom
smagnani96:pr/allowed-ips

Conversation

@smagnani96
Copy link
Copy Markdown
Contributor

@smagnani96 smagnani96 commented Nov 11, 2024

I tried to grasp all the details in the commit messages.

  1. wireguard: test: remove unneeded nodeEncryption test: while preparing unit tests for subsequent commits, I noticed that TestAgent_PeerConfig_WithEncryptNode can be removed, as we always expect node IPs to be in allowedIPs regardless of node encryption being enabled or not. This behavior should already be covered in the other tests.
  2. wireguard: test: rework agent tests: this is the commit that unfortunately does contribute a lot to LOCs, despite not modifying the testing logic. With this commit, I'd like to reuse the logic we have in TestAgent_PeerConfig and TestAgent_AllowedIPsRestoration for the subsequent introduced agent behaviors in different routing modes.
  3. wireguard: reduce syscall ConfigureDevice when not needed: as described in the commit message, there are a few cases in which we still configure the device even when not necessarily needed (no ep changes, no key changes, no IPs to add). This could result in unneeded syscalls being executed anyways.
  4. daemon: wireguard: add WireguardTrackAllIPsFallback flag: this is a precaution flag, used in case the new agent logic after the next commit is breaking connectivity. In tunneling mode, we will only track nodeIPs as all the pod-to-pod connections should go through the overlay. In case we're missing something, enabling this flag would allow the agent to track pod IPs even in tunnel mode.
  5. wireguard: track only nodeIPs with tunneling enabled: pretty self-explanatory. Since in tunneling we'd track only node IPs provided in UpdatePeer() , we don't need to register to IPCache events.

Fixes: #35331

Tracking only nodeIPs in WireGuard AllowedIPs with overlay routing, while preserve native routing behavior of tracking both node and pods IPs from IPCache events.

@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 11, 2024
@smagnani96 smagnani96 added the dont-merge/preview-only Only for preview or testing, don't merge it. label Nov 11, 2024
@jschwinger233 jschwinger233 added the feature/wireguard Relates to Cilium's Wireguard feature label Nov 28, 2024
@smagnani96 smagnani96 force-pushed the pr/allowed-ips branch 2 times, most recently from 8db9850 to 28d5978 Compare December 2, 2024 00:27
@smagnani96 smagnani96 changed the title wip - slim down allowedIPs for wireguard Optimize allowedIPs for wireguard with CIDRs Dec 2, 2024
@smagnani96 smagnani96 added kind/enhancement This would improve or streamline existing functionality. area/encryption Impacts encryption support such as IPSec, WireGuard, or kTLS. release-note/misc This PR makes changes that have no direct user impact. area/agent Cilium agent related. dont-merge/discussion A discussion is ongoing and should be resolved before merging, regardless of reviews & tests status. and removed dont-merge/preview-only Only for preview or testing, don't merge it. dont-merge/needs-release-note-label The author needs to describe the release impact of these changes. labels Dec 2, 2024
@smagnani96 smagnani96 force-pushed the pr/allowed-ips branch 3 times, most recently from b1455f0 to 954a71c Compare December 3, 2024 08:01
@smagnani96 smagnani96 changed the title Optimize allowedIPs for wireguard with CIDRs Wireguard: Tracking AllowedIPs according to dataplane configuration Dec 11, 2024
@smagnani96 smagnani96 marked this pull request as ready for review December 16, 2024 20:52
@smagnani96 smagnani96 requested review from a team as code owners December 16, 2024 20:52
@smagnani96 smagnani96 marked this pull request as draft December 16, 2024 20:56
@jschwinger233
Copy link
Copy Markdown
Member

I created a kind cilium (vxlan routing) using this PR, the wg output from a node is:

$ nscontainer kind-worker wg                                                                                                                                                                                  
interface: cilium_wg0                                                                                                                                                                                                
  public key: e7DcIto1CcNWZasdIPiyES1qpET0KPCU8R73zZd28FI=                                                                                                                                                           
  private key: (hidden)                                                                                                                                                                                              
  listening port: 51871                                                                                                                                                                                              
  fwmark: 0x1e00                                                                                                                                                                                                     
                                                                                                                                                                                                                     
peer: +t7+WQjJyRpVsTBEsrgKWXypwxL5FZOcPZ9y1o4oMCQ=                                                                                                                                                                   
  endpoint: 172.20.0.2:51871                                                                                                                                                                                         
  allowed ips: 10.244.0.0/24, fd00:10:244::/64, 172.20.0.2/32, fc00:c111::2/128                                                                                                                                      
  latest handshake: 1 minute, 37 seconds ago                                                                                                                                                                         
  transfer: 3.63 KiB received, 3.57 KiB sent                                                                                                                                                                         
                                                                                                                                                                                                                     
peer: WY3mQEhOPIG4B/H7tPzhcbaHzBHC3lrkkNEFOLQQukk=                                                                                                                                                                   
  endpoint: 172.20.0.5:51871                                                                                                                                                                                         
  allowed ips: 10.244.2.0/24, fd00:10:244:2::/64, 172.20.0.5/32, fc00:c111::5/128                                                                                                                                    
  latest handshake: 1 minute, 41 seconds ago                                                                                                                                                                         
  transfer: 11.79 KiB received, 11.93 KiB sent                                                                                                                                                                       
                                                                                                                                                                                                                     
peer: vr/azY9vQlnrHIt051zSa7e7SnDcWvBnLIH3Q3S9CAQ=                                                                                                                                                                   
  endpoint: 172.20.0.3:51871                                                                                                                                                                                         
  allowed ips: fd00:10:244:1::/64, 172.20.0.3/32, fc00:c111::3/128, 10.244.1.0/24                                                                                                                                    
  latest handshake: 2 minutes ago                                                                                                                                                                                    
  transfer: 14.43 KiB received, 14.00 KiB sent 

There are still cidrs in allowed ips, are they expected?

@smagnani96 smagnani96 requested a review from asauber January 7, 2025 12:03
Copy link
Copy Markdown
Member

@asauber asauber left a comment

Choose a reason for hiding this comment

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

Approving for CLI, since the new flag and its usage look correct.

Copy link
Copy Markdown
Member

@jschwinger233 jschwinger233 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 question regarding forceUpdate, others lgtm.

@smagnani96
Copy link
Copy Markdown
Contributor Author

/test

@smagnani96 smagnani96 requested a review from gandro January 13, 2025 11:09
Copy link
Copy Markdown
Member

@gandro gandro left a comment

Choose a reason for hiding this comment

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

Awesome work! Looks correct to me. I have left a few minor suggestions, though none of them are blocking to get this merged

@smagnani96 smagnani96 removed the dont-merge/waiting-for-review Requires further review before merging. label Jan 18, 2025
@smagnani96
Copy link
Copy Markdown
Contributor Author

Awesome work! Looks correct to me. I have left a few minor suggestions, though none of them are blocking to get this merged

Awesome review, many many thanks!
I just addressed the comments, hopefully improving the clarity especially in tests (2nd commit).
There's also a small improvement in the agent (last commit): in UpdatePeer we don't lock IPcache anymore when not needed.

Could you please take a look at changes? 🙏

@smagnani96
Copy link
Copy Markdown
Contributor Author

/test

Copy link
Copy Markdown
Member

@gandro gandro left a comment

Choose a reason for hiding this comment

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

Thanks for addressing the feedback! Looks almost good to me, one minor thing regarding the Init() function that I would take a look at.

This commit removes the `TestAgent_PeerConfig_WithEncryptNode` from the
WireGuard agent testing unit. There are two main reasons for this:

1. test doesn't specifically require nodeEncryption to be true to run,
   as it doesn't check the daemon config;
2. nodeEncryption use case is already covered in `TestAgent_PeerConfig`:
   we always insert in allowedIPS the node IPs regardless of the config.
   For this reason, I believe this test can be safely removed.

Signed-off-by: Simone Magnani <[email protected]>
This commit reworks the two test for the WireGuard agent
`TestAgent_AllowedIPsRestoration` and `TestAgent_PeerConfig` while
preserving the tested logic. The main changes are as follows:

1. add an `assertAllowedIPs` also inside `TestAgent_PeerConfig` to slim
   down the n. of assertions: expected allowedIPs are now provided as list
   rather than having to manually test them on multiple lines.
2. introduce `type config struct` to hold the test parameters and
   `type expectation struct` to hold expected allowedIPs for a given peer:
   this is useful for subsequent commits, as we can reuse the testing logic
   that we currently have in the agent for different routing modes. In fact,
   we are trying to slim down the set of tracked allowedIPs in WireGuard,
   and this can lead to different agent behaviors depending on the
   underlying datapath configuration (tunnel, native without CIDRs, native
   with CIDRs, etc.). This new struct defines, other than the name of
   a given test and the routing mode, the expectation that must be met
   everytime invoking the apposite `assertAllowedIPs` in the two tests.
   A single expectation is a `[]*net.IPNet` representing all the
   allowedIPs that we expect to be present on a given assertion.
3. modified the two tests according to (2): the only current behavior of
   the agent is the native routing mode in which we track all IPs.

Signed-off-by: Simone Magnani <[email protected]>
Whenever we call the `updatePeerByConfig` in the Wireguard agent, we always
perform `ConfigureDevice` even in case there are no new allowedIPs to insert.
This could result in many unneeded syscalls being used anyway, such as when:

* finishing restoring IPs for a peer with no IP to be removed;
* handling an IPCache delete event with no new IP to add.
* periodic NodeValidateImplementation with no changes to the node pubkey/IPs

The 1st ever call to `UpsertPeer()` will always configure the device, as
nodeIPs are new. On the other hand, when restoring allowedIPs or when
handling an IPCache event, we can avoid configuring the device when no
relevant changes are recorded. Note that IPs that needs to be removed
would be correctly handled and removed in any case.

Signed-off-by: Simone Magnani <[email protected]>
This commit adds an hidden flag `WireguardTrackAllIPsFallback`.
Subsequent commits will try to modify the logic of the agent depending
on the underlying routing mode, expecting significant changes mainly when
in tunneling. This flag, which is false by default, is introduced in case
the new changes break connectivity that we did not foresee. If that is the
case, reinstalling Cilium with `wireguard-track-all-ips-fallback` should
restore the previous known agent behavior, which is to add all IPs into
its allowedIPs regardless the datapath config.

Signed-off-by: Simone Magnani <[email protected]>
In the WireGuard agent, we constantly update peers configuration whenever
IPs are being upserted/removed, other than keeping track of peers' nodes
IPs. This results in having a multitude of entries both in our userspace
AllowedIPs map and in the kernel trie, requiring more memory and also
computation on each lookup.

Let's keep the datapath configuration in the loop, so that we can avoid
tracking addresses when not needed. Node IPs of a peer are always tracked
to include scenarios such as node encryption, overlay and mixed IPAM modes.
That said, the following two routing scenarios have been identified:

1. Tunnel: when using overlay, we don't need to track all IPs, since for
   pod-to-pod connections we would use node IPs in the overlay traffic.
   Therefore, no further addresses is needed, so we don't event add
   the agent as a listener for IPCache events: nodeIPs changes will
   always be handled by the UpdatePeer() logic. Another advantage of this
   approach is that IPCache updates don't need to be locked by the agent.
2. Native routing: similarly as we were doing before this patch,
   in this configuration we keep track of each IP, since we don't have
   other ways of knowing a-priori from which set of addressed a node
   will receive the traffic. Configurations such as IPAM legacy, Azure,
   AlibabaCloud, "crd" mode, delegated, would fall into this scenario.

Restoration logic when switching from tunneling to native routing should
work without problems: here the only IPs restored from allowedIPs are
node IPs, which are either kept if equal to the new ones or removed in
case they changed. Upon restart, the agent tracks all pod IPs from IPCache.

Restoration logic when switching from native routing to tunneling should
not cause problems: for the whole duration of the restoration until
`RestoreFinished` is called, we would see in the allowedIPs both the
new nodeIPs and all the restored ones. In this case, the agent would not
subscribe to IPCache changes/state, therefore it will not track these
pod IPs anymore, leading to their removal once restoration has finished.
The new pod-to-pod connectivity should go through the tunnel, so nodeIPs
must be sufficient, but if we do see failures we can use the new flag
`WireguardTrackAllIPsFallback`` (`wireguard-track-all-ips-fallback`): it
serves to preserve the old behavior of the agent even with this patch on.

In addition, this commit adds to the current agent tests the tunneling
scenario, both considering the default behavior and the fallback one when
WireguardTrackAllIPsFallback is provided. The fallback testing is intended
for tunneling mode only, as in native routing mode we would already have
the old behavior of the agent.

Fixes: cilium#35331

Signed-off-by: Simone Magnani <[email protected]>
Copy link
Copy Markdown
Member

@gandro gandro left a comment

Choose a reason for hiding this comment

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

Thank you!

@smagnani96
Copy link
Copy Markdown
Contributor Author

/test

@smagnani96 smagnani96 changed the title Wireguard: tracking only nodeIPs as AllowedIPs in tunneling mode wireguard: tracking only nodeIPs as AllowedIPs in tunneling mode Jan 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/agent Cilium agent related. area/encryption Impacts encryption support such as IPSec, WireGuard, or kTLS. feature/wireguard Relates to Cilium's Wireguard feature kind/enhancement This would improve or streamline existing functionality. release-note/misc This PR makes changes that have no direct user impact.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

wireguard: improve tracking of allowedIPs

6 participants