#!/bin/sh
# NetworkManager dispatcher hook — primary-LAN transition handler (ADR-0022).
#
# Fires whenever an interface comes up or goes down. Its whole job is to notice
# that the primary LAN has moved — most importantly that the USB-Eth carrying
# it has died — and kick a reconcile that stands up the eth0.10 fallback and
# re-renders dnsmasq + nftables onto it, so the vendo keeps serving customers
# instead of bricking until someone re-flashes it.
#
# Args (NetworkManager contract):  $1 = interface name,  $2 = action
#
# CRITICAL — this script MUST return immediately:
#   * NetworkManager runs dispatcher scripts SYNCHRONOUSLY and kills ones that
#     overrun its timeout. Spawning python3 on an H3 takes a few hundred ms and
#     the reconcile itself restarts services — far too slow to do inline.
#   * Worse, the reconcile calls nmcli. Calling nmcli synchronously from a
#     dispatcher script DEADLOCKS: NetworkManager is blocked waiting for this
#     script while nmcli waits for NetworkManager to answer.
# So: filter cheaply in shell, then fire-and-forget with setsid. Never block.

IFACE="$1"
ACTION="$2"

# Only interface up/down can move the primary LAN. Ignore the rest
# (pre-up/pre-down are synchronous-by-design and would deadlock; dhcp4-change,
# connectivity-change etc. don't relocate the LAN).
case "$ACTION" in
    up|down) ;;
    *) exit 0 ;;
esac

# Noise filter. ppp* matters most here: every PPPoE subscriber dial and hangup
# raises up/down events (ADR-0018), and none of them can move the primary LAN —
# without this a busy PPPoE site would spawn a reconcile per session churn.
case "$IFACE" in
    lo|ppp*) exit 0 ;;
esac

RECONCILE=/opt/vendora_sbc/tools/vendora-lan-reconcile
[ -x "$RECONCILE" ] || exit 0

# Detach. The reconcile is idempotent and flock-serialized, so overlapping
# events collapse safely; it is also edge-triggered against the deployed
# dnsmasq config, so a burst of events yields at most one regeneration.
setsid "$RECONCILE" >/dev/null 2>&1 &

exit 0
