{
  pkgs,
  config,
  ...
}: {
  networking = {
    hostName = "pbx";
    useDHCP = false;

    # Fix Intel NIC e1000e hardware unit hang
    localCommands = "${pkgs.ethtool}/bin/ethtool -K enp0s25 tso off gso off";

    firewall.interfaces = {
      weinturm.allowedUDPPorts = [53 67];
      public-event.allowedUDPPorts = [53 67];
    };

    vlans = {
      weinturm = {
        id = 7;
        interface = "enp0s25";
      };
      public-event = {
        id = 6;
        interface = "enp0s25";
      };
      voice = {
        id = 8;
        interface = "enp0s25";
      };
      jugendtreff = {
        id = 2;
        interface = "enp0s25";
      };
    };
    interfaces = {
      weinturm = {
        ipv4.addresses = [
          {
            address = "192.168.96.1";
            prefixLength = 24;
          }
        ];
      };
      public-event = {
        ipv4.addresses = [
          {
            address = "10.10.0.1";
            prefixLength = 20;
          }
        ];
      };
      voice = {
        ipv4.addresses = [
          {
            address = "192.168.98.1";
            prefixLength = 24;
          }
        ];
      };
      jugendtreff = {
        useDHCP = true;
      };
    };
    dhcpcd.extraConfig = ''
      noipv6rs
      waitip 6
      denyinterfaces voice
      interface jugendtreff
        ipv6rs
        ia_na 1
        ia_pd 2 weinturm/0 public-event/1
    '';
    nat = {
      enable = true;
      externalInterface = "jugendtreff";
      internalInterfaces = [
        "weinturm"
        "public-event"
        "voice"
      ];
    };
    nftables.tables.pppoe = {
      family = "ip";
      content = let
        headerSize = {
          ipv4 = 20;
          tcp = 20;
          pppoe = 8;
        };
        maxsegSize = with headerSize; 1500 - ipv4 - tcp - pppoe;
      in ''
        chain clamp {
          type filter hook forward priority mangle;
          oifname "${config.networking.nat.externalInterface}" tcp flags syn tcp option maxseg size set ${toString maxsegSize}
        }
      '';
    };
    defaultGateway.address = "192.168.100.1";
    nameservers = [
      "9.9.9.9"
      "149.112.112.112"
      "2620:fe::fe"
      "2620:fe::9"
    ];
  };

  boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = 1;

  services = {
    dnscache = {
      enable = true;
      clientIps = [
        "10.10"
        "192.168.96"
        "192.168.98"
      ];
    };

    radvd = {
      enable = true;
      config = ''
        interface weinturm {
          AdvSendAdvert on;
          prefix ::/64 {
            AdvOnLink on;
            AdvAutonomous on;
            AdvRouterAddr on;
          };
        };
        interface public-event {
          AdvSendAdvert on;
          prefix ::/64 {
            AdvOnLink on;
            AdvAutonomous on;
            AdvRouterAddr on;
          };
        };
      '';
    };

    kea.dhcp4.settings = {
      interfaces-config.interfaces = ["weinturm" "public-event"];
      subnet4 = [
        {
          id = 2;
          subnet = "192.168.96.0/24";
          pools = [{pool = "192.168.96.20-192.168.96.250";}];
          option-data = [
            {
              name = "routers";
              data = "192.168.96.1";
            }
            {
              name = "domain-name-servers";
              data = "192.168.96.1";
            }
          ];
        }
        {
          id = 3;
          subnet = "10.10.0.0/20";
          pools = [{pool = "10.10.1.0-10.10.15.250";}];
          option-data = [
            {
              name = "routers";
              data = "10.10.0.1";
            }
            {
              name = "domain-name-servers";
              data = "10.10.0.1";
            }
          ];
        }
      ];
    };
  };

  environment.persistence."/persist".directories = [
    {
      directory = "/var/lib/dhcpcd";
      user = "dhcpcd";
      group = "dhcpcd";
      mode = "u=rwx,g=rx,o=rx";
    }
    {
      directory = "/var/lib/private/kea";
      user = "nobody";
      group = "nogroup";
      mode = "u=rwx,g=rx,o=rx";
    }
  ];
}
