From: Nogah Frankel <nog...@mellanox.com> Since hardware stats are now returned by default, add a way to query only software stats. They are saved in IFLA_SW_STATS64. (This option is valid only if the driver return HW stats in the default ndo stats)
Signed-off-by: Nogah Frankel <nog...@mellanox.com> Reviewed-by: Ido Schimmel <ido...@mellanox.com> Signed-off-by: Jiri Pirko <j...@mellanox.com> --- include/uapi/linux/if_link.h | 1 + net/core/rtnetlink.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index bb36bd5..98175e7 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -156,6 +156,7 @@ enum { IFLA_GSO_MAX_SEGS, IFLA_GSO_MAX_SIZE, IFLA_PAD, + IFLA_SW_STATS64, __IFLA_MAX }; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index d69c464..a127d67 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1046,20 +1046,40 @@ static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev) return 0; } +static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b) +{ + memcpy(v, b, sizeof(*b)); +} + static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb, struct net_device *dev) { + struct rtnl_link_stats64 sw_stats; struct rtnl_link_stats64 *sp; struct nlattr *attr; + int err; attr = nla_reserve_64bit(skb, IFLA_STATS64, sizeof(struct rtnl_link_stats64), IFLA_PAD); + if (!attr) return -EMSGSIZE; sp = nla_data(attr); dev_get_stats(dev, sp); + err = dev_get_sw_stats(dev, &sw_stats); + if (!err) { + attr = nla_reserve_64bit(skb, IFLA_SW_STATS64, + sizeof(struct rtnl_link_stats64), + IFLA_PAD); + + if (!attr) + return -EMSGSIZE; + + copy_rtnl_link_stats64(nla_data(attr), &sw_stats); + } + attr = nla_reserve(skb, IFLA_STATS, sizeof(struct rtnl_link_stats)); if (!attr) -- 2.5.5