On Fri, 05 Sep 2025 10:07:23 -0700 Breno Leitao wrote: > + int (*get_rxrings)(struct net_device *dev);
I think this can return u32.. The drivers can't possibly fail to know how many queues they have. We already do that for get_rxfh_*_size callbacks > void (*get_pause_stats)(struct net_device *dev, > struct ethtool_pause_stats *pause_stats); > void (*get_pauseparam)(struct net_device *, > diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c > index 1a9ad47f60313..2f3dbef9eb712 100644 > --- a/net/ethtool/ioctl.c > +++ b/net/ethtool/ioctl.c > @@ -1208,6 +1208,22 @@ static noinline_for_stack int ethtool_set_rxnfc(struct > net_device *dev, > return 0; > } > > +static int get_num_rxrings(struct net_device *dev) This one has to indeed keep returning int, until we get rid of get_rxnfc fallback completely. > +{ > + const struct ethtool_ops *ops = dev->ethtool_ops; > + struct ethtool_rxnfc rx_rings; > + int ret; > + > + if (ops->get_rxrings) > + return ops->get_rxrings(dev); > + > + ret = ops->get_rxnfc(dev, &rx_rings, NULL); > + if (ret < 0) > + return ret; > + > + return rx_rings.data; > +} > + > static noinline_for_stack int ethtool_get_rxrings(struct net_device *dev, > u32 cmd, > void __user *useraddr) > @@ -1217,16 +1233,17 @@ static noinline_for_stack int > ethtool_get_rxrings(struct net_device *dev, > const struct ethtool_ops *ops = dev->ethtool_ops; > int ret; > > - if (!ops->get_rxnfc) > + if (!ops->get_rxnfc && !ops->get_rxrings) > return -EOPNOTSUPP; > > ret = ethtool_rxnfc_copy_struct(cmd, &info, &info_size, useraddr); > if (ret) > return ret; > > - ret = ops->get_rxnfc(dev, &info, NULL); > - if (ret < 0) > - return ret; > + if (WARN_ON_ONCE(info.cmd != ETHTOOL_GRXRINGS)) > + return -EOPNOTSUPP; I think malicious user space can trigger this warning with a TOCTOU race. Let's skip the check, it's not really needed? > + info.data = get_num_rxrings(dev);