Commit 160f17e345f5b50484d6cdc985b8686a05bf015d

Authored by Wang Chen
Committed by David S. Miller
1 parent 25296d599c

[SCTP]: Use proc_create() to setup ->proc_fops first

Use proc_create() to make sure that ->proc_fops be setup before gluing
PDE to main tree.

Signed-off-by: Wang Chen <wangchen@cn.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 2 changed files with 3 additions and 6 deletions Inline Diff

1 /* SCTP kernel implementation 1 /* SCTP kernel implementation
2 * (C) Copyright IBM Corp. 2001, 2004 2 * (C) Copyright IBM Corp. 2001, 2004
3 * 3 *
4 * This file is part of the SCTP kernel implementation 4 * This file is part of the SCTP kernel implementation
5 * 5 *
6 * Support for memory object debugging. This allows one to monitor the 6 * Support for memory object debugging. This allows one to monitor the
7 * object allocations/deallocations for types instrumented for this 7 * object allocations/deallocations for types instrumented for this
8 * via the proc fs. 8 * via the proc fs.
9 * 9 *
10 * This SCTP implementation is free software; 10 * This SCTP implementation is free software;
11 * you can redistribute it and/or modify it under the terms of 11 * you can redistribute it and/or modify it under the terms of
12 * the GNU General Public License as published by 12 * the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option) 13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version. 14 * any later version.
15 * 15 *
16 * This SCTP implementation is distributed in the hope that it 16 * This SCTP implementation is distributed in the hope that it
17 * will be useful, but WITHOUT ANY WARRANTY; without even the implied 17 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
18 * ************************ 18 * ************************
19 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 19 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 * See the GNU General Public License for more details. 20 * See the GNU General Public License for more details.
21 * 21 *
22 * You should have received a copy of the GNU General Public License 22 * You should have received a copy of the GNU General Public License
23 * along with GNU CC; see the file COPYING. If not, write to 23 * along with GNU CC; see the file COPYING. If not, write to
24 * the Free Software Foundation, 59 Temple Place - Suite 330, 24 * the Free Software Foundation, 59 Temple Place - Suite 330,
25 * Boston, MA 02111-1307, USA. 25 * Boston, MA 02111-1307, USA.
26 * 26 *
27 * Please send any bug reports or fixes you make to the 27 * Please send any bug reports or fixes you make to the
28 * email address(es): 28 * email address(es):
29 * lksctp developers <lksctp-developers@lists.sourceforge.net> 29 * lksctp developers <lksctp-developers@lists.sourceforge.net>
30 * 30 *
31 * Or submit a bug report through the following website: 31 * Or submit a bug report through the following website:
32 * http://www.sf.net/projects/lksctp 32 * http://www.sf.net/projects/lksctp
33 * 33 *
34 * Written or modified by: 34 * Written or modified by:
35 * Jon Grimm <jgrimm@us.ibm.com> 35 * Jon Grimm <jgrimm@us.ibm.com>
36 * 36 *
37 * Any bugs reported given to us we will try to fix... any fixes shared will 37 * Any bugs reported given to us we will try to fix... any fixes shared will
38 * be incorporated into the next SCTP release. 38 * be incorporated into the next SCTP release.
39 */ 39 */
40 40
41 #include <linux/kernel.h> 41 #include <linux/kernel.h>
42 #include <net/sctp/sctp.h> 42 #include <net/sctp/sctp.h>
43 43
44 /* 44 /*
45 * Global counters to count raw object allocation counts. 45 * Global counters to count raw object allocation counts.
46 * To add new counters, choose a unique suffix for the variable 46 * To add new counters, choose a unique suffix for the variable
47 * name as the helper macros key off this suffix to make 47 * name as the helper macros key off this suffix to make
48 * life easier for the programmer. 48 * life easier for the programmer.
49 */ 49 */
50 50
51 SCTP_DBG_OBJCNT(sock); 51 SCTP_DBG_OBJCNT(sock);
52 SCTP_DBG_OBJCNT(ep); 52 SCTP_DBG_OBJCNT(ep);
53 SCTP_DBG_OBJCNT(transport); 53 SCTP_DBG_OBJCNT(transport);
54 SCTP_DBG_OBJCNT(assoc); 54 SCTP_DBG_OBJCNT(assoc);
55 SCTP_DBG_OBJCNT(bind_addr); 55 SCTP_DBG_OBJCNT(bind_addr);
56 SCTP_DBG_OBJCNT(bind_bucket); 56 SCTP_DBG_OBJCNT(bind_bucket);
57 SCTP_DBG_OBJCNT(chunk); 57 SCTP_DBG_OBJCNT(chunk);
58 SCTP_DBG_OBJCNT(addr); 58 SCTP_DBG_OBJCNT(addr);
59 SCTP_DBG_OBJCNT(ssnmap); 59 SCTP_DBG_OBJCNT(ssnmap);
60 SCTP_DBG_OBJCNT(datamsg); 60 SCTP_DBG_OBJCNT(datamsg);
61 SCTP_DBG_OBJCNT(keys); 61 SCTP_DBG_OBJCNT(keys);
62 62
63 /* An array to make it easy to pretty print the debug information 63 /* An array to make it easy to pretty print the debug information
64 * to the proc fs. 64 * to the proc fs.
65 */ 65 */
66 static sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = { 66 static sctp_dbg_objcnt_entry_t sctp_dbg_objcnt[] = {
67 SCTP_DBG_OBJCNT_ENTRY(sock), 67 SCTP_DBG_OBJCNT_ENTRY(sock),
68 SCTP_DBG_OBJCNT_ENTRY(ep), 68 SCTP_DBG_OBJCNT_ENTRY(ep),
69 SCTP_DBG_OBJCNT_ENTRY(assoc), 69 SCTP_DBG_OBJCNT_ENTRY(assoc),
70 SCTP_DBG_OBJCNT_ENTRY(transport), 70 SCTP_DBG_OBJCNT_ENTRY(transport),
71 SCTP_DBG_OBJCNT_ENTRY(chunk), 71 SCTP_DBG_OBJCNT_ENTRY(chunk),
72 SCTP_DBG_OBJCNT_ENTRY(bind_addr), 72 SCTP_DBG_OBJCNT_ENTRY(bind_addr),
73 SCTP_DBG_OBJCNT_ENTRY(bind_bucket), 73 SCTP_DBG_OBJCNT_ENTRY(bind_bucket),
74 SCTP_DBG_OBJCNT_ENTRY(addr), 74 SCTP_DBG_OBJCNT_ENTRY(addr),
75 SCTP_DBG_OBJCNT_ENTRY(ssnmap), 75 SCTP_DBG_OBJCNT_ENTRY(ssnmap),
76 SCTP_DBG_OBJCNT_ENTRY(datamsg), 76 SCTP_DBG_OBJCNT_ENTRY(datamsg),
77 SCTP_DBG_OBJCNT_ENTRY(keys), 77 SCTP_DBG_OBJCNT_ENTRY(keys),
78 }; 78 };
79 79
80 /* Callback from procfs to read out objcount information. 80 /* Callback from procfs to read out objcount information.
81 * Walk through the entries in the sctp_dbg_objcnt array, dumping 81 * Walk through the entries in the sctp_dbg_objcnt array, dumping
82 * the raw object counts for each monitored type. 82 * the raw object counts for each monitored type.
83 */ 83 */
84 static int sctp_objcnt_seq_show(struct seq_file *seq, void *v) 84 static int sctp_objcnt_seq_show(struct seq_file *seq, void *v)
85 { 85 {
86 int i; 86 int i;
87 char temp[128]; 87 char temp[128];
88 88
89 i = (int)*(loff_t *)v; 89 i = (int)*(loff_t *)v;
90 sprintf(temp, "%s: %d", sctp_dbg_objcnt[i].label, 90 sprintf(temp, "%s: %d", sctp_dbg_objcnt[i].label,
91 atomic_read(sctp_dbg_objcnt[i].counter)); 91 atomic_read(sctp_dbg_objcnt[i].counter));
92 seq_printf(seq, "%-127s\n", temp); 92 seq_printf(seq, "%-127s\n", temp);
93 return 0; 93 return 0;
94 } 94 }
95 95
96 static void *sctp_objcnt_seq_start(struct seq_file *seq, loff_t *pos) 96 static void *sctp_objcnt_seq_start(struct seq_file *seq, loff_t *pos)
97 { 97 {
98 return (*pos >= ARRAY_SIZE(sctp_dbg_objcnt)) ? NULL : (void *)pos; 98 return (*pos >= ARRAY_SIZE(sctp_dbg_objcnt)) ? NULL : (void *)pos;
99 } 99 }
100 100
101 static void sctp_objcnt_seq_stop(struct seq_file *seq, void *v) 101 static void sctp_objcnt_seq_stop(struct seq_file *seq, void *v)
102 { 102 {
103 } 103 }
104 104
105 static void * sctp_objcnt_seq_next(struct seq_file *seq, void *v, loff_t *pos) 105 static void * sctp_objcnt_seq_next(struct seq_file *seq, void *v, loff_t *pos)
106 { 106 {
107 ++*pos; 107 ++*pos;
108 return (*pos >= ARRAY_SIZE(sctp_dbg_objcnt)) ? NULL : (void *)pos; 108 return (*pos >= ARRAY_SIZE(sctp_dbg_objcnt)) ? NULL : (void *)pos;
109 } 109 }
110 110
111 static const struct seq_operations sctp_objcnt_seq_ops = { 111 static const struct seq_operations sctp_objcnt_seq_ops = {
112 .start = sctp_objcnt_seq_start, 112 .start = sctp_objcnt_seq_start,
113 .next = sctp_objcnt_seq_next, 113 .next = sctp_objcnt_seq_next,
114 .stop = sctp_objcnt_seq_stop, 114 .stop = sctp_objcnt_seq_stop,
115 .show = sctp_objcnt_seq_show, 115 .show = sctp_objcnt_seq_show,
116 }; 116 };
117 117
118 static int sctp_objcnt_seq_open(struct inode *inode, struct file *file) 118 static int sctp_objcnt_seq_open(struct inode *inode, struct file *file)
119 { 119 {
120 return seq_open(file, &sctp_objcnt_seq_ops); 120 return seq_open(file, &sctp_objcnt_seq_ops);
121 } 121 }
122 122
123 static const struct file_operations sctp_objcnt_ops = { 123 static const struct file_operations sctp_objcnt_ops = {
124 .open = sctp_objcnt_seq_open, 124 .open = sctp_objcnt_seq_open,
125 .read = seq_read, 125 .read = seq_read,
126 .llseek = seq_lseek, 126 .llseek = seq_lseek,
127 .release = seq_release, 127 .release = seq_release,
128 }; 128 };
129 129
130 /* Initialize the objcount in the proc filesystem. */ 130 /* Initialize the objcount in the proc filesystem. */
131 void sctp_dbg_objcnt_init(void) 131 void sctp_dbg_objcnt_init(void)
132 { 132 {
133 struct proc_dir_entry *ent; 133 struct proc_dir_entry *ent;
134 134
135 ent = create_proc_entry("sctp_dbg_objcnt", 0, proc_net_sctp); 135 ent = proc_create("sctp_dbg_objcnt", 0,
136 proc_net_sctp, &sctp_objcnt_ops);
136 if (!ent) 137 if (!ent)
137 printk(KERN_WARNING 138 printk(KERN_WARNING
138 "sctp_dbg_objcnt: Unable to create /proc entry.\n"); 139 "sctp_dbg_objcnt: Unable to create /proc entry.\n");
139 else
140 ent->proc_fops = &sctp_objcnt_ops;
141 } 140 }
142 141
143 /* Cleanup the objcount entry in the proc filesystem. */ 142 /* Cleanup the objcount entry in the proc filesystem. */
144 void sctp_dbg_objcnt_exit(void) 143 void sctp_dbg_objcnt_exit(void)
145 { 144 {
146 remove_proc_entry("sctp_dbg_objcnt", proc_net_sctp); 145 remove_proc_entry("sctp_dbg_objcnt", proc_net_sctp);
147 } 146 }
148 147
149 148
1 /* SCTP kernel implementation 1 /* SCTP kernel implementation
2 * Copyright (c) 2003 International Business Machines, Corp. 2 * Copyright (c) 2003 International Business Machines, Corp.
3 * 3 *
4 * This file is part of the SCTP kernel implementation 4 * This file is part of the SCTP kernel implementation
5 * 5 *
6 * This SCTP implementation is free software; 6 * This SCTP implementation is free software;
7 * you can redistribute it and/or modify it under the terms of 7 * you can redistribute it and/or modify it under the terms of
8 * the GNU General Public License as published by 8 * the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option) 9 * the Free Software Foundation; either version 2, or (at your option)
10 * any later version. 10 * any later version.
11 * 11 *
12 * This SCTP implementation is distributed in the hope that it 12 * This SCTP implementation is distributed in the hope that it
13 * will be useful, but WITHOUT ANY WARRANTY; without even the implied 13 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
14 * ************************ 14 * ************************
15 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 * See the GNU General Public License for more details. 16 * See the GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with GNU CC; see the file COPYING. If not, write to 19 * along with GNU CC; see the file COPYING. If not, write to
20 * the Free Software Foundation, 59 Temple Place - Suite 330, 20 * the Free Software Foundation, 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA. 21 * Boston, MA 02111-1307, USA.
22 * 22 *
23 * Please send any bug reports or fixes you make to the 23 * Please send any bug reports or fixes you make to the
24 * email address(es): 24 * email address(es):
25 * lksctp developers <lksctp-developers@lists.sourceforge.net> 25 * lksctp developers <lksctp-developers@lists.sourceforge.net>
26 * 26 *
27 * Or submit a bug report through the following website: 27 * Or submit a bug report through the following website:
28 * http://www.sf.net/projects/lksctp 28 * http://www.sf.net/projects/lksctp
29 * 29 *
30 * Written or modified by: 30 * Written or modified by:
31 * Sridhar Samudrala <sri@us.ibm.com> 31 * Sridhar Samudrala <sri@us.ibm.com>
32 * 32 *
33 * Any bugs reported given to us we will try to fix... any fixes shared will 33 * Any bugs reported given to us we will try to fix... any fixes shared will
34 * be incorporated into the next SCTP release. 34 * be incorporated into the next SCTP release.
35 */ 35 */
36 36
37 #include <linux/types.h> 37 #include <linux/types.h>
38 #include <linux/seq_file.h> 38 #include <linux/seq_file.h>
39 #include <linux/init.h> 39 #include <linux/init.h>
40 #include <net/sctp/sctp.h> 40 #include <net/sctp/sctp.h>
41 #include <net/ip.h> /* for snmp_fold_field */ 41 #include <net/ip.h> /* for snmp_fold_field */
42 42
43 static struct snmp_mib sctp_snmp_list[] = { 43 static struct snmp_mib sctp_snmp_list[] = {
44 SNMP_MIB_ITEM("SctpCurrEstab", SCTP_MIB_CURRESTAB), 44 SNMP_MIB_ITEM("SctpCurrEstab", SCTP_MIB_CURRESTAB),
45 SNMP_MIB_ITEM("SctpActiveEstabs", SCTP_MIB_ACTIVEESTABS), 45 SNMP_MIB_ITEM("SctpActiveEstabs", SCTP_MIB_ACTIVEESTABS),
46 SNMP_MIB_ITEM("SctpPassiveEstabs", SCTP_MIB_PASSIVEESTABS), 46 SNMP_MIB_ITEM("SctpPassiveEstabs", SCTP_MIB_PASSIVEESTABS),
47 SNMP_MIB_ITEM("SctpAborteds", SCTP_MIB_ABORTEDS), 47 SNMP_MIB_ITEM("SctpAborteds", SCTP_MIB_ABORTEDS),
48 SNMP_MIB_ITEM("SctpShutdowns", SCTP_MIB_SHUTDOWNS), 48 SNMP_MIB_ITEM("SctpShutdowns", SCTP_MIB_SHUTDOWNS),
49 SNMP_MIB_ITEM("SctpOutOfBlues", SCTP_MIB_OUTOFBLUES), 49 SNMP_MIB_ITEM("SctpOutOfBlues", SCTP_MIB_OUTOFBLUES),
50 SNMP_MIB_ITEM("SctpChecksumErrors", SCTP_MIB_CHECKSUMERRORS), 50 SNMP_MIB_ITEM("SctpChecksumErrors", SCTP_MIB_CHECKSUMERRORS),
51 SNMP_MIB_ITEM("SctpOutCtrlChunks", SCTP_MIB_OUTCTRLCHUNKS), 51 SNMP_MIB_ITEM("SctpOutCtrlChunks", SCTP_MIB_OUTCTRLCHUNKS),
52 SNMP_MIB_ITEM("SctpOutOrderChunks", SCTP_MIB_OUTORDERCHUNKS), 52 SNMP_MIB_ITEM("SctpOutOrderChunks", SCTP_MIB_OUTORDERCHUNKS),
53 SNMP_MIB_ITEM("SctpOutUnorderChunks", SCTP_MIB_OUTUNORDERCHUNKS), 53 SNMP_MIB_ITEM("SctpOutUnorderChunks", SCTP_MIB_OUTUNORDERCHUNKS),
54 SNMP_MIB_ITEM("SctpInCtrlChunks", SCTP_MIB_INCTRLCHUNKS), 54 SNMP_MIB_ITEM("SctpInCtrlChunks", SCTP_MIB_INCTRLCHUNKS),
55 SNMP_MIB_ITEM("SctpInOrderChunks", SCTP_MIB_INORDERCHUNKS), 55 SNMP_MIB_ITEM("SctpInOrderChunks", SCTP_MIB_INORDERCHUNKS),
56 SNMP_MIB_ITEM("SctpInUnorderChunks", SCTP_MIB_INUNORDERCHUNKS), 56 SNMP_MIB_ITEM("SctpInUnorderChunks", SCTP_MIB_INUNORDERCHUNKS),
57 SNMP_MIB_ITEM("SctpFragUsrMsgs", SCTP_MIB_FRAGUSRMSGS), 57 SNMP_MIB_ITEM("SctpFragUsrMsgs", SCTP_MIB_FRAGUSRMSGS),
58 SNMP_MIB_ITEM("SctpReasmUsrMsgs", SCTP_MIB_REASMUSRMSGS), 58 SNMP_MIB_ITEM("SctpReasmUsrMsgs", SCTP_MIB_REASMUSRMSGS),
59 SNMP_MIB_ITEM("SctpOutSCTPPacks", SCTP_MIB_OUTSCTPPACKS), 59 SNMP_MIB_ITEM("SctpOutSCTPPacks", SCTP_MIB_OUTSCTPPACKS),
60 SNMP_MIB_ITEM("SctpInSCTPPacks", SCTP_MIB_INSCTPPACKS), 60 SNMP_MIB_ITEM("SctpInSCTPPacks", SCTP_MIB_INSCTPPACKS),
61 SNMP_MIB_ITEM("SctpT1InitExpireds", SCTP_MIB_T1_INIT_EXPIREDS), 61 SNMP_MIB_ITEM("SctpT1InitExpireds", SCTP_MIB_T1_INIT_EXPIREDS),
62 SNMP_MIB_ITEM("SctpT1CookieExpireds", SCTP_MIB_T1_COOKIE_EXPIREDS), 62 SNMP_MIB_ITEM("SctpT1CookieExpireds", SCTP_MIB_T1_COOKIE_EXPIREDS),
63 SNMP_MIB_ITEM("SctpT2ShutdownExpireds", SCTP_MIB_T2_SHUTDOWN_EXPIREDS), 63 SNMP_MIB_ITEM("SctpT2ShutdownExpireds", SCTP_MIB_T2_SHUTDOWN_EXPIREDS),
64 SNMP_MIB_ITEM("SctpT3RtxExpireds", SCTP_MIB_T3_RTX_EXPIREDS), 64 SNMP_MIB_ITEM("SctpT3RtxExpireds", SCTP_MIB_T3_RTX_EXPIREDS),
65 SNMP_MIB_ITEM("SctpT4RtoExpireds", SCTP_MIB_T4_RTO_EXPIREDS), 65 SNMP_MIB_ITEM("SctpT4RtoExpireds", SCTP_MIB_T4_RTO_EXPIREDS),
66 SNMP_MIB_ITEM("SctpT5ShutdownGuardExpireds", SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS), 66 SNMP_MIB_ITEM("SctpT5ShutdownGuardExpireds", SCTP_MIB_T5_SHUTDOWN_GUARD_EXPIREDS),
67 SNMP_MIB_ITEM("SctpDelaySackExpireds", SCTP_MIB_DELAY_SACK_EXPIREDS), 67 SNMP_MIB_ITEM("SctpDelaySackExpireds", SCTP_MIB_DELAY_SACK_EXPIREDS),
68 SNMP_MIB_ITEM("SctpAutocloseExpireds", SCTP_MIB_AUTOCLOSE_EXPIREDS), 68 SNMP_MIB_ITEM("SctpAutocloseExpireds", SCTP_MIB_AUTOCLOSE_EXPIREDS),
69 SNMP_MIB_ITEM("SctpT3Retransmits", SCTP_MIB_T3_RETRANSMITS), 69 SNMP_MIB_ITEM("SctpT3Retransmits", SCTP_MIB_T3_RETRANSMITS),
70 SNMP_MIB_ITEM("SctpPmtudRetransmits", SCTP_MIB_PMTUD_RETRANSMITS), 70 SNMP_MIB_ITEM("SctpPmtudRetransmits", SCTP_MIB_PMTUD_RETRANSMITS),
71 SNMP_MIB_ITEM("SctpFastRetransmits", SCTP_MIB_FAST_RETRANSMITS), 71 SNMP_MIB_ITEM("SctpFastRetransmits", SCTP_MIB_FAST_RETRANSMITS),
72 SNMP_MIB_ITEM("SctpInPktSoftirq", SCTP_MIB_IN_PKT_SOFTIRQ), 72 SNMP_MIB_ITEM("SctpInPktSoftirq", SCTP_MIB_IN_PKT_SOFTIRQ),
73 SNMP_MIB_ITEM("SctpInPktBacklog", SCTP_MIB_IN_PKT_BACKLOG), 73 SNMP_MIB_ITEM("SctpInPktBacklog", SCTP_MIB_IN_PKT_BACKLOG),
74 SNMP_MIB_ITEM("SctpInPktDiscards", SCTP_MIB_IN_PKT_DISCARDS), 74 SNMP_MIB_ITEM("SctpInPktDiscards", SCTP_MIB_IN_PKT_DISCARDS),
75 SNMP_MIB_ITEM("SctpInDataChunkDiscards", SCTP_MIB_IN_DATA_CHUNK_DISCARDS), 75 SNMP_MIB_ITEM("SctpInDataChunkDiscards", SCTP_MIB_IN_DATA_CHUNK_DISCARDS),
76 SNMP_MIB_SENTINEL 76 SNMP_MIB_SENTINEL
77 }; 77 };
78 78
79 /* Display sctp snmp mib statistics(/proc/net/sctp/snmp). */ 79 /* Display sctp snmp mib statistics(/proc/net/sctp/snmp). */
80 static int sctp_snmp_seq_show(struct seq_file *seq, void *v) 80 static int sctp_snmp_seq_show(struct seq_file *seq, void *v)
81 { 81 {
82 int i; 82 int i;
83 83
84 for (i = 0; sctp_snmp_list[i].name != NULL; i++) 84 for (i = 0; sctp_snmp_list[i].name != NULL; i++)
85 seq_printf(seq, "%-32s\t%ld\n", sctp_snmp_list[i].name, 85 seq_printf(seq, "%-32s\t%ld\n", sctp_snmp_list[i].name,
86 snmp_fold_field((void **)sctp_statistics, 86 snmp_fold_field((void **)sctp_statistics,
87 sctp_snmp_list[i].entry)); 87 sctp_snmp_list[i].entry));
88 88
89 return 0; 89 return 0;
90 } 90 }
91 91
92 /* Initialize the seq file operations for 'snmp' object. */ 92 /* Initialize the seq file operations for 'snmp' object. */
93 static int sctp_snmp_seq_open(struct inode *inode, struct file *file) 93 static int sctp_snmp_seq_open(struct inode *inode, struct file *file)
94 { 94 {
95 return single_open(file, sctp_snmp_seq_show, NULL); 95 return single_open(file, sctp_snmp_seq_show, NULL);
96 } 96 }
97 97
98 static const struct file_operations sctp_snmp_seq_fops = { 98 static const struct file_operations sctp_snmp_seq_fops = {
99 .owner = THIS_MODULE, 99 .owner = THIS_MODULE,
100 .open = sctp_snmp_seq_open, 100 .open = sctp_snmp_seq_open,
101 .read = seq_read, 101 .read = seq_read,
102 .llseek = seq_lseek, 102 .llseek = seq_lseek,
103 .release = single_release, 103 .release = single_release,
104 }; 104 };
105 105
106 /* Set up the proc fs entry for 'snmp' object. */ 106 /* Set up the proc fs entry for 'snmp' object. */
107 int __init sctp_snmp_proc_init(void) 107 int __init sctp_snmp_proc_init(void)
108 { 108 {
109 struct proc_dir_entry *p; 109 struct proc_dir_entry *p;
110 110
111 p = create_proc_entry("snmp", S_IRUGO, proc_net_sctp); 111 p = proc_create("snmp", S_IRUGO, proc_net_sctp, &sctp_snmp_seq_fops);
112 if (!p) 112 if (!p)
113 return -ENOMEM; 113 return -ENOMEM;
114
115 p->proc_fops = &sctp_snmp_seq_fops;
116 114
117 return 0; 115 return 0;
118 } 116 }
119 117
120 /* Cleanup the proc fs entry for 'snmp' object. */ 118 /* Cleanup the proc fs entry for 'snmp' object. */
121 void sctp_snmp_proc_exit(void) 119 void sctp_snmp_proc_exit(void)
122 { 120 {
123 remove_proc_entry("snmp", proc_net_sctp); 121 remove_proc_entry("snmp", proc_net_sctp);
124 } 122 }
125 123
126 /* Dump local addresses of an association/endpoint. */ 124 /* Dump local addresses of an association/endpoint. */
127 static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb) 125 static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_common *epb)
128 { 126 {
129 struct list_head *pos; 127 struct list_head *pos;
130 struct sctp_association *asoc; 128 struct sctp_association *asoc;
131 struct sctp_sockaddr_entry *laddr; 129 struct sctp_sockaddr_entry *laddr;
132 struct sctp_transport *peer; 130 struct sctp_transport *peer;
133 union sctp_addr *addr, *primary = NULL; 131 union sctp_addr *addr, *primary = NULL;
134 struct sctp_af *af; 132 struct sctp_af *af;
135 133
136 if (epb->type == SCTP_EP_TYPE_ASSOCIATION) { 134 if (epb->type == SCTP_EP_TYPE_ASSOCIATION) {
137 asoc = sctp_assoc(epb); 135 asoc = sctp_assoc(epb);
138 peer = asoc->peer.primary_path; 136 peer = asoc->peer.primary_path;
139 primary = &peer->saddr; 137 primary = &peer->saddr;
140 } 138 }
141 139
142 list_for_each(pos, &epb->bind_addr.address_list) { 140 list_for_each(pos, &epb->bind_addr.address_list) {
143 laddr = list_entry(pos, struct sctp_sockaddr_entry, list); 141 laddr = list_entry(pos, struct sctp_sockaddr_entry, list);
144 addr = &laddr->a; 142 addr = &laddr->a;
145 af = sctp_get_af_specific(addr->sa.sa_family); 143 af = sctp_get_af_specific(addr->sa.sa_family);
146 if (primary && af->cmp_addr(addr, primary)) { 144 if (primary && af->cmp_addr(addr, primary)) {
147 seq_printf(seq, "*"); 145 seq_printf(seq, "*");
148 } 146 }
149 af->seq_dump_addr(seq, addr); 147 af->seq_dump_addr(seq, addr);
150 } 148 }
151 } 149 }
152 150
153 /* Dump remote addresses of an association. */ 151 /* Dump remote addresses of an association. */
154 static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_association *assoc) 152 static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_association *assoc)
155 { 153 {
156 struct list_head *pos; 154 struct list_head *pos;
157 struct sctp_transport *transport; 155 struct sctp_transport *transport;
158 union sctp_addr *addr, *primary; 156 union sctp_addr *addr, *primary;
159 struct sctp_af *af; 157 struct sctp_af *af;
160 158
161 primary = &assoc->peer.primary_addr; 159 primary = &assoc->peer.primary_addr;
162 list_for_each(pos, &assoc->peer.transport_addr_list) { 160 list_for_each(pos, &assoc->peer.transport_addr_list) {
163 transport = list_entry(pos, struct sctp_transport, transports); 161 transport = list_entry(pos, struct sctp_transport, transports);
164 addr = &transport->ipaddr; 162 addr = &transport->ipaddr;
165 af = sctp_get_af_specific(addr->sa.sa_family); 163 af = sctp_get_af_specific(addr->sa.sa_family);
166 if (af->cmp_addr(addr, primary)) { 164 if (af->cmp_addr(addr, primary)) {
167 seq_printf(seq, "*"); 165 seq_printf(seq, "*");
168 } 166 }
169 af->seq_dump_addr(seq, addr); 167 af->seq_dump_addr(seq, addr);
170 } 168 }
171 } 169 }
172 170
173 static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos) 171 static void * sctp_eps_seq_start(struct seq_file *seq, loff_t *pos)
174 { 172 {
175 if (*pos >= sctp_ep_hashsize) 173 if (*pos >= sctp_ep_hashsize)
176 return NULL; 174 return NULL;
177 175
178 if (*pos < 0) 176 if (*pos < 0)
179 *pos = 0; 177 *pos = 0;
180 178
181 if (*pos == 0) 179 if (*pos == 0)
182 seq_printf(seq, " ENDPT SOCK STY SST HBKT LPORT UID INODE LADDRS\n"); 180 seq_printf(seq, " ENDPT SOCK STY SST HBKT LPORT UID INODE LADDRS\n");
183 181
184 return (void *)pos; 182 return (void *)pos;
185 } 183 }
186 184
187 static void sctp_eps_seq_stop(struct seq_file *seq, void *v) 185 static void sctp_eps_seq_stop(struct seq_file *seq, void *v)
188 { 186 {
189 return; 187 return;
190 } 188 }
191 189
192 190
193 static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos) 191 static void * sctp_eps_seq_next(struct seq_file *seq, void *v, loff_t *pos)
194 { 192 {
195 if (++*pos >= sctp_ep_hashsize) 193 if (++*pos >= sctp_ep_hashsize)
196 return NULL; 194 return NULL;
197 195
198 return pos; 196 return pos;
199 } 197 }
200 198
201 199
202 /* Display sctp endpoints (/proc/net/sctp/eps). */ 200 /* Display sctp endpoints (/proc/net/sctp/eps). */
203 static int sctp_eps_seq_show(struct seq_file *seq, void *v) 201 static int sctp_eps_seq_show(struct seq_file *seq, void *v)
204 { 202 {
205 struct sctp_hashbucket *head; 203 struct sctp_hashbucket *head;
206 struct sctp_ep_common *epb; 204 struct sctp_ep_common *epb;
207 struct sctp_endpoint *ep; 205 struct sctp_endpoint *ep;
208 struct sock *sk; 206 struct sock *sk;
209 struct hlist_node *node; 207 struct hlist_node *node;
210 int hash = *(loff_t *)v; 208 int hash = *(loff_t *)v;
211 209
212 if (hash >= sctp_ep_hashsize) 210 if (hash >= sctp_ep_hashsize)
213 return -ENOMEM; 211 return -ENOMEM;
214 212
215 head = &sctp_ep_hashtable[hash]; 213 head = &sctp_ep_hashtable[hash];
216 sctp_local_bh_disable(); 214 sctp_local_bh_disable();
217 read_lock(&head->lock); 215 read_lock(&head->lock);
218 sctp_for_each_hentry(epb, node, &head->chain) { 216 sctp_for_each_hentry(epb, node, &head->chain) {
219 ep = sctp_ep(epb); 217 ep = sctp_ep(epb);
220 sk = epb->sk; 218 sk = epb->sk;
221 seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk, 219 seq_printf(seq, "%8p %8p %-3d %-3d %-4d %-5d %5d %5lu ", ep, sk,
222 sctp_sk(sk)->type, sk->sk_state, hash, 220 sctp_sk(sk)->type, sk->sk_state, hash,
223 epb->bind_addr.port, 221 epb->bind_addr.port,
224 sock_i_uid(sk), sock_i_ino(sk)); 222 sock_i_uid(sk), sock_i_ino(sk));
225 223
226 sctp_seq_dump_local_addrs(seq, epb); 224 sctp_seq_dump_local_addrs(seq, epb);
227 seq_printf(seq, "\n"); 225 seq_printf(seq, "\n");
228 } 226 }
229 read_unlock(&head->lock); 227 read_unlock(&head->lock);
230 sctp_local_bh_enable(); 228 sctp_local_bh_enable();
231 229
232 return 0; 230 return 0;
233 } 231 }
234 232
235 static const struct seq_operations sctp_eps_ops = { 233 static const struct seq_operations sctp_eps_ops = {
236 .start = sctp_eps_seq_start, 234 .start = sctp_eps_seq_start,
237 .next = sctp_eps_seq_next, 235 .next = sctp_eps_seq_next,
238 .stop = sctp_eps_seq_stop, 236 .stop = sctp_eps_seq_stop,
239 .show = sctp_eps_seq_show, 237 .show = sctp_eps_seq_show,
240 }; 238 };
241 239
242 240
243 /* Initialize the seq file operations for 'eps' object. */ 241 /* Initialize the seq file operations for 'eps' object. */
244 static int sctp_eps_seq_open(struct inode *inode, struct file *file) 242 static int sctp_eps_seq_open(struct inode *inode, struct file *file)
245 { 243 {
246 return seq_open(file, &sctp_eps_ops); 244 return seq_open(file, &sctp_eps_ops);
247 } 245 }
248 246
249 static const struct file_operations sctp_eps_seq_fops = { 247 static const struct file_operations sctp_eps_seq_fops = {
250 .open = sctp_eps_seq_open, 248 .open = sctp_eps_seq_open,
251 .read = seq_read, 249 .read = seq_read,
252 .llseek = seq_lseek, 250 .llseek = seq_lseek,
253 .release = seq_release, 251 .release = seq_release,
254 }; 252 };
255 253
256 /* Set up the proc fs entry for 'eps' object. */ 254 /* Set up the proc fs entry for 'eps' object. */
257 int __init sctp_eps_proc_init(void) 255 int __init sctp_eps_proc_init(void)
258 { 256 {
259 struct proc_dir_entry *p; 257 struct proc_dir_entry *p;
260 258
261 p = create_proc_entry("eps", S_IRUGO, proc_net_sctp); 259 p = create_proc_entry("eps", S_IRUGO, proc_net_sctp);
262 if (!p) 260 if (!p)
263 return -ENOMEM; 261 return -ENOMEM;
264 262
265 p->proc_fops = &sctp_eps_seq_fops; 263 p->proc_fops = &sctp_eps_seq_fops;
266 264
267 return 0; 265 return 0;
268 } 266 }
269 267
270 /* Cleanup the proc fs entry for 'eps' object. */ 268 /* Cleanup the proc fs entry for 'eps' object. */
271 void sctp_eps_proc_exit(void) 269 void sctp_eps_proc_exit(void)
272 { 270 {
273 remove_proc_entry("eps", proc_net_sctp); 271 remove_proc_entry("eps", proc_net_sctp);
274 } 272 }
275 273
276 274
277 static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos) 275 static void * sctp_assocs_seq_start(struct seq_file *seq, loff_t *pos)
278 { 276 {
279 if (*pos >= sctp_assoc_hashsize) 277 if (*pos >= sctp_assoc_hashsize)
280 return NULL; 278 return NULL;
281 279
282 if (*pos < 0) 280 if (*pos < 0)
283 *pos = 0; 281 *pos = 0;
284 282
285 if (*pos == 0) 283 if (*pos == 0)
286 seq_printf(seq, " ASSOC SOCK STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT " 284 seq_printf(seq, " ASSOC SOCK STY SST ST HBKT ASSOC-ID TX_QUEUE RX_QUEUE UID INODE LPORT "
287 "RPORT LADDRS <-> RADDRS\n"); 285 "RPORT LADDRS <-> RADDRS\n");
288 286
289 return (void *)pos; 287 return (void *)pos;
290 } 288 }
291 289
292 static void sctp_assocs_seq_stop(struct seq_file *seq, void *v) 290 static void sctp_assocs_seq_stop(struct seq_file *seq, void *v)
293 { 291 {
294 return; 292 return;
295 } 293 }
296 294
297 295
298 static void * sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos) 296 static void * sctp_assocs_seq_next(struct seq_file *seq, void *v, loff_t *pos)
299 { 297 {
300 if (++*pos >= sctp_assoc_hashsize) 298 if (++*pos >= sctp_assoc_hashsize)
301 return NULL; 299 return NULL;
302 300
303 return pos; 301 return pos;
304 } 302 }
305 303
306 /* Display sctp associations (/proc/net/sctp/assocs). */ 304 /* Display sctp associations (/proc/net/sctp/assocs). */
307 static int sctp_assocs_seq_show(struct seq_file *seq, void *v) 305 static int sctp_assocs_seq_show(struct seq_file *seq, void *v)
308 { 306 {
309 struct sctp_hashbucket *head; 307 struct sctp_hashbucket *head;
310 struct sctp_ep_common *epb; 308 struct sctp_ep_common *epb;
311 struct sctp_association *assoc; 309 struct sctp_association *assoc;
312 struct sock *sk; 310 struct sock *sk;
313 struct hlist_node *node; 311 struct hlist_node *node;
314 int hash = *(loff_t *)v; 312 int hash = *(loff_t *)v;
315 313
316 if (hash >= sctp_assoc_hashsize) 314 if (hash >= sctp_assoc_hashsize)
317 return -ENOMEM; 315 return -ENOMEM;
318 316
319 head = &sctp_assoc_hashtable[hash]; 317 head = &sctp_assoc_hashtable[hash];
320 sctp_local_bh_disable(); 318 sctp_local_bh_disable();
321 read_lock(&head->lock); 319 read_lock(&head->lock);
322 sctp_for_each_hentry(epb, node, &head->chain) { 320 sctp_for_each_hentry(epb, node, &head->chain) {
323 assoc = sctp_assoc(epb); 321 assoc = sctp_assoc(epb);
324 sk = epb->sk; 322 sk = epb->sk;
325 seq_printf(seq, 323 seq_printf(seq,
326 "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ", 324 "%8p %8p %-3d %-3d %-2d %-4d %4d %8d %8d %7d %5lu %-5d %5d ",
327 assoc, sk, sctp_sk(sk)->type, sk->sk_state, 325 assoc, sk, sctp_sk(sk)->type, sk->sk_state,
328 assoc->state, hash, assoc->assoc_id, 326 assoc->state, hash, assoc->assoc_id,
329 assoc->sndbuf_used, 327 assoc->sndbuf_used,
330 atomic_read(&assoc->rmem_alloc), 328 atomic_read(&assoc->rmem_alloc),
331 sock_i_uid(sk), sock_i_ino(sk), 329 sock_i_uid(sk), sock_i_ino(sk),
332 epb->bind_addr.port, 330 epb->bind_addr.port,
333 assoc->peer.port); 331 assoc->peer.port);
334 332
335 seq_printf(seq, " "); 333 seq_printf(seq, " ");
336 sctp_seq_dump_local_addrs(seq, epb); 334 sctp_seq_dump_local_addrs(seq, epb);
337 seq_printf(seq, "<-> "); 335 seq_printf(seq, "<-> ");
338 sctp_seq_dump_remote_addrs(seq, assoc); 336 sctp_seq_dump_remote_addrs(seq, assoc);
339 seq_printf(seq, "\n"); 337 seq_printf(seq, "\n");
340 } 338 }
341 read_unlock(&head->lock); 339 read_unlock(&head->lock);
342 sctp_local_bh_enable(); 340 sctp_local_bh_enable();
343 341
344 return 0; 342 return 0;
345 } 343 }
346 344
347 static const struct seq_operations sctp_assoc_ops = { 345 static const struct seq_operations sctp_assoc_ops = {
348 .start = sctp_assocs_seq_start, 346 .start = sctp_assocs_seq_start,
349 .next = sctp_assocs_seq_next, 347 .next = sctp_assocs_seq_next,
350 .stop = sctp_assocs_seq_stop, 348 .stop = sctp_assocs_seq_stop,
351 .show = sctp_assocs_seq_show, 349 .show = sctp_assocs_seq_show,
352 }; 350 };
353 351
354 /* Initialize the seq file operations for 'assocs' object. */ 352 /* Initialize the seq file operations for 'assocs' object. */
355 static int sctp_assocs_seq_open(struct inode *inode, struct file *file) 353 static int sctp_assocs_seq_open(struct inode *inode, struct file *file)
356 { 354 {
357 return seq_open(file, &sctp_assoc_ops); 355 return seq_open(file, &sctp_assoc_ops);
358 } 356 }
359 357
360 static const struct file_operations sctp_assocs_seq_fops = { 358 static const struct file_operations sctp_assocs_seq_fops = {
361 .open = sctp_assocs_seq_open, 359 .open = sctp_assocs_seq_open,
362 .read = seq_read, 360 .read = seq_read,
363 .llseek = seq_lseek, 361 .llseek = seq_lseek,
364 .release = seq_release, 362 .release = seq_release,
365 }; 363 };
366 364
367 /* Set up the proc fs entry for 'assocs' object. */ 365 /* Set up the proc fs entry for 'assocs' object. */
368 int __init sctp_assocs_proc_init(void) 366 int __init sctp_assocs_proc_init(void)
369 { 367 {
370 struct proc_dir_entry *p; 368 struct proc_dir_entry *p;
371 369
372 p = create_proc_entry("assocs", S_IRUGO, proc_net_sctp); 370 p = create_proc_entry("assocs", S_IRUGO, proc_net_sctp);
373 if (!p) 371 if (!p)
374 return -ENOMEM; 372 return -ENOMEM;
375 373
376 p->proc_fops = &sctp_assocs_seq_fops; 374 p->proc_fops = &sctp_assocs_seq_fops;
377 375
378 return 0; 376 return 0;
379 } 377 }
380 378
381 /* Cleanup the proc fs entry for 'assocs' object. */ 379 /* Cleanup the proc fs entry for 'assocs' object. */
382 void sctp_assocs_proc_exit(void) 380 void sctp_assocs_proc_exit(void)
383 { 381 {
384 remove_proc_entry("assocs", proc_net_sctp); 382 remove_proc_entry("assocs", proc_net_sctp);
385 } 383 }
386 384