^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /******************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * vlanproc.c VLAN Module. /proc filesystem interface.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * This module is completely hardware-independent and provides
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * access to the router using Linux /proc filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Author: Ben Greear, <greearb@candelatech.com> coppied from wanproc.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * by: Gene Kozin <genek@compuserve.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright: (c) 1998 Ben Greear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * ============================================================================
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Jan 20, 1998 Ben Greear Initial Version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/if_vlan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <net/netns/generic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "vlanproc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "vlan.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) /****** Function Prototypes *************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* Methods for preparing data for reading proc entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static int vlan_seq_show(struct seq_file *seq, void *v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static void *vlan_seq_start(struct seq_file *seq, loff_t *pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static void vlan_seq_stop(struct seq_file *seq, void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static int vlandev_seq_show(struct seq_file *seq, void *v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * Global Data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * Names of the proc directory entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static const char name_root[] = "vlan";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) static const char name_conf[] = "config";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * Structures for interfacing with the /proc filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * VLAN creates its own directory /proc/net/vlan with the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * entries:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * config device status/configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * <device> entry for each device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * Generic /proc/net/vlan/<file> file and inode operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static const struct seq_operations vlan_seq_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .start = vlan_seq_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .next = vlan_seq_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .stop = vlan_seq_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) .show = vlan_seq_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * Proc filesystem directory entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* Strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static const char *const vlan_name_type_str[VLAN_NAME_TYPE_HIGHEST] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) [VLAN_NAME_TYPE_RAW_PLUS_VID] = "VLAN_NAME_TYPE_RAW_PLUS_VID",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) [VLAN_NAME_TYPE_PLUS_VID_NO_PAD] = "VLAN_NAME_TYPE_PLUS_VID_NO_PAD",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) [VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD] = "VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) [VLAN_NAME_TYPE_PLUS_VID] = "VLAN_NAME_TYPE_PLUS_VID",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * Interface functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * Clean up /proc/net/vlan entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) void vlan_proc_cleanup(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct vlan_net *vn = net_generic(net, vlan_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (vn->proc_vlan_conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) remove_proc_entry(name_conf, vn->proc_vlan_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (vn->proc_vlan_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) remove_proc_entry(name_root, net->proc_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* Dynamically added entries should be cleaned up as their vlan_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * is removed, so we should not have to take care of it here...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * Create /proc/net/vlan entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) int __net_init vlan_proc_init(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct vlan_net *vn = net_generic(net, vlan_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) vn->proc_vlan_dir = proc_net_mkdir(net, name_root, net->proc_net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (!vn->proc_vlan_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) vn->proc_vlan_conf = proc_create_net(name_conf, S_IFREG | 0600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) vn->proc_vlan_dir, &vlan_seq_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) sizeof(struct seq_net_private));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (!vn->proc_vlan_conf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) pr_err("can't create entry in proc filesystem!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) vlan_proc_cleanup(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * Add directory entry for VLAN device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) int vlan_proc_add_dev(struct net_device *vlandev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct vlan_net *vn = net_generic(dev_net(vlandev), vlan_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) if (!strcmp(vlandev->name, name_conf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) vlan->dent = proc_create_single_data(vlandev->name, S_IFREG | 0600,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) vn->proc_vlan_dir, vlandev_seq_show, vlandev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (!vlan->dent)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * Delete directory entry for VLAN device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) void vlan_proc_rem_dev(struct net_device *vlandev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /** NOTE: This will consume the memory pointed to by dent, it seems. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) proc_remove(vlan_dev_priv(vlandev)->dent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) vlan_dev_priv(vlandev)->dent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /****** Proc filesystem entry points ****************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * The following few functions build the content of /proc/net/vlan/config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /* start read of /proc/net/vlan/config */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static void *vlan_seq_start(struct seq_file *seq, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) __acquires(rcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct net *net = seq_file_net(seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) loff_t i = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (*pos == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return SEQ_START_TOKEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) for_each_netdev_rcu(net, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (!is_vlan_dev(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) if (i++ == *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static void *vlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct net *net = seq_file_net(seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) dev = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (v == SEQ_START_TOKEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) dev = net_device_entry(&net->dev_base_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) for_each_netdev_continue_rcu(net, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (!is_vlan_dev(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static void vlan_seq_stop(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) __releases(rcu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) static int vlan_seq_show(struct seq_file *seq, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct net *net = seq_file_net(seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) struct vlan_net *vn = net_generic(net, vlan_net_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (v == SEQ_START_TOKEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) const char *nmtype = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) seq_puts(seq, "VLAN Dev name | VLAN ID\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (vn->name_type < ARRAY_SIZE(vlan_name_type_str))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) nmtype = vlan_name_type_str[vn->name_type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) seq_printf(seq, "Name-Type: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) nmtype ? nmtype : "UNKNOWN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) const struct net_device *vlandev = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) const struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) seq_printf(seq, "%-15s| %d | %s\n", vlandev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) vlan->vlan_id, vlan->real_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int vlandev_seq_show(struct seq_file *seq, void *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct net_device *vlandev = (struct net_device *) seq->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) const struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) struct rtnl_link_stats64 temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) const struct rtnl_link_stats64 *stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static const char fmt64[] = "%30s %12llu\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (!is_vlan_dev(vlandev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) stats = dev_get_stats(vlandev, &temp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) seq_printf(seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) "%s VID: %d REORDER_HDR: %i dev->priv_flags: %hx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) vlandev->name, vlan->vlan_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) (int)(vlan->flags & 1), vlandev->priv_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) seq_printf(seq, fmt64, "total frames received", stats->rx_packets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) seq_printf(seq, fmt64, "total bytes received", stats->rx_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) seq_printf(seq, fmt64, "Broadcast/Multicast Rcvd", stats->multicast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) seq_puts(seq, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) seq_printf(seq, fmt64, "total frames transmitted", stats->tx_packets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) seq_printf(seq, fmt64, "total bytes transmitted", stats->tx_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) seq_printf(seq, "Device: %s", vlan->real_dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* now show all PRIORITY mappings relating to this VLAN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) seq_printf(seq, "\nINGRESS priority mappings: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) "0:%u 1:%u 2:%u 3:%u 4:%u 5:%u 6:%u 7:%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) vlan->ingress_priority_map[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) vlan->ingress_priority_map[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) vlan->ingress_priority_map[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) vlan->ingress_priority_map[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) vlan->ingress_priority_map[4],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) vlan->ingress_priority_map[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) vlan->ingress_priority_map[6],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) vlan->ingress_priority_map[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) seq_printf(seq, " EGRESS priority mappings: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) for (i = 0; i < 16; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) const struct vlan_priority_tci_mapping *mp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) = vlan->egress_priority_map[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) while (mp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) seq_printf(seq, "%u:%hu ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) mp->priority, ((mp->vlan_qos >> 13) & 0x7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) mp = mp->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) seq_puts(seq, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }