Blame view

net/llc/llc_proc.c 6.6 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
10
11
12
13
  /*
   * proc_llc.c - proc interface for LLC
   *
   * Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
   *		 2002-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   *
   * This program can be redistributed or modified under the terms of the
   * GNU General Public License as published by the Free Software Foundation.
   * This program is distributed without any warranty or implied warranty
   * of merchantability or fitness for a particular purpose.
   *
   * See the GNU General Public License for more details.
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
14
15
16
17
18
  #include <linux/init.h>
  #include <linux/kernel.h>
  #include <linux/proc_fs.h>
  #include <linux/errno.h>
  #include <linux/seq_file.h>
bc3b2d7fb   Paul Gortmaker   net: Add export.h...
19
  #include <linux/export.h>
457c4cbc5   Eric W. Biederman   [NET]: Make /proc...
20
  #include <net/net_namespace.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
23
24
25
26
  #include <net/sock.h>
  #include <net/llc.h>
  #include <net/llc_c_ac.h>
  #include <net/llc_c_ev.h>
  #include <net/llc_c_st.h>
  #include <net/llc_conn.h>
0795af572   Joe Perches   [NET]: Introduce ...
27
  static void llc_ui_format_mac(struct seq_file *seq, u8 *addr)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
  {
e174961ca   Johannes Berg   net: convert prin...
29
  	seq_printf(seq, "%pM", addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
31
32
33
  }
  
  static struct sock *llc_get_sk_idx(loff_t pos)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
34
  	struct llc_sap *sap;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
  	struct sock *sk = NULL;
52d58aef5   Octavian Purdila   llc: replace the ...
36
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37

8beb9ab6c   Octavian Purdila   llc: convert llc_...
38
  	list_for_each_entry_rcu(sap, &llc_sap_list, node) {
b76f5a842   Octavian Purdila   llc: convert the ...
39
  		spin_lock_bh(&sap->sk_lock);
52d58aef5   Octavian Purdila   llc: replace the ...
40
41
42
43
44
45
46
47
48
  		for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++) {
  			struct hlist_nulls_head *head = &sap->sk_laddr_hash[i];
  			struct hlist_nulls_node *node;
  
  			sk_nulls_for_each(sk, node, head) {
  				if (!pos)
  					goto found; /* keep the lock */
  				--pos;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
  		}
b76f5a842   Octavian Purdila   llc: convert the ...
50
  		spin_unlock_bh(&sap->sk_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
53
54
55
56
57
58
59
  	}
  	sk = NULL;
  found:
  	return sk;
  }
  
  static void *llc_seq_start(struct seq_file *seq, loff_t *pos)
  {
  	loff_t l = *pos;
8beb9ab6c   Octavian Purdila   llc: convert llc_...
60
  	rcu_read_lock_bh();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
  	return l ? llc_get_sk_idx(--l) : SEQ_START_TOKEN;
  }
