aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/proc.c
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-07-18 07:05:17 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-18 07:05:17 -0400
commit7b7a9dfdf6ccda647f54ea5fa3bd0ac17a189eeb (patch)
tree92ab52ffab8bfdc1f3697ff8d02c12a06a43d76c /net/ipv4/proc.c
parentd89cbbb1e69a3bfea38038fb058bd51013902ef3 (diff)
proc: create /proc/net/netstat file in each net
Now all the shown in it statistics is netnsizated, time to show it in appropriate net. The appropriate net init/exit ops already exist - they make the sockstat file per net - so just extend them. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/proc.c')
-rw-r--r--net/ipv4/proc.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index e11144b0134a..df8c4affde0f 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -413,6 +413,7 @@ static const struct file_operations snmp_seq_fops = {
413static int netstat_seq_show(struct seq_file *seq, void *v) 413static int netstat_seq_show(struct seq_file *seq, void *v)
414{ 414{
415 int i; 415 int i;
416 struct net *net = seq->private;
416 417
417 seq_puts(seq, "TcpExt:"); 418 seq_puts(seq, "TcpExt:");
418 for (i = 0; snmp4_net_list[i].name != NULL; i++) 419 for (i = 0; snmp4_net_list[i].name != NULL; i++)
@@ -421,7 +422,7 @@ static int netstat_seq_show(struct seq_file *seq, void *v)
421 seq_puts(seq, "\nTcpExt:"); 422 seq_puts(seq, "\nTcpExt:");
422 for (i = 0; snmp4_net_list[i].name != NULL; i++) 423 for (i = 0; snmp4_net_list[i].name != NULL; i++)
423 seq_printf(seq, " %lu", 424 seq_printf(seq, " %lu",
424 snmp_fold_field((void **)init_net.mib.net_statistics, 425 snmp_fold_field((void **)net->mib.net_statistics,
425 snmp4_net_list[i].entry)); 426 snmp4_net_list[i].entry));
426 427
427 seq_puts(seq, "\nIpExt:"); 428 seq_puts(seq, "\nIpExt:");
@@ -431,7 +432,7 @@ static int netstat_seq_show(struct seq_file *seq, void *v)
431 seq_puts(seq, "\nIpExt:"); 432 seq_puts(seq, "\nIpExt:");
432 for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++) 433 for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++)
433 seq_printf(seq, " %lu", 434 seq_printf(seq, " %lu",
434 snmp_fold_field((void **)init_net.mib.ip_statistics, 435 snmp_fold_field((void **)net->mib.ip_statistics,
435 snmp4_ipextstats_list[i].entry)); 436 snmp4_ipextstats_list[i].entry));
436 437
437 seq_putc(seq, '\n'); 438 seq_putc(seq, '\n');
@@ -440,7 +441,32 @@ static int netstat_seq_show(struct seq_file *seq, void *v)
440 441
441static int netstat_seq_open(struct inode *inode, struct file *file) 442static int netstat_seq_open(struct inode *inode, struct file *file)
442{ 443{
443 return single_open(file, netstat_seq_show, NULL); 444 int err;
445 struct net *net;
446
447 err = -ENXIO;
448 net = get_proc_net(inode);
449 if (net == NULL)
450 goto err_net;
451
452 err = single_open(file, netstat_seq_show, net);
453 if (err < 0)
454 goto err_open;
455
456 return 0;
457
458err_open:
459 put_net(net);
460err_net:
461 return err;
462}
463
464static int netstat_seq_release(struct inode *inode, struct file *file)
465{
466 struct net *net = ((struct seq_file *)file->private_data)->private;
467
468 put_net(net);
469 return single_release(inode, file);
444} 470}
445 471
446static const struct file_operations netstat_seq_fops = { 472static const struct file_operations netstat_seq_fops = {
@@ -448,18 +474,26 @@ static const struct file_operations netstat_seq_fops = {
448 .open = netstat_seq_open, 474 .open = netstat_seq_open,
449 .read = seq_read, 475 .read = seq_read,
450 .llseek = seq_lseek, 476 .llseek = seq_lseek,
451 .release = single_release, 477 .release = netstat_seq_release,
452}; 478};
453 479
454static __net_init int ip_proc_init_net(struct net *net) 480static __net_init int ip_proc_init_net(struct net *net)
455{ 481{
456 if (!proc_net_fops_create(net, "sockstat", S_IRUGO, &sockstat_seq_fops)) 482 if (!proc_net_fops_create(net, "sockstat", S_IRUGO, &sockstat_seq_fops))
457 return -ENOMEM; 483 return -ENOMEM;
484 if (!proc_net_fops_create(net, "netstat", S_IRUGO, &netstat_seq_fops))
485 goto out_netstat;
486
458 return 0; 487 return 0;
488
489out_netstat:
490 proc_net_remove(net, "sockstat");
491 return -ENOMEM;
459} 492}
460 493
461static __net_exit void ip_proc_exit_net(struct net *net) 494static __net_exit void ip_proc_exit_net(struct net *net)
462{ 495{
496 proc_net_remove(net, "netstat");
463 proc_net_remove(net, "sockstat"); 497 proc_net_remove(net, "sockstat");
464} 498}
465 499
@@ -475,16 +509,11 @@ int __init ip_misc_proc_init(void)
475 if (register_pernet_subsys(&ip_proc_ops)) 509 if (register_pernet_subsys(&ip_proc_ops))
476 goto out_pernet; 510 goto out_pernet;
477 511
478 if (!proc_net_fops_create(&init_net, "netstat", S_IRUGO, &netstat_seq_fops))
479 goto out_netstat;
480
481 if (!proc_net_fops_create(&init_net, "snmp", S_IRUGO, &snmp_seq_fops)) 512 if (!proc_net_fops_create(&init_net, "snmp", S_IRUGO, &snmp_seq_fops))
482 goto out_snmp; 513 goto out_snmp;
483out: 514out:
484 return rc; 515 return rc;
485out_snmp: 516out_snmp:
486 proc_net_remove(&init_net, "netstat");
487out_netstat:
488 unregister_pernet_subsys(&ip_proc_ops); 517 unregister_pernet_subsys(&ip_proc_ops);
489out_pernet: 518out_pernet:
490 rc = -ENOMEM; 519 rc = -ENOMEM;