Release 4.18 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,
};
/*
* 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_net(name_conf, S_IFREG | 0600,
vn->proc_vlan_dir, &vlan_seq_ops,
sizeof(struct seq_net_private));
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 | 42 | 40.78% | 1 | 11.11% |
| Pavel Emelyanov | 34 | 33.01% | 2 | 22.22% |
| Patrick McHardy | 14 | 13.59% | 1 | 11.11% |
| Christoph Hellwig | 8 | 7.77% | 1 | 11.11% |
| Wang Chen | 2 | 1.94% | 1 | 11.11% |
| Joe Perches | 2 | 1.94% | 2 | 22.22% |
| Alexey Dobriyan | 1 | 0.97% | 1 | 11.11% |
| Total | 103 | 100.00% | 9 | 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_single_data(vlandev->name, S_IFREG | 0600,
vn->proc_vlan_dir, vlandev_seq_show, vlandev);
if (!vlan->dent)
return -ENOBUFS;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Linus Torvalds | 44 | 50.00% | 1 | 12.50% |
| Pavel Emelyanov | 17 | 19.32% | 1 | 12.50% |
| Américo Wang | 16 | 18.18% | 1 | 12.50% |
| Jiri Pirko | 5 | 5.68% | 1 | 12.50% |
| Christoph Hellwig | 2 | 2.27% | 1 | 12.50% |
| Denis V. Lunev | 2 | 2.27% | 1 | 12.50% |
| Joe Perches | 1 | 1.14% | 1 | 12.50% |
| Wang Chen | 1 | 1.14% | 1 | 12.50% |
| Total | 88 | 100.00% | 8 | 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% |
| Zhang Shengju | 1 | 3.33% | 1 | 25.00% |
| David Howells | 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% |
| Jiri Pirko | 15 | 4.39% | 1 | 10.00% |
| Eric Dumazet | 15 | 4.39% | 2 | 20.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 | 540 | 46.55% | 1 | 2.56% |
| Stephen Hemminger | 294 | 25.34% | 3 | 7.69% |
| Pavel Emelyanov | 186 | 16.03% | 5 | 12.82% |
| Jiri Pirko | 27 | 2.33% | 1 | 2.56% |
| Patrick McHardy | 17 | 1.47% | 3 | 7.69% |
| Américo Wang | 16 | 1.38% | 1 | 2.56% |
| Eric Dumazet | 15 | 1.29% | 2 | 5.13% |
| Ben Hutchings | 11 | 0.95% | 1 | 2.56% |
| Joe Perches | 10 | 0.86% | 2 | 5.13% |
| Christoph Hellwig | 10 | 0.86% | 2 | 5.13% |
| Gao Feng | 5 | 0.43% | 1 | 2.56% |
| Eric W. Biedermann | 5 | 0.43% | 2 | 5.13% |
| David S. Miller | 4 | 0.34% | 2 | 5.13% |
| Wang Chen | 3 | 0.26% | 1 | 2.56% |
| Joonwoo Park | 3 | 0.26% | 1 | 2.56% |
| Oleg Drokin | 2 | 0.17% | 1 | 2.56% |
| Denis V. Lunev | 2 | 0.17% | 1 | 2.56% |
| Hideaki Yoshifuji / 吉藤英明 | 2 | 0.17% | 1 | 2.56% |
| Zhang Shengju | 1 | 0.09% | 1 | 2.56% |
| Alexey Dobriyan | 1 | 0.09% | 1 | 2.56% |
| Anatol Pomozov | 1 | 0.09% | 1 | 2.56% |
| Lucas De Marchi | 1 | 0.09% | 1 | 2.56% |
| Philippe De Muyter | 1 | 0.09% | 1 | 2.56% |
| David Howells | 1 | 0.09% | 1 | 2.56% |
| Wagner Ferenc | 1 | 0.09% | 1 | 2.56% |
| Jan Engelhardt | 1 | 0.09% | 1 | 2.56% |
| Total | 1160 | 100.00% | 39 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.