diff options
Diffstat (limited to 'net/ipv4/proc.c')
-rw-r--r-- | net/ipv4/proc.c | 113 |
1 files changed, 43 insertions, 70 deletions
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 552169b41b16..834356ea99df 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -7,8 +7,6 @@ | |||
7 | * PROC file system. It is mainly used for debugging and | 7 | * PROC file system. It is mainly used for debugging and |
8 | * statistics. | 8 | * statistics. |
9 | * | 9 | * |
10 | * Version: $Id: proc.c,v 1.45 2001/05/16 16:45:35 davem Exp $ | ||
11 | * | ||
12 | * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 10 | * Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
13 | * Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de> | 11 | * Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de> |
14 | * Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de> | 12 | * Fred Baumgarten, <dc6iq@insu1.etec.uni-karlsruhe.de> |
@@ -73,32 +71,7 @@ static int sockstat_seq_show(struct seq_file *seq, void *v) | |||
73 | 71 | ||
74 | static int sockstat_seq_open(struct inode *inode, struct file *file) | 72 | static int sockstat_seq_open(struct inode *inode, struct file *file) |
75 | { | 73 | { |
76 | int err; | 74 | return single_open_net(inode, file, sockstat_seq_show); |
77 | struct net *net; | ||
78 | |||
79 | err = -ENXIO; | ||
80 | net = get_proc_net(inode); | ||
81 | if (net == NULL) | ||
82 | goto err_net; | ||
83 | |||
84 | err = single_open(file, sockstat_seq_show, net); | ||
85 | if (err < 0) | ||
86 | goto err_open; | ||
87 | |||
88 | return 0; | ||
89 | |||
90 | err_open: | ||
91 | put_net(net); | ||
92 | err_net: | ||
93 | return err; | ||
94 | } | ||
95 | |||
96 | static int sockstat_seq_release(struct inode *inode, struct file *file) | ||
97 | { | ||
98 | struct net *net = ((struct seq_file *)file->private_data)->private; | ||
99 | |||
100 | put_net(net); | ||
101 | return single_release(inode, file); | ||
102 | } | 75 | } |
103 | 76 | ||
104 | static const struct file_operations sockstat_seq_fops = { | 77 | static const struct file_operations sockstat_seq_fops = { |
@@ -106,7 +79,7 @@ static const struct file_operations sockstat_seq_fops = { | |||
106 | .open = sockstat_seq_open, | 79 | .open = sockstat_seq_open, |
107 | .read = seq_read, | 80 | .read = seq_read, |
108 | .llseek = seq_lseek, | 81 | .llseek = seq_lseek, |
109 | .release = sockstat_seq_release, | 82 | .release = single_release_net, |
110 | }; | 83 | }; |
111 | 84 | ||
112 | /* snmp items */ | 85 | /* snmp items */ |
@@ -268,11 +241,12 @@ static void icmpmsg_put(struct seq_file *seq) | |||
268 | 241 | ||
269 | int j, i, count; | 242 | int j, i, count; |
270 | static int out[PERLINE]; | 243 | static int out[PERLINE]; |
244 | struct net *net = seq->private; | ||
271 | 245 | ||
272 | count = 0; | 246 | count = 0; |
273 | for (i = 0; i < ICMPMSG_MIB_MAX; i++) { | 247 | for (i = 0; i < ICMPMSG_MIB_MAX; i++) { |
274 | 248 | ||
275 | if (snmp_fold_field((void **) icmpmsg_statistics, i)) | 249 | if (snmp_fold_field((void **) net->mib.icmpmsg_statistics, i)) |
276 | out[count++] = i; | 250 | out[count++] = i; |
277 | if (count < PERLINE) | 251 | if (count < PERLINE) |
278 | continue; | 252 | continue; |
@@ -284,7 +258,7 @@ static void icmpmsg_put(struct seq_file *seq) | |||
284 | seq_printf(seq, "\nIcmpMsg: "); | 258 | seq_printf(seq, "\nIcmpMsg: "); |
285 | for (j = 0; j < PERLINE; ++j) | 259 | for (j = 0; j < PERLINE; ++j) |
286 | seq_printf(seq, " %lu", | 260 | seq_printf(seq, " %lu", |
287 | snmp_fold_field((void **) icmpmsg_statistics, | 261 | snmp_fold_field((void **) net->mib.icmpmsg_statistics, |
288 | out[j])); | 262 | out[j])); |
289 | seq_putc(seq, '\n'); | 263 | seq_putc(seq, '\n'); |
290 | } | 264 | } |
@@ -296,7 +270,7 @@ static void icmpmsg_put(struct seq_file *seq) | |||
296 | seq_printf(seq, "\nIcmpMsg:"); | 270 | seq_printf(seq, "\nIcmpMsg:"); |
297 | for (j = 0; j < count; ++j) | 271 | for (j = 0; j < count; ++j) |
298 | seq_printf(seq, " %lu", snmp_fold_field((void **) | 272 | seq_printf(seq, " %lu", snmp_fold_field((void **) |
299 | icmpmsg_statistics, out[j])); | 273 | net->mib.icmpmsg_statistics, out[j])); |
300 | } | 274 | } |
301 | 275 | ||
302 | #undef PERLINE | 276 | #undef PERLINE |
@@ -305,6 +279,7 @@ static void icmpmsg_put(struct seq_file *seq) | |||
305 | static void icmp_put(struct seq_file *seq) | 279 | static void icmp_put(struct seq_file *seq) |
306 | { | 280 | { |
307 | int i; | 281 | int i; |
282 | struct net *net = seq->private; | ||
308 | 283 | ||
309 | seq_puts(seq, "\nIcmp: InMsgs InErrors"); | 284 | seq_puts(seq, "\nIcmp: InMsgs InErrors"); |
310 | for (i=0; icmpmibmap[i].name != NULL; i++) | 285 | for (i=0; icmpmibmap[i].name != NULL; i++) |
@@ -313,18 +288,18 @@ static void icmp_put(struct seq_file *seq) | |||
313 | for (i=0; icmpmibmap[i].name != NULL; i++) | 288 | for (i=0; icmpmibmap[i].name != NULL; i++) |
314 | seq_printf(seq, " Out%s", icmpmibmap[i].name); | 289 | seq_printf(seq, " Out%s", icmpmibmap[i].name); |
315 | seq_printf(seq, "\nIcmp: %lu %lu", | 290 | seq_printf(seq, "\nIcmp: %lu %lu", |
316 | snmp_fold_field((void **) icmp_statistics, ICMP_MIB_INMSGS), | 291 | snmp_fold_field((void **) net->mib.icmp_statistics, ICMP_MIB_INMSGS), |
317 | snmp_fold_field((void **) icmp_statistics, ICMP_MIB_INERRORS)); | 292 | snmp_fold_field((void **) net->mib.icmp_statistics, ICMP_MIB_INERRORS)); |
318 | for (i=0; icmpmibmap[i].name != NULL; i++) | 293 | for (i=0; icmpmibmap[i].name != NULL; i++) |
319 | seq_printf(seq, " %lu", | 294 | seq_printf(seq, " %lu", |
320 | snmp_fold_field((void **) icmpmsg_statistics, | 295 | snmp_fold_field((void **) net->mib.icmpmsg_statistics, |
321 | icmpmibmap[i].index)); | 296 | icmpmibmap[i].index)); |
322 | seq_printf(seq, " %lu %lu", | 297 | seq_printf(seq, " %lu %lu", |
323 | snmp_fold_field((void **) icmp_statistics, ICMP_MIB_OUTMSGS), | 298 | snmp_fold_field((void **) net->mib.icmp_statistics, ICMP_MIB_OUTMSGS), |
324 | snmp_fold_field((void **) icmp_statistics, ICMP_MIB_OUTERRORS)); | 299 | snmp_fold_field((void **) net->mib.icmp_statistics, ICMP_MIB_OUTERRORS)); |
325 | for (i=0; icmpmibmap[i].name != NULL; i++) | 300 | for (i=0; icmpmibmap[i].name != NULL; i++) |
326 | seq_printf(seq, " %lu", | 301 | seq_printf(seq, " %lu", |
327 | snmp_fold_field((void **) icmpmsg_statistics, | 302 | snmp_fold_field((void **) net->mib.icmpmsg_statistics, |
328 | icmpmibmap[i].index | 0x100)); | 303 | icmpmibmap[i].index | 0x100)); |
329 | } | 304 | } |
330 | 305 | ||
@@ -334,6 +309,7 @@ static void icmp_put(struct seq_file *seq) | |||
334 | static int snmp_seq_show(struct seq_file *seq, void *v) | 309 | static int snmp_seq_show(struct seq_file *seq, void *v) |
335 | { | 310 | { |
336 | int i; | 311 | int i; |
312 | struct net *net = seq->private; | ||
337 | 313 | ||
338 | seq_puts(seq, "Ip: Forwarding DefaultTTL"); | 314 | seq_puts(seq, "Ip: Forwarding DefaultTTL"); |
339 | 315 | ||
@@ -341,12 +317,12 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
341 | seq_printf(seq, " %s", snmp4_ipstats_list[i].name); | 317 | seq_printf(seq, " %s", snmp4_ipstats_list[i].name); |
342 | 318 | ||
343 | seq_printf(seq, "\nIp: %d %d", | 319 | seq_printf(seq, "\nIp: %d %d", |
344 | IPV4_DEVCONF_ALL(&init_net, FORWARDING) ? 1 : 2, | 320 | IPV4_DEVCONF_ALL(net, FORWARDING) ? 1 : 2, |
345 | sysctl_ip_default_ttl); | 321 | sysctl_ip_default_ttl); |
346 | 322 | ||
347 | for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) | 323 | for (i = 0; snmp4_ipstats_list[i].name != NULL; i++) |
348 | seq_printf(seq, " %lu", | 324 | seq_printf(seq, " %lu", |
349 | snmp_fold_field((void **)ip_statistics, | 325 | snmp_fold_field((void **)net->mib.ip_statistics, |
350 | snmp4_ipstats_list[i].entry)); | 326 | snmp4_ipstats_list[i].entry)); |
351 | 327 | ||
352 | icmp_put(seq); /* RFC 2011 compatibility */ | 328 | icmp_put(seq); /* RFC 2011 compatibility */ |
@@ -361,11 +337,11 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
361 | /* MaxConn field is signed, RFC 2012 */ | 337 | /* MaxConn field is signed, RFC 2012 */ |
362 | if (snmp4_tcp_list[i].entry == TCP_MIB_MAXCONN) | 338 | if (snmp4_tcp_list[i].entry == TCP_MIB_MAXCONN) |
363 | seq_printf(seq, " %ld", | 339 | seq_printf(seq, " %ld", |
364 | snmp_fold_field((void **)tcp_statistics, | 340 | snmp_fold_field((void **)net->mib.tcp_statistics, |
365 | snmp4_tcp_list[i].entry)); | 341 | snmp4_tcp_list[i].entry)); |
366 | else | 342 | else |
367 | seq_printf(seq, " %lu", | 343 | seq_printf(seq, " %lu", |
368 | snmp_fold_field((void **)tcp_statistics, | 344 | snmp_fold_field((void **)net->mib.tcp_statistics, |
369 | snmp4_tcp_list[i].entry)); | 345 | snmp4_tcp_list[i].entry)); |
370 | } | 346 | } |
371 | 347 | ||
@@ -376,7 +352,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
376 | seq_puts(seq, "\nUdp:"); | 352 | seq_puts(seq, "\nUdp:"); |
377 | for (i = 0; snmp4_udp_list[i].name != NULL; i++) | 353 | for (i = 0; snmp4_udp_list[i].name != NULL; i++) |
378 | seq_printf(seq, " %lu", | 354 | seq_printf(seq, " %lu", |
379 | snmp_fold_field((void **)udp_statistics, | 355 | snmp_fold_field((void **)net->mib.udp_statistics, |
380 | snmp4_udp_list[i].entry)); | 356 | snmp4_udp_list[i].entry)); |
381 | 357 | ||
382 | /* the UDP and UDP-Lite MIBs are the same */ | 358 | /* the UDP and UDP-Lite MIBs are the same */ |
@@ -387,7 +363,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
387 | seq_puts(seq, "\nUdpLite:"); | 363 | seq_puts(seq, "\nUdpLite:"); |
388 | for (i = 0; snmp4_udp_list[i].name != NULL; i++) | 364 | for (i = 0; snmp4_udp_list[i].name != NULL; i++) |
389 | seq_printf(seq, " %lu", | 365 | seq_printf(seq, " %lu", |
390 | snmp_fold_field((void **)udplite_statistics, | 366 | snmp_fold_field((void **)net->mib.udplite_statistics, |
391 | snmp4_udp_list[i].entry)); | 367 | snmp4_udp_list[i].entry)); |
392 | 368 | ||
393 | seq_putc(seq, '\n'); | 369 | seq_putc(seq, '\n'); |
@@ -396,7 +372,7 @@ static int snmp_seq_show(struct seq_file *seq, void *v) | |||
396 | 372 | ||
397 | static int snmp_seq_open(struct inode *inode, struct file *file) | 373 | static int snmp_seq_open(struct inode *inode, struct file *file) |
398 | { | 374 | { |
399 | return single_open(file, snmp_seq_show, NULL); | 375 | return single_open_net(inode, file, snmp_seq_show); |
400 | } | 376 | } |
401 | 377 | ||
402 | static const struct file_operations snmp_seq_fops = { | 378 | static const struct file_operations snmp_seq_fops = { |
@@ -404,7 +380,7 @@ static const struct file_operations snmp_seq_fops = { | |||
404 | .open = snmp_seq_open, | 380 | .open = snmp_seq_open, |
405 | .read = seq_read, | 381 | .read = seq_read, |
406 | .llseek = seq_lseek, | 382 | .llseek = seq_lseek, |
407 | .release = single_release, | 383 | .release = single_release_net, |
408 | }; | 384 | }; |
409 | 385 | ||
410 | 386 | ||
@@ -415,6 +391,7 @@ static const struct file_operations snmp_seq_fops = { | |||
415 | static int netstat_seq_show(struct seq_file *seq, void *v) | 391 | static int netstat_seq_show(struct seq_file *seq, void *v) |
416 | { | 392 | { |
417 | int i; | 393 | int i; |
394 | struct net *net = seq->private; | ||
418 | 395 | ||
419 | seq_puts(seq, "TcpExt:"); | 396 | seq_puts(seq, "TcpExt:"); |
420 | for (i = 0; snmp4_net_list[i].name != NULL; i++) | 397 | for (i = 0; snmp4_net_list[i].name != NULL; i++) |
@@ -423,7 +400,7 @@ static int netstat_seq_show(struct seq_file *seq, void *v) | |||
423 | seq_puts(seq, "\nTcpExt:"); | 400 | seq_puts(seq, "\nTcpExt:"); |
424 | for (i = 0; snmp4_net_list[i].name != NULL; i++) | 401 | for (i = 0; snmp4_net_list[i].name != NULL; i++) |
425 | seq_printf(seq, " %lu", | 402 | seq_printf(seq, " %lu", |
426 | snmp_fold_field((void **)net_statistics, | 403 | snmp_fold_field((void **)net->mib.net_statistics, |
427 | snmp4_net_list[i].entry)); | 404 | snmp4_net_list[i].entry)); |
428 | 405 | ||
429 | seq_puts(seq, "\nIpExt:"); | 406 | seq_puts(seq, "\nIpExt:"); |
@@ -433,7 +410,7 @@ static int netstat_seq_show(struct seq_file *seq, void *v) | |||
433 | seq_puts(seq, "\nIpExt:"); | 410 | seq_puts(seq, "\nIpExt:"); |
434 | for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++) | 411 | for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++) |
435 | seq_printf(seq, " %lu", | 412 | seq_printf(seq, " %lu", |
436 | snmp_fold_field((void **)ip_statistics, | 413 | snmp_fold_field((void **)net->mib.ip_statistics, |
437 | snmp4_ipextstats_list[i].entry)); | 414 | snmp4_ipextstats_list[i].entry)); |
438 | 415 | ||
439 | seq_putc(seq, '\n'); | 416 | seq_putc(seq, '\n'); |
@@ -442,7 +419,7 @@ static int netstat_seq_show(struct seq_file *seq, void *v) | |||
442 | 419 | ||
443 | static int netstat_seq_open(struct inode *inode, struct file *file) | 420 | static int netstat_seq_open(struct inode *inode, struct file *file) |
444 | { | 421 | { |
445 | return single_open(file, netstat_seq_show, NULL); | 422 | return single_open_net(inode, file, netstat_seq_show); |
446 | } | 423 | } |
447 | 424 | ||
448 | static const struct file_operations netstat_seq_fops = { | 425 | static const struct file_operations netstat_seq_fops = { |
@@ -450,18 +427,32 @@ static const struct file_operations netstat_seq_fops = { | |||
450 | .open = netstat_seq_open, | 427 | .open = netstat_seq_open, |
451 | .read = seq_read, | 428 | .read = seq_read, |
452 | .llseek = seq_lseek, | 429 | .llseek = seq_lseek, |
453 | .release = single_release, | 430 | .release = single_release_net, |
454 | }; | 431 | }; |
455 | 432 | ||
456 | static __net_init int ip_proc_init_net(struct net *net) | 433 | static __net_init int ip_proc_init_net(struct net *net) |
457 | { | 434 | { |
458 | if (!proc_net_fops_create(net, "sockstat", S_IRUGO, &sockstat_seq_fops)) | 435 | if (!proc_net_fops_create(net, "sockstat", S_IRUGO, &sockstat_seq_fops)) |
459 | return -ENOMEM; | 436 | goto out_sockstat; |
437 | if (!proc_net_fops_create(net, "netstat", S_IRUGO, &netstat_seq_fops)) | ||
438 | goto out_netstat; | ||
439 | if (!proc_net_fops_create(net, "snmp", S_IRUGO, &snmp_seq_fops)) | ||
440 | goto out_snmp; | ||
441 | |||
460 | return 0; | 442 | return 0; |
443 | |||
444 | out_snmp: | ||
445 | proc_net_remove(net, "netstat"); | ||
446 | out_netstat: | ||
447 | proc_net_remove(net, "sockstat"); | ||
448 | out_sockstat: | ||
449 | return -ENOMEM; | ||
461 | } | 450 | } |
462 | 451 | ||
463 | static __net_exit void ip_proc_exit_net(struct net *net) | 452 | static __net_exit void ip_proc_exit_net(struct net *net) |
464 | { | 453 | { |
454 | proc_net_remove(net, "snmp"); | ||
455 | proc_net_remove(net, "netstat"); | ||
465 | proc_net_remove(net, "sockstat"); | 456 | proc_net_remove(net, "sockstat"); |
466 | } | 457 | } |
467 | 458 | ||
@@ -472,24 +463,6 @@ static __net_initdata struct pernet_operations ip_proc_ops = { | |||
472 | 463 | ||
473 | int __init ip_misc_proc_init(void) | 464 | int __init ip_misc_proc_init(void) |
474 | { | 465 | { |
475 | int rc = 0; | 466 | return register_pernet_subsys(&ip_proc_ops); |
476 | |||
477 | if (register_pernet_subsys(&ip_proc_ops)) | ||
478 | goto out_pernet; | ||
479 | |||
480 | if (!proc_net_fops_create(&init_net, "netstat", S_IRUGO, &netstat_seq_fops)) | ||
481 | goto out_netstat; | ||
482 | |||
483 | if (!proc_net_fops_create(&init_net, "snmp", S_IRUGO, &snmp_seq_fops)) | ||
484 | goto out_snmp; | ||
485 | out: | ||
486 | return rc; | ||
487 | out_snmp: | ||
488 | proc_net_remove(&init_net, "netstat"); | ||
489 | out_netstat: | ||
490 | unregister_pernet_subsys(&ip_proc_ops); | ||
491 | out_pernet: | ||
492 | rc = -ENOMEM; | ||
493 | goto out; | ||
494 | } | 467 | } |
495 | 468 | ||