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

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [net/] [8021q/] [vlanproc.c] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/******************************************************************************
2
 * vlanproc.c   VLAN Module. /proc filesystem interface.
3
 *
4
 *              This module is completely hardware-independent and provides
5
 *              access to the router using Linux /proc filesystem.
6
 *
7
 * Author:      Ben Greear, <greearb@candelatech.com> coppied from wanproc.c
8
 *               by: Gene Kozin <genek@compuserve.com>
9
 *
10
 * Copyright:   (c) 1998 Ben Greear
11
 *
12
 *              This program is free software; you can redistribute it and/or
13
 *              modify it under the terms of the GNU General Public License
14
 *              as published by the Free Software Foundation; either version
15
 *              2 of the License, or (at your option) any later version.
16
 * ============================================================================
17
 * Jan 20, 1998        Ben Greear     Initial Version
18
 *****************************************************************************/
19
 
20
#include <linux/module.h>
21
#include <linux/stddef.h>       /* offsetof(), etc. */
22
#include <linux/errno.h>        /* return codes */
23
#include <linux/kernel.h>
24
#include <linux/slab.h>         /* kmalloc(), kfree() */
25
#include <linux/mm.h>
26
#include <linux/string.h>       /* inline mem*, str* functions */
27
#include <linux/init.h>         /* __initfunc et al. */
28
#include <asm/byteorder.h>      /* htons(), etc. */
29
#include <asm/uaccess.h>        /* copy_to_user */
30
#include <asm/io.h>
31
#include <linux/proc_fs.h>
32
#include <linux/seq_file.h>
33
#include <linux/fs.h>
34
#include <linux/netdevice.h>
35
#include <linux/if_vlan.h>
36
#include <net/net_namespace.h>
37
#include "vlanproc.h"
38
#include "vlan.h"
39
 
40
/****** Function Prototypes *************************************************/
41
 
42
/* Methods for preparing data for reading proc entries */
43
static int vlan_seq_show(struct seq_file *seq, void *v);
44
static void *vlan_seq_start(struct seq_file *seq, loff_t *pos);
45
static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos);
46
static void vlan_seq_stop(struct seq_file *seq, void *);
47
static int vlandev_seq_show(struct seq_file *seq, void *v);
48
 
49
/*
50
 *      Global Data
51
 */
52
 
53
 
54
/*
55
 *      Names of the proc directory entries
56
 */
57
 
58
static const char name_root[]    = "vlan";
59
static const char name_conf[]    = "config";
60
 
61
/*
62
 *      Structures for interfacing with the /proc filesystem.
63
 *      VLAN creates its own directory /proc/net/vlan with the folowing
64
 *      entries:
65
 *      config          device status/configuration
66
 *      <device>        entry for each  device
67
 */
68
 
69
/*
70
 *      Generic /proc/net/vlan/<file> file and inode operations
71
 */
72
 
73
static const struct seq_operations vlan_seq_ops = {
74
        .start = vlan_seq_start,
75
        .next = vlan_seq_next,
76
        .stop = vlan_seq_stop,
77
        .show = vlan_seq_show,
78
};
79
 
80
static int vlan_seq_open(struct inode *inode, struct file *file)
81
{
82
        return seq_open(file, &vlan_seq_ops);
83
}
84
 
85
static const struct file_operations vlan_fops = {
86
        .owner   = THIS_MODULE,
87
        .open    = vlan_seq_open,
88
        .read    = seq_read,
89
        .llseek  = seq_lseek,
90
        .release = seq_release,
91
};
92
 
93
/*
94
 *      /proc/net/vlan/<device> file and inode operations
95
 */
96
 
97
static int vlandev_seq_open(struct inode *inode, struct file *file)
98
{
99
        return single_open(file, vlandev_seq_show, PDE(inode)->data);
100
}
101
 
102
static const struct file_operations vlandev_fops = {
103
        .owner = THIS_MODULE,
104
        .open    = vlandev_seq_open,
105
        .read    = seq_read,
106
        .llseek  = seq_lseek,
107
        .release = single_release,
108
};
109
 
110
/*
111
 * Proc filesystem derectory entries.
112
 */
113
 
114
/*
115
 *      /proc/net/vlan
116
 */
117
 
118
static struct proc_dir_entry *proc_vlan_dir;
119
 
120
/*
121
 *      /proc/net/vlan/config
122
 */
123
 
124
static struct proc_dir_entry *proc_vlan_conf;
125
 
