{ pkgs, config, lib, ... }: {

  options.configuration.fireqos = with lib; {
    enable = mkEnableOption "enable";
    interface = mkOption {
      default = "enp8s0";
      type = with types; str;
    };
    # nix-shell -p speedtest_cli --run speedtest
    input = mkOption {
      default = 4200;
      type = with types; int;
      description = "in kbit";
    };
    # nix-shell -p speedtest_cli --run speedtest
    output = mkOption {
      default = 1200;
      type = with types; int;
      description = "in kbit";
    };
    balance = mkOption {
      type = with types; bool;
      description = ''
        balance all, this will not prioritise anything.
      '';
    };
  };

  config = let
    kbits = number:
      import (pkgs.runCommand "round-${toString number}" { }
        ''awk 'BEGIN{printf "\"%ikbit\"", ${toString number}}' > $out'');

    interface = config.configuration.fireqos.interface;
    input = "${toString config.configuration.fireqos.input}kbit";
    output = "${toString config.configuration.fireqos.output}kbit";
    tincInput = kbits (config.configuration.fireqos.input * 0.7);
    tincOutput = kbits (config.configuration.fireqos.output * 0.7);
    useBalancedForExperimenting = false;

    tincPorts =
      lib.mapAttrsToList (name: configuration: toString configuration.port)
      config.module.cluster.services.tinc;

  in {

    # https://firehol.org/tutorial/fireqos-new-user/
    services.fireqos.enable = config.configuration.fireqos.enable;
    services.fireqos.config = ''

      # ------------------- world

      interface ${interface} world-in input rate ${input} ${
        lib.optionalString useBalancedForExperimenting "balanced"
      }

        class ssh commit 300kbit
          match tcp port 22

        class http commit 80%
          match tcp port 80,443

        class tinc commit 80%
          match port ${lib.concatStringsSep "," tincPorts}

        class surfing commit 30%
          match tcp sports 0:1023   # include TCP traffic from port 0-1023

        class torrent
          match tcp dports ${toString config.services.custom.transmission.port}

      interface ${interface} world-out output rate ${output} ${
        lib.optionalString useBalancedForExperimenting "balanced"
      }

        class ssh commit 500kbit
          match tcp port 22

        class http commit 80%
          match tcp port 80,443

        class tinc commit 80%
          match port ${lib.concatStringsSep "," tincPorts}

        class surfing commit 5%
          match tcp dports 0:1023   # include TCP traffic to port 0-1023

        class torrent
          match tcp sports ${toString config.services.custom.transmission.port}

      # ------------------- tinc

      interface tinc.private tinc bidirectional input rate ${tincInput} output rate ${tincOutput} ${
        lib.optionalString useBalancedForExperimenting "balanced"
      }

        class ssh commit 300kbit
          match tcp port 22,2222

        # public servers
        class public commit 80%
          match port 80,443
          match port 3000 # gogs
          match port 8000 # bepasty

        class homeassistant commit 100kbit
          match tcp port ${toString config.services.home-assistant.port}

        class prometheus commit 100kbit
          match tcp port 19999 # netdata
          match tcp port 9113  # netdata exporter
          match port 11201     # graylog sink

        class wuis commit 100kbit
          match port 8384 # syncthing
          match port 8123 # home-assistant
          match port 5656 # grafana
          match port 8080 # kodi
          match port 9090 # prometheus
          match port 9000 # graylog

        class syncthing
          match port 22000

    '';

  };

}