Commit 1ff75a3e authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso

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: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 2111515a
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/vmalloc.h>
#include <linux/netfilter.h> #include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nf_tables.h> #include <linux/netfilter/nf_tables.h>
...@@ -3054,10 +3055,11 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, ...@@ -3054,10 +3055,11 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
if (ops->privsize != NULL) if (ops->privsize != NULL)
size = ops->privsize(nla, &desc); size = ops->privsize(nla, &desc);
err = -ENOMEM; set = kvzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
set = kzalloc(sizeof(*set) + size + udlen, GFP_KERNEL); if (!set) {
if (set == NULL) err = -ENOMEM;
goto err1; goto err1;
}
nla_strlcpy(name, nla[NFTA_SET_NAME], sizeof(set->name)); nla_strlcpy(name, nla[NFTA_SET_NAME], sizeof(set->name));
err = nf_tables_set_alloc_name(&ctx, 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, ...@@ -3100,7 +3102,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
err3: err3:
ops->destroy(set); ops->destroy(set);
err2: err2:
kfree(set); kvfree(set);
err1: err1:
module_put(ops->type->owner); module_put(ops->type->owner);
return err; return err;
...@@ -3110,7 +3112,7 @@ static void nft_set_destroy(struct nft_set *set) ...@@ -3110,7 +3112,7 @@ static void nft_set_destroy(struct nft_set *set)
{ {
set->ops->destroy(set); set->ops->destroy(set);
module_put(set->ops->type->owner); 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) static void nf_tables_set_destroy(const struct nft_ctx *ctx, struct nft_set *set)
......
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