From e926dfe3ba5a78acec3b9866ba2dab4095f33ebe Mon Sep 17 00:00:00 2001 From: Jesse Gross Date: Fri, 18 Nov 2011 10:54:12 -0800 Subject: [PATCH] datapath: Fix unaligned access when storing stats. Both datapath and vport stats contain 64-bit members in a struct but we write them directly in Netlink attributes which only guarantee 32-bit alignment. This causes problems on RISC architectures that care about alignment so this computes the stats on the stack and then memcpy's them. Signed-off-by: Jesse Gross Acked-by: Ben Pfaff --- datapath/datapath.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/datapath/datapath.c b/datapath/datapath.c index c43adf9fa..54248e2e6 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -1261,7 +1261,7 @@ static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, u32 pid, u32 seq, u32 flags, u8 cmd) { struct ovs_header *ovs_header; - struct nlattr *nla; + struct ovs_dp_stats dp_stats; int err; ovs_header = genlmsg_put(skb, pid, seq, &dp_datapath_genl_family, @@ -1277,10 +1277,8 @@ static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, if (err) goto nla_put_failure; - nla = nla_reserve(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats)); - if (!nla) - goto nla_put_failure; - get_dp_stats(dp, nla_data(nla)); + get_dp_stats(dp, &dp_stats); + NLA_PUT(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats), &dp_stats); return genlmsg_end(skb, ovs_header); @@ -1604,7 +1602,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, u32 pid, u32 seq, u32 flags, u8 cmd) { struct ovs_header *ovs_header; - struct nlattr *nla; + struct ovs_vport_stats vport_stats; int err; ovs_header = genlmsg_put(skb, pid, seq, &dp_vport_genl_family, @@ -1619,12 +1617,9 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, NLA_PUT_STRING(skb, OVS_VPORT_ATTR_NAME, vport->ops->get_name(vport)); NLA_PUT_U32(skb, OVS_VPORT_ATTR_UPCALL_PID, vport->upcall_pid); - nla = nla_reserve(skb, OVS_VPORT_ATTR_STATS, - sizeof(struct ovs_vport_stats)); - if (!nla) - goto nla_put_failure; - - vport_get_stats(vport, nla_data(nla)); + vport_get_stats(vport, &vport_stats); + NLA_PUT(skb, OVS_VPORT_ATTR_STATS, sizeof(struct ovs_vport_stats), + &vport_stats); NLA_PUT(skb, OVS_VPORT_ATTR_ADDRESS, ETH_ALEN, vport->ops->get_addr(vport)); -- 2.43.0