int snmp6_free_dev(struct inet6_dev *idev);
int snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign);
void snmp6_mib_free(void *ptr[2]);
-void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, int bytes);
+void snmp6_fill_stats(void *stats, struct inet6_dev *idev, int attrtype, int bytes);
struct ip6_ra_chain
{
};
#endif /* CONFIG_PROC_FS */
+/*
+ * Stats may not be aligned for u64, so use memcpy to avoid
+ * unaligned accesses.
+ */
+static inline void __set_u64(void *p, u64 v)
+{
+ memcpy(p, &v, sizeof(u64));
+}
+
static inline void
-__snmp6_fill_stats(u64 *stats, void **mib, int items, int bytes)
+__snmp6_fill_stats(void *stats, void **mib, int items, int bytes)
{
int i;
+ u8 *p = stats;
int pad = bytes - sizeof(u64) * items;
BUG_ON(pad < 0);
- stats[0] = items;
- for (i = 1; i < items; i++)
- stats[i] = (u64)fold_field(mib, i);
- memset(&stats[items], 0, pad);
+ __set_u64(p, items);
+ for (i = 1, p += sizeof(u64); i < items; i++, p += sizeof(u64))
+ __set_u64(p, fold_field(mib, i));
+ memset(p, 0, pad);
}
void
-snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, int bytes)
+snmp6_fill_stats(void *stats, struct inet6_dev *idev, int attrtype, int bytes)
{
switch(attrtype) {
case IFLA_INET6_STATS: