net: rtnetlink: rtnl_fill_statsinfo(): Permit non-EMSGSIZE error returns
authorPetr Machata <petrm@nvidia.com>
Wed, 2 Mar 2022 16:31:19 +0000 (18:31 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 3 Mar 2022 10:37:22 +0000 (10:37 +0000)
Obtaining stats for the IFLA_STATS_LINK_OFFLOAD_XSTATS nest involves a HW
access, and can fail for more reasons than just netlink message size
exhaustion. Therefore do not always return -EMSGSIZE on the failure path,
but respect the error code provided by the callee. Set the error explicitly
where it is reasonable to assume -EMSGSIZE as the failure reason.

Signed-off-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/rtnetlink.c

index 594aba321f424646f914f4cd1bc21f03ca0478ff..4db1d6c01a7d7488802f5a5f9d699c4e2394d353 100644 (file)
@@ -5177,8 +5177,10 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
                attr = nla_reserve_64bit(skb, IFLA_STATS_LINK_64,
                                         sizeof(struct rtnl_link_stats64),
                                         IFLA_STATS_UNSPEC);
-               if (!attr)
+               if (!attr) {
+                       err = -EMSGSIZE;
                        goto nla_put_failure;
+               }
 
                sp = nla_data(attr);
                dev_get_stats(dev, sp);
@@ -5191,8 +5193,10 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
                        *idxattr = IFLA_STATS_LINK_XSTATS;
                        attr = nla_nest_start_noflag(skb,
                                                     IFLA_STATS_LINK_XSTATS);
-                       if (!attr)
+                       if (!attr) {
+                               err = -EMSGSIZE;
                                goto nla_put_failure;
+                       }
 
                        err = ops->fill_linkxstats(skb, dev, prividx, *idxattr);
                        nla_nest_end(skb, attr);
@@ -5214,8 +5218,10 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
                        *idxattr = IFLA_STATS_LINK_XSTATS_SLAVE;
                        attr = nla_nest_start_noflag(skb,
                                                     IFLA_STATS_LINK_XSTATS_SLAVE);
-                       if (!attr)
+                       if (!attr) {
+                               err = -EMSGSIZE;
                                goto nla_put_failure;
+                       }
 
                        err = ops->fill_linkxstats(skb, dev, prividx, *idxattr);
                        nla_nest_end(skb, attr);
@@ -5233,8 +5239,10 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
                *idxattr = IFLA_STATS_LINK_OFFLOAD_XSTATS;
                attr = nla_nest_start_noflag(skb,
                                             IFLA_STATS_LINK_OFFLOAD_XSTATS);
-               if (!attr)
+               if (!attr) {
+                       err = -EMSGSIZE;
                        goto nla_put_failure;
+               }
 
                err = rtnl_offload_xstats_fill(skb, dev, prividx,
                                               off_filter_mask, extack);
@@ -5253,8 +5261,10 @@ static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
 
                *idxattr = IFLA_STATS_AF_SPEC;
                attr = nla_nest_start_noflag(skb, IFLA_STATS_AF_SPEC);
-               if (!attr)
+               if (!attr) {
+                       err = -EMSGSIZE;
                        goto nla_put_failure;
+               }
 
                rcu_read_lock();
                list_for_each_entry_rcu(af_ops, &rtnl_af_ops, list) {
@@ -5298,7 +5308,7 @@ nla_put_failure:
        else
                nlmsg_end(skb, nlh);
 
-       return -EMSGSIZE;
+       return err;
 }
 
 static size_t if_nlmsg_stats_size(const struct net_device *dev,