Blame view

net/atm/mpoa_proc.c 7.15 KB
99824461e   Joe Perches   net/atm: Convert ...
1
  #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
  
  #ifdef CONFIG_PROC_FS
  #include <linux/errno.h>
  #include <linux/kernel.h>
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
6
  #include <linux/string.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
8
9
10
11
  #include <linux/mm.h>
  #include <linux/module.h>
  #include <linux/proc_fs.h>
  #include <linux/time.h>
  #include <linux/seq_file.h>
f1e100491   Joe Perches   net/atm/mpoa_proc...
12
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
  #include <linux/atmmpc.h>
  #include <linux/atm.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
15
  #include <linux/gfp.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
16
17
18
19
20
  #include "mpc.h"
  #include "mpoa_caches.h"
  
  /*
   * mpoa_proc.c: Implementation MPOA client's proc
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
21
   * file system statistics
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
22
23
24
   */
  
  #if 1
b50c2ea72   Joe Perches   net/atm: Cleanup ...
25
26
  #define dprintk(format, args...)					\
  	printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args)  /* debug */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
  #else
b50c2ea72   Joe Perches   net/atm: Cleanup ...
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  #define dprintk(format, args...)					\
  	do { if (0)							\
  		printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args);\
  	} while (0)
  #endif
  
  #if 0
  #define ddprintk(format, args...)					\
  	printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args)  /* debug */
  #else
  #define ddprintk(format, args...)					\
  	do { if (0)							\
  		printk(KERN_DEBUG "mpoa:%s: " format, __FILE__, ##args);\
  	} while (0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42
43
44
45
46
47
48
49
50
  #endif
  
  #define STAT_FILE_NAME "mpc"     /* Our statistic file's name */
  
  extern struct mpoa_client *mpcs;
  extern struct proc_dir_entry *atm_proc_root;  /* from proc.c. */
  
  static int proc_mpc_open(struct inode *inode, struct file *file);
  static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
51
  			      size_t nbytes, loff_t *ppos);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
52
53
54
55
56
57
  
  static int parse_qos(const char *buff);
  
  /*
   *   Define allowed FILE OPERATIONS
   */
9a32144e9   Arjan van de Ven   [PATCH] mark stru...
58
  static const struct file_operations mpc_file_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
61
62
63
64
65
66
67
68
69
  	.owner =	THIS_MODULE,
  	.open =		proc_mpc_open,
  	.read =		seq_read,
  	.llseek =	seq_lseek,
  	.write =	proc_mpc_write,
  	.release =	seq_release,
  };
  
  /*
   * Returns the state of an ingress cache entry as a string
   */
f1e100491   Joe Perches   net/atm/mpoa_proc...
70
71
72
  static const char *ingress_state_string(int state)
  {
  	switch (state) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
  	case INGRESS_RESOLVING:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
74
  		return "resolving  ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
  	case INGRESS_RESOLVED:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
76
  		return "resolved   ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
  	case INGRESS_INVALID:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
78
  		return "invalid    ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
  	case INGRESS_REFRESHING:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
80
  		return "refreshing ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
  	}
f1e100491   Joe Perches   net/atm/mpoa_proc...
82
83
  
  	return "";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84
85
86
87
88
  }
  
  /*
   * Returns the state of an egress cache entry as a string
   */
f1e100491   Joe Perches   net/atm/mpoa_proc...
89
90
91
  static const char *egress_state_string(int state)
  {
  	switch (state) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
  	case EGRESS_RESOLVED:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
93
  		return "resolved   ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
  	case EGRESS_PURGE:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
95
  		return "purge      ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
  	case EGRESS_INVALID:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
97
  		return "invalid    ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
98
  	}
