diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2008-07-18 07:06:04 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-07-18 07:06:04 -0400 |
commit | 229bf0cbaa054f1502ab4ee219f05985d2c838d1 (patch) | |
tree | 7f542b1f5f3c249a66b7decd2ae22ae5067e97df /net/ipv4 | |
parent | 7b7a9dfdf6ccda647f54ea5fa3bd0ac17a189eeb (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')
-rw-r--r-- | net/ipv4/proc.c | 70 |
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) | |||
303 | static void icmp_put(struct seq_file *seq) | 304 | static 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) | |||
332 | static int snmp_seq_show(struct seq_file *seq, void *v) | 334 | static 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 | ||
395 | static int snmp_seq_open(struct inode *inode, struct file *file) | 398 | static 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 | |||
414 | err_open: | ||
415 | put_net(net); | ||
416 | err_net: | ||
417 | return err; | ||
418 | } | ||
419 | |||
420 | static 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 | ||
400 | static const struct file_operations snmp_seq_fops = { | 428 | static 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 | ||
519 | out_snmp: | ||
520 | proc_net_remove(net, "netstat"); | ||
489 | out_netstat: | 521 | out_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 | ||
494 | static __net_exit void ip_proc_exit_net(struct net *net) | 526 | static __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; | ||
514 | out: | 545 | out: |
515 | return rc; | 546 | return rc; |
516 | out_snmp: | 547 | |
517 | unregister_pernet_subsys(&ip_proc_ops); | ||
518 | out_pernet: | 548 | out_pernet: |
519 | rc = -ENOMEM; | 549 | rc = -ENOMEM; |
520 | goto out; | 550 | goto out; |