[ previous ] [ next ] [ threads ]
 From:  Manuel Kasper <mk at neon1 dot net>
 To:  m0n0wall dash dev at lists dot m0n0 dot ch
 Subject:  Increasing ipfilter NAT/state table sizes by default?
 Date:  Tue, 14 Sep 2004 20:29:06 +0200
Hi folks,

in case one of you is looking for something to do/help with: I'm
wondering if it would be a good idea to increase the ipfilter NAT and
state table sizes by default in m0n0wall, seeing as changing those
values requires recompiling the kernel. I've only had a quick glance
at the ip_state and ip_nat code, so please correct me if I'm wrong in
my following assumptions.

The state table is a hash table with separate chaining collision
handling, and the current size (ipfilter defaults) is 5737 buckets
(IPSTATE_SIZE), although ipfilter limits the number of states held to
4013 (IPSTATE_MAX) to keep the load factor below 0.7. Both numbers
are obviously prime to help with the compression function, modulo
(although I don't see why IPSTATE_MAX would necessarily have to be
prime). This means that there's currently a hard limit of 4013
states, after which it starts to flush TCP connections that have been
idle for a while.

The NAT table seems to be a different issue. While 127 should be
enough for the NAT rules list (NAT_SIZE/RDR_SIZE) and probably also
the hostmap list (HOSTMAP_SIZE), the default for the NAT table itself
(NAT_TABLE_SZ) is also 127. This looks like another hash table with
separate chaining, although with no hard limit, so it will just keep
getting slower as more entries are added, more collisions are
generated and the load factor exceeds 1.0.

Since both tables only consist of pointers, I'm wondering what keeps
us from bumping these values considerably? It doesn't look like that
would affect memory consumption that much as long as the hash buckets
are unused. I've not checked if the hash functions look like they'd
make good use of a larger table instead of just clustering up
everything. The memory for the entries themselves is malloc'd
dynamically anyway. Although we might have to tune VM_KMEM_SIZE_SCALE
to make sure that the available physical memory can actually be used.

Again, I haven't spent much time trying to understand the details of
how ipfilter handles this, and I'm simply looking for an answer
whether it would be wise to bump the state/NAT table sizes by default
(advantages, disadvantages...), and if so, which values would be
reasonable. Also, some rough calculations on how much memory is
needed to handle x states would be handy for documentation purposes.