Deploying the previous commit's fix live exposed a real bug: nodogsplash's
OpenWrt package postinst auto-enables and starts the service immediately
on install, using its stock default config — gatewayinterface=br-lan.
Since NoDogSplash only touches IPv4 iptables, this silently cut IPv4
(not IPv6) connectivity for anything on br-lan, including the admin
management box plugged into this router's LAN port, for the window
between install and our own configure step.
Split nodogsplash provisioning into install_and_stop() (runs first,
closes that window immediately) and configure() (runs after
wifi::provision_ssid has created br-tollgate, so gatewayinterface is
pointed at the isolated tollgate bridge instead of br-lan).
tollgate-wrt has no firewall/netfilter code of its own (confirmed via
strings on the binary and the upstream Go source) — it delegates all
MAC authorization and gate open/close to NoDogSplash via ndsctl.
Upstream's package declares +nodogsplash as a hard dependency, but
neither of our install paths pull it in: the opkg fast path only
resolves deps against a real feed, and the raw .ipk-extraction
fallback (used whenever the package isn't in a feed, and always on
ApkNative) skips dependency resolution entirely. Result: tollgate-wrt
ran, accepted payments, and tracked balances, but never actually
blocked unpaid clients — the static firewall zone just forwarded
everyone to WAN unconditionally.
Also fixes the config.json mismatch: tollgate-wrt reads
/etc/tollgate/config.json exclusively, never the tollgate.main.* UCI
keys we were writing — so mint/price changes through this project's
UI silently had no effect on what the daemon actually advertised.
- tollgate/nodogsplash.rs: install nodogsplash, configure it to gate
the dedicated br-tollgate bridge, open the pre-auth walled-garden
ports (2121 payment, 2050 portal).
- tollgate/wifi.rs: bind network.tollgate to a stable br-tollgate
bridge device (NoDogSplash needs a known interface name — the
driver-assigned name of a bare wifi vif isn't guaranteed); disable
IPv6 RA/DHCPv6 on it (NoDogSplash only manages IPv4 iptables, so
IPv6 would let clients bypass the portal entirely).
- tollgate/config.rs: apply_daemon_config() merges pricing/mint into
the real config.json instead of (only) UCI.
- opkg.rs: generic install_package() for standard feed packages under
either PkgManager mode.
- router.rs: upload_file() (SCP) for non-UCI config files.