Watch the network over netlink instead of polling operstate #122

Open
opened 2026-08-22 23:01:12 -04:00 by mysticalsoap · 0 comments
Owner

NetObserver (#111) is a straight port of NetMon's mechanism: poll /sys/class/net/*/operstate every 2 seconds and confirm a default gateway before reporting up. It works, but it is polling -- up to 2s of latency on a transition, plus a wakeup every 2s forever.

The kernel already broadcasts these events: an RTMGRP_LINK/RTMGRP_IPV4_ROUTE/RTMGRP_IPV6_ROUTE netlink socket would make the observer event-driven -- react on the route change itself, no sleep loop, no missed 2s window. Route messages would also replace the ip -j route subprocess calls in observer.default_routes.

Split out of #111 deliberately (poll-first port keeps that diff reviewable). Design points for whoever picks it up:

  • Dependency choice: raw socket.AF_NETLINK (stdlib, but hand-parsing rtattr) vs pyroute2 (clean, but a new hard dependency across distros -- check what target distros package).
  • Keep the "up means usable" rule: a link-up event without a default route must stay "down" until a route event backs it (today that is the gateway check + retry-next-poll).
  • The kernel does not drop subscribers the way a perf ring buffer drops events, but the socket buffer can still overflow -- on ENOBUFS, re-derive state from a fresh default_routes() read rather than trusting the event stream (an unbounded watcher that silently loses events is the upstream bug this fork exists to avoid).
NetObserver (#111) is a straight port of NetMon's mechanism: poll `/sys/class/net/*/operstate` every 2 seconds and confirm a default gateway before reporting up. It works, but it is polling -- up to 2s of latency on a transition, plus a wakeup every 2s forever. The kernel already broadcasts these events: an `RTMGRP_LINK`/`RTMGRP_IPV4_ROUTE`/`RTMGRP_IPV6_ROUTE` netlink socket would make the observer event-driven -- react on the route change itself, no sleep loop, no missed 2s window. Route messages would also replace the `ip -j route` subprocess calls in `observer.default_routes`. Split out of #111 deliberately (poll-first port keeps that diff reviewable). Design points for whoever picks it up: - Dependency choice: raw `socket.AF_NETLINK` (stdlib, but hand-parsing rtattr) vs `pyroute2` (clean, but a new hard dependency across distros -- check what target distros package). - Keep the "up means usable" rule: a link-up event without a default route must stay "down" until a route event backs it (today that is the gateway check + retry-next-poll). - The kernel does not drop subscribers the way a perf ring buffer drops events, but the socket buffer can still overflow -- on `ENOBUFS`, re-derive state from a fresh `default_routes()` read rather than trusting the event stream (an unbounded watcher that silently loses events is the upstream bug this fork exists to avoid).
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
mysticalsoap/aqomui#122
No description provided.