Skip to content

Commit ee78667

Browse files
authored
fix(netwatch): detect IPv6 default routes on Linux (#132)
## Description `default_route()` is special-cased on linux to not use rtnetlink but read `/proc/net/route` first, which contains only IPv4 entries. When no IPv4 default route exists it returns `Ok(None)`, and the code treated any Ok result as final without falling through to the netlink-based detection that handles both address families. On a v6-only network this made default_route_interface permanently `None`, which caused iroh's `has_usable_network()` to return false after network switches. The fix narrows the early return to Ok(Some(..)) so that Ok(None) falls through to the netlink path. <!-- A summary of what this pull request achieves and a rough list of changes. --> ## Breaking Changes <!-- Optional, if there are any breaking changes document them, including how to migrate older code. --> ## Notes & open questions Why do we even special case linux here and not just rely on rtnetlink always? ## Change checklist - [ ] Self-review. - [ ] Documentation updates following the [style guide](https://rust-lang.github.io/rfcs/1574-more-api-documentation-conventions.html#appendix-a-full-conventions-text), if relevant. - [ ] Tests if relevant. - [ ] All breaking changes documented.
1 parent ae5833e commit ee78667

2 files changed

Lines changed: 5 additions & 5 deletions

File tree

netwatch/src/interfaces/linux.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@ pub enum Error {
4141
}
4242

4343
pub async fn default_route() -> Option<DefaultRouteDetails> {
44-
let route = default_route_proc().await;
45-
if let Ok(route) = route {
46-
return route;
44+
// /proc/net/route only contains IPv4 routes. If it finds one, return it.
45+
// If it returns Ok(None) (no IPv4 default route) or Err (file unreadable),
46+
// fall through to netlink which checks both IPv4 and IPv6.
47+
if let Ok(Some(route)) = default_route_proc().await {
48+
return Some(route);
4749
}
4850

4951
#[cfg(target_os = "android")]

netwatch/tests/patchbay.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ async fn default_route_v4_only() -> TestResult {
5151

5252
/// Netwatch detects a default route on a v6-only network.
5353
#[tokio::test]
54-
#[ignore = "default_route() does not fall through to netlink when /proc/net/route has no IPv4 default"]
5554
async fn default_route_v6_only() -> TestResult {
5655
let state = state_for_routed_device(IpSupport::V6Only).await?;
5756

@@ -75,7 +74,6 @@ async fn default_route_dual_stack() -> TestResult {
7574
/// After replugging from a v4 router to a v6 router, netwatch detects the new
7675
/// default route.
7776
#[tokio::test]
78-
#[ignore = "default_route() does not fall through to netlink when /proc/net/route has no IPv4 default"]
7977
async fn default_route_after_replug_v4_to_v6() -> TestResult {
8078
let lab = Lab::new().await?;
8179
let v4_router = lab

0 commit comments

Comments
 (0)