aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/proc.c
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2008-07-18 07:06:04 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-18 07:06:04 -0400
commit229bf0cbaa054f1502ab4ee219f05985d2c838d1 (patch)
tree7f542b1f5f3c249a66b7decd2ae22ae5067e97df /net/ipv4/proc.c
parent7b7a9dfdf6ccda647f54ea5fa3bd0ac17a189eeb (diff)
proc: create /proc/net/snmp file in each net
All the statistics shown in this file have been made per-net already. 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.c70
1 files changed, 50 insertions, 20 deletions
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index df8c4affde0f..367b81f6f57a 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -266,11 +266,12 @@ static void icmpmsg_put(struct seq_file *seq)
266 266
267 int j, i, count; 267 int j, i, count;
268 static int out[PERLINE]; 268 static int out[PERLINE];
269 struct net *net = seq->private;
269 270
270 count = 0; 271 count = 0;
271 for (i = 0; i < ICMPMSG_MIB_MAX; i++) { 272 for (i = 0; i < ICMPMSG_MIB_MAX; i++) {
272 273
273 if (snmp_fold_field((void **) init_net.mib.icmpmsg_statistics, i)) 274 if (snmp_fold_field((void **) net->mib.icmpmsg_statistics, i))
274 out[count++] = i; 275 out[count++] = i;
275 if (count < PERLINE) 276 if (count < PERLINE)
276 continue; 277 continue;
@@ -282,7 +283,7 @@ static void icmpmsg_put(struct seq_file *seq)
282 seq_printf(seq, "\nIcmpMsg: "); 283 seq_printf(seq, "\nIcmpMsg: ");
283 for (j = 0; j < PERLINE; ++j) 284 for (j = 0; j < PERLINE; ++j)
284 seq_printf(seq, " %lu", 285 seq_printf(seq, " %lu",
285 snmp_fold_field((void **) init_net.mib.icmpmsg_statistics, 286 snmp_fold_field((void **) net->mib.icmpmsg_statistics,
286 out[j])); 287 out[j]));
287 seq_putc(seq, '\n'); 288 seq_putc(seq, '\n');
288 } 289 }
@@ -294,7 +295,7 @@ static void icmpmsg_put(struct seq_file *seq)
294 seq_printf(seq, "\nIcmpMsg:"); 295 seq_printf(seq, "\nIcmpMsg:");
295 for (j = 0; j < count; ++j) 296 for (j = 0; j < count; ++j)
296 seq_printf(seq, " %lu", snmp_fold_field((void **) 297 seq_printf(seq, " %lu", snmp_fold_field((void **)
297 init_net.mib.icmpmsg_statistics, out[j])); 298 net->mib.icmpmsg_statistics, out[j]));
298 } 299 }
299 300
300#undef PERLINE 301#undef PERLINE
@@ -303,6 +304,7 @@ static void icmpmsg_put(struct seq_file *seq)
303static void icmp_put(struct seq_file *seq) 304static void icmp_put(struct seq_file *seq)
304{ 305{
305 int i; 306 int i;
307 struct net *net = seq->private;
306 308
307 seq_puts(seq, "\nIcmp: InMsgs InErrors"); 309 seq_puts(seq, "\nIcmp: InMsgs InErrors");
308 for (i=0; icmpmibmap[i].name != NULL; i++) 310 for (i=0; icmpmibmap[i].name != NULL; i++)
@@ -311,18 +313,18 @@ static void icmp_put(struct seq_file *seq)
311 for (i=0; icmpmibmap[i].name != NULL; i++) 313 for (i=0; icmpmibmap[i].name != NULL; i++)
312 seq_printf(seq, " Out%s", icmpmibmap[i].name); 314 seq_printf(seq, " Out%s", icmpmibmap[i].name);
313 seq_printf(seq, "\nIcmp: %lu %lu", 315 seq_printf(seq, "\nIcmp: %lu %lu",
314 snmp_fold_field((void **) init_net.mib.icmp_statistics, ICMP_MIB_INMSGS), 316 snmp_fold_field((void **) net->mib.icmp_statistics, ICMP_MIB_INMSGS),
315 snmp_fold_field((void **) init_net.mib.icmp_statistics, ICMP_MIB_INERRORS)); 317 snmp_fold_field((void **) net->mib.icmp_statistics, ICMP_MIB_INERRORS));
316 for (i=0; icmpmibmap[i].name != NULL; i++) 318 for (i=0; icmpmibmap[i].name != NULL; i++)
317 seq_printf(seq, " %lu", 319 seq_printf(seq, " %lu",
318 snmp_fold_field((void **) init_net.mib.icmpmsg_statistics, 320 snmp_fold_field((void **) net->mib.icmpmsg_statistics,
319 icmpmibmap[i].index)); 321 icmpmibmap[i].index));
320 seq_printf(seq, " %lu %lu", 322 seq_printf(seq, " %lu %lu",
321 snmp_fold_field((void **) init_net.mib.icmp_statistics, ICMP_MIB_OUTMSGS), 323 snmp_fold_field((void **) net->mib.icmp_statistics, ICMP_MIB_OUTMSGS),
322 snmp_fold_field((void **) init_net.mib.icmp_statistics, ICMP_MIB_OUTERRORS)); 324 snmp_fold_field((void **) net->mib.icmp_statistics, ICMP_MIB_OUTERRORS));
323 for (i=0; icmpmibmap[i].name != NULL; i++) 325 for (i=0; icmpmibmap[i].name != NULL; i++)
324 seq_printf(seq, " %lu", 326 seq_printf(seq, " %lu",
325 snmp_fold_field((void **) init_net.mib.icmpmsg_statistics, 327 snmp_fold_field((void **) net->mib.icmpmsg_statistics,
326 icmpmibmap[i].index | 0x100)); 328 icmpmibmap[i].index | 0x100));
327} 329}
328 330
@@ -332,6 +334,7 @@ static void icmp_put(struct seq_file *seq)
332static int snmp_seq_show(struct seq_file *seq, void *v) 334static int snmp_seq_show(struct seq_file *seq, void *v)
333{ 335{
334 int i; 336 int i;
337 struct net *net = seq->private;
335 338
336 seq_puts(seq, "Ip: Forwarding DefaultTTL"); 339 seq_puts(seq, "Ip: Forwarding DefaultTTL");
337 340
@@ -344,7 +347,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
344 347
345 for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) 348 for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
346 seq_printf(seq, " %lu", 349 seq_printf(seq, " %lu",
347 snmp_fold_field((void **)init_net.mib.ip_statistics, 350 snmp_fold_field((void **)net->mib.ip_statistics,
348 snmp4_ipstats_list[i].entry)); 351 snmp4_ipstats_list[i].entry));
349 352
350 icmp_put(seq); /* RFC 2011 compatibility */ 353 icmp_put(seq); /* RFC 2011 compatibility */
@@ -359,11 +362,11 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
359 /* MaxConn field is signed, RFC 2012 */ 362 /* MaxConn field is signed, RFC 2012 */
360 if (snmp4_tcp_list[i].entry == TCP_MIB_MAXCONN) 363 if (snmp4_tcp_list[i].entry == TCP_MIB_MAXCONN)
361 seq_printf(seq, " %ld", 364 seq_printf(seq, " %ld",
362 snmp_fold_field((void **)init_net.mib.tcp_statistics, 365 snmp_fold_field((void **)net->mib.tcp_statistics,
363 snmp4_tcp_list[i].entry)); 366 snmp4_tcp_list[i].entry));
364 else 367 else
365 seq_printf(seq, " %lu", 368 seq_printf(seq, " %lu",
366 snmp_fold_field((void **)init_net.mib.tcp_statistics, 369 snmp_fold_field((void **)net->mib.tcp_statistics,
367 snmp4_tcp_list[i].entry)); 370 snmp4_tcp_list[i].entry));
368 } 371 }
369 372
@@ -374,7 +377,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
374 seq_puts(seq, "\nUdp:"); 377 seq_puts(seq, "\nUdp:");
375 for (i = 0; snmp4_udp_list[i].name != NULL; i++) 378 for (i = 0; snmp4_udp_list[i].name != NULL; i++)
376 seq_printf(seq, " %lu", 379 seq_printf(seq, " %lu",
377 snmp_fold_field((void **)init_net.mib.udp_statistics, 380 snmp_fold_field((void **)net->mib.udp_statistics,
378 snmp4_udp_list[i].entry)); 381 snmp4_udp_list[i].entry));
379 382
380 /* the UDP and UDP-Lite MIBs are the same */ 383 /* the UDP and UDP-Lite MIBs are the same */
@@ -385,7 +388,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
385 seq_puts(seq, "\nUdpLite:"); 388 seq_puts(seq, "\nUdpLite:");
386 for (i = 0; snmp4_udp_list[i].name != NULL; i++) 389 for (i = 0; snmp4_udp_list[i].name != NULL; i++)
387 seq_printf(seq, " %lu", 390 seq_printf(seq, " %lu",
388 snmp_fold_field((void **)init_net.mib.udplite_statistics, 391 snmp_fold_field((void **)net->mib.udplite_statistics,
389 snmp4_udp_list[i].entry)); 392 snmp4_udp_list[i].entry));
390 393
391 seq_putc(seq, '\n'); 394 seq_putc(seq, '\n');
@@ -394,7 +397,32 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
394 397
395static int snmp_seq_open(struct inode *inode, struct file *file) 398static int snmp_seq_open(struct inode *inode, struct file *file)
396{ 399{
397 return single_open(file, snmp_seq_show, NULL); 400 int err;
401 struct net *net;
402
403 err = -ENXIO;
404 net = get_proc_net(inode);
405 if (net == NULL)
406 goto err_net;
407
408 err = single_open(file, snmp_seq_show, net);
409 if (err < 0)
410 goto err_open;
411
412 return 0;
413
414err_open:
415 put_net(net);
416err_net:
417 return err;
418}
419
420static int snmp_seq_release(struct inode *inode, struct file *file)
421{
422 struct net *net = ((struct seq_file *)file->private_data)->private;
423
424 put_net(net);
425 return single_release(inode, file);
398} 426}
399 427
400static const struct file_operations snmp_seq_fops = { 428static const struct file_operations snmp_seq_fops = {
@@ -402,7 +430,7 @@ static const struct file_operations snmp_seq_fops = {
402 .open = snmp_seq_open, 430 .open = snmp_seq_open,
403 .read = seq_read, 431 .read = seq_read,
404 .llseek = seq_lseek, 432 .llseek = seq_lseek,
405 .release = single_release, 433 .release = snmp_seq_release,
406}; 434};
407 435
408 436
@@ -483,9 +511,13 @@ static __net_init int ip_proc_init_net(struct net *net)
483 return -ENOMEM; 511 return -ENOMEM;
484 if (!proc_net_fops_create(net, "netstat", S_IRUGO, &netstat_seq_fops)) 512 if (!proc_net_fops_create(net, "netstat", S_IRUGO, &netstat_seq_fops))
485 goto out_netstat; 513 goto out_netstat;
514 if (!proc_net_fops_create(net, "snmp", S_IRUGO, &snmp_seq_fops))
515 goto out_snmp;
486 516
487 return 0; 517 return 0;
488 518
519out_snmp:
520 proc_net_remove(net, "netstat");
489out_netstat: 521out_netstat:
490 proc_net_remove(net, "sockstat"); 522 proc_net_remove(net, "sockstat");
491 return -ENOMEM; 523 return -ENOMEM;
@@ -493,6 +525,7 @@ out_netstat:
493 525
494static __net_exit void ip_proc_exit_net(struct net *net) 526static __net_exit void ip_proc_exit_net(struct net *net)
495{ 527{
528 proc_net_remove(net, "snmp");
496 proc_net_remove(net, "netstat"); 529 proc_net_remove(net, "netstat");
497 proc_net_remove(net, "sockstat"); 530 proc_net_remove(net, "sockstat");
498} 531}
@@ -509,12 +542,9 @@ int __init ip_misc_proc_init(void)
509 if (register_pernet_subsys(&ip_proc_ops)) 542 if (register_pernet_subsys(&ip_proc_ops))
510 goto out_pernet; 543 goto out_pernet;
511 544
512 if (!proc_net_fops_create(&init_net, "snmp", S_IRUGO, &snmp_seq_fops))
513 goto out_snmp;
514out: 545out:
515 return rc; 546 return rc;
516out_snmp: 547
517 unregister_pernet_subsys(&ip_proc_ops);
518out_pernet: 548out_pernet:
519 rc = -ENOMEM; 549 rc = -ENOMEM;
520 goto out; 550 goto out;