linux/net/x25/x25_proc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *      X.25 Packet Layer release 002
   4 *
   5 *      This is ALPHA test software. This code may break your machine,
   6 *      randomly fail to work with new releases, misbehave and/or generally
   7 *      screw up. It might even work.
   8 *
   9 *      This code REQUIRES 2.4 with seq_file support
  10 *
  11 *      History
  12 *      2002/10/06      Arnaldo Carvalho de Melo  seq_file support
  13 */
  14
  15#include <linux/init.h>
  16#include <linux/proc_fs.h>
  17#include <linux/seq_file.h>
  18#include <linux/export.h>
  19#include <net/net_namespace.h>
  20#include <net/sock.h>
  21#include <net/x25.h>
  22
  23#ifdef CONFIG_PROC_FS
  24
  25static void *x25_seq_route_start(struct seq_file *seq, loff_t *pos)
  26        __acquires(x25_route_list_lock)
  27{
  28        read_lock_bh(&x25_route_list_lock);
  29        return seq_list_start_head(&x25_route_list, *pos);
  30}
  31
  32static void *x25_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
  33{
  34        return seq_list_next(v, &x25_route_list, pos);
  35}
  36
  37static void x25_seq_route_stop(struct seq_file *seq, void *v)
  38        __releases(x25_route_list_lock)
  39{
  40        read_unlock_bh(&x25_route_list_lock);
  41}
  42
  43static int x25_seq_route_show(struct seq_file *seq, void *v)
  44{
  45        struct x25_route *rt = list_entry(v, struct x25_route, node);
  46
  47        if (v == &x25_route_list) {
  48                seq_puts(seq, "Address          Digits  Device\n");
  49                goto out;
  50        }
  51
  52        rt = v;
  53        seq_printf(seq, "%-15s  %-6d  %-5s\n",
  54                   rt->address.x25_addr, rt->sigdigits,
  55                   rt->dev ? rt->dev->name : "???");
  56out:
  57        return 0;
  58}
  59
  60static void *x25_seq_socket_start(struct seq_file *seq, loff_t *pos)
  61        __acquires(x25_list_lock)
  62{
  63        read_lock_bh(&x25_list_lock);
  64        return seq_hlist_start_head(&x25_list, *pos);
  65}
  66
  67static void *x25_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
  68{
  69        return seq_hlist_next(v, &x25_list, pos);
  70}
  71
  72static void x25_seq_socket_stop(struct seq_file *seq, void *v)
  73        __releases(x25_list_lock)
  74{
  75        read_unlock_bh(&x25_list_lock);
  76}
  77
  78static int x25_seq_socket_show(struct seq_file *seq, void *v)
  79{
  80        struct sock *s;
  81        struct x25_sock *x25;
  82        struct net_device *dev;
  83        const char *devname;
  84
  85        if (v == SEQ_START_TOKEN) {
  86                seq_printf(seq, "dest_addr  src_addr   dev   lci st vs vr "
  87                                "va   t  t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
  88                goto out;
  89        }
  90
  91        s = sk_entry(v);
  92        x25 = x25_sk(s);
  93
  94        if (!x25->neighbour || (dev = x25->neighbour->dev) == NULL)
  95                devname = "???";
  96        else
  97                devname = x25->neighbour->dev->name;
  98
  99        seq_printf(seq, "%-10s %-10s %-5s %3.3X  %d  %d  %d  %d %3lu %3lu "
 100                        "%3lu %3lu %3lu %5d %5d %ld\n",
 101                   !x25->dest_addr.x25_addr[0] ? "*" : x25->dest_addr.x25_addr,
 102                   !x25->source_addr.x25_addr[0] ? "*" : x25->source_addr.x25_addr,
 103                   devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr,
 104                   x25->va, x25_display_timer(s) / HZ, x25->t2  / HZ,
 105                   x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ,
 106                   sk_wmem_alloc_get(s),
 107                   sk_rmem_alloc_get(s),
 108                   s->sk_socket ? SOCK_INODE(s->sk_socket)->i_ino : 0L);
 109out:
 110        return 0;
 111}
 112
 113static void *x25_seq_forward_start(struct seq_file *seq, loff_t *pos)
 114        __acquires(x25_forward_list_lock)
 115{
 116        read_lock_bh(&x25_forward_list_lock);
 117        return seq_list_start_head(&x25_forward_list, *pos);
 118}
 119
 120static void *x25_seq_forward_next(struct seq_file *seq, void *v, loff_t *pos)
 121{
 122        return seq_list_next(v, &x25_forward_list, pos);
 123}
 124
 125static void x25_seq_forward_stop(struct seq_file *seq, void *v)
 126        __releases(x25_forward_list_lock)
 127{
 128        read_unlock_bh(&x25_forward_list_lock);
 129}
 130
 131static int x25_seq_forward_show(struct seq_file *seq, void *v)
 132{
 133        struct x25_forward *f = list_entry(v, struct x25_forward, node);
 134
 135        if (v == &x25_forward_list) {
 136                seq_printf(seq, "lci dev1       dev2\n");
 137                goto out;
 138        }
 139
 140        f = v;
 141
 142        seq_printf(seq, "%d %-10s %-10s\n",
 143                        f->lci, f->dev1->name, f->dev2->name);
 144out:
 145        return 0;
 146}
 147
 148static const struct seq_operations x25_seq_route_ops = {
 149        .start  = x25_seq_route_start,
 150        .next   = x25_seq_route_next,
 151        .stop   = x25_seq_route_stop,
 152        .show   = x25_seq_route_show,
 153};
 154
 155static const struct seq_operations x25_seq_socket_ops = {
 156        .start  = x25_seq_socket_start,
 157        .next   = x25_seq_socket_next,
 158        .stop   = x25_seq_socket_stop,
 159        .show   = x25_seq_socket_show,
 160};
 161
 162static const struct seq_operations x25_seq_forward_ops = {
 163        .start  = x25_seq_forward_start,
 164        .next   = x25_seq_forward_next,
 165        .stop   = x25_seq_forward_stop,
 166        .show   = x25_seq_forward_show,
 167};
 168
 169int __init x25_proc_init(void)
 170{
 171        if (!proc_mkdir("x25", init_net.proc_net))
 172                return -ENOMEM;
 173
 174        if (!proc_create_seq("x25/route", 0444, init_net.proc_net,
 175                         &x25_seq_route_ops))
 176                goto out;
 177
 178        if (!proc_create_seq("x25/socket", 0444, init_net.proc_net,
 179                         &x25_seq_socket_ops))
 180                goto out;
 181
 182        if (!proc_create_seq("x25/forward", 0444, init_net.proc_net,
 183                         &x25_seq_forward_ops))
 184                goto out;
 185        return 0;
 186
 187out:
 188        remove_proc_subtree("x25", init_net.proc_net);
 189        return -ENOMEM;
 190}
 191
 192void __exit x25_proc_exit(void)
 193{
 194        remove_proc_subtree("x25", init_net.proc_net);
 195}
 196
 197#else /* CONFIG_PROC_FS */
 198
 199int __init x25_proc_init(void)
 200{
 201        return 0;
 202}
 203
 204void __exit x25_proc_exit(void)
 205{
 206}
 207#endif /* CONFIG_PROC_FS */
 208