OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [atm/] [mpoa_proc.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
#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
        int 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 0;
114
        page = get_free_page(GFP_KERNEL);
115
        if(!page)
116
                return -ENOMEM;
117
        atm_mpoa_disp_qos((char *)page, &length);
118
        while(mpc != NULL){
119
                length += print_header((char *)page + length, mpc);
120
                length += sprintf((char *)page + length,"Ingress Entries:\nIP address      State      Holding time  Packets fwded  VPI  VCI\n");
121
                in_entry = mpc->in_cache;
122
                do_gettimeofday(&now);
123
                while(in_entry != NULL){
124
                        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]);
125
                        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);
126
                        if(in_entry->shortcut)
127
                                length += sprintf((char *)page + length,"   %-3d  %-3d",in_entry->shortcut->vpi,in_entry->shortcut->vci);
128
                        length += sprintf((char *)page + length,"\n");
129
                        in_entry = in_entry->next;
130
                }
131
                length += sprintf((char *)page + length,"\n");
132
                eg_entry = mpc->eg_cache;
133
                length += sprintf((char *)page + length,"Egress Entries:\nIngress MPC ATM addr\nCache-id        State      Holding time  Packets recvd  Latest IP addr   VPI VCI\n");
134
                while(eg_entry != NULL){
135
                  for(i=0;i<ATM_ESA_LEN;i++){
136
                          length += sprintf((char *)page + length,"%02x",eg_entry->ctrl_info.in_MPC_data_ATM_addr[i]);}
137
                        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);
138
 
139
                        /* latest IP address */
140
                        temp = (unsigned char *)&eg_entry->latest_ip_addr;
141
                        sprintf(ip_string, "%d.%d.%d.%d", temp[0], temp[1], temp[2], temp[3]);
142
                        length += sprintf((char *)page + length, "%-16s", ip_string);
143
 
144
                        if(eg_entry->shortcut)
145
                                length += sprintf((char *)page + length," %-3d %-3d",eg_entry->shortcut->vpi,eg_entry->shortcut->vci);
146
                        length += sprintf((char *)page + length,"\n");
147
                        eg_entry = eg_entry->next;
148
                }
149
                length += sprintf((char *)page + length,"\n");
150
                mpc = mpc->next;
151
        }
152
 
153
        if (*pos >= length) length = 0;
154
        else {
155
          if ((count + *pos) > length) count = length - *pos;
156
          if (copy_to_user(buff, (char *)page , count)) {
157
                  free_page(page);
158
                  return -EFAULT;
159
          }
160
          *pos += count;
161
        }
162
 
163
        free_page(page);
164
        return length;
165
}
166
 
167
static ssize_t proc_mpc_write(struct file *file, const char *buff,
168
                              size_t nbytes, loff_t *ppos)
169
{
170
        int incoming, error, retval;
171
        char *page, c;
172
        const char *tmp;
173
 
174
        if (nbytes == 0) return 0;
175
        if (nbytes >= PAGE_SIZE) nbytes = PAGE_SIZE-1;
176
 
177
        error = verify_area(VERIFY_READ, buff, nbytes);
178
        if (error) return error;
179
 
180
        page = (char *)__get_free_page(GFP_KERNEL);
181
        if (page == NULL) return -ENOMEM;
182
 
183
        incoming = 0;
184
        tmp = buff;
185
        while(incoming < nbytes){
186
                if (get_user(c, tmp++)) return -EFAULT;
187
                incoming++;
188
                if (c == '\0' || c == '\n')
189
                        break;
190
        }
191
 
192
        retval = copy_from_user(page, buff, incoming);
193
        if (retval != 0) {
194
                printk("mpoa: proc_mpc_write: copy_from_user() failed\n");
195
                return -EFAULT;
196
        }
197
 
198
        *ppos += incoming;
199
 
200
        page[incoming] = '\0';
201
        retval = parse_qos(page, incoming);
202
        if (retval == 0)
203
                printk("mpoa: proc_mpc_write: could not parse '%s'\n", page);
204
 
205
        free_page((unsigned long)page);
206
 
207
        return nbytes;
208
}
209
 
