Blame view

net/atm/mpoa_proc.c 6.93 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
  
  #ifdef CONFIG_PROC_FS
  #include <linux/errno.h>
  #include <linux/kernel.h>
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
5
  #include <linux/string.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
7
8
9
10
11
12
13
14
15
16
17
18
  #include <linux/mm.h>
  #include <linux/module.h>
  #include <linux/proc_fs.h>
  #include <linux/time.h>
  #include <linux/seq_file.h>
  #include <asm/uaccess.h>
  #include <linux/atmmpc.h>
  #include <linux/atm.h>
  #include "mpc.h"
  #include "mpoa_caches.h"
  
  /*
   * mpoa_proc.c: Implementation MPOA client's proc
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
19
   * file system statistics
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
   */
  
  #if 1
  #define dprintk printk   /* debug */
  #else
  #define dprintk(format,args...)
  #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...
35
  			      size_t nbytes, loff_t *ppos);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
38
39
40
41
  
  static int parse_qos(const char *buff);
  
  /*
   *   Define allowed FILE OPERATIONS
   */
9a32144e9   Arjan van de Ven   [PATCH] mark stru...
42
  static const struct file_operations mpc_file_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
43
44
45
46
47
48
49
50
51
52
53
54
  	.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
   */
  static const char *ingress_state_string(int state){
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
55
  	switch(state) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
  	case INGRESS_RESOLVING:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
57
  		return "resolving  ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
  		break;
  	case INGRESS_RESOLVED:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
60
  		return "resolved   ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
62
  		break;
  	case INGRESS_INVALID:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
63
  		return "invalid    ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
64
65
  		break;
  	case INGRESS_REFRESHING:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
66
  		return "refreshing ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
68
69
70
71
72
73
74
75
76
  		break;
  	default:
  	       return "";
  	}
  }
  
  /*
   * Returns the state of an egress cache entry as a string
   */
  static const char *egress_state_string(int state){
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
77
  	switch(state) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
78
  	case EGRESS_RESOLVED:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
79
  		return "resolved   ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
  		break;
  	case EGRESS_PURGE:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
82
  		return "purge      ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
84
  		break;
  	case EGRESS_INVALID:
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
85
  		return "invalid    ";
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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
  		break;
  	default:
  	       return "";
  	}
  }
  
  /*
   * 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;
  	unsigned char *temp;
  	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...
137
138
139
140
  	seq_printf(m, "
  Interface %d:
  
  ", mpc->dev_num);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
  	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) {
  		temp = (unsigned char *)&in_entry->ctrl_info.in_dst_ip;
  		sprintf(ip_string,"%d.%d.%d.%d", temp[0], temp[1], temp[2], temp[3]);
  		seq_printf(m, "%-16s%s%-14lu%-12u",
  			      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);
  		if (in_entry->shortcut)
  			seq_printf(m, "   %-3d  %-3d",in_entry->shortcut->vpi,in_entry->shortcut->vci);
  		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;
  		for(i = 0; i < ATM_ESA_LEN; i++)
  			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),
  			   (eg_entry->ctrl_info.holding_time-(now.tv_sec-eg_entry->tv.tv_sec)),
  			   eg_entry->packets_rcvd);
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
176

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
178
179
180
181
182
183
184
185
186
187
188
189
190
  		/* latest IP address */
  		temp = (unsigned char *)&eg_entry->latest_ip_addr;
  		sprintf(ip_string, "%d.%d.%d.%d", temp[0], temp[1], temp[2], temp[3]);
  		seq_printf(m, "%-16s", ip_string);
  
  		if (eg_entry->shortcut)
  			seq_printf(m, " %-3d %-3d",eg_entry->shortcut->vpi,eg_entry->shortcut->vci);
  		seq_printf(m, "
  ");
  	}
  	seq_printf(m, "
  ");
  	return 0;
  }
56b3d975b   Philippe De Muyter   [NET]: Make all i...
191
  static const struct seq_operations mpc_op = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
194
195
196
197
198
199
200
201
202
203
  	.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...
204
  			      size_t nbytes, loff_t *ppos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205
  {
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
206
  	char *page, *p;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207
  	unsigned len;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
208
  	if (nbytes == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209
  		return 0;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
210
  	if (nbytes >= PAGE_SIZE)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
  		nbytes = PAGE_SIZE-1;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
212
213
  	page = (char *)__get_free_page(GFP_KERNEL);
  	if (!page)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
  		return -ENOMEM;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
215
216
  	for (p = page, len = 0; len < nbytes; p++, len++) {
  		if (get_user(*p, buff++)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
218
219
  			free_page((unsigned long)page);
  			return -EFAULT;
  		}
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
220
221
222
223
  		if (*p == '\0' || *p == '
  ')
  			break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224

f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
225
  	*p = '\0';
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
226
227
  
  	if (!parse_qos(page))
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
228
229
230
231
  		printk("mpoa: proc_mpc_write: could not parse '%s'
  ", page);
  
  	free_page((unsigned long)page);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
232

f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
233
  	return len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
235
236
237
  }
  
  static int parse_qos(const char *buff)
  {
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
238
239
240
241
  	/* 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
242
  	int tx_pcr, tx_sdu, rx_pcr, rx_sdu;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
243
244
245
246
  	__be32 ipaddr;
  	struct atm_qos qos;
  
  	memset(&qos, 0, sizeof(struct atm_qos));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
248
249
  
  	if (sscanf(buff, "del %hhu.%hhu.%hhu.%hhu",
  			ip, ip+1, ip+2, ip+3) == 4) {
30d492da7   Al Viro   [ATM]: Annotations.
250
  		ipaddr = *(__be32 *)ip;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
252
253
254
255
256
257
258
259
260
  		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...
261
  	ipaddr = *(__be32 *)ip;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
263
264
265
266
267
  	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...
268
  	qos.aal = ATM_AAL5;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  	dprintk("mpoa: mpoa_proc.c: 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
  		);
  
  	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;
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
287
  	p = create_proc_entry(STAT_FILE_NAME, 0, atm_proc_root);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
288
  	if (!p) {
f7d57453d   YOSHIFUJI Hideaki   [NET] ATM: Fix wh...
289
290
291
292
  		printk(KERN_ERR "Unable to initialize /proc/atm/%s
  ", STAT_FILE_NAME);
  		return -ENOMEM;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
  	p->proc_fops = &mpc_file_operations;
  	p->owner = THIS_MODULE;
  	return 0;
  }
  
  /*
   * DELETING function - called when module is removed.
   */
  void mpc_proc_clean(void)
  {
  	remove_proc_entry(STAT_FILE_NAME,atm_proc_root);
  }
  
  
  #endif /* CONFIG_PROC_FS */