Skip to content

fix(netwatch): detect IPv6 default routes on Linux#132

Merged
Frando merged 1 commit intomainfrom
fix/v6-default-route
Apr 13, 2026
Merged

fix(netwatch): detect IPv6 default routes on Linux#132
Frando merged 1 commit intomainfrom
fix/v6-default-route

Conversation

@Frando
Copy link
Copy Markdown
Member

@Frando Frando commented Apr 10, 2026

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.

Breaking Changes

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, if relevant.
  • Tests if relevant.
  • All breaking changes documented.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 10, 2026

Documentation for this PR has been generated and is available at: https://n0-computer.github.io/net-tools/pr/132/docs/net_tools/

Last updated: 2026-04-13T09:07:33Z

@n0bot n0bot Bot added this to iroh Apr 10, 2026
@github-project-automation github-project-automation Bot moved this to 🚑 Needs Triage in iroh Apr 10, 2026
@Frando Frando force-pushed the fix/v6-default-route branch 2 times, most recently from e0e2249 to b0bbcce Compare April 13, 2026 08:27
Frando added a commit that referenced this pull request Apr 13, 2026
## Description

Add patchbay tests that exercise netwatch's interface and route
detection inside virtual network namespaces. The tests cover v4-only,
v6-only, dual-stack, and v4-to-v6 replug scenarios.


Also adds patchbay CI workflow, nextest patchbay profile, and a
cargo-make task to match the iroh project's patchbay setup.

## Notes & open questions

Two of the four tests are currently ignored: they expose a bug where
default_route() fails to detect IPv6 default routes on Linux because
/proc/net/route only contains IPv4 entries and the netlink fallback is
never reached.
See #132 for a fix.
<!-- Any notes, remarks or open questions you have to make about the PR.
-->
## 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.
default_route() reads /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 5-second debounce timeout would expire before
the QUIC stack learned about the change, leaving connections stuck on
dead paths.

The fix narrows the early return to Ok(Some(..)) so that Ok(None)
falls through to the netlink path.
@Frando Frando force-pushed the fix/v6-default-route branch from b0bbcce to 3e2f897 Compare April 13, 2026 09:06
@Frando Frando changed the base branch from tests/patchbay to main April 13, 2026 09:07
@Frando Frando merged commit ee78667 into main Apr 13, 2026
26 of 28 checks passed
@github-project-automation github-project-automation Bot moved this from 🚑 Needs Triage to ✅ Done in iroh Apr 13, 2026
Frando added a commit to n0-computer/iroh that referenced this pull request Apr 14, 2026
## Description

Adds a patchbay test matrix for testing uplink switching across IP
family transitions (v4/v6/dual-stack) for both client and server side.
Each test holepunches a direct path, replugs the switching side to a
different router, and verifies that a new direct path is selected and
data flows over it.

The tests all pass. Initially, the server side tests failed, and this
uncovered two issues which are now fixed:
* We currently fail to detect the default route when switching to a
v6-only interface in netwatch, see
n0-computer/net-tools#132. This leads to iroh
not forwarding the major network change to quinn, because we only do
this if we determine the network to be usable, which fails because the
default route check fails.
* noq's `handle_network_change` only checks whether a path is
recoverable on the client side; the server side always assumed paths
were recoverable, so dead direct paths were never proactively abandoned
after a server replug. See n0-computer/noq#579
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: ✅ Done

Development

Successfully merging this pull request may close these issues.

2 participants