mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
rtnetlink: extend RTEXT_FILTER_SKIP_STATS to IFLA_VF_INFO
This filter already exists for excluding IPv6 SNMP stats. Extend its definition to also exclude IFLA_VF_INFO stats in RTM_GETLINK. This patch constitutes a partial fix for a netlink attribute nesting overflow bug in IFLA_VFINFO_LIST. By excluding the stats when the requester doesn't need them, the truncation of the VF list is avoided. While it was technically only the stats added in commitc5a9f6f0ab
("net/core: Add drop counters to VF statistics") breaking the camel's back, the appreciable size of the stats data should never have been included without due consideration for the maximum number of VFs supported by PCI. Fixes:3b766cd832
("net/core: Add reading VF statistics through the PF netdevice") Fixes:c5a9f6f0ab
("net/core: Add drop counters to VF statistics") Signed-off-by: Edwin Peer <edwin.peer@broadcom.com> Cc: Edwin Peer <espeer@gmail.com> Signed-off-by: Gal Pressman <gal@nvidia.com> Link: https://lore.kernel.org/r/20230611105108.122586-1-gal@nvidia.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
c180f85825
commit
fa0e21fa44
@ -961,24 +961,27 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev,
|
||||
nla_total_size(sizeof(struct ifla_vf_rate)) +
|
||||
nla_total_size(sizeof(struct ifla_vf_link_state)) +
|
||||
nla_total_size(sizeof(struct ifla_vf_rss_query_en)) +
|
||||
nla_total_size(0) + /* nest IFLA_VF_STATS */
|
||||
/* IFLA_VF_STATS_RX_PACKETS */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_TX_PACKETS */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_RX_BYTES */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_TX_BYTES */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_BROADCAST */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_MULTICAST */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_RX_DROPPED */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_TX_DROPPED */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
nla_total_size(sizeof(struct ifla_vf_trust)));
|
||||
if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) {
|
||||
size += num_vfs *
|
||||
(nla_total_size(0) + /* nest IFLA_VF_STATS */
|
||||
/* IFLA_VF_STATS_RX_PACKETS */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_TX_PACKETS */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_RX_BYTES */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_TX_BYTES */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_BROADCAST */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_MULTICAST */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_RX_DROPPED */
|
||||
nla_total_size_64bit(sizeof(__u64)) +
|
||||
/* IFLA_VF_STATS_TX_DROPPED */
|
||||
nla_total_size_64bit(sizeof(__u64)));
|
||||
}
|
||||
return size;
|
||||
} else
|
||||
return 0;
|
||||
@ -1270,7 +1273,8 @@ static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb,
|
||||
static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
int vfs_num,
|
||||
struct nlattr *vfinfo)
|
||||
struct nlattr *vfinfo,
|
||||
u32 ext_filter_mask)
|
||||
{
|
||||
struct ifla_vf_rss_query_en vf_rss_query_en;
|
||||
struct nlattr *vf, *vfstats, *vfvlanlist;
|
||||
@ -1376,33 +1380,35 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
|
||||
goto nla_put_vf_failure;
|
||||
}
|
||||
nla_nest_end(skb, vfvlanlist);
|
||||
memset(&vf_stats, 0, sizeof(vf_stats));
|
||||
if (dev->netdev_ops->ndo_get_vf_stats)
|
||||
dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
|
||||
&vf_stats);
|
||||
vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS);
|
||||
if (!vfstats)
|
||||
goto nla_put_vf_failure;
|
||||
if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS,
|
||||
vf_stats.rx_packets, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS,
|
||||
vf_stats.tx_packets, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES,
|
||||
vf_stats.rx_bytes, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES,
|
||||
vf_stats.tx_bytes, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
|
||||
vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
|
||||
vf_stats.multicast, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED,
|
||||
vf_stats.rx_dropped, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED,
|
||||
vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) {
|
||||
nla_nest_cancel(skb, vfstats);
|
||||
goto nla_put_vf_failure;
|
||||
if (~ext_filter_mask & RTEXT_FILTER_SKIP_STATS) {
|
||||
memset(&vf_stats, 0, sizeof(vf_stats));
|
||||
if (dev->netdev_ops->ndo_get_vf_stats)
|
||||
dev->netdev_ops->ndo_get_vf_stats(dev, vfs_num,
|
||||
&vf_stats);
|
||||
vfstats = nla_nest_start_noflag(skb, IFLA_VF_STATS);
|
||||
if (!vfstats)
|
||||
goto nla_put_vf_failure;
|
||||
if (nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_PACKETS,
|
||||
vf_stats.rx_packets, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_PACKETS,
|
||||
vf_stats.tx_packets, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_BYTES,
|
||||
vf_stats.rx_bytes, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_BYTES,
|
||||
vf_stats.tx_bytes, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_BROADCAST,
|
||||
vf_stats.broadcast, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_MULTICAST,
|
||||
vf_stats.multicast, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_RX_DROPPED,
|
||||
vf_stats.rx_dropped, IFLA_VF_STATS_PAD) ||
|
||||
nla_put_u64_64bit(skb, IFLA_VF_STATS_TX_DROPPED,
|
||||
vf_stats.tx_dropped, IFLA_VF_STATS_PAD)) {
|
||||
nla_nest_cancel(skb, vfstats);
|
||||
goto nla_put_vf_failure;
|
||||
}
|
||||
nla_nest_end(skb, vfstats);
|
||||
}
|
||||
nla_nest_end(skb, vfstats);
|
||||
nla_nest_end(skb, vf);
|
||||
return 0;
|
||||
|
||||
@ -1435,7 +1441,7 @@ static noinline_for_stack int rtnl_fill_vf(struct sk_buff *skb,
|
||||
return -EMSGSIZE;
|
||||
|
||||
for (i = 0; i < num_vfs; i++) {
|
||||
if (rtnl_fill_vfinfo(skb, dev, i, vfinfo))
|
||||
if (rtnl_fill_vfinfo(skb, dev, i, vfinfo, ext_filter_mask))
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user