[PATCH net-next 4/4] rtnetlink: promote IFLA_VF_STATS to same level as IFLA_VF_INFO
From: Edwin Peer <hidden>
Date: 2021-01-23 04:54:53
Subsystem:
networking drivers, networking [general], the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Separating the VF stats out of IFLA_VF_INFO appears to be the least
impact way of resolving the nlattr overflow bug in IFLA_VFINFO_LIST.
Since changing the hierarchy does constitute an ABI change, it must
be explicitly requested via RTEXT_FILTER_VF_SEPARATE_STATS. Otherwise,
the old location is maintained for compatibility.
A new container type, namely IFLA_VFSTATS_LIST, is introduced to group
the stats objects into an ordered list that corresponds with the order
of VFs in IFLA_VFINFO_LIST.
Fixes: 3b766cd83232 ("net/core: Add reading VF statistics through the PF netdevice")
Fixes: c5a9f6f0ab40 ("net/core: Add drop counters to VF statistics")
Signed-off-by: Edwin Peer <redacted>
---
include/uapi/linux/if_link.h | 1 +
include/uapi/linux/rtnetlink.h | 1 +
net/core/rtnetlink.c | 24 +++++++++++++++++++++---
3 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 2bd0d8bbcdb2..db12ffd2bffd 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h@@ -341,6 +341,7 @@ enum { IFLA_ALT_IFNAME, /* Alternative ifname */ IFLA_PERM_ADDRESS, IFLA_PROTO_DOWN_REASON, + IFLA_VFSTATS_LIST, __IFLA_MAX };
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index b841caa4657e..f2f4f9b4d595 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h@@ -789,6 +789,7 @@ enum { #define RTEXT_FILTER_MRP (1 << 4) #define RTEXT_FILTER_CFM_CONFIG (1 << 5) #define RTEXT_FILTER_CFM_STATUS (1 << 6) +#define RTEXT_FILTER_VF_SEPARATE_STATS (1 << 7) /* End of information exported to user level */
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 95564fd12f24..cddd3945bc11 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c@@ -933,6 +933,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev, nla_total_size(sizeof(struct ifla_vf_rss_query_en)) + nla_total_size(sizeof(struct ifla_vf_trust))); if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) { + if (ext_filter_mask & RTEXT_FILTER_VF_SEPARATE_STATS) + size += nla_total_size(0); /* IFLA_VFSTATS_LIST */ size += num_vfs * (nla_total_size(0) + /* nest IFLA_VF_STATS */ /* IFLA_VF_STATS_RX_PACKETS */
@@ -1368,7 +1370,8 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb, goto nla_put_vf_failure; } nla_nest_end(skb, vfvlanlist); - if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) { + if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS && + ~ext_filter_mask & RTEXT_FILTER_VF_SEPARATE_STATS) { if (rtnl_fill_vfstats(skb, dev, vfs_num)) goto nla_put_vf_failure; }
@@ -1386,7 +1389,7 @@ static noinline_for_stack int rtnl_fill_vf(struct sk_buff *skb, struct net_device *dev, u32 ext_filter_mask) { - struct nlattr *vfinfo; + struct nlattr *vfinfo, *vfstats; int i, num_vfs; if (!dev->dev.parent || ((ext_filter_mask & RTEXT_FILTER_VF) == 0))
@@ -1407,8 +1410,23 @@ static noinline_for_stack int rtnl_fill_vf(struct sk_buff *skb, if (rtnl_fill_vfinfo(skb, dev, i, vfinfo, ext_filter_mask)) return -EMSGSIZE; } - nla_nest_end(skb, vfinfo); + + if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS && + ext_filter_mask & RTEXT_FILTER_VF_SEPARATE_STATS) { + vfstats = nla_nest_start_noflag(skb, IFLA_VFSTATS_LIST); + if (!vfstats) + return -EMSGSIZE; + + for (i = 0; i < num_vfs; i++) { + if (rtnl_fill_vfstats(skb, dev, i)) { + nla_nest_cancel(skb, vfstats); + return -EMSGSIZE; + } + } + nla_nest_end(skb, vfstats); + } + return 0; }
--
2.30.0
Attachments
- smime.p7s [application/pkcs7-signature] 4160 bytes