Skip to content

Commit a67dd26

Browse files
Florian Westphalummakynes
authored andcommitted
netfilter: xtables: prepare for on-demand hook register
This change prepares for upcoming on-demand xtables hook registration. We change the protoypes of the register/unregister functions. A followup patch will then add nf_hook_register/unregister calls to the iptables one. Once a hook is registered packets will be picked up, so all assignments of the form net->ipv4.iptable_$table = new_table have to be moved to ip(6)t_register_table, else we can see NULL net->ipv4.iptable_$table later. This patch doesn't change functionality; without this the actual change simply gets too big. Signed-off-by: Florian Westphal <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 5f54739 commit a67dd26

File tree

17 files changed

+107
-88
lines changed

17 files changed

+107
-88
lines changed

include/linux/netfilter_arp/arp_tables.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ struct arpt_error {
4848
}
4949

5050
extern void *arpt_alloc_initial_table(const struct xt_table *);
51-
extern struct xt_table *arpt_register_table(struct net *net,
52-
const struct xt_table *table,
53-
const struct arpt_replace *repl);
54-
extern void arpt_unregister_table(struct xt_table *table);
51+
int arpt_register_table(struct net *net, const struct xt_table *table,
52+
const struct arpt_replace *repl,
53+
const struct nf_hook_ops *ops, struct xt_table **res);
54+
void arpt_unregister_table(struct net *net, struct xt_table *table,
55+
const struct nf_hook_ops *ops);
5556
extern unsigned int arpt_do_table(struct sk_buff *skb,
5657
const struct nf_hook_state *state,
5758
struct xt_table *table);

include/linux/netfilter_ipv4/ip_tables.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@
2424

2525
extern void ipt_init(void) __init;
2626

27-
extern struct xt_table *ipt_register_table(struct net *net,
28-
const struct xt_table *table,
29-
const struct ipt_replace *repl);
30-
extern void ipt_unregister_table(struct net *net, struct xt_table *table);
27+
int ipt_register_table(struct net *net, const struct xt_table *table,
28+
const struct ipt_replace *repl,
29+
const struct nf_hook_ops *ops, struct xt_table **res);
30+
void ipt_unregister_table(struct net *net, struct xt_table *table,
31+
const struct nf_hook_ops *ops);
3132

3233
/* Standard entry. */
3334
struct ipt_standard {

include/linux/netfilter_ipv6/ip6_tables.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@
2525
extern void ip6t_init(void) __init;
2626

2727
extern void *ip6t_alloc_initial_table(const struct xt_table *);
28-
extern struct xt_table *ip6t_register_table(struct net *net,
29-
const struct xt_table *table,
30-
const struct ip6t_replace *repl);
31-
extern void ip6t_unregister_table(struct net *net, struct xt_table *table);
28+
int ip6t_register_table(struct net *net, const struct xt_table *table,
29+
const struct ip6t_replace *repl,
30+
const struct nf_hook_ops *ops, struct xt_table **res);
31+
void ip6t_unregister_table(struct net *net, struct xt_table *table,
32+
const struct nf_hook_ops *ops);
3233
extern unsigned int ip6t_do_table(struct sk_buff *skb,
3334
const struct nf_hook_state *state,
3435
struct xt_table *table);

net/ipv4/netfilter/arp_tables.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1780,9 +1780,11 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
17801780
return ret;
17811781
}
17821782

