-
Notifications
You must be signed in to change notification settings - Fork 3.4k
wireguard: restore allowedIPs upon agent restart #34095
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
/test |
4e8ac12
to
8736161
Compare
/test |
8736161
to
85e5114
Compare
Rebased and fix a conflict with #34373 |
/test |
2 similar comments
/test |
/test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nothing stands out to me here that would hold this back
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM for sig-agent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great find and great fix, thanks so much!
85e5114
to
73df40a
Compare
Currently, temporary connection disruption can occur on agent restart when Cilium is configured in native routing mode, and WireGuard encryption is enabled, because the list of AllowedIPs gets recreated from scratch upon the reception of the node event for each given remote node, possibly removing entries for valid endpoints that have not yet been discovered at that point through the CiliumEndpoint CRD or the corresponding kvstore representation. This issue, instead, does not affect the current implementation in tunnel mode, as in that case we encrypt encapsulated traffic, which always has source and destination addresses corresponding to Node Internal IPs, that are immediately added as Allowed IPs. Let's prevent this issue restoring the list of Allowed IPs for each peer from the WireGuard state after agent restart and preserving them until ipcache synchronization has been completed. At that point, we do a final GC pass to clean up possible stale entries for pods that got removed while the given agent was down. Special logic is introduced to prevent a possible flipping behavior in case upon restore an allowed IP is associated with a given peer, but gets associated with a different one later on. Indeed, WireGuard enforces that any allowed IP is associated to at most a single peer. Fixes: 31979 Signed-off-by: Marco Iorio <marco.iorio@isovalent.com>
73df40a
to
5ba874d
Compare
/test |
Recent flakes in the "Network performance GKE" tests, in particular those that use wireguard, uncovered an issue where updates to a peer's allowed IPs can cause connectivity issues. In the best case this may just result in dropped packets while in the worst case may lead to failed calls to sendto/sendmsg (see ciliumGH-33159 for more detail on some of the symptoms observed while running netperf). This issue happens when ReplaceAllowedIPs is set, as it causes the wireguard driver to completely clear the set of allowed IPs for a peer before the set is rebuilt. This leaves a gap where packets sent or received at that time will appear to not have a peer associated with them. The current implementation sets ReplaceAllowedIPs every time updatePeerByConfig is called, but we can avoid ever needing to use it. This commit uses a "dummy peer" as a way to remove allowed IPs from a peer rather than using ReplaceAllowedIPs. We use peerConfig to track any pending IP inserts and removals and split these into two different sets of updates in updatePeerByConfig. The first call to ConfigureDevice() adds any IPs that are pending insertion. Next, any IPs that are pending removal are moved to the "dummy peer" before removing the dummy peer altogether, the net effect being that the IP is removed from the original peer's list of allowed IPs. In order to preserve the behavior introduced by ciliumGH-34095 ("wireguard: restore allowedIPs upon agent restart") this commit adds syncPeersWithDevice which removes any stale peers or allowed IPs on initialization. This commit mostly sidesteps the issue that ciliumGH-34095 set out to solve since we only ever explitly remove allowed IPs, meaning we can do away with a lot of the accounting previously done in restoredPeers and restoredAllowedIPs. Fixes: cilium#33159 Signed-off-by: Jordan Rife <jrife@google.com>
Recent flakes in the "Network performance GKE" tests, in particular those that use wireguard, uncovered an issue where updates to a peer's allowed IPs can cause connectivity issues. In the best case this may just result in dropped packets while in the worst case may lead to failed calls to sendto/sendmsg (see ciliumGH-33159 for more detail on some of the symptoms observed while running netperf). This issue happens when ReplaceAllowedIPs is set, as it causes the wireguard driver to completely clear the set of allowed IPs for a peer before the set is rebuilt. This leaves a gap where packets sent or received at that time will appear to not have a peer associated with them. The current implementation sets ReplaceAllowedIPs every time updatePeerByConfig is called, but we can avoid ever needing to use it. This commit uses a "dummy peer" as a way to remove allowed IPs from a peer rather than using ReplaceAllowedIPs. We use peerConfig to track any pending IP inserts and removals and split these into two different sets of updates in updatePeerByConfig. The first call to ConfigureDevice() adds any IPs that are pending insertion. Next, any IPs that are pending removal are moved to the "dummy peer" before removing the dummy peer altogether, the net effect being that the IP is removed from the original peer's list of allowed IPs. This commit mostly sidesteps the issue that ciliumGH-34095 ("wireguard: restore allowedIPs upong agent restart") set out to solve since we only ever explicitly remove allowed IPs, meaning we can do away with a lot of the accounting previously done by restoredPeers and restoredAllowedIPs. However, we retain the behavior in RestoreFinished() that removes stale peers and allowed IPs. Fixes: cilium#33159 Signed-off-by: Jordan Rife <jrife@google.com>
Recent flakes in the "Network performance GKE" tests, in particular those that use wireguard, uncovered an issue where updates to a peer's allowed IPs can cause connectivity issues. In the best case this may just result in dropped packets while in the worst case may lead to failed calls to sendto/sendmsg (see ciliumGH-33159 for more detail on some of the symptoms observed while running netperf). This issue happens when ReplaceAllowedIPs is set, as it causes the wireguard driver to completely clear the set of allowed IPs for a peer before the set is rebuilt. This leaves a gap where packets sent or received at that time will appear to not have a peer associated with them. The current implementation sets ReplaceAllowedIPs every time updatePeerByConfig is called, but we can avoid ever needing to use it. This commit uses a "dummy peer" as a way to remove allowed IPs from a peer rather than using ReplaceAllowedIPs. We use peerConfig to track any pending IP inserts and removals and split these into two different sets of updates in updatePeerByConfig. The first call to ConfigureDevice() adds any IPs that are pending insertion. Next, any IPs that are pending removal are moved to the "dummy peer" before removing the dummy peer altogether, the net effect being that the IP is removed from the original peer's list of allowed IPs. This commit mostly sidesteps the issue that ciliumGH-34095 ("wireguard: restore allowedIPs upong agent restart") set out to solve since we only ever explicitly remove allowed IPs, meaning we can do away with a lot of the accounting previously done by restoredPeers and restoredAllowedIPs. However, we retain the behavior in RestoreFinished() that removes stale peers and allowed IPs. Fixes: cilium#33159 Signed-off-by: Jordan Rife <jrife@google.com>
Recent flakes in the "Network performance GKE" tests, in particular those that use wireguard, uncovered an issue where updates to a peer's allowed IPs can cause connectivity issues. In the best case this may just result in dropped packets while in the worst case may lead to failed calls to sendto/sendmsg (see ciliumGH-33159 for more detail on some of the symptoms observed while running netperf). This issue happens when ReplaceAllowedIPs is set, as it causes the wireguard driver to completely clear the set of allowed IPs for a peer before the set is rebuilt. This leaves a gap where packets sent or received at that time will appear to not have a peer associated with them. The current implementation sets ReplaceAllowedIPs every time updatePeerByConfig is called, but we can avoid ever needing to use it. This commit uses a "dummy peer" as a way to remove allowed IPs from a peer rather than using ReplaceAllowedIPs. We use peerConfig to track any pending IP inserts and removals and split these into two different sets of updates in updatePeerByConfig. The first call to ConfigureDevice() adds any IPs that are pending insertion. Next, any IPs that are pending removal are moved to the "dummy peer" before removing the dummy peer altogether, the net effect being that the IP is removed from the original peer's list of allowed IPs. This commit mostly sidesteps the issue that ciliumGH-34095 ("wireguard: restore allowedIPs upong agent restart") set out to solve since we only ever explicitly remove allowed IPs, meaning we can do away with a lot of the accounting previously done by restoredPeers and restoredAllowedIPs. However, we retain the behavior in RestoreFinished() that removes stale peers and allowed IPs. Fixes: cilium#33159 Signed-off-by: Jordan Rife <jrife@google.com>
Recent flakes in the "Network performance GKE" tests, in particular those that use wireguard, uncovered an issue where updates to a peer's allowed IPs can cause connectivity issues. In the best case this may just result in dropped packets while in the worst case may lead to failed calls to sendto/sendmsg (see GH-33159 for more detail on some of the symptoms observed while running netperf). This issue happens when ReplaceAllowedIPs is set, as it causes the wireguard driver to completely clear the set of allowed IPs for a peer before the set is rebuilt. This leaves a gap where packets sent or received at that time will appear to not have a peer associated with them. The current implementation sets ReplaceAllowedIPs every time updatePeerByConfig is called, but we can avoid ever needing to use it. This commit uses a "dummy peer" as a way to remove allowed IPs from a peer rather than using ReplaceAllowedIPs. We use peerConfig to track any pending IP inserts and removals and split these into two different sets of updates in updatePeerByConfig. The first call to ConfigureDevice() adds any IPs that are pending insertion. Next, any IPs that are pending removal are moved to the "dummy peer" before removing the dummy peer altogether, the net effect being that the IP is removed from the original peer's list of allowed IPs. This commit mostly sidesteps the issue that GH-34095 ("wireguard: restore allowedIPs upong agent restart") set out to solve since we only ever explicitly remove allowed IPs, meaning we can do away with a lot of the accounting previously done by restoredPeers and restoredAllowedIPs. However, we retain the behavior in RestoreFinished() that removes stale peers and allowed IPs. Fixes: #33159 Signed-off-by: Jordan Rife <jrife@google.com>
[ upstream commit 3ebfa4d ] [ backporter's note: minor conflict in agent_test.go due to missing iter packeage in go 1.22 ] Recent flakes in the "Network performance GKE" tests, in particular those that use wireguard, uncovered an issue where updates to a peer's allowed IPs can cause connectivity issues. In the best case this may just result in dropped packets while in the worst case may lead to failed calls to sendto/sendmsg (see GH-33159 for more detail on some of the symptoms observed while running netperf). This issue happens when ReplaceAllowedIPs is set, as it causes the wireguard driver to completely clear the set of allowed IPs for a peer before the set is rebuilt. This leaves a gap where packets sent or received at that time will appear to not have a peer associated with them. The current implementation sets ReplaceAllowedIPs every time updatePeerByConfig is called, but we can avoid ever needing to use it. This commit uses a "dummy peer" as a way to remove allowed IPs from a peer rather than using ReplaceAllowedIPs. We use peerConfig to track any pending IP inserts and removals and split these into two different sets of updates in updatePeerByConfig. The first call to ConfigureDevice() adds any IPs that are pending insertion. Next, any IPs that are pending removal are moved to the "dummy peer" before removing the dummy peer altogether, the net effect being that the IP is removed from the original peer's list of allowed IPs. This commit mostly sidesteps the issue that GH-34095 ("wireguard: restore allowedIPs upong agent restart") set out to solve since we only ever explicitly remove allowed IPs, meaning we can do away with a lot of the accounting previously done by restoredPeers and restoredAllowedIPs. However, we retain the behavior in RestoreFinished() that removes stale peers and allowed IPs. Fixes: #33159 Signed-off-by: Jordan Rife <jrife@google.com>
[ upstream commit 3ebfa4d ] [ backporter's note: minor conflict in agent_test.go due to missing iter packeage in go 1.22 ] Recent flakes in the "Network performance GKE" tests, in particular those that use wireguard, uncovered an issue where updates to a peer's allowed IPs can cause connectivity issues. In the best case this may just result in dropped packets while in the worst case may lead to failed calls to sendto/sendmsg (see GH-33159 for more detail on some of the symptoms observed while running netperf). This issue happens when ReplaceAllowedIPs is set, as it causes the wireguard driver to completely clear the set of allowed IPs for a peer before the set is rebuilt. This leaves a gap where packets sent or received at that time will appear to not have a peer associated with them. The current implementation sets ReplaceAllowedIPs every time updatePeerByConfig is called, but we can avoid ever needing to use it. This commit uses a "dummy peer" as a way to remove allowed IPs from a peer rather than using ReplaceAllowedIPs. We use peerConfig to track any pending IP inserts and removals and split these into two different sets of updates in updatePeerByConfig. The first call to ConfigureDevice() adds any IPs that are pending insertion. Next, any IPs that are pending removal are moved to the "dummy peer" before removing the dummy peer altogether, the net effect being that the IP is removed from the original peer's list of allowed IPs. This commit mostly sidesteps the issue that GH-34095 ("wireguard: restore allowedIPs upong agent restart") set out to solve since we only ever explicitly remove allowed IPs, meaning we can do away with a lot of the accounting previously done by restoredPeers and restoredAllowedIPs. However, we retain the behavior in RestoreFinished() that removes stale peers and allowed IPs. Fixes: #33159 Signed-off-by: Jordan Rife <jrife@google.com>
Currently, temporary connection disruption can occur on agent restart when Cilium is configured in native routing mode, and WireGuard encryption is enabled, because the list of AllowedIPs gets recreated from scratch upon the reception of the node event for each given remote node, possibly removing entries for valid endpoints that have not yet been discovered at that point through the CiliumEndpoint CRD or the corresponding kvstore representation. This issue, instead, does not affect the current implementation in tunnel mode, as in that case we encrypt encapsulated traffic, which always has source and destination addresses corresponding to Node Internal IPs, that are immediately added as Allowed IPs.
Let's prevent this issue restoring the list of Allowed IPs for each peer from the WireGuard state after agent restart and preserving them until ipcache synchronization has been completed. At that point, we do a final GC pass to clean up possible stale entries for pods that got removed while the given agent was down. Special logic is introduced
to prevent a possible flipping behavior in case upon restore an allowed IP is associated with a given peer, but gets associated with a different one later on. Indeed, WireGuard enforces that any allowed IP is associated to at most a single peer.
Fixes: #31979