0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0018
0019 #include <linux/module.h>
0020 #include <linux/errno.h>
0021 #include <linux/kernel.h>
0022 #include <linux/string.h>
0023 #include <linux/proc_fs.h>
0024 #include <linux/seq_file.h>
0025 #include <linux/fs.h>
0026 #include <linux/netdevice.h>
0027 #include <linux/if_vlan.h>
0028 #include <net/net_namespace.h>
0029 #include <net/netns/generic.h>
0030 #include "vlanproc.h"
0031 #include "vlan.h"
0032
0033
0034
0035
0036 static int vlan_seq_show(struct seq_file *seq, void *v);
0037 static void *vlan_seq_start(struct seq_file *seq, loff_t *pos);
0038 static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos);
0039 static void vlan_seq_stop(struct seq_file *seq, void *);
0040 static int vlandev_seq_show(struct seq_file *seq, void *v);
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 static const char name_root[] = "vlan";
0052 static const char name_conf[] = "config";
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 static const struct seq_operations vlan_seq_ops = {
0067 .start = vlan_seq_start,
0068 .next = vlan_seq_next,
0069 .stop = vlan_seq_stop,
0070 .show = vlan_seq_show,
0071 };
0072
0073
0074
0075
0076
0077
0078 static const char *const vlan_name_type_str[VLAN_NAME_TYPE_HIGHEST] = {
0079 [VLAN_NAME_TYPE_RAW_PLUS_VID] = "VLAN_NAME_TYPE_RAW_PLUS_VID",
0080 [VLAN_NAME_TYPE_PLUS_VID_NO_PAD] = "VLAN_NAME_TYPE_PLUS_VID_NO_PAD",
0081 [VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD] = "VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD",
0082 [VLAN_NAME_TYPE_PLUS_VID] = "VLAN_NAME_TYPE_PLUS_VID",
0083 };
0084
0085
0086
0087
0088
0089
0090
0091
0092 void vlan_proc_cleanup(struct net *net)
0093 {
0094 struct vlan_net *vn = net_generic(net, vlan_net_id);
0095
0096 if (vn->proc_vlan_conf)
0097 remove_proc_entry(name_conf, vn->proc_vlan_dir);
0098
0099 if (vn->proc_vlan_dir)
0100 remove_proc_entry(name_root, net->proc_net);
0101
0102
0103
0104
0105 }
0106
0107
0108
0109
0110
0111 int __net_init vlan_proc_init(struct net *net)
0112 {
0113 struct vlan_net *vn = net_generic(net, vlan_net_id);
0114
0115 vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net);
0116 if (!vn->proc_vlan_dir)
0117 goto err;
0118
0119 vn->proc_vlan_conf = proc_create_net(name_conf, S_IFREG | 0600,
0120 vn->proc_vlan_dir, &vlan_seq_ops,
0121 sizeof(struct seq_net_private));
0122 if (!vn->proc_vlan_conf)
0123 goto err;
0124 return 0;
0125
0126 err:
0127 pr_err("can't create entry in proc filesystem!\n");
0128 vlan_proc_cleanup(net);
0129 return -ENOBUFS;
0130 }
0131
0132
0133
0134
0135
0136 int vlan_proc_add_dev(struct net_device *vlandev)
0137 {
0138 struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
0139 struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id);
0140
0141 if (!strcmp(vlandev->name, name_conf))
0142 return -EINVAL;
0143 vlan->dent = proc_create_single_data(vlandev->name, S_IFREG | 0600,
0144 vn->proc_vlan_dir, vlandev_seq_show, vlandev);
0145 if (!vlan->dent)
0146 return -ENOBUFS;
0147 return 0;
0148 }
0149
0150
0151
0152
0153 void vlan_proc_rem_dev(struct net_device *vlandev)
0154 {
0155
0156 proc_remove(vlan_dev_priv(vlandev)->dent);
0157 vlan_dev_priv(vlandev)->dent = NULL;
0158 }
0159
0160
0161
0162
0163
0164
0165
0166
0167 static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
0168 __acquires(rcu)
0169 {
0170 struct net_device *dev;
0171 struct net *net = seq_file_net(seq);
0172 loff_t i = 1;
0173
0174 rcu_read_lock();
0175 if (*pos == 0)
0176 return SEQ_START_TOKEN;
0177
0178 for_each_netdev_rcu(net, dev) {
0179 if (!is_vlan_dev(dev))
0180 continue;
0181
0182 if (i++ == *pos)
0183 return dev;
0184 }
0185
0186 return NULL;
0187 }
0188
0189 static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
0190 {
0191 struct net_device *dev;
0192 struct net *net = seq_file_net(seq);
0193
0194 ++*pos;
0195
0196 dev = v;
0197 if (v == SEQ_START_TOKEN)
0198 dev = net_device_entry(&net->dev_base_head);
0199
0200 for_each_netdev_continue_rcu(net, dev) {
0201 if (!is_vlan_dev(dev))
0202 continue;
0203
0204 return dev;
0205 }
0206
0207 return NULL;
0208 }
0209
0210 static void vlan_seq_stop(struct seq_file *seq, void *v)
0211 __releases(rcu)
0212 {
0213 rcu_read_unlock();
0214 }
0215
0216 static int vlan_seq_show(struct seq_file *seq, void *v)
0217 {
0218 struct net *net = seq_file_net(seq);
0219 struct vlan_net *vn = net_generic(net, vlan_net_id);
0220
0221 if (v == SEQ_START_TOKEN) {
0222 const char *nmtype = NULL;
0223
0224 seq_puts(seq, "VLAN Dev name | VLAN ID\n");
0225
0226 if (vn->name_type < ARRAY_SIZE(vlan_name_type_str))
0227 nmtype = vlan_name_type_str[vn->name_type];
0228
0229 seq_printf(seq, "Name-Type: %s\n",
0230 nmtype ? nmtype : "UNKNOWN");
0231 } else {
0232 const struct net_device *vlandev = v;
0233 const struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
0234
0235 seq_printf(seq, "%-15s| %d | %s\n", vlandev->name,
0236 vlan->vlan_id, vlan->real_dev->name);
0237 }
0238 return 0;
0239 }
0240
0241 static int vlandev_seq_show(struct seq_file *seq, void *offset)
0242 {
0243 struct net_device *vlandev = (struct net_device *) seq->private;
0244 const struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
0245 struct rtnl_link_stats64 temp;
0246 const struct rtnl_link_stats64 *stats;
0247 static const char fmt64[] = "%30s %12llu\n";
0248 int i;
0249
0250 if (!is_vlan_dev(vlandev))
0251 return 0;
0252
0253 stats = dev_get_stats(vlandev, &temp);
0254 seq_printf(seq,
0255 "%s VID: %d REORDER_HDR: %i dev->priv_flags: %llx\n",
0256 vlandev->name, vlan->vlan_id,
0257 (int)(vlan->flags & 1), vlandev->priv_flags);
0258
0259 seq_printf(seq, fmt64, "total frames received", stats->rx_packets);
0260 seq_printf(seq, fmt64, "total bytes received", stats->rx_bytes);
0261 seq_printf(seq, fmt64, "Broadcast/Multicast Rcvd", stats->multicast);
0262 seq_puts(seq, "\n");
0263 seq_printf(seq, fmt64, "total frames transmitted", stats->tx_packets);
0264 seq_printf(seq, fmt64, "total bytes transmitted", stats->tx_bytes);
0265 seq_printf(seq, "Device: %s", vlan->real_dev->name);
0266
0267 seq_printf(seq, "\nINGRESS priority mappings: "
0268 "0:%u 1:%u 2:%u 3:%u 4:%u 5:%u 6:%u 7:%u\n",
0269 vlan->ingress_priority_map[0],
0270 vlan->ingress_priority_map[1],
0271 vlan->ingress_priority_map[2],
0272 vlan->ingress_priority_map[3],
0273 vlan->ingress_priority_map[4],
0274 vlan->ingress_priority_map[5],
0275 vlan->ingress_priority_map[6],
0276 vlan->ingress_priority_map[7]);
0277
0278 seq_printf(seq, " EGRESS priority mappings: ");
0279 for (i = 0; i < 16; i++) {
0280 const struct vlan_priority_tci_mapping *mp
0281 = vlan->egress_priority_map[i];
0282 while (mp) {
0283 seq_printf(seq, "%u:%d ",
0284 mp->priority, ((mp->vlan_qos >> 13) & 0x7));
0285 mp = mp->next;
0286 }
0287 }
0288 seq_puts(seq, "\n");
0289
0290 return 0;
0291 }