aboutsummaryrefslogtreecommitdiff
path: root/net/netfilter/xt_connlimit.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-04-06 11:29:59 -0400
committerDavid S. Miller <davem@davemloft.net>2014-04-06 11:29:59 -0400
commitd80e773f16f66a610e04f6875d4da84e74a8fb6c (patch)
tree5734eaa39c94ee47fddd8b9077de93c5b0267d0d /net/netfilter/xt_connlimit.c
parent00aefceb2fffcf4ea2fbc97ef5d4f79ef2668ecc (diff)
parentc58dd2dd443c26d856a168db108a0cd11c285bf3 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
Pablo Neira Ayuso says: ==================== The following patchset contains Netfilter fixes for your net tree, they are: * Use 16-bits offset and length fields instead of 8-bits in the conntrack extension to avoid an overflow when many conntrack extension are used, from Andrey Vagin. * Allow to use cgroup match from LOCAL_IN, there is no apparent reason for not allowing this, from Alexey Perevalov. * Fix build of the connlimit match after recent changes to let it scale up that result in a divide by zero compilation error in UP, from Florian Westphal. * Move the lock out of the structure connlimit_data to avoid a false sharing spotted by Eric Dumazet and Jesper D. Brouer, this needed as part of the recent connlimit scalability improvements, also from Florian Westphal. * Add missing module aliases in xt_osf to fix loading of rules using this match, from Kirill Tkhai. * Restrict set names in nf_tables to 15 characters instead of silently trimming them off, from me. * Fix wrong format in nf_tables request module call for chain types, spotted by Florian Westphal, patch from me. * Fix crash in xtables when it fails to copy the counters back to userspace after having replaced the table already. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter/xt_connlimit.c')
-rw-r--r--net/netfilter/xt_connlimit.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index 458464e7bd7..fbc66bb250d 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -32,8 +32,14 @@
#include <net/netfilter/nf_conntrack_tuple.h>
#include <net/netfilter/nf_conntrack_zones.h>
-#define CONNLIMIT_SLOTS 32
-#define CONNLIMIT_LOCK_SLOTS 32
+#define CONNLIMIT_SLOTS 256U
+
+#ifdef CONFIG_LOCKDEP
+#define CONNLIMIT_LOCK_SLOTS 8U
+#else
+#define CONNLIMIT_LOCK_SLOTS 256U
+#endif
+
#define CONNLIMIT_GC_MAX_NODES 8
/* we will save the tuples of all connections we care about */
@@ -49,10 +55,11 @@ struct xt_connlimit_rb {
union nf_inet_addr addr; /* search key */
};
+static spinlock_t xt_connlimit_locks[CONNLIMIT_LOCK_SLOTS] __cacheline_aligned_in_smp;
+
struct xt_connlimit_data {
struct rb_root climit_root4[CONNLIMIT_SLOTS];
struct rb_root climit_root6[CONNLIMIT_SLOTS];
- spinlock_t locks[CONNLIMIT_LOCK_SLOTS];
};
static u_int32_t connlimit_rnd __read_mostly;
@@ -297,11 +304,11 @@ static int count_them(struct net *net,
root = &data->climit_root4[hash];
}
- spin_lock_bh(&data->locks[hash % CONNLIMIT_LOCK_SLOTS]);
+ spin_lock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]);
count = count_tree(net, root, tuple, addr, mask, family);
- spin_unlock_bh(&data->locks[hash % CONNLIMIT_LOCK_SLOTS]);
+ spin_unlock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]);
return count;
}
@@ -377,9 +384,6 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par)
return -ENOMEM;
}
- for (i = 0; i < ARRAY_SIZE(info->data->locks); ++i)
- spin_lock_init(&info->data->locks[i]);
-
for (i = 0; i < ARRAY_SIZE(info->data->climit_root4); ++i)
info->data->climit_root4[i] = RB_ROOT;
for (i = 0; i < ARRAY_SIZE(info->data->climit_root6); ++i)
@@ -435,11 +439,14 @@ static struct xt_match connlimit_mt_reg __read_mostly = {
static int __init connlimit_mt_init(void)
{
- int ret;
+ int ret, i;
BUILD_BUG_ON(CONNLIMIT_LOCK_SLOTS > CONNLIMIT_SLOTS);
BUILD_BUG_ON((CONNLIMIT_SLOTS % CONNLIMIT_LOCK_SLOTS) != 0);
+ for (i = 0; i < CONNLIMIT_LOCK_SLOTS; ++i)
+ spin_lock_init(&xt_connlimit_locks[i]);
+
connlimit_conn_cachep = kmem_cache_create("xt_connlimit_conn",
sizeof(struct xt_connlimit_conn),
0, 0, NULL);