-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Fix source address selection for multi-IP interfaces in mirrored networking #13560
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
base: master
Are you sure you want to change the base?
Fix source address selection for multi-IP interfaces in mirrored networking #13560
Conversation
…orking In mirrored networking mode, when Windows interfaces have multiple IP addresses, WSL2 was incorrectly selecting source addresses for routes with non-onlink next-hops. This caused packets to use the wrong source address when communicating with gateways on specific subnets. The issue occurred when creating host routes (onlink routes) for next-hop addresses. These routes were created without source address hints, leading to incorrect source address selection by the Linux kernel's routing subsystem. This fix: - Adds PreferredSource field to the route schema (hns::Route) - Implements source address selection logic that matches the subnet of the next-hop address with local interface addresses - Passes the preferred source address through the GNS messaging system - Sets RTA_PREFSRC netlink attribute when creating routes in Linux Example scenario: - Interface has IPs: 192.168.9.147/24 and 192.168.101.147/24 - Route: 192.168.102.0/24 via 192.168.101.238 - When pinging 192.168.101.238, WSL2 now correctly uses 192.168.101.147 as source (same subnet as next-hop) Fixes microsoft#13505 Signed-off-by: Giovanni Magliocchetti <[email protected]>
…est prefix match for improved accuracy in multi-IP scenarios. Signed-off-by: Giovanni Magliocchetti <[email protected]>
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.
Pull Request Overview
Fixes incorrect source address selection in WSL2 mirrored networking when Windows interfaces have multiple IP addresses. Previously, WSL2 would create host routes without source address hints, causing the Linux kernel to select the wrong source address for communications with gateways.
Key changes:
- Implements subnet-aware source address selection algorithm using longest prefix matching
- Adds
PreferredSourcefield to route schema and data structures across Windows and Linux components - Updates route creation to set
RTA_PREFSRCnetlink attribute for proper source address hints
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/windows/service/exe/WslMirroredNetworking.cpp |
Implements source address selection algorithm and applies it during route creation |
src/windows/service/exe/WslCoreTcpIpStateTracking.h |
Updates route message conversion to include preferred source |
src/windows/service/exe/WslCoreNetworkEndpointSettings.h |
Adds PreferredSource fields to EndpointRoute struct |
src/shared/inc/hns_schema.h |
Adds PreferredSource field to Route schema |
src/linux/netlinkutil/RoutingTable.cpp |
Updates netlink message creation to set RTA_PREFSRC attribute |
src/linux/netlinkutil/Route.h |
Adds preferredSource field to Route struct |
src/linux/init/GnsEngine.cpp |
Extracts and processes preferred source from incoming route messages |
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Algorithm Improvements (7dbd7b3)The source address selection algorithm has been optimized with longest prefix match logic:
This matches the routing behavior of standard network protocols and ensures correct source address selection in complex multi-subnet configurations. |
OneBlue
left a comment
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.
@obrobrio2000: You currently have 6 open pull requests in this repository. Let's focus on the existing pull requests before opening new ones.
Fixes #13505
Summary
Fixes incorrect source address selection when Windows interfaces have multiple IP addresses in mirrored networking mode. WSL2 now correctly selects the source address from the same subnet as the next-hop gateway.
Problem Description
In mirrored networking mode, when a Windows interface has multiple IP addresses (e.g.,
192.168.9.147/24and192.168.101.147/24), WSL2 was creating host routes for next-hop addresses without source address hints. This caused the Linux kernel to select an incorrect source address when communicating with gateways.Example scenario:
192.168.9.147/24and192.168.101.147/24192.168.102.0/24via192.168.101.238192.168.101.238, source should be192.168.101.147192.168.9.147Root Cause
When WSL2 creates on-link host routes for next-hop addresses (required for Linux routing), it was not setting the preferred source address hint (
RTA_PREFSRC). Without this hint, the Linux kernel's default source address selection could pick the wrong interface address.The route created was:
But should have been:
Solution
This PR implements end-to-end source address selection for mirrored networking routes:
Changes Made
Schema Changes:
PreferredSourcefield tohns::Routestruct inhns_schema.hPreferredSourceandPreferredSourceStringfields toEndpointRoutestructWindows Side (Route Creation):
FindSourceAddressForNextHop()helper function with:memcmp()instead of byte-by-byte iterationProcessRouteChange()to call the helper and setPreferredSourcewhen creating host routesTrackedRoute::ConvertToHnsSettingsMsg()to includePreferredSourcein GNS messagesLinux Side (Route Application):
preferredSourcefield toRoutestructGnsEngine::ProcessRouteChange()to extractPreferredSourcefrom incoming messagesRoutingTable::ModifyLinkLocalRouteImpl()to setRTA_PREFSRCnetlink attributeModifyOfflinkRouteImpl()for consistency and future use casesAlgorithm
The source address selection algorithm uses longest prefix match to select the most specific matching subnet when multiple addresses match:
IPv4 Implementation:
/0(match any),/32(exact match), and all intermediate prefixesmask <<= 32by explicit case handlingntohl()for correct bitwise operationsIPv6 Implementation:
memcmp()for full bytes (2-4x faster than byte-by-byte)Example Scenario:
Interface has addresses:
10.0.0.5/8(prefix length 8)10.1.0.5/16(prefix length 16)10.1.2.5/24(prefix length 24)Next-hop:
10.1.2.1Algorithm finds all three addresses match, but selects
10.1.2.5/24because it has the longest prefix (most specific subnet).Testing
Manual Testing Scenario
To test this fix:
Configure Windows interface with multiple IPs:
Add a route with a gateway in one of the subnets:
In WSL2, verify the route has the correct source address:
Test connectivity:
ping 192.168.101.238 tcpdump -i eth3 -n icmp # Verify source address is 192.168.101.147, not 192.168.9.147Expected Results
Compatibility
PreferredSourcefield is optional and defaults to empty stringFiles Changed
src/shared/inc/hns_schema.h- Added PreferredSource to Route schemasrc/windows/service/exe/WslCoreNetworkEndpointSettings.h- Added PreferredSource fieldssrc/windows/service/exe/WslMirroredNetworking.cpp- Implemented source selection logicsrc/windows/service/exe/WslCoreTcpIpStateTracking.h- Updated message conversionsrc/linux/netlinkutil/Route.h- Added preferredSource fieldsrc/linux/init/GnsEngine.cpp- Extract and apply PreferredSourcesrc/linux/netlinkutil/RoutingTable.cpp- Set RTA_PREFSRC netlink attributeAdditional Notes
This fix specifically addresses the mirrored networking mode scenario. NAT mode networking uses a different architecture and is not affected by this issue.
The implementation follows the existing pattern for route attributes and integrates cleanly with the GNS (Guest Network Service) messaging protocol.