]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/ipv6/addrconf.c
snmp: 64bit ipstats_mib for all arches
[net-next-2.6.git] / net / ipv6 / addrconf.c
index 2514adf5251e94005db3a58935eb6981b6454fb0..e81155d2f251c94295c514660552469c25dff384 100644 (file)
@@ -3862,12 +3862,28 @@ static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib,
        memset(&stats[items], 0, pad);
 }
 
+static inline void __snmp6_fill_stats64(u64 *stats, void __percpu **mib,
+                                     int items, int bytes, size_t syncpoff)
+{
+       int i;
+       int pad = bytes - sizeof(u64) * items;
+       BUG_ON(pad < 0);
+
+       /* Use put_unaligned() because stats may not be aligned for u64. */
+       put_unaligned(items, &stats[0]);
+       for (i = 1; i < items; i++)
+               put_unaligned(snmp_fold_field64(mib, i, syncpoff), &stats[i]);
+
+       memset(&stats[items], 0, pad);
+}
+
 static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
                             int bytes)
 {
        switch (attrtype) {
        case IFLA_INET6_STATS:
-               __snmp6_fill_stats(stats, (void __percpu **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
+               __snmp6_fill_stats64(stats, (void __percpu **)idev->stats.ipv6,
+                                    IPSTATS_MIB_MAX, bytes, offsetof(struct ipstats_mib, syncp));
                break;
        case IFLA_INET6_ICMP6STATS:
                __snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);