f1e100491   Joe Perches   net/atm/mpoa_proc...
99
100
  
  	return "";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
  }
  
  /*
   * FIXME: mpcs (and per-mpc lists) have no locking whatsoever.
   */
  
  static void *mpc_start(struct seq_file *m, loff_t *pos)
  {
  	loff_t l = *pos;
  	struct mpoa_client *mpc;
  
  	if (!l--)
  		return SEQ_START_TOKEN;
  	for (mpc = mpcs; mpc; mpc = mpc->next)
  		if (!l--)
  			return mpc;
  	return NULL;
  }
  
  static void *mpc_next(struct seq_file *m, void *v, loff_t *pos)
  {
  	struct mpoa_client *p = v;
  	(*pos)++;
  	return v == SEQ_START_TOKEN ? mpcs : p->next;
  }
  
  static void mpc_stop(struct seq_file *m, void *v)
  {
  }
  
  /*
   * READING function - called when the /proc/atm/mpoa file is read from.
   */
  static int mpc_show(struct seq_file *m, void *v)
  {
  	struct mpoa_client *mpc = v;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
137
138
139
140
141
142
143
144
145
146
  	int i;
  	in_cache_entry *in_entry;
  	eg_cache_entry *eg_entry;
  	struct timeval now;
  	unsigned char ip_string[16];
  
  	if (v == SEQ_START_TOKEN) {
  		atm_mpoa_disp_qos(m);
  		return 0;
  	}
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
147
148
149
150
  	seq_printf(m, "
  Interface %d:
  
  ", mpc->dev_num);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
152
153
154
155
156
  	seq_printf(m, "Ingress Entries:
  IP address      State      Holding time  Packets fwded  VPI  VCI
  ");
  	do_gettimeofday(&now);
  
  	for (in_entry = mpc->in_cache; in_entry; in_entry = in_entry->next) {
f1e100491   Joe Perches   net/atm/mpoa_proc...
157
  		sprintf(ip_string, "%pI4", &in_entry->ctrl_info.in_dst_ip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
  		seq_printf(m, "%-16s%s%-14lu%-12u",
f1e100491   Joe Perches   net/atm/mpoa_proc...
159
160
161
162
163
  			   ip_string,
  			   ingress_state_string(in_entry->entry_state),
  			   in_entry->ctrl_info.holding_time -
  			   (now.tv_sec-in_entry->tv.tv_sec),
  			   in_entry->packets_fwded);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
164
  		if (in_entry->shortcut)
f1e100491   Joe Perches   net/atm/mpoa_proc...
165
166
167
  			seq_printf(m, "   %-3d  %-3d",
  				   in_entry->shortcut->vpi,
  				   in_entry->shortcut->vci);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
170
171
172
173
174
175
176
177
178
179
  		seq_printf(m, "
  ");
  	}
  
  	seq_printf(m, "
  ");
  	seq_printf(m, "Egress Entries:
  Ingress MPC ATM addr
  Cache-id        State      Holding time  Packets recvd  Latest IP addr   VPI VCI
  ");
  	for (eg_entry = mpc->eg_cache; eg_entry; eg_entry = eg_entry->next) {
  		unsigned char *p = eg_entry->ctrl_info.in_MPC_data_ATM_addr;
f1e100491   Joe Perches   net/atm/mpoa_proc...
180
  		for (i = 0; i < ATM_ESA_LEN; i++)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
182
183
184
185
  			seq_printf(m, "%02x", p[i]);
  		seq_printf(m, "
  %-16lu%s%-14lu%-15u",
  			   (unsigned long)ntohl(eg_entry->ctrl_info.cache_id),
  			   egress_state_string(eg_entry->entry_state),
f1e100491   Joe Perches   net/atm/mpoa_proc...
186
187
  			   (eg_entry->ctrl_info.holding_time -
  			    (now.tv_sec-eg_entry->tv.tv_sec)),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
  			   eg_entry->packets_rcvd);
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
189

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
  		/* latest IP address */
f1e100491   Joe Perches   net/atm/mpoa_proc...
191
  		sprintf(ip_string, "%pI4", &eg_entry->latest_ip_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
194
  		seq_printf(m, "%-16s", ip_string);
  
  		if (eg_entry->shortcut)
f1e100491   Joe Perches   net/atm/mpoa_proc...
195
196
197
  			seq_printf(m, " %-3d %-3d",
  				   eg_entry->shortcut->vpi,
  				   eg_entry->shortcut->vci);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
199
200
201
202
203
204
  		seq_printf(m, "
  ");
  	}
  	seq_printf(m, "
  ");
  	return 0;
  }
56b3d975b   Philippe De Muyter   [NET]: Make all i...
205
  static const struct seq_operations mpc_op = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
206
207
208
209
210
211
212
213
214
215
216
217
  	.start =	mpc_start,
  	.next =		mpc_next,
  	.stop =		mpc_stop,
  	.show =		mpc_show
  };
  
  static int proc_mpc_open(struct inode *inode, struct file *file)
  {
  	return seq_open(file, &mpc_op);
  }
  
  static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
218
  			      size_t nbytes, loff_t *ppos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219
  {
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
220
  	char *page, *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
221
  	unsigned len;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
222
  	if (nbytes == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223
  		return 0;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
224
  	if (nbytes >= PAGE_SIZE)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
  		nbytes = PAGE_SIZE-1;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
226
227
  	page = (char *)__get_free_page(GFP_KERNEL);
  	if (!page)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
  		return -ENOMEM;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
229
230
  	for (p = page, len = 0; len < nbytes; p++, len++) {
  		if (get_user(*p, buff++)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
231
232
233
  			free_page((unsigned long)page);
  			return -EFAULT;
  		}
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
234
235
236
237
  		if (*p == '\0' || *p == '
  ')
  			break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
238

f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
239
  	*p = '\0';
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
241
  
  	if (!parse_qos(page))
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
242
243
244
245
  		printk("mpoa: proc_mpc_write: could not parse '%s'
  ", page);
  
  	free_page((unsigned long)page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246

f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
247
  	return len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
248
249
250
251
  }
  
  static int parse_qos(const char *buff)
  {
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
252
253
254
255
  	/* possible lines look like this
  	 * add 130.230.54.142 tx=max_pcr,max_sdu rx=max_pcr,max_sdu
  	 */
  	unsigned char ip[4];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
  	int tx_pcr, tx_sdu, rx_pcr, rx_sdu;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
257
258
259
260
  	__be32 ipaddr;
  	struct atm_qos qos;
  
  	memset(&qos, 0, sizeof(struct atm_qos));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
262
263
  
  	if (sscanf(buff, "del %hhu.%hhu.%hhu.%hhu",
  			ip, ip+1, ip+2, ip+3) == 4) {
30d492da7   Al Viro   [ATM]: Annotations.
264
  		ipaddr = *(__be32 *)ip;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
268
269
270
271
272
273
274
  		return atm_mpoa_delete_qos(atm_mpoa_search_qos(ipaddr));
  	}
  
  	if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=tx",
  			ip, ip+1, ip+2, ip+3, &tx_pcr, &tx_sdu) == 6) {
  		rx_pcr = tx_pcr;
  		rx_sdu = tx_sdu;
  	} else if (sscanf(buff, "add %hhu.%hhu.%hhu.%hhu tx=%d,%d rx=%d,%d",
  		ip, ip+1, ip+2, ip+3, &tx_pcr, &tx_sdu, &rx_pcr, &rx_sdu) != 8)
  		return 0;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
275
  	ipaddr = *(__be32 *)ip;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
276
277
278
279
280
281
  	qos.txtp.traffic_class = ATM_CBR;
  	qos.txtp.max_pcr = tx_pcr;
  	qos.txtp.max_sdu = tx_sdu;
  	qos.rxtp.traffic_class = ATM_CBR;
  	qos.rxtp.max_pcr = rx_pcr;
  	qos.rxtp.max_sdu = rx_sdu;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
282
  	qos.aal = ATM_AAL5;
b50c2ea72   Joe Perches   net/atm: Cleanup ...
283
284
285
286
  	dprintk("parse_qos(): setting qos paramameters to tx=%d,%d rx=%d,%d
  ",
  		qos.txtp.max_pcr, qos.txtp.max_sdu,
  		qos.rxtp.max_pcr, qos.rxtp.max_sdu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
288
289
290
291
292
293
294
295
296
297
  
  	atm_mpoa_add_qos(ipaddr, &qos);
  	return 1;
  }
  
  /*
   * INITIALIZATION function - called when module is initialized/loaded.
   */
  int mpc_proc_init(void)
  {
  	struct proc_dir_entry *p;
16e297b35   Wang Chen   [ATM]: Use proc_c...
298
  	p = proc_create(STAT_FILE_NAME, 0, atm_proc_root, &mpc_file_operations);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
299
  	if (!p) {
99824461e   Joe Perches   net/atm: Convert ...
300
301
  		pr_err("Unable to initialize /proc/atm/%s
  ", STAT_FILE_NAME);
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
302
303
  		return -ENOMEM;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
304
305
306
307
308
309
310
311
  	return 0;
  }
  
  /*
   * DELETING function - called when module is removed.
   */
  void mpc_proc_clean(void)
  {
f1e100491   Joe Perches   net/atm/mpoa_proc...
312
  	remove_proc_entry(STAT_FILE_NAME, atm_proc_root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314
  #endif /* CONFIG_PROC_FS */