aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2014-03-07 08:37:12 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2014-03-12 08:55:03 -0400
commit14e1a977767e95ca48504975efff2bdf1b198ca0 (patch)
tree62ed6b64a16d079df973ae1d9898bd76a68b8f20
parent3bcc5fdf1b1a00be162159c420ea04e0adf709ec (diff)
netfilter: connlimit: use kmem_cache for conn objects
We might allocate thousands of these (one object per connection). Use distinct kmem cache to permit simplte tracking on how many objects are currently used by the connlimit match via the sysfs. Reviewed-by: Jesper Dangaard Brouer <brouer@redhat.com> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/netfilter/xt_connlimit.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index 0220d406cbe0..a8eaabb03be9 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -44,6 +44,7 @@ struct xt_connlimit_data {
44}; 44};
45 45
46static u_int32_t connlimit_rnd __read_mostly; 46static u_int32_t connlimit_rnd __read_mostly;
47static struct kmem_cache *connlimit_conn_cachep __read_mostly;
47 48
48static inline unsigned int connlimit_iphash(__be32 addr) 49static inline unsigned int connlimit_iphash(__be32 addr)
49{ 50{
@@ -113,7 +114,7 @@ static int count_hlist(struct net *net,
113 &conn->tuple); 114 &conn->tuple);
114 if (found == NULL) { 115 if (found == NULL) {
115 hlist_del(&conn->node); 116 hlist_del(&conn->node);
116 kfree(conn); 117 kmem_cache_free(connlimit_conn_cachep, conn);
117 continue; 118 continue;
118 } 119 }
119 120
@@ -133,7 +134,7 @@ static int count_hlist(struct net *net,
133 */ 134 */
134 nf_ct_put(found_ct); 135 nf_ct_put(found_ct);
135 hlist_del(&conn->node); 136 hlist_del(&conn->node);
136 kfree(conn); 137 kmem_cache_free(connlimit_conn_cachep, conn);
137 continue; 138 continue;
138 } 139 }
139 140
@@ -152,7 +153,9 @@ static bool add_hlist(struct hlist_head *head,
152 const struct nf_conntrack_tuple *tuple, 153 const struct nf_conntrack_tuple *tuple,
153 const union nf_inet_addr *addr) 154 const union nf_inet_addr *addr)
154{ 155{
155 struct xt_connlimit_conn *conn = kmalloc(sizeof(*conn), GFP_ATOMIC); 156 struct xt_connlimit_conn *conn;
157
158 conn = kmem_cache_alloc(connlimit_conn_cachep, GFP_ATOMIC);
156 if (conn == NULL) 159 if (conn == NULL)
157 return false; 160 return false;
158 conn->tuple = *tuple; 161 conn->tuple = *tuple;
@@ -285,7 +288,7 @@ static void connlimit_mt_destroy(const struct xt_mtdtor_param *par)
285 for (i = 0; i < ARRAY_SIZE(info->data->iphash); ++i) { 288 for (i = 0; i < ARRAY_SIZE(info->data->iphash); ++i) {
286 hlist_for_each_entry_safe(conn, n, &hash[i], node) { 289 hlist_for_each_entry_safe(conn, n, &hash[i], node) {
287 hlist_del(&conn->node); 290 hlist_del(&conn->node);
288 kfree(conn); 291 kmem_cache_free(connlimit_conn_cachep, conn);
289 } 292 }
290 } 293 }
291 294
@@ -305,12 +308,23 @@ static struct xt_match connlimit_mt_reg __read_mostly = {
305 308
306static int __init connlimit_mt_init(void) 309static int __init connlimit_mt_init(void)
307{ 310{
308 return xt_register_match(&connlimit_mt_reg); 311 int ret;
312 connlimit_conn_cachep = kmem_cache_create("xt_connlimit_conn",
313 sizeof(struct xt_connlimit_conn),
314 0, 0, NULL);
315 if (!connlimit_conn_cachep)
316 return -ENOMEM;
317
318 ret = xt_register_match(&connlimit_mt_reg);
319 if (ret != 0)
320 kmem_cache_destroy(connlimit_conn_cachep);
321 return ret;
309} 322}
310 323
311static void __exit connlimit_mt_exit(void) 324static void __exit connlimit_mt_exit(void)
312{ 325{
313 xt_unregister_match(&connlimit_mt_reg); 326 xt_unregister_match(&connlimit_mt_reg);
327 kmem_cache_destroy(connlimit_conn_cachep);
314} 328}
315 329
316module_init(connlimit_mt_init); 330module_init(connlimit_mt_init);