diff options
author | Florian Westphal <fw@strlen.de> | 2021-04-21 09:51:08 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2021-04-26 03:20:46 +0200 |
commit | f9006acc8dfe59e25aa75729728ac57a8d84fc32 (patch) | |
tree | 9a9b62d8a613174254611680826f23eafc5ca058 /net/ipv4 | |
parent | ae689334225ff0e4ef112459ecd24aea932c2b00 (diff) |
netfilter: arp_tables: pass table pointer via nf_hook_ops
Same change as previous patch. Only difference:
no need to handle NULL template_ops parameter, the only caller
(arptable_filter) always passes non-NULL argument.
This removes all remaining accesses to net->ipv4.arptable_filter.
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 43 | ||||
-rw-r--r-- | net/ipv4/netfilter/arptable_filter.c | 6 |
2 files changed, 31 insertions, 18 deletions
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 8a16b0dc5271..b1bb6a7e2dd7 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -1499,10 +1499,11 @@ static void __arpt_unregister_table(struct net *net, struct xt_table *table) int arpt_register_table(struct net *net, const struct xt_table *table, const struct arpt_replace *repl, - const struct nf_hook_ops *ops, - struct xt_table **res) + const struct nf_hook_ops *template_ops) { - int ret; + struct nf_hook_ops *ops; + unsigned int num_ops; + int ret, i; struct xt_table_info *newinfo; struct xt_table_info bootstrap = {0}; void *loc_cpu_entry; @@ -1516,28 +1517,42 @@ int arpt_register_table(struct net *net, memcpy(loc_cpu_entry, repl->entries, repl->size); ret = translate_table(net, newinfo, loc_cpu_entry, repl); - if (ret != 0) - goto out_free; + if (ret != 0) { + xt_free_table_info(newinfo); + return ret; + } new_table = xt_register_table(net, table, &bootstrap, newinfo); if (IS_ERR(new_table)) { - ret = PTR_ERR(new_table); - goto out_free; + xt_free_table_info(newinfo); + return PTR_ERR(new_table); } - /* set res now, will see skbs right after nf_register_net_hooks */ - WRITE_ONCE(*res, new_table); + num_ops = hweight32(table->valid_hooks); + if (num_ops == 0) { + ret = -EINVAL; + goto out_free; + } - ret = nf_register_net_hooks(net, ops, hweight32(table->valid_hooks)); - if (ret != 0) { - __arpt_unregister_table(net, new_table); - *res = NULL; + ops = kmemdup(template_ops, sizeof(*ops) * num_ops, GFP_KERNEL); + if (!ops) { + ret = -ENOMEM; + goto out_free; } + for (i = 0; i < num_ops; i++) + ops[i].priv = new_table; + + new_table->ops = ops; + + ret = nf_register_net_hooks(net, ops, num_ops); + if (ret != 0) + goto out_free; + return ret; out_free: - xt_free_table_info(newinfo); + __arpt_unregister_table(net, new_table); return ret; } diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c index 924f096a6d89..b8f45e9bbec8 100644 --- a/net/ipv4/netfilter/arptable_filter.c +++ b/net/ipv4/netfilter/arptable_filter.c @@ -34,7 +34,7 @@ static unsigned int arptable_filter_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) { - return arpt_do_table(skb, state, state->net->ipv4.arptable_filter); + return arpt_do_table(skb, state, priv); } static struct nf_hook_ops *arpfilter_ops __read_mostly; @@ -47,8 +47,7 @@ static int __net_init arptable_filter_table_init(struct net *net) repl = arpt_alloc_initial_table(&packet_filter); if (repl == NULL) return -ENOMEM; - err = arpt_register_table(net, &packet_filter, repl, arpfilter_ops, - &net->ipv4.arptable_filter); + err = arpt_register_table(net, &packet_filter, repl, arpfilter_ops); kfree(repl); return err; } @@ -61,7 +60,6 @@ static void __net_exit arptable_filter_net_pre_exit(struct net *net) static void __net_exit arptable_filter_net_exit(struct net *net) { arpt_unregister_table(net, "filter"); - net->ipv4.arptable_filter = NULL; } static struct pernet_operations arptable_filter_net_ops = { |