diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-10-08 05:35:10 -0400 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2008-10-08 05:35:10 -0400 |
commit | e099a173573ce1ba171092aee7bb3c72ea686e59 (patch) | |
tree | e2ad85c122d022f400d2f6260a7e90c2481bd671 | |
parent | b8b8063e0d0835fb44c88d9fded2be31c9a1757e (diff) |
netfilter: netns nat: per-netns NAT table
Same story as with iptable_filter, iptables_raw tables.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r-- | include/net/netns/ipv4.h | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_rule.c | 40 |
2 files changed, 30 insertions, 11 deletions
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index a6ed83853dcc..b286b840493c 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h | |||
@@ -38,6 +38,7 @@ struct netns_ipv4 { | |||
38 | struct xt_table *iptable_raw; | 38 | struct xt_table *iptable_raw; |
39 | struct xt_table *arptable_filter; | 39 | struct xt_table *arptable_filter; |
40 | struct xt_table *iptable_security; | 40 | struct xt_table *iptable_security; |
41 | struct xt_table *nat_table; | ||
41 | #endif | 42 | #endif |
42 | 43 | ||
43 | int sysctl_icmp_echo_ignore_all; | 44 | int sysctl_icmp_echo_ignore_all; |
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c index e8b4d0d4439e..0a02a8caf3b3 100644 --- a/net/ipv4/netfilter/nf_nat_rule.c +++ b/net/ipv4/netfilter/nf_nat_rule.c | |||
@@ -33,7 +33,7 @@ static struct | |||
33 | struct ipt_replace repl; | 33 | struct ipt_replace repl; |
34 | struct ipt_standard entries[3]; | 34 | struct ipt_standard entries[3]; |
35 | struct ipt_error term; | 35 | struct ipt_error term; |
36 | } nat_initial_table __initdata = { | 36 | } nat_initial_table __net_initdata = { |
37 | .repl = { | 37 | .repl = { |
38 | .name = "nat", | 38 | .name = "nat", |
39 | .valid_hooks = NAT_VALID_HOOKS, | 39 | .valid_hooks = NAT_VALID_HOOKS, |
@@ -58,14 +58,13 @@ static struct | |||
58 | .term = IPT_ERROR_INIT, /* ERROR */ | 58 | .term = IPT_ERROR_INIT, /* ERROR */ |
59 | }; | 59 | }; |
60 | 60 | ||
61 | static struct xt_table __nat_table = { | 61 | static struct xt_table nat_table = { |
62 | .name = "nat", | 62 | .name = "nat", |
63 | .valid_hooks = NAT_VALID_HOOKS, | 63 | .valid_hooks = NAT_VALID_HOOKS, |
64 | .lock = __RW_LOCK_UNLOCKED(__nat_table.lock), | 64 | .lock = __RW_LOCK_UNLOCKED(__nat_table.lock), |
65 | .me = THIS_MODULE, | 65 | .me = THIS_MODULE, |
66 | .af = AF_INET, | 66 | .af = AF_INET, |
67 | }; | 67 | }; |
68 | static struct xt_table *nat_table; | ||
69 | 68 | ||
70 | /* Source NAT */ | 69 | /* Source NAT */ |
71 | static unsigned int ipt_snat_target(struct sk_buff *skb, | 70 | static unsigned int ipt_snat_target(struct sk_buff *skb, |
@@ -194,9 +193,10 @@ int nf_nat_rule_find(struct sk_buff *skb, | |||
194 | const struct net_device *out, | 193 | const struct net_device *out, |
195 | struct nf_conn *ct) | 194 | struct nf_conn *ct) |
196 | { | 195 | { |
196 | struct net *net = nf_ct_net(ct); | ||
197 | int ret; | 197 | int ret; |
198 | 198 | ||
199 | ret = ipt_do_table(skb, hooknum, in, out, nat_table); | 199 | ret = ipt_do_table(skb, hooknum, in, out, net->ipv4.nat_table); |
200 | 200 | ||
201 | if (ret == NF_ACCEPT) { | 201 | if (ret == NF_ACCEPT) { |
202 | if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum))) | 202 | if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum))) |
@@ -226,14 +226,32 @@ static struct xt_target ipt_dnat_reg __read_mostly = { | |||
226 | .family = AF_INET, | 226 | .family = AF_INET, |
227 | }; | 227 | }; |
228 | 228 | ||
229 | static int __net_init nf_nat_rule_net_init(struct net *net) | ||
230 | { | ||
231 | net->ipv4.nat_table = ipt_register_table(net, &nat_table, | ||
232 | &nat_initial_table.repl); | ||
233 | if (IS_ERR(net->ipv4.nat_table)) | ||
234 | return PTR_ERR(net->ipv4.nat_table); | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static void __net_exit nf_nat_rule_net_exit(struct net *net) | ||
239 | { | ||
240 | ipt_unregister_table(net->ipv4.nat_table); | ||
241 | } | ||
242 | |||
243 | static struct pernet_operations nf_nat_rule_net_ops = { | ||
244 | .init = nf_nat_rule_net_init, | ||
245 | .exit = nf_nat_rule_net_exit, | ||
246 | }; | ||
247 | |||
229 | int __init nf_nat_rule_init(void) | 248 | int __init nf_nat_rule_init(void) |
230 | { | 249 | { |
231 | int ret; | 250 | int ret; |
232 | 251 | ||
233 | nat_table = ipt_register_table(&init_net, &__nat_table, | 252 | ret = register_pernet_subsys(&nf_nat_rule_net_ops); |
234 | &nat_initial_table.repl); | 253 | if (ret != 0) |
235 | if (IS_ERR(nat_table)) | 254 | goto out; |
236 | return PTR_ERR(nat_table); | ||
237 | ret = xt_register_target(&ipt_snat_reg); | 255 | ret = xt_register_target(&ipt_snat_reg); |
238 | if (ret != 0) | 256 | if (ret != 0) |
239 | goto unregister_table; | 257 | goto unregister_table; |
@@ -247,8 +265,8 @@ int __init nf_nat_rule_init(void) | |||
247 | unregister_snat: | 265 | unregister_snat: |
248 | xt_unregister_target(&ipt_snat_reg); | 266 | xt_unregister_target(&ipt_snat_reg); |
249 | unregister_table: | 267 | unregister_table: |
250 | ipt_unregister_table(nat_table); | 268 | unregister_pernet_subsys(&nf_nat_rule_net_ops); |
251 | 269 | out: | |
252 | return ret; | 270 | return ret; |
253 | } | 271 | } |
254 | 272 | ||
@@ -256,5 +274,5 @@ void nf_nat_rule_cleanup(void) | |||
256 | { | 274 | { |
257 | xt_unregister_target(&ipt_dnat_reg); | 275 | xt_unregister_target(&ipt_dnat_reg); |
258 | xt_unregister_target(&ipt_snat_reg); | 276 | xt_unregister_target(&ipt_snat_reg); |
259 | ipt_unregister_table(nat_table); | 277 | unregister_pernet_subsys(&nf_nat_rule_net_ops); |
260 | } | 278 | } |