126
/* Strings */
127
static const char *vlan_name_type_str[VLAN_NAME_TYPE_HIGHEST] = {
128
    [VLAN_NAME_TYPE_RAW_PLUS_VID]       = "VLAN_NAME_TYPE_RAW_PLUS_VID",
129
    [VLAN_NAME_TYPE_PLUS_VID_NO_PAD]    = "VLAN_NAME_TYPE_PLUS_VID_NO_PAD",
130
    [VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD]= "VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD",
131
    [VLAN_NAME_TYPE_PLUS_VID]           = "VLAN_NAME_TYPE_PLUS_VID",
132
};
133
/*
134
 *      Interface functions
135
 */
136
 
137
/*
138
 *      Clean up /proc/net/vlan entries
139
 */
140
 
141
void vlan_proc_cleanup(void)
142
{
143
        if (proc_vlan_conf)
144
                remove_proc_entry(name_conf, proc_vlan_dir);
145
 
146
        if (proc_vlan_dir)
147
                proc_net_remove(&init_net, name_root);
148
 
149
        /* Dynamically added entries should be cleaned up as their vlan_device
150
         * is removed, so we should not have to take care of it here...
151
         */
152
}
153
 
154
/*
155
 *      Create /proc/net/vlan entries
156
 */
157
 
158
int __init vlan_proc_init(void)
159
{
160
        proc_vlan_dir = proc_mkdir(name_root, init_net.proc_net);
161
        if (proc_vlan_dir) {
162
                proc_vlan_conf = create_proc_entry(name_conf,
163
                                                   S_IFREG|S_IRUSR|S_IWUSR,
164
                                                   proc_vlan_dir);
165
                if (proc_vlan_conf) {
166
                        proc_vlan_conf->proc_fops = &vlan_fops;
167
                        return 0;
168
                }
169
        }
170
        vlan_proc_cleanup();
171
        return -ENOBUFS;
172
}
173
 
174
/*
175
 *      Add directory entry for VLAN device.
176
 */
177
 
178
int vlan_proc_add_dev (struct net_device *vlandev)
179
{
180
        struct vlan_dev_info *dev_info = VLAN_DEV_INFO(vlandev);
181
 
182
        if (!(vlandev->priv_flags & IFF_802_1Q_VLAN)) {
183
                printk(KERN_ERR
184
                       "ERROR:  vlan_proc_add, device -:%s:- is NOT a VLAN\n",
185
                       vlandev->name);
186
                return -EINVAL;
187
        }
188
 
189
        dev_info->dent = create_proc_entry(vlandev->name,
190
                                           S_IFREG|S_IRUSR|S_IWUSR,
191
                                           proc_vlan_dir);
192
        if (!dev_info->dent)
193
                return -ENOBUFS;
194
 
195
        dev_info->dent->proc_fops = &vlandev_fops;
196
        dev_info->dent->data = vlandev;
197
 
198
#ifdef VLAN_DEBUG
199
        printk(KERN_ERR "vlan_proc_add, device -:%s:- being added.\n",
200
               vlandev->name);
201
#endif
202
        return 0;
203
}
204
 
205
/*
206
 *      Delete directory entry for VLAN device.
207
 */
208
int vlan_proc_rem_dev(struct net_device *vlandev)
209
{
210
        if (!vlandev) {
211
                printk(VLAN_ERR "%s: invalid argument: %p\n",
212
                        __FUNCTION__, vlandev);
213
                return -EINVAL;
214
        }
215
 
216
        if (!(vlandev->priv_flags & IFF_802_1Q_VLAN)) {
217
                printk(VLAN_DBG "%s: invalid argument, device: %s is not a VLAN device, priv_flags: 0x%4hX.\n",
218
                        __FUNCTION__, vlandev->name, vlandev->priv_flags);
219
                return -EINVAL;
220
        }
221
 
222
#ifdef VLAN_DEBUG
223
        printk(VLAN_DBG "%s: dev: %p\n", __FUNCTION__, vlandev);
224
#endif
225
 
226
        /** NOTE:  This will consume the memory pointed to by dent, it seems. */
227
        if (VLAN_DEV_INFO(vlandev)->dent) {
228
                remove_proc_entry(VLAN_DEV_INFO(vlandev)->dent->name, proc_vlan_dir);
229
                VLAN_DEV_INFO(vlandev)->dent = NULL;
230
        }
231
 
232
        return 0;
233
}
234
 
235
/****** Proc filesystem entry points ****************************************/
236
 
237
/*
238
 * The following few functions build the content of /proc/net/vlan/config
239
 */
240
 
241
static inline int is_vlan_dev(struct net_device *dev)
242
{
243
        return dev->priv_flags & IFF_802_1Q_VLAN;
244
}
245
 
246
/* start read of /proc/net/vlan/config */
247
static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
248
{
249
        struct net_device *dev;
250
        loff_t i = 1;
251
 
252
        read_lock(&dev_base_lock);
253
 
254
        if (*pos == 0)
255
                return SEQ_START_TOKEN;
256
 
257
        for_each_netdev(&init_net, dev) {
258
                if (!is_vlan_dev(dev))
259
                        continue;
260
 
261
                if (i++ == *pos)
262
                        return dev;
263
        }
264
 
265
        return  NULL;
266
}
267
 
