~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/atm/mpoa_proc.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #include <linux/config.h>
  2 
  3 #ifdef CONFIG_PROC_FS
  4 #include <linux/errno.h>
  5 #include <linux/kernel.h>
  6 #include <linux/string.h> 
  7 #include <linux/mm.h>
  8 #include <linux/module.h>
  9 #include <linux/proc_fs.h>
 10 #include <linux/time.h>
 11 #include <asm/uaccess.h>
 12 #include <linux/atmmpc.h>
 13 #include <linux/atm.h>
 14 #include "mpc.h"
 15 #include "mpoa_caches.h"
 16 
 17 /*
 18  * mpoa_proc.c: Implementation MPOA client's proc
 19  * file system statistics 
 20  */
 21 
 22 #if 1
 23 #define dprintk printk   /* debug */
 24 #else
 25 #define dprintk(format,args...)
 26 #endif
 27 
 28 #define STAT_FILE_NAME "mpc"     /* Our statistic file's name */
 29 
 30 extern struct mpoa_client *mpcs;
 31 extern struct proc_dir_entry *atm_proc_root;  /* from proc.c. */
 32 
 33 static ssize_t proc_mpc_read(struct file *file, char *buff,
 34                              size_t count, loff_t *pos);
 35 
 36 static ssize_t proc_mpc_write(struct file *file, const char *buff,
 37                               size_t nbytes, loff_t *ppos);
 38 
 39 static int parse_qos(const char *buff, int len);
 40 
 41 /*
 42  *   Define allowed FILE OPERATIONS
 43  */
 44 static struct file_operations mpc_file_operations = {
 45         read:           proc_mpc_read,
 46         write:          proc_mpc_write,
 47 };
 48 
 49 static int print_header(char *buff,struct mpoa_client *mpc){
 50         if(mpc != NULL){
 51                 return sprintf(buff,"\nInterface %d:\n\n",mpc->dev_num);  
 52           
 53         }
 54         return 0;
 55 }
 56 
 57 /*
 58  * Returns the state of an ingress cache entry as a string
 59  */
 60 static const char *ingress_state_string(int state){
 61         switch(state) {
 62         case INGRESS_RESOLVING:
 63                 return "resolving  ";
 64                 break;
 65         case INGRESS_RESOLVED:
 66                 return "resolved   ";
 67                 break;
 68         case INGRESS_INVALID:
 69                 return "invalid    ";
 70                 break;
 71         case INGRESS_REFRESHING:
 72                 return "refreshing ";
 73                 break;
 74         default:
 75                return "";
 76         }
 77 }
 78 
 79 /*
 80  * Returns the state of an egress cache entry as a string
 81  */
 82 static const char *egress_state_string(int state){
 83         switch(state) {
 84         case EGRESS_RESOLVED:
 85                 return "resolved   ";
 86                 break;
 87         case EGRESS_PURGE:
 88                 return "purge      ";
 89                 break;
 90         case EGRESS_INVALID:
 91                 return "invalid    ";
 92                 break;
 93         default:
 94                return "";
 95         }
 96 }
 97 
 98 /*
 99  * READING function - called when the /proc/atm/mpoa file is read from.
100  */
101 static ssize_t proc_mpc_read(struct file *file, char *buff,
102                              size_t count, loff_t *pos){
103         unsigned long page = 0;
104         unsigned char *temp;
105         ssize_t length  = 0;
106         int i = 0;
107         struct mpoa_client *mpc = mpcs;
108         in_cache_entry *in_entry;
109         eg_cache_entry *eg_entry;
110         struct timeval now;
111         unsigned char ip_string[16];
112         if(count < 0)
113                 return -EINVAL;
114         if(count == 0)
115                 return 0;
116         page = get_free_page(GFP_KERNEL);
117         if(!page)
118                 return -ENOMEM;
119         atm_mpoa_disp_qos((char *)page, &length);
120         while(mpc != NULL){
121                 length += print_header((char *)page + length, mpc);
122                 length += sprintf((char *)page + length,"Ingress Entries:\nIP address      State      Holding time  Packets fwded  VPI  VCI\n");
123                 in_entry = mpc->in_cache;
124                 do_gettimeofday(&now);
125                 while(in_entry != NULL){
126                         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]);
127                         length += sprintf((char *)page + length,"%-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);
128                         if(in_entry->shortcut)
129                                 length += sprintf((char *)page + length,"   %-3d  %-3d",in_entry->shortcut->vpi,in_entry->shortcut->vci);
130                         length += sprintf((char *)page + length,"\n");
131                         in_entry = in_entry->next;
132                 }
133                 length += sprintf((char *)page + length,"\n");
134                 eg_entry = mpc->eg_cache;
135                 length += sprintf((char *)page + length,"Egress Entries:\nIngress MPC ATM addr\nCache-id        State      Holding time  Packets recvd  Latest IP addr   VPI VCI\n");
136                 while(eg_entry != NULL){
137                   for(i=0;i<ATM_ESA_LEN;i++){
138                           length += sprintf((char *)page + length,"%02x",eg_entry->ctrl_info.in_MPC_data_ATM_addr[i]);}  
139                         length += sprintf((char *)page + length,"\n%-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);
140                         
141                         /* latest IP address */
142                         temp = (unsigned char *)&eg_entry->latest_ip_addr;
143                         sprintf(ip_string, "%d.%d.%d.%d", temp[0], temp[1], temp[2], temp[3]);
144                         length += sprintf((char *)page + length, "%-16s", ip_string);
145 
146                         if(eg_entry->shortcut)
147                                 length += sprintf((char *)page + length," %-3d %-3d",eg_entry->shortcut->vpi,eg_entry->shortcut->vci);
148                         length += sprintf((char *)page + length,"\n");
149                         eg_entry = eg_entry->next;
150                 }
151                 length += sprintf((char *)page + length,"\n");
152                 mpc = mpc->next;
153         }
154 
155         if (*pos >= length) length = 0;
156         else {
157           if ((count + *pos) > length) count = length - *pos;
158           if (copy_to_user(buff, (char *)page , count)) {
159                   free_page(page);
160                   return -EFAULT;
161           }
162           *pos += count;
163         }
164 
165         free_page(page);
166         return length;
167 }
168 
169 static ssize_t proc_mpc_write(struct file *file, const char *buff,
170                               size_t nbytes, loff_t *ppos)
171 {
172         int incoming, error, retval;
173         char *page, c;
174         const char *tmp;
175 
176         if (nbytes < 0) return -EINVAL;
177         if (nbytes == 0) return 0;
178         if (nbytes > PAGE_SIZE) nbytes = PAGE_SIZE-1;
179 
180         error = verify_area(VERIFY_READ, buff, nbytes);
181         if (error) return error;
182 
183         page = (char *)__get_free_page(GFP_KERNEL);
184         if (page == NULL) return -ENOMEM;
185 
186         incoming = 0;
187         tmp = buff;
188         while(incoming < nbytes){
189                 if (get_user(c, tmp++)) return -EFAULT;
190                 incoming++;
191                 if (c == '\0' || c == '\n')
192                         break;
193         }
194 
195         retval = copy_from_user(page, buff, incoming);
196         if (retval != 0) {
197                 printk("mpoa: proc_mpc_write: copy_from_user() failed\n");
198                 return -EFAULT;
199         }
200 
201         *ppos += incoming;
202 
203         page[incoming] = '\0';
204         retval = parse_qos(page, incoming);
205         if (retval == 0)
206                 printk("mpoa: proc_mpc_write: could not parse '%s'\n", page);
207 
208         free_page((unsigned long)page);
209         
210         return nbytes;
211 }
212 
213 static int parse_qos(const char *buff, int len)
214 {
215         /* possible lines look like this
216          * add 130.230.54.142 tx=max_pcr,max_sdu rx=max_pcr,max_sdu
217          */
218         
219         int pos, i;
220         uint32_t ipaddr;
221         unsigned char ip[4]; 
222         char cmd[4], temp[256];
223         const char *tmp, *prev;
224         struct atm_qos qos; 
225         int value[5];
226         
227         memset(&qos, 0, sizeof(struct atm_qos));
228         strncpy(cmd, buff, 3);
229         if( strncmp(cmd,"add", 3) &&  strncmp(cmd,"del", 3))
230                 return 0;  /* not add or del */
231 
232         pos = 4;
233         /* next parse ip */
234         prev = buff + pos;
235         for (i = 0; i < 3; i++) {
236                 tmp = strchr(prev, '.');
237                 if (tmp == NULL) return 0;
238                 memset(temp, '\0', 256);
239                 memcpy(temp, prev, tmp-prev);
240                 ip[i] = (char)simple_strtoul(temp, NULL, 0);
241                 tmp ++; 
242                 prev = tmp;
243         }
244         tmp = strchr(prev, ' ');
245         if (tmp == NULL) return 0;
246         memset(temp, '\0', 256);
247         memcpy(temp, prev, tmp-prev);
248         ip[i] = (char)simple_strtoul(temp, NULL, 0);
249         ipaddr = *(uint32_t *)ip;
250                 
251         if(!strncmp(cmd, "del", 3))
252                  return atm_mpoa_delete_qos(atm_mpoa_search_qos(ipaddr));
253 
254         /* next transmit values */
255         tmp = strstr(buff, "tx=");
256         if(tmp == NULL) return 0;
257         tmp += 3;
258         prev = tmp;
259         for( i = 0; i < 1; i++){
260                  tmp = strchr(prev, ',');
261                  if (tmp == NULL) return 0;
262                  memset(temp, '\0', 256);
263                  memcpy(temp, prev, tmp-prev);
264                  value[i] = (int)simple_strtoul(temp, NULL, 0);
265                  tmp ++; 
266                  prev = tmp;
267         }
268         tmp = strchr(prev, ' ');
269         if (tmp == NULL) return 0;
270         memset(temp, '\0', 256);
271         memcpy(temp, prev, tmp-prev);
272         value[i] = (int)simple_strtoul(temp, NULL, 0);
273         qos.txtp.traffic_class = ATM_CBR;
274         qos.txtp.max_pcr = value[0];
275         qos.txtp.max_sdu = value[1];
276 
277         /* next receive values */
278         tmp = strstr(buff, "rx=");
279         if(tmp == NULL) return 0;
280         if (strstr(buff, "rx=tx")) { /* rx == tx */
281                 qos.rxtp.traffic_class = qos.txtp.traffic_class;
282                 qos.rxtp.max_pcr = qos.txtp.max_pcr;
283                 qos.rxtp.max_cdv = qos.txtp.max_cdv;
284                 qos.rxtp.max_sdu = qos.txtp.max_sdu;
285         } else {
286                 tmp += 3;
287                 prev = tmp;
288                 for( i = 0; i < 1; i++){
289                         tmp = strchr(prev, ',');
290                         if (tmp == NULL) return 0;
291                         memset(temp, '\0', 256);
292                         memcpy(temp, prev, tmp-prev);
293                         value[i] = (int)simple_strtoul(temp, NULL, 0);
294                         tmp ++; 
295                         prev = tmp;
296                 }
297                 tmp = strchr(prev, '\0');
298                 if (tmp == NULL) return 0;
299                 memset(temp, '\0', 256);
300                 memcpy(temp, prev, tmp-prev);
301                 value[i] = (int)simple_strtoul(temp, NULL, 0);
302                 qos.rxtp.traffic_class = ATM_CBR;
303                 qos.rxtp.max_pcr = value[0];
304                 qos.rxtp.max_sdu = value[1];
305         }
306         qos.aal = ATM_AAL5;
307         dprintk("mpoa: mpoa_proc.c: parse_qos(): setting qos paramameters to tx=%d,%d rx=%d,%d\n",
308                 qos.txtp.max_pcr,
309                 qos.txtp.max_sdu,
310                 qos.rxtp.max_pcr,
311                 qos.rxtp.max_sdu
312                 );
313 
314         atm_mpoa_add_qos(ipaddr, &qos);
315         return 1;
316 }
317 
318 /*
319  * INITIALIZATION function - called when module is initialized/loaded.
320  */
321 int mpc_proc_init(void)
322 {
323         struct proc_dir_entry *p;
324 
325         p = create_proc_entry(STAT_FILE_NAME, 0, atm_proc_root);
326         if (!p) {
327                 printk(KERN_ERR "Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME);
328                 return -ENOMEM;
329         }
330         p->proc_fops = &mpc_file_operations;
331         p->owner = THIS_MODULE;
332         return 0;
333 }
334 
335 /*
336  * DELETING function - called when module is removed.
337  */
338 void mpc_proc_clean(void)
339 {
340         remove_proc_entry(STAT_FILE_NAME,atm_proc_root);
341 }
342 
343 
344 #endif /* CONFIG_PROC_FS */
345 
346 
347 
348 
349 
350 
351 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.