#!/bin/sh
# Load the nftables ruleset. Called by the s6-rc oneshot "nftables".
#
# Debian's nftables.service does
#   ExecStart=/usr/sbin/nft -f /etc/nftables.conf
#   ExecStop=/usr/sbin/nft flush ruleset
# and nothing else -- no daemon, no reload logic. The ruleset lives in the
# kernel; the "service" is the act of loading it. That is why this is a oneshot
# and not a longrun.
#
# The check before the load is the equivalent of an ExecStartPre and is the
# reason this is a script and not a one-line "up" file: "nft -f" applies the
# file statement by statement, so a syntax error in the middle leaves the
# kernel with half the ruleset -- neither the old one nor the new one, and on a
# router that is the worst of the three outcomes. "nft -c -f" parses the whole
# file without touching the kernel.
set -e

NFT=/usr/sbin/nft
NFTABLES_CONF=/etc/nftables.conf
[ -r /etc/default/nftables ] && . /etc/default/nftables

if [ ! -r "${NFTABLES_CONF}" ]; then
  echo "nftables: ${NFTABLES_CONF} does not exist -- nothing to load" >&2
  exit 1
fi

if ! "${NFT}" -c -f "${NFTABLES_CONF}"; then
  echo "nftables: ${NFTABLES_CONF} does not parse -- ruleset NOT loaded" >&2
  exit 1
fi

"${NFT}" -f "${NFTABLES_CONF}"
echo "nftables: ruleset from ${NFTABLES_CONF} loaded"
