my understanding is that the hashlimit module of netfilter is supposed to implement the leaky bucket algorithm... i'm using the below iptables configuration

iptables -A INPUT -s 207.[...] -m hashlimit --hashlimit-above 34722b/s \
--hashlimit-burst 600m --hashlimit-name hashlimitTable1 \
--hashlimit-htable-expire 604800000 -j DROP

this works perfectly for a single large download of 700 MB but if I wait three hours after the the download completes and then do another download the rule is still matching immediately (no burst) and limiting the bandwidth to ~34kB/s.

and examining cat /proc/net/ipt_hashlimit/hashlimitTable1 shows after the first large download

                     This seems to represent the burst "bucket" size
                      and it does go down and reach 0 after 600 MB
                      have been downloaded, but it never increases
                              no matter how long I wait.
604555> 4194304000 0 1931967

Does hashlimit not implement the "leaky bucket" algorithm? Or is my configuration incorrect?

from man 8 iptables-extensions|grep -e 'hashlimit-burst amount' -A 7

--hashlimit-burst amount
       Maximum  initial  number  of  packets to match: this number gets
       recharged by one every time the limit  specified  above  is  not
       reached,  up  to this number; the default is 5.  When byte-based
       rate matching is requested, this option specifies the amount  of
       bytes  that  can  exceed  the given rate.  This option should be
       used with caution -- if the entry expires, the  burst  value  is
       reset too.

this indicates that my expected behavior is correct but maybe I need to ensure that the rule is matched from the opposite perspective:

iptables -A INPUT -s 207.[...] -m hashlimit --hashlimit-upto 34722b/s \
--hashlimit-burst 600m --hashlimit-name hashlimitTable1 \
--hashlimit-htable-expire 604800000 -j ACCEPT;
iptables -A INPUT -s 207.[...] -j DROP;

Unfortunately this results in exactly the same observed behavior, even when using wget --limit-rate=1024 http://207.[...]/testFile.bin to download at an absurdly low rate of 1KiBps for 19+ minutes, yet the max number of tokens never increases above zero and the bandwidth after waiting an additional hour without downloads is still restricted to ~34KBps...

I have confirmed that the expire time, garbage collect interval, htable-size, and htable-max do not have any effect on the problem. If I make the expire really short like 10 seconds then obviously it will reset the burst, but that would result in violating the average bandwidth.

  • As it often happens to be true, people do shoot in own feet with other parts of theirs rulesets. Simplify it first till the point you can publish it in the whole or better till only relevant lines are left alone. – poige Jul 23 at 6:41
  • @poige I'm not aware of how another rule I have could modify the behavior of hashlimitTable1, I use iptables-restore rules.txt so that I can see the whole thing, and there is only one hashlimit or 207 ip rule in there (the one in this question). The only other rule that could apply to these packets are the standard global INVALID,RELATED,ESTABLISHED ip state rules at the very end. I don't believe any other rules are interfering with the hashllimit since the timeout (the first number in cat /proc/net/ipt_hashlimit/hashlimitTable1) doesn't get reset when I'm not doing a download. – user3338098 Jul 23 at 14:51
  • if I change my rules to a packet rate hashlimit -A INPUT -s 207.[...] -m hashlimit --hashlimit-above 23/s \ --hashlimit-burst 400k --hashlimit-name hashlimitTable1 \ --hashlimit-htable-expire 604800000 -j DROP everything works perfectly and the "burst bucket" increases and I get bursts in bandwidth if I don't use any bandwidth for a few seconds even after a long download, but unfortunately this has no reliable relationship with actual bandwidth as there is nothing to stop the server from using jumbo packets that would result in large changes in bandwidth despite similar IP packet rates. – user3338098 Jul 23 at 14:58
  • As far as I can tell, hashlimit's implementation is fundamentally broken. The limiter doesn't really work correctly, or at least, not as documented. – Otheus Oct 28 at 10:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.