Commit 97fc8d0b authored by YOSHIFUJI Hideaki's avatar YOSHIFUJI Hideaki Committed by David S. Miller

[IPV6] SNMP: Use put_unaligned() instead of memcpy().

Hint from David Miller <davem@davemloft.net>.
Signed-off-by: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 952a10be
...@@ -172,7 +172,7 @@ int snmp6_alloc_dev(struct inet6_dev *idev); ...@@ -172,7 +172,7 @@ int snmp6_alloc_dev(struct inet6_dev *idev);
int snmp6_free_dev(struct inet6_dev *idev); int snmp6_free_dev(struct inet6_dev *idev);
int snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign); int snmp6_mib_init(void *ptr[2], size_t mibsize, size_t mibalign);
void snmp6_mib_free(void *ptr[2]); void snmp6_mib_free(void *ptr[2]);
void snmp6_fill_stats(void *stats, struct inet6_dev *idev, int attrtype, int bytes); void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, int bytes);
struct ip6_ra_chain struct ip6_ra_chain
{ {
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/stddef.h> #include <linux/stddef.h>
#include <asm/unaligned.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/tcp.h> #include <net/tcp.h>
#include <net/transp_v6.h> #include <net/transp_v6.h>
...@@ -210,30 +211,23 @@ static const struct file_operations snmp6_seq_fops = { ...@@ -210,30 +211,23 @@ static const struct file_operations snmp6_seq_fops = {
}; };
#endif /* CONFIG_PROC_FS */ #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 static inline void
__snmp6_fill_stats(void *stats, void **mib, int items, int bytes) __snmp6_fill_stats(u64 *stats, void **mib, int items, int bytes)
{ {
int i; int i;
u8 *p = stats;
int pad = bytes - sizeof(u64) * items; int pad = bytes - sizeof(u64) * items;
BUG_ON(pad < 0); BUG_ON(pad < 0);
__set_u64(p, items);
for (i = 1, p += sizeof(u64); i < items; i++, p += sizeof(u64)) /* Use put_unaligned() because stats may not be aligned for u64. */
__set_u64(p, fold_field(mib, i)); put_unaligned(items, &stats[0]);
memset(p, 0, pad); for (i = 1; i < items; i++)
put_unaligned(fold_field(mib, i), &stats[i]);
memset(&stats[items], 0, pad);
} }
void void
snmp6_fill_stats(void *stats, struct inet6_dev *idev, int attrtype, int bytes) snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype, int bytes)
{ {
switch(attrtype) { switch(attrtype) {
case IFLA_INET6_STATS: case IFLA_INET6_STATS:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment