arptable: make slim()'s hunt for packets scale better

The second part of slim(), which searches for queued IP packets to
delete when ARPTable is at packet capacity, starts its search from
somewhere near the beginning of the _age list. However, in some
scenarios (such as a during nmap host discovery or an nmap-like attack),
the entries that contain packets will be found towards the end of the
list.  In the case that ARPTable is constantly at packet capacity (as
would be the case during nmap host discovery), slim() ends up performing
an O(n) traversal for each new IP packet, which kills performance.

This commit has slim() clean up half of the saved packets (instead of
just one) when ARPTable reaches capacity, giving an O(1) traversal. The
downside is that the number of saved packets now fluctuates between 0.5
* CAPACITY and CAPACITY under nmap conditions.

This trade-off can be tuned using CAPACITY_SLIM_FACTOR (default 2).
ARPTable removes 1/CAPACITY_SLIM_FACTOR of saved packets on exceeding
CAPACITY. Effective capacity then fluctuates between CAPACITY *
(1-1/CAPACITY_SLIM_FACTOR) and CAPACITY under nmap conditions.  slim()
performs CAPACITY_SLIM_FACTOR*ENTRY_CAPACITY/CAPACITY traversals for
each new IP packet.  The old behaviour is equivalent to
CAPACITY_SLIM_FACTOR == CAPACITY.

The idea for this solution came from Eddie. The original solution I came
up with was to add a pointer into _age list for slim() to start its
search at. However, that solution didn't handle the case well where in
addition to nmap host discovery / attack, packets are frequently sent to
IP addresses that already appear earlier in the list.

Signed-off-by: Patrick Verkaik <patrick@meraki.net>
Merge pull request #114 from trackpick/arpq-slim2

arptable: make slim()'s hunt for packets scale better