1ee5d8f4dSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * X.25 Packet Layer release 002
41da177e4SLinus Torvalds *
51da177e4SLinus Torvalds * This is ALPHA test software. This code may break your machine,
61da177e4SLinus Torvalds * randomly fail to work with new releases, misbehave and/or generally
71da177e4SLinus Torvalds * screw up. It might even work.
81da177e4SLinus Torvalds *
91da177e4SLinus Torvalds * This code REQUIRES 2.4 with seq_file support
101da177e4SLinus Torvalds *
111da177e4SLinus Torvalds * History
121da177e4SLinus Torvalds * 2002/10/06 Arnaldo Carvalho de Melo seq_file support
131da177e4SLinus Torvalds */
141da177e4SLinus Torvalds
151da177e4SLinus Torvalds #include <linux/init.h>
161da177e4SLinus Torvalds #include <linux/proc_fs.h>
171da177e4SLinus Torvalds #include <linux/seq_file.h>
18bc3b2d7fSPaul Gortmaker #include <linux/export.h>
19457c4cbcSEric W. Biederman #include <net/net_namespace.h>
201da177e4SLinus Torvalds #include <net/sock.h>
211da177e4SLinus Torvalds #include <net/x25.h>
221da177e4SLinus Torvalds
231da177e4SLinus Torvalds #ifdef CONFIG_PROC_FS
241da177e4SLinus Torvalds
x25_seq_route_start(struct seq_file * seq,loff_t * pos)251da177e4SLinus Torvalds static void *x25_seq_route_start(struct seq_file *seq, loff_t *pos)
266bf1574eSEric Dumazet __acquires(x25_route_list_lock)
271da177e4SLinus Torvalds {
281da177e4SLinus Torvalds read_lock_bh(&x25_route_list_lock);
294f134204SLi Zefan return seq_list_start_head(&x25_route_list, *pos);
301da177e4SLinus Torvalds }
311da177e4SLinus Torvalds
x25_seq_route_next(struct seq_file * seq,void * v,loff_t * pos)321da177e4SLinus Torvalds static void *x25_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
331da177e4SLinus Torvalds {
344f134204SLi Zefan return seq_list_next(v, &x25_route_list, pos);
351da177e4SLinus Torvalds }
361da177e4SLinus Torvalds
x25_seq_route_stop(struct seq_file * seq,void * v)371da177e4SLinus Torvalds static void x25_seq_route_stop(struct seq_file *seq, void *v)
386bf1574eSEric Dumazet __releases(x25_route_list_lock)
391da177e4SLinus Torvalds {
401da177e4SLinus Torvalds read_unlock_bh(&x25_route_list_lock);
411da177e4SLinus Torvalds }
421da177e4SLinus Torvalds
x25_seq_route_show(struct seq_file * seq,void * v)431da177e4SLinus Torvalds static int x25_seq_route_show(struct seq_file *seq, void *v)
441da177e4SLinus Torvalds {
454f134204SLi Zefan struct x25_route *rt = list_entry(v, struct x25_route, node);
461da177e4SLinus Torvalds
474f134204SLi Zefan if (v == &x25_route_list) {
481da177e4SLinus Torvalds seq_puts(seq, "Address Digits Device\n");
491da177e4SLinus Torvalds goto out;
501da177e4SLinus Torvalds }
511da177e4SLinus Torvalds
521da177e4SLinus Torvalds rt = v;
531da177e4SLinus Torvalds seq_printf(seq, "%-15s %-6d %-5s\n",
541da177e4SLinus Torvalds rt->address.x25_addr, rt->sigdigits,
551da177e4SLinus Torvalds rt->dev ? rt->dev->name : "???");
561da177e4SLinus Torvalds out:
571da177e4SLinus Torvalds return 0;
581da177e4SLinus Torvalds }
591da177e4SLinus Torvalds
x25_seq_socket_start(struct seq_file * seq,loff_t * pos)601da177e4SLinus Torvalds static void *x25_seq_socket_start(struct seq_file *seq, loff_t *pos)
616bf1574eSEric Dumazet __acquires(x25_list_lock)
621da177e4SLinus Torvalds {
631da177e4SLinus Torvalds read_lock_bh(&x25_list_lock);
6432d2e3a1SLi Zefan return seq_hlist_start_head(&x25_list, *pos);
651da177e4SLinus Torvalds }
661da177e4SLinus Torvalds
x25_seq_socket_next(struct seq_file * seq,void * v,loff_t * pos)671da177e4SLinus Torvalds static void *x25_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
681da177e4SLinus Torvalds {
6932d2e3a1SLi Zefan return seq_hlist_next(v, &x25_list, pos);
701da177e4SLinus Torvalds }
711da177e4SLinus Torvalds
x25_seq_socket_stop(struct seq_file * seq,void * v)721da177e4SLinus Torvalds static void x25_seq_socket_stop(struct seq_file *seq, void *v)
736bf1574eSEric Dumazet __releases(x25_list_lock)
741da177e4SLinus Torvalds {
751da177e4SLinus Torvalds read_unlock_bh(&x25_list_lock);
761da177e4SLinus Torvalds }
771da177e4SLinus Torvalds
x25_seq_socket_show(struct seq_file * seq,void * v)781da177e4SLinus Torvalds static int x25_seq_socket_show(struct seq_file *seq, void *v)
791da177e4SLinus Torvalds {
801da177e4SLinus Torvalds struct sock *s;
811da177e4SLinus Torvalds struct x25_sock *x25;
821da177e4SLinus Torvalds const char *devname;
831da177e4SLinus Torvalds
841da177e4SLinus Torvalds if (v == SEQ_START_TOKEN) {
851da177e4SLinus Torvalds seq_printf(seq, "dest_addr src_addr dev lci st vs vr "
861da177e4SLinus Torvalds "va t t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
871da177e4SLinus Torvalds goto out;
881da177e4SLinus Torvalds }
891da177e4SLinus Torvalds
9032d2e3a1SLi Zefan s = sk_entry(v);
911da177e4SLinus Torvalds x25 = x25_sk(s);
921da177e4SLinus Torvalds
93*ecd17a87SColin Ian King if (!x25->neighbour || !x25->neighbour->dev)
941da177e4SLinus Torvalds devname = "???";
951da177e4SLinus Torvalds else
961da177e4SLinus Torvalds devname = x25->neighbour->dev->name;
971da177e4SLinus Torvalds
981da177e4SLinus Torvalds seq_printf(seq, "%-10s %-10s %-5s %3.3X %d %d %d %d %3lu %3lu "
991da177e4SLinus Torvalds "%3lu %3lu %3lu %5d %5d %ld\n",
1001da177e4SLinus Torvalds !x25->dest_addr.x25_addr[0] ? "*" : x25->dest_addr.x25_addr,
1011da177e4SLinus Torvalds !x25->source_addr.x25_addr[0] ? "*" : x25->source_addr.x25_addr,
1021da177e4SLinus Torvalds devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr,
1031da177e4SLinus Torvalds x25->va, x25_display_timer(s) / HZ, x25->t2 / HZ,
1041da177e4SLinus Torvalds x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ,
10531e6d363SEric Dumazet sk_wmem_alloc_get(s),
10631e6d363SEric Dumazet sk_rmem_alloc_get(s),
1071da177e4SLinus Torvalds s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L);
1081da177e4SLinus Torvalds out:
1091da177e4SLinus Torvalds return 0;
1101da177e4SLinus Torvalds }
1111da177e4SLinus Torvalds
x25_seq_forward_start(struct seq_file * seq,loff_t * pos)112c9c2e9dcSAndrew Hendry static void *x25_seq_forward_start(struct seq_file *seq, loff_t *pos)
1136bf1574eSEric Dumazet __acquires(x25_forward_list_lock)
114c9c2e9dcSAndrew Hendry {
115c9c2e9dcSAndrew Hendry read_lock_bh(&x25_forward_list_lock);
1164f134204SLi Zefan return seq_list_start_head(&x25_forward_list, *pos);
117c9c2e9dcSAndrew Hendry }
118c9c2e9dcSAndrew Hendry
x25_seq_forward_next(struct seq_file * seq,void * v,loff_t * pos)119c9c2e9dcSAndrew Hendry static void *x25_seq_forward_next(struct seq_file *seq, void *v, loff_t *pos)
120c9c2e9dcSAndrew Hendry {
1214f134204SLi Zefan return seq_list_next(v, &x25_forward_list, pos);
122c9c2e9dcSAndrew Hendry }
123c9c2e9dcSAndrew Hendry
x25_seq_forward_stop(struct seq_file * seq,void * v)124c9c2e9dcSAndrew Hendry static void x25_seq_forward_stop(struct seq_file *seq, void *v)
1256bf1574eSEric Dumazet __releases(x25_forward_list_lock)
126c9c2e9dcSAndrew Hendry {
127c9c2e9dcSAndrew Hendry read_unlock_bh(&x25_forward_list_lock);
128c9c2e9dcSAndrew Hendry }
129c9c2e9dcSAndrew Hendry
x25_seq_forward_show(struct seq_file * seq,void * v)130c9c2e9dcSAndrew Hendry static int x25_seq_forward_show(struct seq_file *seq, void *v)
131c9c2e9dcSAndrew Hendry {
1324f134204SLi Zefan struct x25_forward *f = list_entry(v, struct x25_forward, node);
133c9c2e9dcSAndrew Hendry
1344f134204SLi Zefan if (v == &x25_forward_list) {
135c9c2e9dcSAndrew Hendry seq_printf(seq, "lci dev1 dev2\n");
136c9c2e9dcSAndrew Hendry goto out;
137c9c2e9dcSAndrew Hendry }
138c9c2e9dcSAndrew Hendry
139c9c2e9dcSAndrew Hendry f = v;
140c9c2e9dcSAndrew Hendry
141c9c2e9dcSAndrew Hendry seq_printf(seq, "%d %-10s %-10s\n",
142c9c2e9dcSAndrew Hendry f->lci, f->dev1->name, f->dev2->name);
143c9c2e9dcSAndrew Hendry out:
144c9c2e9dcSAndrew Hendry return 0;
145c9c2e9dcSAndrew Hendry }
146c9c2e9dcSAndrew Hendry
14756b3d975SPhilippe De Muyter static const struct seq_operations x25_seq_route_ops = {
1481da177e4SLinus Torvalds .start = x25_seq_route_start,
1491da177e4SLinus Torvalds .next = x25_seq_route_next,
1501da177e4SLinus Torvalds .stop = x25_seq_route_stop,
1511da177e4SLinus Torvalds .show = x25_seq_route_show,
1521da177e4SLinus Torvalds };
1531da177e4SLinus Torvalds
15456b3d975SPhilippe De Muyter static const struct seq_operations x25_seq_socket_ops = {
1551da177e4SLinus Torvalds .start = x25_seq_socket_start,
1561da177e4SLinus Torvalds .next = x25_seq_socket_next,
1571da177e4SLinus Torvalds .stop = x25_seq_socket_stop,
1581da177e4SLinus Torvalds .show = x25_seq_socket_show,
1591da177e4SLinus Torvalds };
1601da177e4SLinus Torvalds
16156b3d975SPhilippe De Muyter static const struct seq_operations x25_seq_forward_ops = {
162c9c2e9dcSAndrew Hendry .start = x25_seq_forward_start,
163c9c2e9dcSAndrew Hendry .next = x25_seq_forward_next,
164c9c2e9dcSAndrew Hendry .stop = x25_seq_forward_stop,
165c9c2e9dcSAndrew Hendry .show = x25_seq_forward_show,
166c9c2e9dcSAndrew Hendry };
167c9c2e9dcSAndrew Hendry
x25_proc_init(void)1681da177e4SLinus Torvalds int __init x25_proc_init(void)
1691da177e4SLinus Torvalds {
170345566bdSAl Viro if (!proc_mkdir("x25", init_net.proc_net))
171345566bdSAl Viro return -ENOMEM;
1721da177e4SLinus Torvalds
173fddda2b7SChristoph Hellwig if (!proc_create_seq("x25/route", 0444, init_net.proc_net,
174fddda2b7SChristoph Hellwig &x25_seq_route_ops))
1751da177e4SLinus Torvalds goto out;
1761da177e4SLinus Torvalds
177fddda2b7SChristoph Hellwig if (!proc_create_seq("x25/socket", 0444, init_net.proc_net,
178fddda2b7SChristoph Hellwig &x25_seq_socket_ops))
179345566bdSAl Viro goto out;
1801da177e4SLinus Torvalds
181fddda2b7SChristoph Hellwig if (!proc_create_seq("x25/forward", 0444, init_net.proc_net,
182fddda2b7SChristoph Hellwig &x25_seq_forward_ops))
183345566bdSAl Viro goto out;
184345566bdSAl Viro return 0;
185c9c2e9dcSAndrew Hendry
1861da177e4SLinus Torvalds out:
187345566bdSAl Viro remove_proc_subtree("x25", init_net.proc_net);
188345566bdSAl Viro return -ENOMEM;
1891da177e4SLinus Torvalds }
1901da177e4SLinus Torvalds
x25_proc_exit(void)1911da177e4SLinus Torvalds void __exit x25_proc_exit(void)
1921da177e4SLinus Torvalds {
193345566bdSAl Viro remove_proc_subtree("x25", init_net.proc_net);
1941da177e4SLinus Torvalds }
1951da177e4SLinus Torvalds
1961da177e4SLinus Torvalds #else /* CONFIG_PROC_FS */
1971da177e4SLinus Torvalds
x25_proc_init(void)1981da177e4SLinus Torvalds int __init x25_proc_init(void)
1991da177e4SLinus Torvalds {
2001da177e4SLinus Torvalds return 0;
2011da177e4SLinus Torvalds }
2021da177e4SLinus Torvalds
x25_proc_exit(void)2031da177e4SLinus Torvalds void __exit x25_proc_exit(void)
2041da177e4SLinus Torvalds {
2051da177e4SLinus Torvalds }
2061da177e4SLinus Torvalds #endif /* CONFIG_PROC_FS */
207