aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2008-10-08 05:35:06 -0400
committerPatrick McHardy <kaber@trash.net>2008-10-08 05:35:06 -0400
commit5e6b29972b7e9c9c39882227e36fe0cd3463fe96 (patch)
treec3eff078c0e18757691ac25682c1cd4a30f3b66d
parentdc5129f8df7cc3f2f04b322728d71c42795d34cc (diff)
netfilter: netns nf_conntrack: per-netns /proc/net/ip_conntrack, /proc/net/stat/ip_conntrack, /proc/net/ip_conntrack_expect
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com> Signed-off-by: Patrick McHardy <kaber@trash.net>
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index f8636a57e8cc..b2940836d107 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -21,18 +21,20 @@
21#include <net/netfilter/nf_conntrack_acct.h> 21#include <net/netfilter/nf_conntrack_acct.h>
22 22
23struct ct_iter_state { 23struct ct_iter_state {
24 struct seq_net_private p;
24 unsigned int bucket; 25 unsigned int bucket;
25}; 26};
26 27
27static struct hlist_node *ct_get_first(struct seq_file *seq) 28static struct hlist_node *ct_get_first(struct seq_file *seq)
28{ 29{
30 struct net *net = seq_file_net(seq);
29 struct ct_iter_state *st = seq->private; 31 struct ct_iter_state *st = seq->private;
30 struct hlist_node *n; 32 struct hlist_node *n;
31 33
32 for (st->bucket = 0; 34 for (st->bucket = 0;
33 st->bucket < nf_conntrack_htable_size; 35 st->bucket < nf_conntrack_htable_size;
34 st->bucket++) { 36 st->bucket++) {
35 n = rcu_dereference(init_net.ct.hash[st->bucket].first); 37 n = rcu_dereference(net->ct.hash[st->bucket].first);
36 if (n) 38 if (n)
37 return n; 39 return n;
38 } 40 }
@@ -42,13 +44,14 @@ static struct hlist_node *ct_get_first(struct seq_file *seq)
42static struct hlist_node *ct_get_next(struct seq_file *seq, 44static struct hlist_node *ct_get_next(struct seq_file *seq,
43 struct hlist_node *head) 45 struct hlist_node *head)
44{ 46{
47 struct net *net = seq_file_net(seq);
45 struct ct_iter_state *st = seq->private; 48 struct ct_iter_state *st = seq->private;
46 49
47 head = rcu_dereference(head->next); 50 head = rcu_dereference(head->next);
48 while (head == NULL) { 51 while (head == NULL) {
49 if (++st->bucket >= nf_conntrack_htable_size) 52 if (++st->bucket >= nf_conntrack_htable_size)
50 return NULL; 53 return NULL;
51 head = rcu_dereference(init_net.ct.hash[st->bucket].first); 54 head = rcu_dereference(net->ct.hash[st->bucket].first);
52 } 55 }
53 return head; 56 return head;
54} 57}
@@ -158,8 +161,8 @@ static const struct seq_operations ct_seq_ops = {
158 161
159static int ct_open(struct inode *inode, struct file *file) 162static int ct_open(struct inode *inode, struct file *file)
160{ 163{
161 return seq_open_private(file, &ct_seq_ops, 164 return seq_open_net(inode, file, &ct_seq_ops,
162 sizeof(struct ct_iter_state)); 165 sizeof(struct ct_iter_state));
163} 166}
164 167
165static const struct file_operations ct_file_ops = { 168static const struct file_operations ct_file_ops = {
@@ -167,17 +170,18 @@ static const struct file_operations ct_file_ops = {
167 .open = ct_open, 170 .open = ct_open,
168 .read = seq_read, 171 .read = seq_read,
169 .llseek = seq_lseek, 172 .llseek = seq_lseek,
170 .release = seq_release_private, 173 .release = seq_release_net,
171}; 174};
172 175
173/* expects */ 176/* expects */
174struct ct_expect_iter_state { 177struct ct_expect_iter_state {
178 struct seq_net_private p;
175 unsigned int bucket; 179 unsigned int bucket;
176}; 180};
177 181
178static struct hlist_node *ct_expect_get_first(struct seq_file *seq) 182static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
179{ 183{
180 struct net *net = &init_net; 184 struct net *net = seq_file_net(seq);
181 struct ct_expect_iter_state *st = seq->private; 185 struct ct_expect_iter_state *st = seq->private;
182 struct hlist_node *n; 186 struct hlist_node *n;
183 187
@@ -192,7 +196,7 @@ static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
192static struct hlist_node *ct_expect_get_next(struct seq_file *seq, 196static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
193 struct hlist_node *head) 197 struct hlist_node *head)
194{ 198{
195 struct net *net = &init_net; 199 struct net *net = seq_file_net(seq);
196 struct ct_expect_iter_state *st = seq->private; 200 struct ct_expect_iter_state *st = seq->private;
197 201
198 head = rcu_dereference(head->next); 202 head = rcu_dereference(head->next);
@@ -267,8 +271,8 @@ static const struct seq_operations exp_seq_ops = {
267 271
268static int exp_open(struct inode *inode, struct file *file) 272static int exp_open(struct inode *inode, struct file *file)
269{ 273{
270 return seq_open_private(file, &exp_seq_ops, 274 return seq_open_net(inode, file, &exp_seq_ops,
271 sizeof(struct ct_expect_iter_state)); 275 sizeof(struct ct_expect_iter_state));
272} 276}
273 277
274static const struct file_operations ip_exp_file_ops = { 278static const struct file_operations ip_exp_file_ops = {
@@ -276,7 +280,7 @@ static const struct file_operations ip_exp_file_ops = {
276 .open = exp_open, 280 .open = exp_open,
277 .read = seq_read, 281 .read = seq_read,
278 .llseek = seq_lseek, 282 .llseek = seq_lseek,
279 .release = seq_release_private, 283 .release = seq_release_net,
280}; 284};
281 285
282static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) 286static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
@@ -367,36 +371,51 @@ static const struct file_operations ct_cpu_seq_fops = {
367 .release = seq_release, 371 .release = seq_release,
368}; 372};
369 373
370int __init nf_conntrack_ipv4_compat_init(void) 374static int __net_init ip_conntrack_net_init(struct net *net)
371{ 375{
372 struct proc_dir_entry *proc, *proc_exp, *proc_stat; 376 struct proc_dir_entry *proc, *proc_exp, *proc_stat;
373 377
374 proc = proc_net_fops_create(&init_net, "ip_conntrack", 0440, &ct_file_ops); 378 proc = proc_net_fops_create(net, "ip_conntrack", 0440, &ct_file_ops);
375 if (!proc) 379 if (!proc)
376 goto err1; 380 goto err1;
377 381
378 proc_exp = proc_net_fops_create(&init_net, "ip_conntrack_expect", 0440, 382 proc_exp = proc_net_fops_create(net, "ip_conntrack_expect", 0440,
379 &ip_exp_file_ops); 383 &ip_exp_file_ops);
380 if (!proc_exp) 384 if (!proc_exp)
381 goto err2; 385 goto err2;
382 386
383 proc_stat = proc_create("ip_conntrack", S_IRUGO, 387 proc_stat = proc_create("ip_conntrack", S_IRUGO,
384 init_net.proc_net_stat, &ct_cpu_seq_fops); 388 net->proc_net_stat, &ct_cpu_seq_fops);
385 if (!proc_stat) 389 if (!proc_stat)
386 goto err3; 390 goto err3;
387 return 0; 391 return 0;
388 392
389err3: 393err3:
390 proc_net_remove(&init_net, "ip_conntrack_expect"); 394 proc_net_remove(net, "ip_conntrack_expect");
391err2: 395err2:
392 proc_net_remove(&init_net, "ip_conntrack"); 396 proc_net_remove(net, "ip_conntrack");
393err1: 397err1:
394 return -ENOMEM; 398 return -ENOMEM;
395} 399}
396 400
401static void __net_exit ip_conntrack_net_exit(struct net *net)
402{
403 remove_proc_entry("ip_conntrack", net->proc_net_stat);
404 proc_net_remove(net, "ip_conntrack_expect");
405 proc_net_remove(net, "ip_conntrack");
406}
407
408static struct pernet_operations ip_conntrack_net_ops = {
409 .init = ip_conntrack_net_init,
410 .exit = ip_conntrack_net_exit,
411};
412
413int __init nf_conntrack_ipv4_compat_init(void)
414{
415 return register_pernet_subsys(&ip_conntrack_net_ops);
416}
417
397void __exit nf_conntrack_ipv4_compat_fini(void) 418void __exit nf_conntrack_ipv4_compat_fini(void)
398{ 419{
399 remove_proc_entry("ip_conntrack", init_net.proc_net_stat); 420 unregister_pernet_subsys(&ip_conntrack_net_ops);
400 proc_net_remove(&init_net, "ip_conntrack_expect");
401 proc_net_remove(&init_net, "ip_conntrack");
402} 421}