> 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
> 

Reply via email to