52d58aef5   Octavian Purdila   llc: replace the ...
63
64
65
66
67
68
69
70
71
72
73
74
  static struct sock *laddr_hash_next(struct llc_sap *sap, int bucket)
  {
  	struct hlist_nulls_node *node;
  	struct sock *sk = NULL;
  
  	while (++bucket < LLC_SK_LADDR_HASH_ENTRIES)
  		sk_nulls_for_each(sk, node, &sap->sk_laddr_hash[bucket])
  			goto out;
  
  out:
  	return sk;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
76
77
78
79
80
81
82
83
84
85
86
  static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
  {
  	struct sock* sk, *next;
  	struct llc_sock *llc;
  	struct llc_sap *sap;
  
  	++*pos;
  	if (v == SEQ_START_TOKEN) {
  		sk = llc_get_sk_idx(0);
  		goto out;
  	}
  	sk = v;
b76f5a842   Octavian Purdila   llc: convert the ...
87
  	next = sk_nulls_next(sk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
89
90
91
92
93
  	if (next) {
  		sk = next;
  		goto out;
  	}
  	llc = llc_sk(sk);
  	sap = llc->sap;
52d58aef5   Octavian Purdila   llc: replace the ...
94
95
96
  	sk = laddr_hash_next(sap, llc_sk_laddr_hashfn(sap, &llc->laddr));
  	if (sk)
  		goto out;
b76f5a842   Octavian Purdila   llc: convert the ...
97
  	spin_unlock_bh(&sap->sk_lock);
8beb9ab6c   Octavian Purdila   llc: convert llc_...
98
  	list_for_each_entry_continue_rcu(sap, &llc_sap_list, node) {
b76f5a842   Octavian Purdila   llc: convert the ...
99
  		spin_lock_bh(&sap->sk_lock);
52d58aef5   Octavian Purdila   llc: replace the ...
100
101
102
  		sk = laddr_hash_next(sap, -1);
  		if (sk)
  			break; /* keep the lock */
b76f5a842   Octavian Purdila   llc: convert the ...
103
  		spin_unlock_bh(&sap->sk_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
105
106
107
108
109
110
111
112
113
114
  	}
  out:
  	return sk;
  }
  
  static void llc_seq_stop(struct seq_file *seq, void *v)
  {
  	if (v && v != SEQ_START_TOKEN) {
  		struct sock *sk = v;
  		struct llc_sock *llc = llc_sk(sk);
  		struct llc_sap *sap = llc->sap;
b76f5a842   Octavian Purdila   llc: convert the ...
115
  		spin_unlock_bh(&sap->sk_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
  	}
8beb9ab6c   Octavian Purdila   llc: convert llc_...
117
  	rcu_read_unlock_bh();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
  }
  
  static int llc_seq_socket_show(struct seq_file *seq, void *v)
  {
  	struct sock* sk;
  	struct llc_sock *llc;
  
  	if (v == SEQ_START_TOKEN) {
  		seq_puts(seq, "SKt Mc local_mac_sap        remote_mac_sap   "
  			      "    tx_queue rx_queue st uid link
  ");
  		goto out;
  	}
  	sk = v;
  	llc = llc_sk(sk);
  
  	/* FIXME: check if the address is multicast */
  	seq_printf(seq, "%2X  %2X ", sk->sk_type, 0);
  
  	if (llc->dev)
  		llc_ui_format_mac(seq, llc->dev->dev_addr);
0795af572   Joe Perches   [NET]: Introduce ...
139
140
141
142
  	else {
  		u8 addr[6] = {0,0,0,0,0,0};
  		llc_ui_format_mac(seq, addr);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
144
  	seq_printf(seq, "@%02X ", llc->sap->laddr.lsap);
  	llc_ui_format_mac(seq, llc->daddr.mac);
d14c5ab6b   Francesco Fusco   net: proc_fs: tri...
145
146
  	seq_printf(seq, "@%02X %8d %8d %2d %3u %4d
  ", llc->daddr.lsap,
31e6d363a   Eric Dumazet   net: correct off-...
147
148
  		   sk_wmem_alloc_get(sk),
  		   sk_rmem_alloc_get(sk) - llc->copied_seq,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
149
  		   sk->sk_state,
a7cb5a49b   Eric W. Biederman   userns: Print out...
150
  		   from_kuid_munged(seq_user_ns(seq), sock_i_uid(sk)),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
154
  		   llc->link);
  out:
  	return 0;
  }
36cbd3dcc   Jan Engelhardt   net: mark read-on...
155
  static const char *const llc_conn_state_names[] = {
d57b1869b   YOSHIFUJI Hideaki   [NET] LLC: Fix wh...
156
157
  	[LLC_CONN_STATE_ADM] =        "adm",
  	[LLC_CONN_STATE_SETUP] =      "setup",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  	[LLC_CONN_STATE_NORMAL] =     "normal",
d57b1869b   YOSHIFUJI Hideaki   [NET] LLC: Fix wh...
159
160
161
  	[LLC_CONN_STATE_BUSY] =       "busy",
  	[LLC_CONN_STATE_REJ] =        "rej",
  	[LLC_CONN_STATE_AWAIT] =      "await",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
163
164
  	[LLC_CONN_STATE_AWAIT_BUSY] = "await_busy",
  	[LLC_CONN_STATE_AWAIT_REJ] =  "await_rej",
  	[LLC_CONN_STATE_D_CONN]	=     "d_conn",
d57b1869b   YOSHIFUJI Hideaki   [NET] LLC: Fix wh...
165
166
167
  	[LLC_CONN_STATE_RESET] =      "reset",
  	[LLC_CONN_STATE_ERROR] =      "error",
  	[LLC_CONN_STATE_TEMP] =       "temp",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  };
  
  static int llc_seq_core_show(struct seq_file *seq, void *v)
  {
  	struct sock* sk;
  	struct llc_sock *llc;
  
  	if (v == SEQ_START_TOKEN) {
  		seq_puts(seq, "Connection list:
  "
  			      "dsap state      retr txw rxw pf ff sf df rs cs "
  			      "tack tpfc trs tbs blog busr
  ");
  		goto out;
  	}
  	sk = v;
  	llc = llc_sk(sk);
  
  	seq_printf(seq, " %02X  %-10s %3d  %3d %3d %2d %2d %2d %2d %2d %2d "
  			"%4d %4d %3d %3d %4d %4d
  ",
  		   llc->daddr.lsap, llc_conn_state_names[llc->state],
  		   llc->retry_count, llc->k, llc->rw, llc->p_flag, llc->f_flag,
  		   llc->s_flag, llc->data_flag, llc->remote_busy_flag,
  		   llc->cause_flag, timer_pending(&llc->ack_timer.timer),
  		   timer_pending(&llc->pf_cycle_timer.timer),
  		   timer_pending(&llc->rej_sent_timer.timer),
  		   timer_pending(&llc->busy_state_timer.timer),
fafc4e1ea   Hannes Frederic Sowa   sock: tigthen loc...
196
  		   !!sk->sk_backlog.tail, !!sk->sk_lock.owned);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
198
199
  out:
  	return 0;
  }
56b3d975b   Philippe De Muyter   [NET]: Make all i...
200
  static const struct seq_operations llc_seq_socket_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
203
204
205
  	.start  = llc_seq_start,
  	.next   = llc_seq_next,
  	.stop   = llc_seq_stop,
  	.show   = llc_seq_socket_show,
  };
56b3d975b   Philippe De Muyter   [NET]: Make all i...
206
  static const struct seq_operations llc_seq_core_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
  	.start  = llc_seq_start,
  	.next   = llc_seq_next,
  	.stop   = llc_seq_stop,
  	.show   = llc_seq_core_show,
  };
  
  static int llc_seq_socket_open(struct inode *inode, struct file *file)
  {
  	return seq_open(file, &llc_seq_socket_ops);
  }
  
  static int llc_seq_core_open(struct inode *inode, struct file *file)
  {
  	return seq_open(file, &llc_seq_core_ops);
  }
da7071d7e   Arjan van de Ven   [PATCH] mark stru...
222
  static const struct file_operations llc_seq_socket_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223
224
225
226
227
228
  	.owner		= THIS_MODULE,
  	.open		= llc_seq_socket_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= seq_release,
  };
da7071d7e   Arjan van de Ven   [PATCH] mark stru...
229
  static const struct file_operations llc_seq_core_fops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
232
233
234
235
236
237
238
239
240
241
242
  	.owner		= THIS_MODULE,
  	.open		= llc_seq_core_open,
  	.read		= seq_read,
  	.llseek		= seq_lseek,
  	.release	= seq_release,
  };
  
  static struct proc_dir_entry *llc_proc_dir;
  
  int __init llc_proc_init(void)
  {
  	int rc = -ENOMEM;
  	struct proc_dir_entry *p;
457c4cbc5   Eric W. Biederman   [NET]: Make /proc...
243
  	llc_proc_dir = proc_mkdir("llc", init_net.proc_net);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
244
245
  	if (!llc_proc_dir)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246

7e0218099   Wang Chen   [LLC]: Use proc_c...
247
  	p = proc_create("socket", S_IRUGO, llc_proc_dir, &llc_seq_socket_fops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
248
249
  	if (!p)
  		goto out_socket;
7e0218099   Wang Chen   [LLC]: Use proc_c...
250
  	p = proc_create("core", S_IRUGO, llc_proc_dir, &llc_seq_core_fops);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
252
  	if (!p)
  		goto out_core;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
253
254
255
256
257
258
  	rc = 0;
  out:
  	return rc;
  out_core:
  	remove_proc_entry("socket", llc_proc_dir);
  out_socket:
457c4cbc5   Eric W. Biederman   [NET]: Make /proc...
259
  	remove_proc_entry("llc", init_net.proc_net);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
260
261
262
263
264
265
266
  	goto out;
  }
  
  void llc_proc_exit(void)
  {
  	remove_proc_entry("socket", llc_proc_dir);
  	remove_proc_entry("core", llc_proc_dir);
457c4cbc5   Eric W. Biederman   [NET]: Make /proc...
267
  	remove_proc_entry("llc", init_net.proc_net);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268
  }