diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r-- | net/ipv6/addrconf.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2514adf5251..e81155d2f25 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3862,12 +3862,28 @@ static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib, | |||
3862 | memset(&stats[items], 0, pad); | 3862 | memset(&stats[items], 0, pad); |
3863 | } | 3863 | } |
3864 | 3864 | ||
3865 | static inline void __snmp6_fill_stats64(u64 *stats, void __percpu **mib, | ||
3866 | int items, int bytes, size_t syncpoff) | ||
3867 | { | ||
3868 | int i; | ||
3869 | int pad = bytes - sizeof(u64) * items; | ||
3870 | BUG_ON(pad < 0); | ||
3871 | |||
3872 | /* Use put_unaligned() because stats may not be aligned for u64. */ | ||
3873 | put_unaligned(items, &stats[0]); | ||
3874 | for (i = 1; i < items; i++) | ||
3875 | put_unaligned(snmp_fold_field64(mib, i, syncpoff), &stats[i]); | ||
3876 | |||
3877 | memset(&stats[items], 0, pad); | ||
3878 | } | ||
3879 | |||
3865 | static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, | 3880 | static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, |
3866 | int bytes) | 3881 | int bytes) |
3867 | { | 3882 | { |
3868 | switch (attrtype) { | 3883 | switch (attrtype) { |
3869 | case IFLA_INET6_STATS: | 3884 | case IFLA_INET6_STATS: |
3870 | __snmp6_fill_stats(stats, (void __percpu **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes); | 3885 | __snmp6_fill_stats64(stats, (void __percpu **)idev->stats.ipv6, |
3886 | IPSTATS_MIB_MAX, bytes, offsetof(struct ipstats_mib, syncp)); | ||
3871 | break; | 3887 | break; |
3872 | case IFLA_INET6_ICMP6STATS: | 3888 | case IFLA_INET6_ICMP6STATS: |
3873 | __snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes); | 3889 | __snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes); |