aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c18
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
3865static 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
3865static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, 3880static 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);