{
  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;
      systemd.services.fireqos.wantedBy = [ "multi-user.target" ];
      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

        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

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

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

          class ssh commit 300kbit
            match dport 22              # ssh
            match dport 2222            # gogs ssh
            match udp dport 60001:60999 # mosh

          # 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

      '';

    };

}