@@ -52,7 +52,8 @@ struct nf_flow_rule {
struct nf_flowtable_type {
struct list_head list;
int family;
- int (*init)(struct nf_flowtable *ft);
+ struct nf_flowtable * (*create)(struct net *net,
+ const struct nf_flowtable_type *type);
bool (*gc)(const struct flow_offload *flow);
int (*setup)(struct nf_flowtable *ft,
struct net_device *dev,
@@ -279,7 +280,7 @@ void nf_flow_table_gc_cleanup(struct nf_flowtable *flowtable,
struct net_device *dev);
void nf_flow_table_cleanup(struct net_device *dev);
-int nf_flow_table_init(struct nf_flowtable *flow_table);
+struct nf_flowtable *nf_flow_table_create(struct net *net, const struct nf_flowtable_type *type);
void nf_flow_table_free(struct nf_flowtable *flow_table);
void flow_offload_teardown(struct flow_offload *flow);
@@ -531,29 +531,38 @@ void nf_flow_dnat_port(const struct flow_offload *flow, struct sk_buff *skb,
}
EXPORT_SYMBOL_GPL(nf_flow_dnat_port);
-int nf_flow_table_init(struct nf_flowtable *flowtable)
+struct nf_flowtable *nf_flow_table_create(struct net *net, const struct nf_flowtable_type *type)
{
+ struct nf_flowtable *flowtable = kzalloc(sizeof(*flowtable), GFP_KERNEL_ACCOUNT);
int err;
+ if (!flowtable)
+ return NULL;
+
INIT_DELAYED_WORK(&flowtable->gc_work, nf_flow_offload_work_gc);
flow_block_init(&flowtable->flow_block);
init_rwsem(&flowtable->flow_block_lock);
err = rhashtable_init(&flowtable->rhashtable,
&nf_flow_offload_rhash_params);
- if (err < 0)
- return err;
+ if (err < 0) {
+ kfree(flowtable);
+ return NULL;
+ }
queue_delayed_work(system_power_efficient_wq,
&flowtable->gc_work, HZ);
+ write_pnet(&flowtable->net, net);
+ flowtable->type = type;
+
mutex_lock(&flowtable_lock);
list_add(&flowtable->list, &flowtables);
mutex_unlock(&flowtable_lock);
- return 0;
+ return flowtable;
}
-EXPORT_SYMBOL_GPL(nf_flow_table_init);
+EXPORT_SYMBOL_GPL(nf_flow_table_create);
static void nf_flow_table_do_cleanup(struct nf_flowtable *flow_table,
struct flow_offload *flow, void *data)
@@ -63,7 +63,7 @@ static int nf_flow_rule_route_inet(struct net *net,
static struct nf_flowtable_type flowtable_inet = {
.family = NFPROTO_INET,
- .init = nf_flow_table_init,
+ .create = nf_flow_table_create,
.setup = nf_flow_table_offload_setup,
.action = nf_flow_rule_route_inet,
.free = nf_flow_table_free,
@@ -73,7 +73,7 @@ static struct nf_flowtable_type flowtable_inet = {
static struct nf_flowtable_type flowtable_ipv4 = {
.family = NFPROTO_IPV4,
- .init = nf_flow_table_init,
+ .create = nf_flow_table_create,
.setup = nf_flow_table_offload_setup,
.action = nf_flow_rule_route_ipv4,
.free = nf_flow_table_free,
@@ -83,7 +83,7 @@ static struct nf_flowtable_type flowtable_ipv4 = {
static struct nf_flowtable_type flowtable_ipv6 = {
.family = NFPROTO_IPV6,
- .init = nf_flow_table_init,
+ .create = nf_flow_table_create,
.setup = nf_flow_table_offload_setup,
.action = nf_flow_rule_route_ipv6,
.free = nf_flow_table_free,
@@ -8400,7 +8400,7 @@ static int nf_tables_newflowtable(struct sk_buff *skb,
goto err2;
}
- flowtable->ft = kzalloc(sizeof(*flowtable->ft), GFP_KERNEL_ACCOUNT);
+ flowtable->ft = type->create(net, type);
if (!flowtable->ft) {
err = -ENOMEM;
goto err3;
@@ -8415,12 +8415,6 @@ static int nf_tables_newflowtable(struct sk_buff *skb,
}
}
- write_pnet(&flowtable->ft->net, net);
- flowtable->ft->type = type;
- err = type->init(flowtable->ft);
- if (err < 0)
- goto err3;
-
err = nft_flowtable_parse_hook(&ctx, nla, &flowtable_hook, flowtable,
extack, true);
if (err < 0)
@@ -313,17 +313,13 @@ static int tcf_ct_flow_table_get(struct net *net, struct tcf_ct_params *params)
if (err)
goto err_insert;
- ct_ft->nf_ft = kzalloc(sizeof(*ct_ft->nf_ft), GFP_KERNEL);
+ ct_ft->nf_ft->type = &flowtable_ct;
+ ct_ft->nf_ft = nf_flow_table_create(net, &flowtable_ct);
if (!ct_ft->nf_ft)
- goto err_alloc;
+ goto err_create;
- ct_ft->nf_ft->type = &flowtable_ct;
ct_ft->nf_ft->flags |= NF_FLOWTABLE_HW_OFFLOAD |
NF_FLOWTABLE_COUNTER;
- err = nf_flow_table_init(ct_ft->nf_ft);
- if (err)
- goto err_init;
- write_pnet(&ct_ft->nf_ft->net, net);
__module_get(THIS_MODULE);
out_unlock:
@@ -333,7 +329,7 @@ static int tcf_ct_flow_table_get(struct net *net, struct tcf_ct_params *params)
return 0;
-err_init:
+err_create:
rhashtable_remove_fast(&zones_ht, &ct_ft->node, zones_params);
kfree(ct_ft->nf_ft);
err_insert:
Let the flowtable core allocate the nf_flowtable structure itself. While at it, move the net and type assignment into the flowtable core. The returned nf_flowtable pointer can still be released with plain kfree(), this will be changed in a followup patch. Signed-off-by: Florian Westphal <fw@strlen.de> --- include/net/netfilter/nf_flow_table.h | 5 +++-- net/netfilter/nf_flow_table_core.c | 19 ++++++++++++++----- net/netfilter/nf_flow_table_inet.c | 6 +++--- net/netfilter/nf_tables_api.c | 8 +------- net/sched/act_ct.c | 12 ++++-------- 5 files changed, 25 insertions(+), 25 deletions(-)