Commit 160f17e345f5b50484d6cdc985b8686a05bf015d
Committed by
David S. Miller
1 parent
25296d599c
Exists in
master
and in
7 other branches
[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
net/sctp/objcnt.c
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 |
net/sctp/proc.c
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 |