From: Denis V. Lunev Date: Tue, 7 Oct 2008 21:47:12 +0000 (-0700) Subject: ipv6: separate seq_ops for global & per/device ipv6 statistics X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=7b43ccecc77480353a5657d993d671cae9e94efd;p=GitHub%2FLineageOS%2Fandroid_kernel_motorola_exynos9610.git ipv6: separate seq_ops for global & per/device ipv6 statistics idev has been stored on seq->private. NULL has been stored for global statistics. The situation is changed with net namespace. We need to store pointer to struct net and the only place is seq->private. So, we'll have for /proc/net/dev_snmp6/* and for /proc/net/snmp6 pointers of two different types stored in the same field. This effectively requires to separate seq_ops of these files. Signed-off-by: Denis V. Lunev Signed-off-by: David S. Miller --- diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index 25eda8bf2182..7601f56ce915 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c @@ -175,26 +175,17 @@ snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist) static int snmp6_seq_show(struct seq_file *seq, void *v) { - struct inet6_dev *idev = (struct inet6_dev *)seq->private; - - if (idev) { - seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex); - snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list); - snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list); - snmp6_seq_show_icmpv6msg(seq, (void **)idev->stats.icmpv6msg); - } else { - snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list); - snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list); - snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics); - snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list); - snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list); - } + snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list); + snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list); + snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics); + snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list); + snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list); return 0; } static int snmp6_seq_open(struct inode *inode, struct file *file) { - return single_open(file, snmp6_seq_show, PDE(inode)->data); + return single_open(file, snmp6_seq_show, NULL); } static const struct file_operations snmp6_seq_fops = { @@ -205,6 +196,30 @@ static const struct file_operations snmp6_seq_fops = { .release = single_release, }; +static int snmp6_dev_seq_show(struct seq_file *seq, void *v) +{ + struct inet6_dev *idev = (struct inet6_dev *)seq->private; + + seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex); + snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list); + snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list); + snmp6_seq_show_icmpv6msg(seq, (void **)idev->stats.icmpv6msg); + return 0; +} + +static int snmp6_dev_seq_open(struct inode *inode, struct file *file) +{ + return single_open(file, snmp6_dev_seq_show, PDE(inode)->data); +} + +static const struct file_operations snmp6_dev_seq_fops = { + .owner = THIS_MODULE, + .open = snmp6_dev_seq_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + int snmp6_register_dev(struct inet6_dev *idev) { struct proc_dir_entry *p; @@ -221,7 +236,8 @@ int snmp6_register_dev(struct inet6_dev *idev) return -ENOENT; p = proc_create_data(idev->dev->name, S_IRUGO, - net->mib.proc_net_devsnmp6, &snmp6_seq_fops, idev); + net->mib.proc_net_devsnmp6, + &snmp6_dev_seq_fops, idev); if (!p) return -ENOMEM;