diff options
Diffstat (limited to 'net/x25/x25_proc.c')
-rw-r--r-- | net/x25/x25_proc.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c index a11837d361d2..e0470bd8c2f9 100644 --- a/net/x25/x25_proc.c +++ b/net/x25/x25_proc.c | |||
@@ -165,6 +165,75 @@ out: | |||
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | 167 | ||
168 | static __inline__ struct x25_forward *x25_get_forward_idx(loff_t pos) | ||
169 | { | ||
170 | struct x25_forward *f; | ||
171 | struct list_head *entry; | ||
172 | |||
173 | list_for_each(entry, &x25_forward_list) { | ||
174 | f = list_entry(entry, struct x25_forward, node); | ||
175 | if (!pos--) | ||
176 | goto found; | ||
177 | } | ||
178 | |||
179 | f = NULL; | ||
180 | found: | ||
181 | return f; | ||
182 | } | ||
183 | |||
184 | static void *x25_seq_forward_start(struct seq_file *seq, loff_t *pos) | ||
185 | { | ||
186 | loff_t l = *pos; | ||
187 | |||
188 | read_lock_bh(&x25_forward_list_lock); | ||
189 | return l ? x25_get_forward_idx(--l) : SEQ_START_TOKEN; | ||
190 | } | ||
191 | |||
192 | static void *x25_seq_forward_next(struct seq_file *seq, void *v, loff_t *pos) | ||
193 | { | ||
194 | struct x25_forward *f; | ||
195 | |||
196 | ++*pos; | ||
197 | if (v == SEQ_START_TOKEN) { | ||
198 | f = NULL; | ||
199 | if (!list_empty(&x25_forward_list)) | ||
200 | f = list_entry(x25_forward_list.next, | ||
201 | struct x25_forward, node); | ||
202 | goto out; | ||
203 | } | ||
204 | f = v; | ||
205 | if (f->node.next != &x25_forward_list) | ||
206 | f = list_entry(f->node.next, struct x25_forward, node); | ||
207 | else | ||
208 | f = NULL; | ||
209 | out: | ||
210 | return f; | ||
211 | |||
212 | } | ||
213 | |||
214 | static void x25_seq_forward_stop(struct seq_file *seq, void *v) | ||
215 | { | ||
216 | read_unlock_bh(&x25_forward_list_lock); | ||
217 | } | ||
218 | |||
219 | static int x25_seq_forward_show(struct seq_file *seq, void *v) | ||
220 | { | ||
221 | struct x25_forward *f; | ||
222 | |||
223 | if (v == SEQ_START_TOKEN) { | ||
224 | seq_printf(seq, "lci dev1 dev2\n"); | ||
225 | goto out; | ||
226 | } | ||
227 | |||
228 | f = v; | ||
229 | |||
230 | seq_printf(seq, "%d %-10s %-10s\n", | ||
231 | f->lci, f->dev1->name, f->dev2->name); | ||
232 | |||
233 | out: | ||
234 | return 0; | ||
235 | } | ||
236 | |||
168 | static struct seq_operations x25_seq_route_ops = { | 237 | static struct seq_operations x25_seq_route_ops = { |
169 | .start = x25_seq_route_start, | 238 | .start = x25_seq_route_start, |
170 | .next = x25_seq_route_next, | 239 | .next = x25_seq_route_next, |
@@ -179,6 +248,13 @@ static struct seq_operations x25_seq_socket_ops = { | |||
179 | .show = x25_seq_socket_show, | 248 | .show = x25_seq_socket_show, |
180 | }; | 249 | }; |
181 | 250 | ||
251 | static struct seq_operations x25_seq_forward_ops = { | ||
252 | .start = x25_seq_forward_start, | ||
253 | .next = x25_seq_forward_next, | ||
254 | .stop = x25_seq_forward_stop, | ||
255 | .show = x25_seq_forward_show, | ||
256 | }; | ||
257 | |||
182 | static int x25_seq_socket_open(struct inode *inode, struct file *file) | 258 | static int x25_seq_socket_open(struct inode *inode, struct file *file) |
183 | { | 259 | { |
184 | return seq_open(file, &x25_seq_socket_ops); | 260 | return seq_open(file, &x25_seq_socket_ops); |
@@ -189,6 +265,11 @@ static int x25_seq_route_open(struct inode *inode, struct file *file) | |||
189 | return seq_open(file, &x25_seq_route_ops); | 265 | return seq_open(file, &x25_seq_route_ops); |
190 | } | 266 | } |
191 | 267 | ||
268 | static int x25_seq_forward_open(struct inode *inode, struct file *file) | ||
269 | { | ||
270 | return seq_open(file, &x25_seq_forward_ops); | ||
271 | } | ||
272 | |||
192 | static struct file_operations x25_seq_socket_fops = { | 273 | static struct file_operations x25_seq_socket_fops = { |
193 | .owner = THIS_MODULE, | 274 | .owner = THIS_MODULE, |
194 | .open = x25_seq_socket_open, | 275 | .open = x25_seq_socket_open, |
@@ -205,6 +286,14 @@ static struct file_operations x25_seq_route_fops = { | |||
205 | .release = seq_release, | 286 | .release = seq_release, |
206 | }; | 287 | }; |
207 | 288 | ||
289 | static struct file_operations x25_seq_forward_fops = { | ||
290 | .owner = THIS_MODULE, | ||
291 | .open = x25_seq_forward_open, | ||
292 | .read = seq_read, | ||
293 | .llseek = seq_lseek, | ||
294 | .release = seq_release, | ||
295 | }; | ||
296 | |||
208 | static struct proc_dir_entry *x25_proc_dir; | 297 | static struct proc_dir_entry *x25_proc_dir; |
209 | 298 | ||
210 | int __init x25_proc_init(void) | 299 | int __init x25_proc_init(void) |
@@ -225,9 +314,17 @@ int __init x25_proc_init(void) | |||
225 | if (!p) | 314 | if (!p) |
226 | goto out_socket; | 315 | goto out_socket; |
227 | p->proc_fops = &x25_seq_socket_fops; | 316 | p->proc_fops = &x25_seq_socket_fops; |
317 | |||
318 | p = create_proc_entry("forward", S_IRUGO, x25_proc_dir); | ||
319 | if (!p) | ||
320 | goto out_forward; | ||
321 | p->proc_fops = &x25_seq_forward_fops; | ||
228 | rc = 0; | 322 | rc = 0; |
323 | |||
229 | out: | 324 | out: |
230 | return rc; | 325 | return rc; |
326 | out_forward: | ||
327 | remove_proc_entry("socket", x25_proc_dir); | ||
231 | out_socket: | 328 | out_socket: |
232 | remove_proc_entry("route", x25_proc_dir); | 329 | remove_proc_entry("route", x25_proc_dir); |
233 | out_route: | 330 | out_route: |
@@ -237,6 +334,7 @@ out_route: | |||
237 | 334 | ||
238 | void __exit x25_proc_exit(void) | 335 | void __exit x25_proc_exit(void) |
239 | { | 336 | { |
337 | remove_proc_entry("forward", x25_proc_dir); | ||
240 | remove_proc_entry("route", x25_proc_dir); | 338 | remove_proc_entry("route", x25_proc_dir); |
241 | remove_proc_entry("socket", x25_proc_dir); | 339 | remove_proc_entry("socket", x25_proc_dir); |
242 | remove_proc_entry("x25", proc_net); | 340 | remove_proc_entry("x25", proc_net); |