#!/bin/sh
# Strict through a firmware upgrade (PRD FWU-2 "Under Strict they stay blocked", E7, review-router M4).
#
# A firmware upgrade removes the package, and with it the nft table that blocks protected devices and the include that loads it. This
# file is the second firewall include `render` adds under Strict (config include `fvpn_hold`), and it lives in the kept directory, as
# does the table's snapshot (hold.nft, written by `render apply` from the same code that renders the live table). The firewall
# config is kept by the upgrade, so on the new firmware's first boot fw4/fw3 runs this file before netifd, before the network is up:
# protected devices are blocked from the first packet until the reinstall step has brought the package back, and the package's own
# include (`arm`) takes the table over from there.
#
# It does nothing when the package is here (`arm` is: its include does this and more), when the kill switch was never armed (the
# armed flag is kept, AD-1) and when there is no snapshot (Standard, protection off, or a router that never rendered one).
# It blocks forwarding and lookups for the devices the snapshot names; it never touches the router's own traffic (the table has
# no rule on output but for its address and ICMP guards), so the reinstall step reaches the software source.
# To take it away: rm /etc/forestvpn-reinstall/hold.nft (the include then does nothing).
#
# Test seams (environment): FVPN_HOLD_{ETC,ARM,NFT}.
ETC=${FVPN_HOLD_ETC:-/etc}
ARM=${FVPN_HOLD_ARM:-/usr/libexec/forestvpn/arm}
NFT=${FVPN_HOLD_NFT:-nft}
SNAP=$ETC/forestvpn-reinstall/hold.nft

[ -x "$ARM" ] && exit 0
[ -f "$ETC/forestvpn/armed" ] && [ -s "$SNAP" ] || exit 0
if "$NFT" -f "$SNAP" 2>/dev/null; then
	logger -t forestvpn-hold "ForestVPN is not installed (a firmware upgrade): protected devices stay blocked until it is back" 2>/dev/null
elif grep -v 'ct zone set' "$SNAP" | "$NFT" -f - 2>/dev/null; then
	# a kernel without conntrack zones refuses the track chain's rules (adapter.sh does the same)
	logger -t forestvpn-hold "ForestVPN is not installed: protected devices stay blocked (no conntrack zones)" 2>/dev/null
else
	logger -t forestvpn-hold "the block could not be loaded: protected devices are NOT held" 2>/dev/null
	exit 1
fi
exit 0
