summaryrefslogtreecommitdiff
path: root/net/netfilter
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2017-05-22 17:47:59 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2017-05-29 12:46:20 +0200
commit1ff75a3e9ab72368fc3ad63d9bc6c7518cbd1389 (patch)
treeb09ba0c2a482cbcc9dcd55f5b5709f806292a8ed /net/netfilter
parent2111515abc46cb3e18b22d8551067029acfd1f55 (diff)
netfilter: nf_tables: allow large allocations for new sets
The new fixed size hashtable backend implementation may result in a large array of buckets that would spew splats from mm. Update this code to fall back on vmalloc in case the memory allocation order is too costly. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/nf_tables_api.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 2969016d8cad..bc8f03a53734 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -13,6 +13,7 @@
#include <linux/list.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
+#include <linux/vmalloc.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h>
@@ -3054,10 +3055,11 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
if (ops->privsize != NULL)
size = ops->privsize(nla, &desc);
- err = -ENOMEM;
- set = kzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
- if (set == NULL)
+ set = kvzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
+ if (!set) {
+ err = -ENOMEM;
goto err1;
+ }
nla_strlcpy(name, nla[NFTA_SET_NAME], sizeof(set->name));
err = nf_tables_set_alloc_name(&ctx, set, name);
@@ -3100,7 +3102,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
err3:
ops->destroy(set);
err2:
- kfree(set);
+ kvfree(set);
err1:
module_put(ops->type->owner);
return err;
@@ -3110,7 +3112,7 @@ static void nft_set_destroy(struct nft_set *set)
{
set->ops->destroy(set);
module_put(set->ops->type->owner);
- kfree(set);
+ kvfree(set);
}
static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)