268
static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
269
{
270
        struct net_device *dev;
271
 
272
        ++*pos;
273
 
274
        dev = (struct net_device *)v;
275
        if (v == SEQ_START_TOKEN)
276
                dev = net_device_entry(&init_net.dev_base_head);
277
 
278
        for_each_netdev_continue(&init_net, dev) {
279
                if (!is_vlan_dev(dev))
280
                        continue;
281
 
282
                return dev;
283
        }
284
 
285
        return NULL;
286
}
287
 
288
static void vlan_seq_stop(struct seq_file *seq, void *v)
289
{
290
        read_unlock(&dev_base_lock);
291
}
292
 
293
static int vlan_seq_show(struct seq_file *seq, void *v)
294
{
295
        if (v == SEQ_START_TOKEN) {
296
                const char *nmtype = NULL;
297
 
298
                seq_puts(seq, "VLAN Dev name     | VLAN ID\n");
299
 
300
                if (vlan_name_type < ARRAY_SIZE(vlan_name_type_str))
301
                    nmtype =  vlan_name_type_str[vlan_name_type];
302
 
303
                seq_printf(seq, "Name-Type: %s\n",
304
                           nmtype ? nmtype :  "UNKNOWN" );
305
        } else {
306
                const struct net_device *vlandev = v;
307
                const struct vlan_dev_info *dev_info = VLAN_DEV_INFO(vlandev);
308
 
309
                seq_printf(seq, "%-15s| %d  | %s\n",  vlandev->name,
310
                           dev_info->vlan_id,    dev_info->real_dev->name);
311
        }
312
        return 0;
313
}
314
 
315
static int vlandev_seq_show(struct seq_file *seq, void *offset)
316
{
317
        struct net_device *vlandev = (struct net_device *) seq->private;
318
        const struct vlan_dev_info *dev_info = VLAN_DEV_INFO(vlandev);
319
        struct net_device_stats *stats;
320
        static const char fmt[] = "%30s %12lu\n";
321
        int i;
322
 
323
        if (!(vlandev->priv_flags & IFF_802_1Q_VLAN))
324
                return 0;
325
 
326
        seq_printf(seq, "%s  VID: %d     REORDER_HDR: %i  dev->priv_flags: %hx\n",
327
                       vlandev->name, dev_info->vlan_id,
328
                       (int)(dev_info->flags & 1), vlandev->priv_flags);
329
 
330
 
331
        stats = vlan_dev_get_stats(vlandev);
332
 
333
        seq_printf(seq, fmt, "total frames received", stats->rx_packets);
334
        seq_printf(seq, fmt, "total bytes received", stats->rx_bytes);
335
        seq_printf(seq, fmt, "Broadcast/Multicast Rcvd", stats->multicast);
336
        seq_puts(seq, "\n");
337
        seq_printf(seq, fmt, "total frames transmitted", stats->tx_packets);
338
        seq_printf(seq, fmt, "total bytes transmitted", stats->tx_bytes);
339
        seq_printf(seq, fmt, "total headroom inc",
340
                   dev_info->cnt_inc_headroom_on_tx);
341
        seq_printf(seq, fmt, "total encap on xmit",
342
                   dev_info->cnt_encap_on_xmit);
343
        seq_printf(seq, "Device: %s", dev_info->real_dev->name);
344
        /* now show all PRIORITY mappings relating to this VLAN */
345
        seq_printf(seq,
346
                       "\nINGRESS priority mappings: 0:%u  1:%u  2:%u  3:%u  4:%u  5:%u  6:%u 7:%u\n",
347
                       dev_info->ingress_priority_map[0],
348
                       dev_info->ingress_priority_map[1],
349
                       dev_info->ingress_priority_map[2],
350
                       dev_info->ingress_priority_map[3],
351
                       dev_info->ingress_priority_map[4],
352
                       dev_info->ingress_priority_map[5],
353
                       dev_info->ingress_priority_map[6],
354
                       dev_info->ingress_priority_map[7]);
355
 
356
        seq_printf(seq, "EGRESSS priority Mappings: ");
357
        for (i = 0; i < 16; i++) {
358
                const struct vlan_priority_tci_mapping *mp
359
                        = dev_info->egress_priority_map[i];
360
                while (mp) {
361
                        seq_printf(seq, "%u:%hu ",
362
                                   mp->priority, ((mp->vlan_qos >> 13) & 0x7));
363
                        mp = mp->next;
364
                }
365
        }
366
        seq_puts(seq, "\n");
367
 
368
        return 0;
369
}

powered by: WebSVN 2.1.0

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