#!/bin/sh
## Wires the logrus0 TUN interface into fw4 so LAN traffic actually
## traverses the tunnel.
##
## What this does:
##   1. Adds /etc/config/network entry for the logrus0 interface with
##      proto=none (the logrus-client process owns the addressing; we
##      just register the device so fw4 can target it by zone).
##   2. Adds a firewall zone "logrus" covering logrus0, with masquerade
##      so reply traffic NATs back to the LAN client correctly.
##   3. Adds a forwarding rule lan -> logrus.
##
## Idempotent: each section is keyed by name and re-running is a no-op
## if the entry already exists.
##
## NOT done here:
##   - Killswitch (lan -> wan blocked while tunnel is down): tracked
##     separately, will land as a hotplug script driven by ifup/ifdown
##     events on logrus0.
##   - DNS-leak prevention: dnsmasq still forwards :53 to wan-side
##     resolvers. Once the default route is through logrus0 the upstream
##     query physically traverses the tunnel, but the destination
##     resolver IP is still the wan-side default — we'll force tunnel-
##     side resolvers in a follow-up.

set -e

. /lib/functions.sh

# --- network: register logrus0 device ---
# Needed so fw4 can resolve the zone -> device mapping at firewall
# reload time. proto=none means OpenWrt won't try to bring it up or
# assign IPs — that's logrus-client's job.
if ! uci -q get network.logrus >/dev/null; then
	uci -q batch <<-EOF
		set network.logrus=interface
		set network.logrus.device='logrus0'
		set network.logrus.proto='none'
	EOF
	uci commit network
	logger -t logrus "added network.logrus interface (device=logrus0, proto=none)"
fi

# --- firewall: zone + forwarding ---
# Locate the existing lan zone so we can add a forwarding rule from
# it. If the user has renamed it we won't find it and skip — better
# than guessing wrong.
LAN_ZONE=""
config_load firewall
find_lan() {
	local zone="$1"
	local name
	config_get name "$zone" name
	[ "$name" = "lan" ] && LAN_ZONE="$zone"
	# `return 0`, and it is doing real work.
	#
	# Without it the function's exit status is the test's, so the first
	# zone NOT named lan returns 1, config_foreach propagates that, and
	# `set -e` at the top of this file ends the script on the spot. On
	# stock OpenWrt the zone order is lan then wan, so that is every
	# router: the lan zone was found and then everything below — the
	# logrus zone, the lan -> logrus forwarding, the firewall reload —
	# never ran. opkg reported a clean install throughout.
	#
	# What made it worse than a no-op is that 91-logrus-killswitch runs
	# afterwards and succeeds. The result was a router that blocks
	# lan -> wan and has no lan -> logrus path to replace it: LAN clients
	# lose the internet entirely, which is the opposite of the package's
	# purpose. Found by the first OpenWrt attestation run.
	return 0
}
config_foreach find_lan zone

if [ -z "$LAN_ZONE" ]; then
	logger -t logrus "no firewall zone named 'lan' found — skipping fw4 wiring;" \
		"add a forwarding rule manually if you've renamed your LAN zone"
	exit 0
fi

# Add the logrus zone if missing. Named section so it's obvious in
# `uci show firewall` and easy to remove on uninstall.
if ! uci -q get firewall.logrus_zone >/dev/null; then
	uci -q batch <<-EOF
		set firewall.logrus_zone=zone
		set firewall.logrus_zone.name='logrus'
		set firewall.logrus_zone.network='logrus'
		set firewall.logrus_zone.input='REJECT'
		set firewall.logrus_zone.output='ACCEPT'
		set firewall.logrus_zone.forward='REJECT'
		set firewall.logrus_zone.masq='1'
		set firewall.logrus_zone.mtu_fix='1'
	EOF
	logger -t logrus "added firewall zone 'logrus' (masq=1, mtu_fix=1)"
fi

if ! uci -q get firewall.logrus_fwd >/dev/null; then
	uci -q batch <<-EOF
		set firewall.logrus_fwd=forwarding
		set firewall.logrus_fwd.src='lan'
		set firewall.logrus_fwd.dest='logrus'
	EOF
	logger -t logrus "added firewall forwarding lan -> logrus"
fi

uci commit firewall

# Reload firewall so the changes take effect without a reboot. fw4
# is the OpenWrt 22.03+ nftables-based firewall; on older fw3 systems
# this falls back to the same `service firewall reload` semantics.
/etc/init.d/firewall reload >/dev/null 2>&1 || \
	logger -t logrus "firewall reload failed; run '/etc/init.d/firewall reload' manually"

exit 0
