Commit bea74641 authored by Vishwanath Pai's avatar Vishwanath Pai Committed by Pablo Neira Ayuso

netfilter: xt_hashlimit: add rate match mode

This patch adds a new feature to hashlimit that allows matching on the
current packet/byte rate without rate limiting. This can be enabled
with a new flag --hashlimit-rate-match. The match returns true if the
current rate of packets is above/below the user specified value.

The main difference between the existing algorithm and the new one is
that the existing algorithm rate-limits the flow whereas the new
algorithm does not. Instead it *classifies* the flow based on whether
it is above or below a certain rate. I will demonstrate this with an
example below. Let us assume this rule:

iptables -A INPUT -m hashlimit --hashlimit-above 10/s -j new_chain

If the packet rate is 15/s, the existing algorithm would ACCEPT 10
packets every second and send 5 packets to "new_chain".

But with the new algorithm, as long as the rate of 15/s is sustained,
all packets will continue to match and every packet is sent to new_chain.

This new functionality will let us classify different flows based on
their current rate, so that further decisions can be made on them based on
what the current rate is.

This is how the new algorithm works:
We divide time into intervals of 1 (sec/min/hour) as specified by
the user. We keep track of the number of packets/bytes processed in the
current interval. After each interval we reset the counter to 0.

When we receive a packet for match, we look at the packet rate
during the current interval and the previous interval to make a
decision:

if [ prev_rate < user and cur_rate < user ]
        return Below
else
        return Above

Where cur_rate is the number of packets/bytes seen in the current
interval, prev is the number of packets/bytes seen in the previous
interval and 'user' is the rate specified by the user.

We also provide flexibility to the user for choosing the time
interval using the option --hashilmit-interval. For example the user can
keep a low rate like x/hour but still keep the interval as small as 1
second.

To preserve backwards compatibility we have to add this feature in a new
revision, so I've created revision 3 for hashlimit. The two new options
we add are:

--hashlimit-rate-match
--hashlimit-rate-interval

I have updated the help text to add these new options. Also added a few
tests for the new options.
Suggested-by: default avatarIgor Lubashev <ilubashe@akamai.com>
Reviewed-by: default avatarJosh Hunt <johunt@akamai.com>
Signed-off-by: default avatarVishwanath Pai <vpai@akamai.com>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 3cf2e08f
...@@ -5,5 +5,6 @@ ...@@ -5,5 +5,6 @@
#define XT_HASHLIMIT_ALL (XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT | \ #define XT_HASHLIMIT_ALL (XT_HASHLIMIT_HASH_DIP | XT_HASHLIMIT_HASH_DPT | \
XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT | \ XT_HASHLIMIT_HASH_SIP | XT_HASHLIMIT_HASH_SPT | \
XT_HASHLIMIT_INVERT | XT_HASHLIMIT_BYTES) XT_HASHLIMIT_INVERT | XT_HASHLIMIT_BYTES |\
XT_HASHLIMIT_RATE_MATCH)
#endif /*_XT_HASHLIMIT_H*/ #endif /*_XT_HASHLIMIT_H*/
...@@ -19,12 +19,13 @@ ...@@ -19,12 +19,13 @@
struct xt_hashlimit_htable; struct xt_hashlimit_htable;
enum { enum {
XT_HASHLIMIT_HASH_DIP = 1 << 0, XT_HASHLIMIT_HASH_DIP = 1 << 0,
XT_HASHLIMIT_HASH_DPT = 1 << 1, XT_HASHLIMIT_HASH_DPT = 1 << 1,
XT_HASHLIMIT_HASH_SIP = 1 << 2, XT_HASHLIMIT_HASH_SIP = 1 << 2,
XT_HASHLIMIT_HASH_SPT = 1 << 3, XT_HASHLIMIT_HASH_SPT = 1 << 3,
XT_HASHLIMIT_INVERT = 1 << 4, XT_HASHLIMIT_INVERT = 1 << 4,
XT_HASHLIMIT_BYTES = 1 << 5, XT_HASHLIMIT_BYTES = 1 << 5,
XT_HASHLIMIT_RATE_MATCH = 1 << 6,
}; };
struct hashlimit_cfg { struct hashlimit_cfg {
...@@ -79,6 +80,21 @@ struct hashlimit_cfg2 { ...@@ -79,6 +80,21 @@ struct hashlimit_cfg2 {
__u8 srcmask, dstmask; __u8 srcmask, dstmask;
}; };
struct hashlimit_cfg3 {
__u64 avg; /* Average secs between packets * scale */
__u64 burst; /* Period multiplier for upper limit. */
__u32 mode; /* bitmask of XT_HASHLIMIT_HASH_* */
/* user specified */
__u32 size; /* how many buckets */
__u32 max; /* max number of entries */
__u32 gc_interval; /* gc interval */
__u32 expire; /* when do entries expire? */
__u32 interval;
__u8 srcmask, dstmask;
};
struct xt_hashlimit_mtinfo1 { struct xt_hashlimit_mtinfo1 {
char name[IFNAMSIZ]; char name[IFNAMSIZ];
struct hashlimit_cfg1 cfg; struct hashlimit_cfg1 cfg;
...@@ -95,4 +111,12 @@ struct xt_hashlimit_mtinfo2 { ...@@ -95,4 +111,12 @@ struct xt_hashlimit_mtinfo2 {
struct xt_hashlimit_htable *hinfo __attribute__((aligned(8))); struct xt_hashlimit_htable *hinfo __attribute__((aligned(8)));
}; };
struct xt_hashlimit_mtinfo3 {
char name[NAME_MAX];
struct hashlimit_cfg3 cfg;
/* Used internally by the kernel */
struct xt_hashlimit_htable *hinfo __attribute__((aligned(8)));
};
#endif /* _UAPI_XT_HASHLIMIT_H */ #endif /* _UAPI_XT_HASHLIMIT_H */
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment