Hi, I just converted /proc/net/{sockstat6,snmp6} to use seq_file. Patch is to 2.5.66. It compiles, runs, increments counters during ping6. Comments? Acme, have you already done this? If there are no problems, please apply it. Patch also corrects 1 typo and fixes 1 other bug: it removes the correct proc-fs file in a failure/init path. Thanks, -- ~Randy patch_name: snmpv6-seqfile.patch patch_version: 2003-04-01.15:10:56 author: Randy.Dunlap <rddunlap@osdl.org> description: convert /proc/net/{sockstat6, snmp6} to seq_file; also remove correct proc-fs-file in failure mode; correct 1 typo; product: Linux product_versions: 2.5.66 changelog: _ maintainer: Dave Miller (davem@redhat.com) diffstat: = net/ipv6/af_inet6.c | 18 +++++------ net/ipv6/proc.c | 79 ++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 67 insertions(+), 30 deletions(-) diff -Naur ./net/ipv6/proc.c%SNMPV6 ./net/ipv6/proc.c --- ./net/ipv6/proc.c%SNMPV6 Mon Mar 24 14:00:19 2003 +++ ./net/ipv6/proc.c Tue Apr 1 15:09:13 2003 @@ -20,6 +20,8 @@ #include <linux/socket.h> #include <linux/net.h> #include <linux/ipv6.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <linux/stddef.h> #include <net/sock.h> #include <net/tcp.h> @@ -37,22 +39,17 @@ return res; } -int afinet6_get_info(char *buffer, char **start, off_t offset, int length) +static int sockstat6_seq_show(struct seq_file *seq, void *v) { - int len = 0; - len += sprintf(buffer+len, "TCP6: inuse %d\n", + seq_printf(seq, "TCP6: inuse %d\n", fold_prot_inuse(&tcpv6_prot)); - len += sprintf(buffer+len, "UDP6: inuse %d\n", + seq_printf(seq, "UDP6: inuse %d\n", fold_prot_inuse(&udpv6_prot)); - len += sprintf(buffer+len, "RAW6: inuse %d\n", + seq_printf(seq, "RAW6: inuse %d\n", fold_prot_inuse(&rawv6_prot)); - len += sprintf(buffer+len, "FRAG6: inuse %d memory %d\n", + seq_printf(seq, "FRAG6: inuse %d memory %d\n", ip6_frag_nqueues, atomic_read(&ip6_frag_mem)); - *start = buffer + offset; - len -= offset; - if(len > length) - len = length; - return len; + return 0; } @@ -154,23 +151,63 @@ return res; } -int afinet6_get_snmp(char *buffer, char **start, off_t offset, int length) +static int snmp6_seq_show(struct seq_file *seq, void *v) { - int len = 0; int i; for (i=0; i<sizeof(snmp6_list)/sizeof(snmp6_list[0]); i++) - len += sprintf(buffer+len, "%-32s\t%ld\n", snmp6_list[i].name, + seq_printf(seq, "%-32s\t%ld\n", snmp6_list[i].name, fold_field(snmp6_list[i].mib, snmp6_list[i].offset)); - len -= offset; + return 0; +} + + +static int sockstat6_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, sockstat6_seq_show, NULL); +} + +static struct file_operations sockstat6_seq_fops = { + .open = sockstat6_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int snmp6_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, snmp6_seq_show, NULL); +} - if (len > length) - len = length; - if(len < 0) - len = 0; +static struct file_operations snmp6_seq_fops = { + .open = snmp6_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; - *start = buffer + offset; +int __init ipv6_misc_proc_init(void) +{ + int rc = 0; + struct proc_dir_entry *p; - return len; + p = create_proc_entry("snmp6", S_IRUGO, proc_net); + if (!p) + goto proc_snmp6_fail; + else + p->proc_fops = &snmp6_seq_fops; + p = create_proc_entry("sockstat6", S_IRUGO, proc_net); + if (!p) + goto proc_sockstat6_fail; + else + p->proc_fops = &sockstat6_seq_fops; +out: + return rc; + +proc_sockstat6_fail: + remove_proc_entry("snmp6", proc_net); +proc_snmp6_fail: + rc = -ENOMEM; + goto out; } diff -Naur ./net/ipv6/af_inet6.c%SNMPV6 ./net/ipv6/af_inet6.c --- ./net/ipv6/af_inet6.c%SNMPV6 Mon Mar 24 14:00:45 2003 +++ ./net/ipv6/af_inet6.c Tue Apr 1 14:33:03 2003 @@ -701,7 +701,9 @@ kfree_percpu(udp_stats_in6[0]); kfree_percpu(udp_stats_in6[1]); } - + +extern int ipv6_misc_proc_init(void); + static int __init inet6_init(void) { struct sk_buff *dummy_skb; @@ -785,10 +787,9 @@ goto proc_tcp6_fail; if (!proc_net_create("udp6", 0, udp6_get_info)) goto proc_udp6_fail; - if (!proc_net_create("sockstat6", 0, afinet6_get_info)) - goto proc_sockstat6_fail; - if (!proc_net_create("snmp6", 0, afinet6_get_snmp)) - goto proc_snmp6_fail; + if (ipv6_misc_proc_init()) + goto proc_misc6_fail; + if (!proc_net_create("anycast6", 0, anycast6_get_info)) goto proc_anycast6_fail; #endif @@ -799,7 +800,7 @@ addrconf_init(); sit_init(); - /* Init v6 extention headers. */ + /* Init v6 extension headers. */ ipv6_hopopts_init(); ipv6_rthdr_init(); ipv6_frag_init(); @@ -814,10 +815,9 @@ #ifdef CONFIG_PROC_FS proc_anycast6_fail: - proc_net_remove("anycast6"); -proc_snmp6_fail: + proc_net_remove("snmp6"); proc_net_remove("sockstat6"); -proc_sockstat6_fail: +proc_misc6_fail: proc_net_remove("udp6"); proc_udp6_fail: proc_net_remove("tcp6"); - : send the line "unsubscribe linux-net" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html