{ pkgs, lib, config, ... }:
let
  inherit (builtins) hasAttr readFile;
  inherit (pkgs.lib) unlinesAttrs;
  inherit (config) networking;
  inherit (config.users) users groups;
in
{
networking.firewall.enable = false;
security.lockKernelModules = false;
systemd.services.disable-kernel-module-loading.after = [ "nftables.service" ];
systemd.services.nftables.serviceConfig.TimeoutStartSec = "20";
networking.nftables = {
  enable = true;
  ruleset = lib.mkBefore (''
    table inet filter {
      include "${../../../networking/nftables/filter.txt}"
      # A set containing the udp port(s) to which SSDP replies are allowed.
      set ssdp_out {
        type inet_service
        timeout 5s
      }
      chain net2fw {
        #udp dport mdns ip6 daddr ff02::fb counter accept comment "Accept mDNS"
        #udp dport mdns ip daddr 224.0.0.251 counter accept comment "Accept mDNS"
        #jump non-internet

        #ct state new add @connlimit { ip saddr ct count over 20 } counter tcp reject with tcp reset

        # Some .nix append rules here with: add rule inet filter net2fw ...
      }
      chain fw2net {
        tcp dport { 80, 443 } counter accept comment "HTTP"
        udp dport 123 skuid ${users.systemd-timesync.name} counter accept comment "NTP"
        tcp dport 1965 counter accept comment "Gemini"
        tcp dport 9418 counter accept comment "Git"

        # Some .nix append rules here with: add rule inet filter fw2net ...
      }
      chain wifi2fw {
        # Some .nix append rules here with: add rule inet filter wifi2fw ...
      }
      chain fw2wifi {
        # Some .nix append rules here with: add rule inet filter fw2wifi ...
      }
      chain fwd-wifi {
        # Some .nix append rules here with: add rule inet filter fwd-wifi ...
      }
      chain intra2fw {
        # Some .nix append rules here with: add rule inet filter intra2fw ...
      }
      chain fw2intra {
        # Some .nix append rules here with: add rule inet filter fw2intra ...
      }
      chain fwd-intra {
        # Some .nix append rules here with: add rule inet filter fwd-intra ...
      }
      chain extra2fw {
        # Some .nix append rules here with: add rule inet filter extra2fw ...
      }

      chain input {
        type filter hook input priority filter
        policy drop

        iifname lo accept

        jump check-tcp
        ct state { established, related } accept
        jump accept-connectivity-input
        ct state invalid counter drop

        # admin services
        tcp dport 22 counter accept comment "SSH"
        udp dport 60000-61000 counter accept comment "Mosh"

        # Some .nix append gotos here with: add rule inet filter input iffname ... goto ...
      }
      chain forward {
        type filter hook forward priority filter
        policy drop

        ct state { related, established } accept
        jump accept-connectivity-forward
      }
      chain output {
        type filter hook output priority filter
        policy drop

        oifname lo accept

        ct state { related, established } accept
        jump accept-connectivity-output

        tcp dport 22 counter accept comment "SSH"

        # Some .nix append gotos here with: add rule inet filter output oifname ... goto ...
      }
    }
    table inet nat {
      chain prerouting {
        type nat hook prerouting priority filter
        policy accept
      }
      chain postrouting {
        type nat hook postrouting priority srcnat
        policy accept
      }
    }
  '' + lib.optionalString (config.services.upnpc.redirections != []) (''
    # Create a rule for accepting any SSDP packets going to a remembered port.
    add rule inet filter net2fw udp dport @ssdp_out \
      counter accept comment "SSDP answer"
    add rule inet filter fw2net \
      skuid {${users.upnpc.name},${users.nsupdate.name}} \
      tcp dport 1900 \
      counter accept \
      comment "SSDP automatic opening"
    add rule inet filter fw2net \
      skuid {${users.upnpc.name},${users.nsupdate.name}} \
      ip daddr 239.255.255.250 udp dport 1900 \
      set add udp sport @ssdp_out \
      comment "SSDP automatic opening"
    add rule inet filter fw2net \
      skuid {${users.upnpc.name},${users.nsupdate.name}} \
      ip daddr 239.255.255.250 udp dport 1900 \
      counter accept comment "SSDP"
    '' + lib.optionalString config.networking.enableIPv6 ''
    add rule inet filter fw2net \
      skuid {${users.upnpc.name},${users.nsupdate.name}} \
      ip6 daddr {FF02::C, FF05::C, FF08::C, FF0E::C} udp dport 1900 \
      set add udp sport @ssdp_out comment "SSDP automatic opening"
    add rule inet filter fw2net \
      skuid {${users.upnpc.name},${users.nsupdate.name}} \
      ip6 daddr {FF02::C, FF05::C, FF08::C, FF0E::C} udp dport 1900 \
      counter accept comment "SSDP"
    '')
  );
};
}