> On May 12, 2016, at 12:59 PM, Jiri Pirko <j...@resnulli.us> wrote: > > From: Nogah Frankel <nog...@mellanox.com> > > If there is a dedicated ndo to return SW stats - use > it. Otherwise (indicates that there is no HW stats) use > the default stats ndo. > Return results under IFLA_STATS_LINK_SW_64. > > 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 | 35 +++++++++++++++++++++++++++++------ > 2 files changed, 30 insertions(+), 6 deletions(-) > > diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h > index 98175e7..fcfb944 100644 > --- a/include/uapi/linux/if_link.h > +++ b/include/uapi/linux/if_link.h > @@ -823,6 +823,7 @@ enum { > IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */ > IFLA_STATS_LINK_64, > IFLA_STATS_LINK_XSTATS, > + IFLA_STATS_LINK_SW_64, > __IFLA_STATS_MAX, > }; > > diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c > index a127d67..f8b12e4 100644 > --- a/net/core/rtnetlink.c > +++ b/net/core/rtnetlink.c > @@ -3481,6 +3481,9 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, > struct net_device *dev, > struct nlmsghdr *nlh; > struct nlattr *attr; > int s_prividx = *prividx; > + struct rtnl_link_stats64 *sp; > + struct rtnl_link_stats64 *stats64_sp = 0;
s/0/NULL/ net/core//rtnetlink.c:3485:48: warning: Using plain integer as NULL pointer > + int err; > > ASSERT_RTNL(); > > @@ -3493,24 +3496,20 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, > struct net_device *dev, > ifsm->filter_mask = filter_mask; > > if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, *idxattr)) { > - struct rtnl_link_stats64 *sp; > - > attr = nla_reserve_64bit(skb, IFLA_STATS_LINK_64, > sizeof(struct rtnl_link_stats64), > IFLA_STATS_UNSPEC); > if (!attr) > goto nla_put_failure; > > - sp = nla_data(attr); > - dev_get_stats(dev, sp); > + stats64_sp = nla_data(attr); > + dev_get_stats(dev, stats64_sp); > } > > if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS, *idxattr)) { > const struct rtnl_link_ops *ops = dev->rtnl_link_ops; > > if (ops && ops->fill_linkxstats) { > - int err; > - > *idxattr = IFLA_STATS_LINK_XSTATS; > attr = nla_nest_start(skb, > IFLA_STATS_LINK_XSTATS); > @@ -3525,6 +3524,27 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, > struct net_device *dev, > } > } > > + if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_SW_64, *idxattr)) { > + attr = nla_reserve_64bit(skb, IFLA_STATS_LINK_SW_64, > + sizeof(struct rtnl_link_stats64), > + IFLA_STATS_UNSPEC); > + if (!attr) > + goto nla_put_failure; > + > + sp = nla_data(attr); > + err = dev_get_sw_stats(dev, sp); > + if (err) { > + /* if err it means there is no dedicated ndo to > + * get SW stats - so it is returned by the default > + * stats ndo > + */ > + if (stats64_sp) > + copy_rtnl_link_stats64(sp, stats64_sp); > + else > + dev_get_stats(dev, sp); > + } > + } > + > nlmsg_end(skb, nlh); > > return 0; > @@ -3541,6 +3561,7 @@ nla_put_failure: > > static const struct nla_policy ifla_stats_policy[IFLA_STATS_MAX + 1] = { > [IFLA_STATS_LINK_64] = { .len = sizeof(struct rtnl_link_stats64) }, > + [IFLA_STATS_LINK_SW_64] = { .len = sizeof(struct rtnl_link_stats64) }, > }; > > static size_t if_nlmsg_stats_size(const struct net_device *dev, > @@ -3550,6 +3571,8 @@ static size_t if_nlmsg_stats_size(const struct > net_device *dev, > > if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, 0)) > size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64)); > + if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_SW_64, 0)) > + size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64)); > > if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS, 0)) { > const struct rtnl_link_ops *ops = dev->rtnl_link_ops; > -- > 2.5.5 >