Skip to content

examples: add netfailover (reactive policy routing) - #618

Open
lneto wants to merge 1 commit into
masterfrom
claude_netfailover
Open

examples: add netfailover (reactive policy routing)#618
lneto wants to merge 1 commit into
masterfrom
claude_netfailover

Conversation

@lneto

@lneto lneto commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

A demoable use case for the netlink support: reactive policy routing driven by a link event, entirely in-kernel, in Lua, hot-loaded — no userspace routing daemon, no recompile.

When the watched interface goes down, reactor.lua installs a backup route via netlink.rt (visible in ip route show table 200) and broadcasts the action on a netlink.channel; it removes the route when the link is back up.

The design point (worth a slide)

A notifier.netdevice callback runs holding rtnl_lock. Issuing rtnetlink from it would re-enter rtnl_lock and self-deadlock, so the work is split across two runtimes:

  • control.lua (process runtime) — the callback only records the link state into a shared rcu.table. Lock-safe, non-blocking.
  • reactor.lua (spawned kthread, sleepable) — polls the state and reprograms routing with netlink.rt, rtnl_lock not held, then broadcasts on netlink.channel.

They are deliberately separate runtimes: one shared runtime would deadlock ABBA (reactor holds the runtime lock waiting on rtnl_lock; the notifier holds rtnl_lock waiting on the runtime lock).

Validated end-to-end against a dummy0 interface: toggling it down/up installs and removes the backup route in table 200, confirmed in ip route and dmesg. Run steps in the README.

Second of three use-case PRs toward the Netdev talk.

🤖 Generated with Claude Code

A demoable use case for the netlink support: when a watched interface goes down,
a kernel Lua script installs a backup route via netlink.rt and broadcasts the
action on a netlink.channel; it removes the route when the link is back up. No
userspace routing daemon, hot-loaded.

The netdevice notifier callback runs holding rtnl_lock, so it only records the
link state into a shared rcu.table; a separately spawned sleepable reactor does
the rtnetlink work without the lock held. The two run in distinct runtimes to
avoid an ABBA deadlock between the runtime lock and rtnl_lock.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@lneto
lneto changed the base branch from claude_netlink_rule to master August 3, 2026 13:13
@lneto
lneto force-pushed the claude_netfailover branch from fe57ca1 to edb07da Compare August 3, 2026 13:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant