aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/netfilter/iptable_nat.c
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2021-04-21 09:51:07 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2021-04-26 03:20:46 +0200
commitae689334225ff0e4ef112459ecd24aea932c2b00 (patch)
treec1bc1091f9f95be7de8745d578d95ed8368f730e /net/ipv4/netfilter/iptable_nat.c
parenta4aeafa28cf706f65f763026c26d83e7e8c96592 (diff)
downloadlinux-ae689334225ff0e4ef112459ecd24aea932c2b00.tar.gz
netfilter: ip_tables: pass table pointer via nf_hook_ops
iptable_x modules rely on 'struct net' to contain a pointer to the table that should be evaluated. In order to remove these pointers from struct net, pass them via the 'priv' pointer in a similar fashion as nf_tables passes the rule data. To do that, duplicate the nf_hook_info array passed in from the iptable_x modules, update the ops->priv pointers of the copy to refer to the table and then change the hookfn implementations to just pass the 'priv' argument to the traverser. After this patch, the xt_table pointers can already be removed from struct net. However, changes to struct net result in re-compile of the entire network stack, so do the removal after arptables and ip6tables have been converted as well. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/ipv4/netfilter/iptable_nat.c')
-rw-r--r--net/ipv4/netfilter/iptable_nat.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
index dfa9dc63a7b51..a9913842ef18e 100644
--- a/net/ipv4/netfilter/iptable_nat.c
+++ b/net/ipv4/netfilter/iptable_nat.c
@@ -66,12 +66,19 @@ static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
},
};
-static int ipt_nat_register_lookups(struct net *net, struct xt_table *table)
+static int ipt_nat_register_lookups(struct net *net)
{
- struct nf_hook_ops *ops = kmemdup(nf_nat_ipv4_ops, sizeof(nf_nat_ipv4_ops), GFP_KERNEL);
- struct iptable_nat_pernet *xt_nat_net = net_generic(net, iptable_nat_net_id);
+ struct iptable_nat_pernet *xt_nat_net;
+ struct nf_hook_ops *ops;
+ struct xt_table *table;
int i, ret;
+ xt_nat_net = net_generic(net, iptable_nat_net_id);
+ table = xt_find_table(net, NFPROTO_IPV4, "nat");
+ if (WARN_ON_ONCE(!table))
+ return -ENOENT;
+
+ ops = kmemdup(nf_nat_ipv4_ops, sizeof(nf_nat_ipv4_ops), GFP_KERNEL);
if (!ops)
return -ENOMEM;
@@ -109,25 +116,21 @@ static void ipt_nat_unregister_lookups(struct net *net)
static int __net_init iptable_nat_table_init(struct net *net)
{
struct ipt_replace *repl;
- struct xt_table *table;
int ret;
repl = ipt_alloc_initial_table(&nf_nat_ipv4_table);
if (repl == NULL)
return -ENOMEM;
- ret = ipt_register_table(net, &nf_nat_ipv4_table, repl,
- NULL, &table);
+
+ ret = ipt_register_table(net, &nf_nat_ipv4_table, repl, NULL);
if (ret < 0) {
kfree(repl);
return ret;
}
- ret = ipt_nat_register_lookups(net, table);
- if (ret < 0) {
+ ret = ipt_nat_register_lookups(net);
+ if (ret < 0)
ipt_unregister_table_exit(net, "nat");
- } else {
- net->ipv4.nat_table = table;
- }
kfree(repl);
return ret;
@@ -141,7 +144,6 @@ static void __net_exit iptable_nat_net_pre_exit(struct net *net)
static void __net_exit iptable_nat_net_exit(struct net *net)
{
ipt_unregister_table_exit(net, "nat");
- net->ipv4.nat_table = NULL;
}
static struct pernet_operations iptable_nat_net_ops = {