210
static int parse_qos(const char *buff, int len)
211
{
212
        /* possible lines look like this
213
         * add 130.230.54.142 tx=max_pcr,max_sdu rx=max_pcr,max_sdu
214
         */
215
 
216
        int pos, i;
217
        uint32_t ipaddr;
218
        unsigned char ip[4];
219
        char cmd[4], temp[256];
220
        const char *tmp, *prev;
221
        struct atm_qos qos;
222
        int value[5];
223
 
224
        memset(&qos, 0, sizeof(struct atm_qos));
225
        strncpy(cmd, buff, 3);
226
        if( strncmp(cmd,"add", 3) &&  strncmp(cmd,"del", 3))
227
                return 0;  /* not add or del */
228
 
229
        pos = 4;
230
        /* next parse ip */
231
        prev = buff + pos;
232
        for (i = 0; i < 3; i++) {
233
                tmp = strchr(prev, '.');
234
                if (tmp == NULL) return 0;
235
                memset(temp, '\0', 256);
236
                memcpy(temp, prev, tmp-prev);
237
                ip[i] = (char)simple_strtoul(temp, NULL, 0);
238
                tmp ++;
239
                prev = tmp;
240
        }
241
        tmp = strchr(prev, ' ');
242
        if (tmp == NULL) return 0;
243
        memset(temp, '\0', 256);
244
        memcpy(temp, prev, tmp-prev);
245
        ip[i] = (char)simple_strtoul(temp, NULL, 0);
246
        ipaddr = *(uint32_t *)ip;
247
 
248
        if(!strncmp(cmd, "del", 3))
249
                 return atm_mpoa_delete_qos(atm_mpoa_search_qos(ipaddr));
250
 
251
        /* next transmit values */
252
        tmp = strstr(buff, "tx=");
253
        if(tmp == NULL) return 0;
254
        tmp += 3;
255
        prev = tmp;
256
        for( i = 0; i < 1; i++){
257
                 tmp = strchr(prev, ',');
258
                 if (tmp == NULL) return 0;
259
                 memset(temp, '\0', 256);
260
                 memcpy(temp, prev, tmp-prev);
261
                 value[i] = (int)simple_strtoul(temp, NULL, 0);
262
                 tmp ++;
263
                 prev = tmp;
264
        }
265
        tmp = strchr(prev, ' ');
266
        if (tmp == NULL) return 0;
267
        memset(temp, '\0', 256);
268
        memcpy(temp, prev, tmp-prev);
269
        value[i] = (int)simple_strtoul(temp, NULL, 0);
270
        qos.txtp.traffic_class = ATM_CBR;
271
        qos.txtp.max_pcr = value[0];
272
        qos.txtp.max_sdu = value[1];
273
 
274
        /* next receive values */
275
        tmp = strstr(buff, "rx=");
276
        if(tmp == NULL) return 0;
277
        if (strstr(buff, "rx=tx")) { /* rx == tx */
278
                qos.rxtp.traffic_class = qos.txtp.traffic_class;
279
                qos.rxtp.max_pcr = qos.txtp.max_pcr;
280
                qos.rxtp.max_cdv = qos.txtp.max_cdv;
281
                qos.rxtp.max_sdu = qos.txtp.max_sdu;
282
        } else {
283
                tmp += 3;
284
                prev = tmp;
285
                for( i = 0; i < 1; i++){
286
                        tmp = strchr(prev, ',');
287
                        if (tmp == NULL) return 0;
288
                        memset(temp, '\0', 256);
289
                        memcpy(temp, prev, tmp-prev);
290
                        value[i] = (int)simple_strtoul(temp, NULL, 0);
291
                        tmp ++;
292
                        prev = tmp;
293
                }
294
                tmp = strchr(prev, '\0');
295
                if (tmp == NULL) return 0;
296
                memset(temp, '\0', 256);
297
                memcpy(temp, prev, tmp-prev);
298
                value[i] = (int)simple_strtoul(temp, NULL, 0);
299
                qos.rxtp.traffic_class = ATM_CBR;
300
                qos.rxtp.max_pcr = value[0];
301
                qos.rxtp.max_sdu = value[1];
302
        }
303
        qos.aal = ATM_AAL5;
304
        dprintk("mpoa: mpoa_proc.c: parse_qos(): setting qos paramameters to tx=%d,%d rx=%d,%d\n",
305
                qos.txtp.max_pcr,
306
                qos.txtp.max_sdu,
307
                qos.rxtp.max_pcr,
308
                qos.rxtp.max_sdu
309
                );
310
 
311
        atm_mpoa_add_qos(ipaddr, &qos);
312
        return 1;
313
}
314
 
315
/*
316
 * INITIALIZATION function - called when module is initialized/loaded.
317
 */
318
int mpc_proc_init(void)
319
{
320
        struct proc_dir_entry *p;
321
 
322
        p = create_proc_entry(STAT_FILE_NAME, 0, atm_proc_root);
323
        if (!p) {
324
                printk(KERN_ERR "Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME);
325
                return -ENOMEM;
326
        }
327
        p->proc_fops = &mpc_file_operations;
328
        p->owner = THIS_MODULE;
329
        return 0;
330
}
331
 
332
/*
333
 * DELETING function - called when module is removed.
334
 */
335
void mpc_proc_clean(void)
336
{
337
        remove_proc_entry(STAT_FILE_NAME,atm_proc_root);
338
}
339
 
340
 
341
#endif /* CONFIG_PROC_FS */
342
 
343
 
344
 
345
 
346
 
347
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.