Release 4.11 net/8021q/vlanproc.c
/******************************************************************************
* vlanproc.c VLAN Module. /proc filesystem interface.
*
* This module is completely hardware-independent and provides
* access to the router using Linux /proc filesystem.
*
* Author: Ben Greear, <greearb@candelatech.com> coppied from wanproc.c
* by: Gene Kozin <genek@compuserve.com>
*
* Copyright: (c) 1998 Ben Greear
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
* ============================================================================
* Jan 20, 1998 Ben Greear Initial Version
*****************************************************************************/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/fs.h>
#include <linux/netdevice.h>
#include <linux/if_vlan.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
#include "vlanproc.h"
#include "vlan.h"
/****** Function Prototypes *************************************************/
/* Methods for preparing data for reading proc entries */
static int vlan_seq_show(struct seq_file *seq, void *v);
static void *vlan_seq_start(struct seq_file *seq, loff_t *pos);
static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos);
static void vlan_seq_stop(struct seq_file *seq, void *);
static int vlandev_seq_show(struct seq_file *seq, void *v);
/*
* Global Data
*/
/*
* Names of the proc directory entries
*/
static const char name_root[] = "vlan";
static const char name_conf[] = "config";
/*
* Structures for interfacing with the /proc filesystem.
* VLAN creates its own directory /proc/net/vlan with the following
* entries:
* config device status/configuration
* <device> entry for each device
*/
/*
* Generic /proc/net/vlan/<file> file and inode operations
*/
static const struct seq_operations vlan_seq_ops = {
.start = vlan_seq_start,
.next = vlan_seq_next,
.stop = vlan_seq_stop,
.show = vlan_seq_show,
};
static int vlan_seq_open(struct inode *inode, struct file *file)
{
return seq_open_net(inode, file, &vlan_seq_ops,
sizeof(struct seq_net_private));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Stephen Hemminger | 24 | 72.73% | 1 | 50.00% |
Pavel Emelyanov | 9 | 27.27% | 1 | 50.00% |
Total | 33 | 100.00% | 2 | 100.00% |
static const struct file_operations vlan_fops = {
.owner = THIS_MODULE,
.open = vlan_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release_net,
};
/*
* /proc/net/vlan/<device> file and inode operations
*/
static int vlandev_seq_open(struct inode *inode, struct file *file)
{
return single_open(file, vlandev_seq_show, PDE_DATA(inode));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Stephen Hemminger | 28 | 96.55% | 1 | 50.00% |
Al Viro | 1 | 3.45% | 1 | 50.00% |
Total | 29 | 100.00% | 2 | 100.00% |
static const struct file_operations vlandev_fops = {
.owner = THIS_MODULE,
.open = vlandev_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
/*
* Proc filesystem directory entries.
*/
/* Strings */
static const char *const vlan_name_type_str[VLAN_NAME_TYPE_HIGHEST] = {
[VLAN_NAME_TYPE_RAW_PLUS_VID] = "VLAN_NAME_TYPE_RAW_PLUS_VID",
[VLAN_NAME_TYPE_PLUS_VID_NO_PAD] = "VLAN_NAME_TYPE_PLUS_VID_NO_PAD",
[VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD] = "VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD",
[VLAN_NAME_TYPE_PLUS_VID] = "VLAN_NAME_TYPE_PLUS_VID",
};
/*
* Interface functions
*/
/*
* Clean up /proc/net/vlan entries
*/
void vlan_proc_cleanup(struct net *net)
{
struct vlan_net *vn = net_generic(net, vlan_net_id);
if (vn->proc_vlan_conf)
remove_proc_entry(name_conf, vn->proc_vlan_dir);
if (vn->proc_vlan_dir)
remove_proc_entry(name_root, net->proc_net);
/* Dynamically added entries should be cleaned up as their vlan_device
* is removed, so we should not have to take care of it here...
*/
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 24 | 45.28% | 1 | 25.00% |
Pavel Emelyanov | 24 | 45.28% | 2 | 50.00% |
Gao Feng | 5 | 9.43% | 1 | 25.00% |
Total | 53 | 100.00% | 4 | 100.00% |
/*
* Create /proc/net/vlan entries
*/
int __net_init vlan_proc_init(struct net *net)
{
struct vlan_net *vn = net_generic(net, vlan_net_id);
vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net);
if (!vn->proc_vlan_dir)
goto err;
vn->proc_vlan_conf = proc_create(name_conf, S_IFREG|S_IRUSR|S_IWUSR,
vn->proc_vlan_dir, &vlan_fops);
if (!vn->proc_vlan_conf)
goto err;
return 0;
err:
pr_err("can't create entry in proc filesystem!\n");
vlan_proc_cleanup(net);
return -ENOBUFS;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 45 | 45.45% | 1 | 14.29% |
Pavel Emelyanov | 34 | 34.34% | 2 | 28.57% |
Patrick McHardy | 14 | 14.14% | 1 | 14.29% |
Wang Chen | 4 | 4.04% | 1 | 14.29% |
Joe Perches | 1 | 1.01% | 1 | 14.29% |
Alexey Dobriyan | 1 | 1.01% | 1 | 14.29% |
Total | 99 | 100.00% | 7 | 100.00% |
/*
* Add directory entry for VLAN device.
*/
int vlan_proc_add_dev(struct net_device *vlandev)
{
struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id);
if (!strcmp(vlandev->name, name_conf))
return -EINVAL;
vlan->dent =
proc_create_data(vlandev->name, S_IFREG|S_IRUSR|S_IWUSR,
vn->proc_vlan_dir, &vlandev_fops, vlandev);
if (!vlan->dent)
return -ENOBUFS;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 47 | 51.65% | 1 | 16.67% |
Pavel Emelyanov | 17 | 18.68% | 1 | 16.67% |
Américo Wang | 16 | 17.58% | 1 | 16.67% |
Jiri Pirko | 5 | 5.49% | 1 | 16.67% |
Wang Chen | 3 | 3.30% | 1 | 16.67% |
Denis V. Lunev | 3 | 3.30% | 1 | 16.67% |
Total | 91 | 100.00% | 6 | 100.00% |
/*
* Delete directory entry for VLAN device.
*/
void vlan_proc_rem_dev(struct net_device *vlandev)
{
/** NOTE: This will consume the memory pointed to by dent, it seems. */
proc_remove(vlan_dev_priv(vlandev)->dent);
vlan_dev_priv(vlandev)->dent = NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 26 | 86.67% | 1 | 25.00% |
Jiri Pirko | 2 | 6.67% | 1 | 25.00% |
David Howells | 1 | 3.33% | 1 | 25.00% |
Zhang Shengju | 1 | 3.33% | 1 | 25.00% |
Total | 30 | 100.00% | 4 | 100.00% |
/****** Proc filesystem entry points ****************************************/
/*
* The following few functions build the content of /proc/net/vlan/config
*/
/* start read of /proc/net/vlan/config */
static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
__acquires
(rcu)
{
struct net_device *dev;
struct net *net = seq_file_net(seq);
loff_t i = 1;
rcu_read_lock();
if (*pos == 0)
return SEQ_START_TOKEN;
for_each_netdev_rcu(net, dev) {
if (!is_vlan_dev(dev))
continue;
if (i++ == *pos)
return dev;
}
return NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Stephen Hemminger | 34 | 40.48% | 3 | 42.86% |
Pavel Emelyanov | 27 | 32.14% | 2 | 28.57% |
Linus Torvalds | 22 | 26.19% | 1 | 14.29% |
Eric W. Biedermann | 1 | 1.19% | 1 | 14.29% |
Total | 84 | 100.00% | 7 | 100.00% |
static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct net_device *dev;
struct net *net = seq_file_net(seq);
++*pos;
dev = v;
if (v == SEQ_START_TOKEN)
dev = net_device_entry(&net->dev_base_head);
for_each_netdev_continue_rcu(net, dev) {
if (!is_vlan_dev(dev))
continue;
return dev;
}
return NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Pavel Emelyanov | 53 | 64.63% | 2 | 28.57% |
Stephen Hemminger | 22 | 26.83% | 2 | 28.57% |
Linus Torvalds | 4 | 4.88% | 1 | 14.29% |
Oleg Drokin | 2 | 2.44% | 1 | 14.29% |
Eric W. Biedermann | 1 | 1.22% | 1 | 14.29% |
Total | 82 | 100.00% | 7 | 100.00% |
static void vlan_seq_stop(struct seq_file *seq, void *v)
__releases
(rcu)
{
rcu_read_unlock();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Stephen Hemminger | 19 | 86.36% | 3 | 75.00% |
Linus Torvalds | 3 | 13.64% | 1 | 25.00% |
Total | 22 | 100.00% | 4 | 100.00% |
static int vlan_seq_show(struct seq_file *seq, void *v)
{
struct net *net = seq_file_net(seq);
struct vlan_net *vn = net_generic(net, vlan_net_id);
if (v == SEQ_START_TOKEN) {
const char *nmtype = NULL;
seq_puts(seq, "VLAN Dev name | VLAN ID\n");
if (vn->name_type < ARRAY_SIZE(vlan_name_type_str))
nmtype = vlan_name_type_str[vn->name_type];
seq_printf(seq, "Name-Type: %s\n",
nmtype ? nmtype : "UNKNOWN");
} else {
const struct net_device *vlandev = v;
const struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
seq_printf(seq, "%-15s| %d | %s\n", vlandev->name,
vlan->vlan_id, vlan->real_dev->name);
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 53 | 38.41% | 1 | 20.00% |
Stephen Hemminger | 51 | 36.96% | 1 | 20.00% |
Pavel Emelyanov | 28 | 20.29% | 1 | 20.00% |
Jiri Pirko | 5 | 3.62% | 1 | 20.00% |
David S. Miller | 1 | 0.72% | 1 | 20.00% |
Total | 138 | 100.00% | 5 | 100.00% |
static int vlandev_seq_show(struct seq_file *seq, void *offset)
{
struct net_device *vlandev = (struct net_device *) seq->private;
const struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
struct rtnl_link_stats64 temp;
const struct rtnl_link_stats64 *stats;
static const char fmt64[] = "%30s %12llu\n";
int i;
if (!is_vlan_dev(vlandev))
return 0;
stats = dev_get_stats(vlandev, &temp);
seq_printf(seq,
"%s VID: %d REORDER_HDR: %i dev->priv_flags: %hx\n",
vlandev->name, vlan->vlan_id,
(int)(vlan->flags & 1), vlandev->priv_flags);
seq_printf(seq, fmt64, "total frames received", stats->rx_packets);
seq_printf(seq, fmt64, "total bytes received", stats->rx_bytes);
seq_printf(seq, fmt64, "Broadcast/Multicast Rcvd", stats->multicast);
seq_puts(seq, "\n");
seq_printf(seq, fmt64, "total frames transmitted", stats->tx_packets);
seq_printf(seq, fmt64, "total bytes transmitted", stats->tx_bytes);
seq_printf(seq, "Device: %s", vlan->real_dev->name);
/* now show all PRIORITY mappings relating to this VLAN */
seq_printf(seq, "\nINGRESS priority mappings: "
"0:%u 1:%u 2:%u 3:%u 4:%u 5:%u 6:%u 7:%u\n",
vlan->ingress_priority_map[0],
vlan->ingress_priority_map[1],
vlan->ingress_priority_map[2],
vlan->ingress_priority_map[3],
vlan->ingress_priority_map[4],
vlan->ingress_priority_map[5],
vlan->ingress_priority_map[6],
vlan->ingress_priority_map[7]);
seq_printf(seq, " EGRESS priority mappings: ");
for (i = 0; i < 16; i++) {
const struct vlan_priority_tci_mapping *mp
= vlan->egress_priority_map[i];
while (mp) {
seq_printf(seq, "%u:%hu ",
mp->priority, ((mp->vlan_qos >> 13) & 0x7));
mp = mp->next;
}
}
seq_puts(seq, "\n");
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 239 | 69.88% | 1 | 10.00% |
Stephen Hemminger | 55 | 16.08% | 1 | 10.00% |
Eric Dumazet | 15 | 4.39% | 2 | 20.00% |
Jiri Pirko | 15 | 4.39% | 1 | 10.00% |
Ben Hutchings | 11 | 3.22% | 1 | 10.00% |
Joonwoo Park | 3 | 0.88% | 1 | 10.00% |
Patrick McHardy | 3 | 0.88% | 2 | 20.00% |
Wagner Ferenc | 1 | 0.29% | 1 | 10.00% |
Total | 342 | 100.00% | 10 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds | 567 | 44.02% | 1 | 2.50% |
Stephen Hemminger | 371 | 28.80% | 3 | 7.50% |
Pavel Emelyanov | 196 | 15.22% | 5 | 12.50% |
Jiri Pirko | 27 | 2.10% | 1 | 2.50% |
Patrick McHardy | 17 | 1.32% | 3 | 7.50% |
Américo Wang | 16 | 1.24% | 1 | 2.50% |
Eric Dumazet | 15 | 1.16% | 2 | 5.00% |
Hideaki Yoshifuji / 吉藤英明 | 12 | 0.93% | 2 | 5.00% |
Ben Hutchings | 11 | 0.85% | 1 | 2.50% |
Joe Perches | 8 | 0.62% | 1 | 2.50% |
Rusty Russell | 8 | 0.62% | 1 | 2.50% |
Wang Chen | 7 | 0.54% | 1 | 2.50% |
Eric W. Biedermann | 5 | 0.39% | 2 | 5.00% |
Gao Feng | 5 | 0.39% | 1 | 2.50% |
David S. Miller | 4 | 0.31% | 2 | 5.00% |
Denis V. Lunev | 3 | 0.23% | 1 | 2.50% |
Joonwoo Park | 3 | 0.23% | 1 | 2.50% |
Oleg Drokin | 2 | 0.16% | 1 | 2.50% |
Arjan van de Ven | 2 | 0.16% | 1 | 2.50% |
Zhang Shengju | 1 | 0.08% | 1 | 2.50% |
Philippe De Muyter | 1 | 0.08% | 1 | 2.50% |
Al Viro | 1 | 0.08% | 1 | 2.50% |
David Howells | 1 | 0.08% | 1 | 2.50% |
Wagner Ferenc | 1 | 0.08% | 1 | 2.50% |
Jan Engelhardt | 1 | 0.08% | 1 | 2.50% |
Lucas De Marchi | 1 | 0.08% | 1 | 2.50% |
Alexey Dobriyan | 1 | 0.08% | 1 | 2.50% |
Anatol Pomozov | 1 | 0.08% | 1 | 2.50% |
Total | 1288 | 100.00% | 40 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.