1783-
struct xt_table *arpt_register_table(struct net *net,
1784-
const struct xt_table *table,
1785-
const struct arpt_replace *repl)
1783+
int arpt_register_table(struct net *net,
1784+
const struct xt_table *table,
1785+
const struct arpt_replace *repl,
1786+
const struct nf_hook_ops *ops,
1787+
struct xt_table **res)
17861788
{
17871789
int ret;
17881790
struct xt_table_info *newinfo;
@@ -1791,10 +1793,8 @@ struct xt_table *arpt_register_table(struct net *net,
17911793
struct xt_table *new_table;
17921794

17931795
newinfo = xt_alloc_table_info(repl->size);
1794-
if (!newinfo) {
1795-
ret = -ENOMEM;
1796-
goto out;
1797-
}
1796+
if (!newinfo)
1797+
return -ENOMEM;
17981798

17991799
loc_cpu_entry = newinfo->entries;
18001800
memcpy(loc_cpu_entry, repl->entries, repl->size);
@@ -1809,15 +1809,18 @@ struct xt_table *arpt_register_table(struct net *net,
18091809
ret = PTR_ERR(new_table);
18101810
goto out_free;
18111811
}
1812-
return new_table;
1812+
1813+
WRITE_ONCE(*res, new_table);
1814+
1815+
return ret;
18131816

18141817
out_free:
18151818
xt_free_table_info(newinfo);
1816-
out:
1817-
return ERR_PTR(ret);
1819+
return ret;
18181820
}
18191821

1820-
void arpt_unregister_table(struct xt_table *table)
1822+
void arpt_unregister_table(struct net *net, struct xt_table *table,
1823+
const struct nf_hook_ops *ops)
18211824
{
18221825
struct xt_table_info *private;
18231826
void *loc_cpu_entry;

net/ipv4/netfilter/arptable_filter.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,20 @@ static struct nf_hook_ops *arpfilter_ops __read_mostly;
3838
static int __net_init arptable_filter_net_init(struct net *net)
3939
{
4040
struct arpt_replace *repl;
41-
41+
int err;
42+
4243
repl = arpt_alloc_initial_table(&packet_filter);
4344
if (repl == NULL)
4445
return -ENOMEM;
45-
net->ipv4.arptable_filter =
46-
arpt_register_table(net, &packet_filter, repl);
46+
err = arpt_register_table(net, &packet_filter, repl, arpfilter_ops,
47+
&net->ipv4.arptable_filter);
4748
kfree(repl);
48-
return PTR_ERR_OR_ZERO(net->ipv4.arptable_filter);
49+
return err;
4950
}
5051

5152
static void __net_exit arptable_filter_net_exit(struct net *net)
5253
{
53-
arpt_unregister_table(net->ipv4.arptable_filter);
54+
arpt_unregister_table(net, net->ipv4.arptable_filter, arpfilter_ops);
5455
}
5556

5657
static struct pernet_operations arptable_filter_net_ops = {

net/ipv4/netfilter/ip_tables.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2062,9 +2062,9 @@ do_ipt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
20622062
return ret;
20632063
}
20642064

2065-
struct xt_table *ipt_register_table(struct net *net,
2066-
const struct xt_table *table,
2067-
const struct ipt_replace *repl)
2065+
int ipt_register_table(struct net *net, const struct xt_table *table,
2066+
const struct ipt_replace *repl,
2067+
const struct nf_hook_ops *ops, struct xt_table **res)
20682068
{
20692069
int ret;
20702070
struct xt_table_info *newinfo;
@@ -2073,10 +2073,8 @@ struct xt_table *ipt_register_table(struct net *net,
20732073
struct xt_table *new_table;
20742074

20752075
newinfo = xt_alloc_table_info(repl->size);
2076-
if (!newinfo) {
2077-
ret = -ENOMEM;
2078-
goto out;
2079-
}
2076+
if (!newinfo)
2077+
return -ENOMEM;
20802078

20812079
loc_cpu_entry = newinfo->entries;
20822080
memcpy(loc_cpu_entry, repl->entries, repl->size);
@@ -2091,15 +2089,16 @@ struct xt_table *ipt_register_table(struct net *net,
20912089
goto out_free;
20922090
}
20932091

2094-
return new_table;
2092+
WRITE_ONCE(*res, new_table);
2093+
return ret;
20952094

20962095
out_free:
20972096
xt_free_table_info(newinfo);
2098-
out:
2099-
return ERR_PTR(ret);
2097+
return ret;
21002098
}
21012099

2102-
void ipt_unregister_table(struct net *net, struct xt_table *table)
2100+
void ipt_unregister_table(struct net *net, struct xt_table *table,
2101+
const struct nf_hook_ops *ops)
21032102
{
21042103
struct xt_table_info *private;
21052104
void *loc_cpu_entry;

net/ipv4/netfilter/iptable_filter.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ module_param(forward, bool, 0000);
5454
static int __net_init iptable_filter_net_init(struct net *net)
5555
{
5656
struct ipt_replace *repl;
57+
int err;
5758

5859
repl = ipt_alloc_initial_table(&packet_filter);
5960
if (repl == NULL)
@@ -62,15 +63,15 @@ static int __net_init iptable_filter_net_init(struct net *net)
6263
((struct ipt_standard *)repl->entries)[1].target.verdict =
6364
forward ? -NF_ACCEPT - 1 : -NF_DROP - 1;
6465

65-
net->ipv4.iptable_filter =
66-
ipt_register_table(net, &packet_filter, repl);
66+
err = ipt_register_table(net, &packet_filter, repl, filter_ops,
67+
&net->ipv4.iptable_filter);
6768
kfree(repl);
68-
return PTR_ERR_OR_ZERO(net->ipv4.iptable_filter);
69+
return err;
6970
}
7071

7172
static void __net_exit iptable_filter_net_exit(struct net *net)
7273
{
73-
ipt_unregister_table(net, net->ipv4.iptable_filter);
74+
ipt_unregister_table(net, net->ipv4.iptable_filter, filter_ops);
7475
}
7576

7677
static struct pernet_operations iptable_filter_net_ops = {

net/ipv4/netfilter/iptable_mangle.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,19 +96,20 @@ static struct nf_hook_ops *mangle_ops __read_mostly;
9696
static int __net_init iptable_mangle_net_init(struct net *net)
9797
{
9898
struct ipt_replace *repl;
99+
int ret;
99100

100101
repl = ipt_alloc_initial_table(&packet_mangler);
101102
if (repl == NULL)
102103
return -ENOMEM;
103-
net->ipv4.iptable_mangle =
104-
ipt_register_table(net, &packet_mangler, repl);
104+
ret = ipt_register_table(net, &packet_mangler, repl, mangle_ops,
105+
&net->ipv4.iptable_mangle);
105106
kfree(repl);
106-
return PTR_ERR_OR_ZERO(net->ipv4.iptable_mangle);
107+
return ret;
107108
}
108109

109110
static void __net_exit iptable_mangle_net_exit(struct net *net)
110111
{
111-
ipt_unregister_table(net, net->ipv4.iptable_mangle);
112+
ipt_unregister_table(net, net->ipv4.iptable_mangle, mangle_ops);
112113
}
113114

114115
static struct pernet_operations iptable_mangle_net_ops = {

net/ipv4/netfilter/iptable_nat.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,18 +98,20 @@ static struct nf_hook_ops nf_nat_ipv4_ops[] __read_mostly = {
9898
static int __net_init iptable_nat_net_init(struct net *net)
9999
{
100100
struct ipt_replace *repl;
101+
int ret;
101102

102103
repl = ipt_alloc_initial_table(&nf_nat_ipv4_table);
103104
if (repl == NULL)
104105
return -ENOMEM;
105-
net->ipv4.nat_table = ipt_register_table(net, &nf_nat_ipv4_table, repl);
106+
ret = ipt_register_table(net, &nf_nat_ipv4_table, repl,
107+
nf_nat_ipv4_ops, &net->ipv4.nat_table);
106108
kfree(repl);
107-
return PTR_ERR_OR_ZERO(net->ipv4.nat_table);
109+
return ret;
108110
}
109111

110112
static void __net_exit iptable_nat_net_exit(struct net *net)
111113
{
112-
ipt_unregister_table(net, net->ipv4.nat_table);
114+
ipt_unregister_table(net, net->ipv4.nat_table, nf_nat_ipv4_ops);
113115
}
114116

115117
static struct pernet_operations iptable_nat_net_ops = {

net/ipv4/netfilter/iptable_raw.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,20 @@ static struct nf_hook_ops *rawtable_ops __read_mostly;
3737
static int __net_init iptable_raw_net_init(struct net *net)
3838
{
3939
struct ipt_replace *repl;
40+
int ret;
4041

4142
repl = ipt_alloc_initial_table(&packet_raw);
4243
if (repl == NULL)
4344
return -ENOMEM;
44-
net->ipv4.iptable_raw =
45-
ipt_register_table(net, &packet_raw, repl);
45+
ret = ipt_register_table(net, &packet_raw, repl, rawtable_ops,
46+
&net->ipv4.iptable_raw);
4647
kfree(repl);
47-
return PTR_ERR_OR_ZERO(net->ipv4.iptable_raw);
48+
return ret;
4849
}
4950

5051
static void __net_exit iptable_raw_net_exit(struct net *net)
5152
{
52-
ipt_unregister_table(net, net->ipv4.iptable_raw);
53+
ipt_unregister_table(net, net->ipv4.iptable_raw, rawtable_ops);
5354
}
5455

5556
static struct pernet_operations iptable_raw_net_ops = {

net/ipv4/netfilter/iptable_security.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,19 +54,20 @@ static struct nf_hook_ops *sectbl_ops __read_mostly;
5454
static int __net_init iptable_security_net_init(struct net *net)
5555
{
5656
struct ipt_replace *repl;
57+
int ret;
5758

5859
repl = ipt_alloc_initial_table(&security_table);
5960
if (repl == NULL)
6061
return -ENOMEM;
61-
net->ipv4.iptable_security =
62-
ipt_register_table(net, &security_table, repl);
62+
ret = ipt_register_table(net, &security_table, repl, sectbl_ops,
63+
&net->ipv4.iptable_security);
6364
kfree(repl);
64-
return PTR_ERR_OR_ZERO(net->ipv4.iptable_security);
65+
return ret;
6566
}
6667

6768
static void __net_exit iptable_security_net_exit(struct net *net)
6869
{
69-
ipt_unregister_table(net, net->ipv4.iptable_security);
70+
ipt_unregister_table(net, net->ipv4.iptable_security, sectbl_ops);
7071
}
7172

7273
static struct pernet_operations iptable_security_net_ops = {

net/ipv6/netfilter/ip6_tables.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2071,9 +2071,10 @@ do_ip6t_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
20712071
return ret;
20722072
}
20732073

2074-
struct xt_table *ip6t_register_table(struct net *net,
2075-
const struct xt_table *table,
2076-
const struct ip6t_replace *repl)
2074+
int ip6t_register_table(struct net *net, const struct xt_table *table,
2075+
const struct ip6t_replace *repl,
2076+
const struct nf_hook_ops *ops,
2077+
struct xt_table **res)
20772078
{
20782079
int ret;
20792080
struct xt_table_info *newinfo;
@@ -2082,10 +2083,8 @@ struct xt_table *ip6t_register_table(struct net *net,
20822083
struct xt_table *new_table;
20832084

20842085
newinfo = xt_alloc_table_info(repl->size);
2085-
if (!newinfo) {
2086-
ret = -ENOMEM;
2087-
goto out;
2088-
}
2086+
if (!newinfo)
2087+
return -ENOMEM;
20892088

20902089
loc_cpu_entry = newinfo->entries;
20912090
memcpy(loc_cpu_entry, repl->entries, repl->size);
@@ -2099,15 +2098,17 @@ struct xt_table *ip6t_register_table(struct net *net,
20992098
ret = PTR_ERR(new_table);
21002099
goto out_free;
21012100
}
2102-
return new_table;
2101+
2102+
WRITE_ONCE(*res, new_table);
2103+
return ret;
21032104

21042105
out_free:
21052106
xt_free_table_info(newinfo);
2106-
out:
2107-
return ERR_PTR(ret);
2107+
return ret;
21082108
}
21092109

2110-
void ip6t_unregister_table(struct net *net, struct xt_table *table)
2110+
void ip6t_unregister_table(struct net *net, struct xt_table *table,
2111+
const struct nf_hook_ops *ops)
21112112
{
21122113
struct xt_table_info *private;
21132114
void *loc_cpu_entry;

net/ipv6/netfilter/ip6table_filter.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ module_param(forward, bool, 0000);
4747
static int __net_init ip6table_filter_net_init(struct net *net)
4848
{
4949
struct ip6t_replace *repl;
50+
int err;
5051

5152
repl = ip6t_alloc_initial_table(&packet_filter);
5253
if (repl == NULL)
@@ -55,15 +56,15 @@ static int __net_init ip6table_filter_net_init(struct net *net)
5556
((struct ip6t_standard *)repl->entries)[1].target.verdict =
5657
forward ? -NF_ACCEPT - 1 : -NF_DROP - 1;
5758

58-
net->ipv6.ip6table_filter =
59-
ip6t_register_table(net, &packet_filter, repl);
59+
err = ip6t_register_table(net, &packet_filter, repl, filter_ops,
60+
&net->ipv6.ip6table_filter);
6061
kfree(repl);
61-
return PTR_ERR_OR_ZERO(net->ipv6.ip6table_filter);
62+
return err;
6263
}
6364

6465
static void __net_exit ip6table_filter_net_exit(struct net *net)
6566
{
66-
ip6t_unregister_table(net, net->ipv6.ip6table_filter);
67+
ip6t_unregister_table(net, net->ipv6.ip6table_filter, filter_ops);
6768
}
6869

6970
static struct pernet_operations ip6table_filter_net_ops = {

0 commit comments

Comments
 (0)