summaryrefslogtreecommitdiffstats
path: root/net/ethtool/ioctl.c
diff options
context:
space:
mode:
authorGal Pressman <gal@nvidia.com>2022-11-06 14:31:27 +0200
committerPaolo Abeni <pabeni@redhat.com>2022-11-08 12:08:44 +0100
commit47f3ecf4763d3fea37d3453c9ee1f9f2169d71b3 (patch)
tree90403e03187c2518d8543ab37fe045d74109aee4 /net/ethtool/ioctl.c
parent9a0f830f80265bd1ef816e1541ac24bee80e9a3c (diff)
downloadlinux-47f3ecf4763d3fea37d3453c9ee1f9f2169d71b3.tar.gz
linux-47f3ecf4763d3fea37d3453c9ee1f9f2169d71b3.tar.bz2
linux-47f3ecf4763d3fea37d3453c9ee1f9f2169d71b3.zip
ethtool: Fail number of channels change when it conflicts with rxnfc
Similar to what we do with the hash indirection table [1], when network flow classification rules are forwarding traffic to channels greater than the requested number of channels, fail the operation. Without this, traffic could be directed to channels which no longer exist (dropped) after changing number of channels. [1] commit d4ab4286276f ("ethtool: correctly ensure {GS}CHANNELS doesn't conflict with GS{RXFH}") Reviewed-by: Tariq Toukan <tariqt@nvidia.com> Signed-off-by: Gal Pressman <gal@nvidia.com> Link: https://lore.kernel.org/r/20221106123127.522985-1-gal@nvidia.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'net/ethtool/ioctl.c')
-rw-r--r--net/ethtool/ioctl.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/net/ethtool/ioctl.c b/net/ethtool/ioctl.c
index b6835136c53f..e40f5e9e109b 100644
--- a/net/ethtool/ioctl.c
+++ b/net/ethtool/ioctl.c
@@ -1789,7 +1789,8 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
{
struct ethtool_channels channels, curr = { .cmd = ETHTOOL_GCHANNELS };
u16 from_channel, to_channel;
- u32 max_rx_in_use = 0;
+ u64 max_rxnfc_in_use;
+ u32 max_rxfh_in_use;
unsigned int i;
int ret;
@@ -1820,11 +1821,15 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
return -EINVAL;
/* ensure the new Rx count fits within the configured Rx flow
- * indirection table settings */
- if (netif_is_rxfh_configured(dev) &&
- !ethtool_get_max_rxfh_channel(dev, &max_rx_in_use) &&
- (channels.combined_count + channels.rx_count) <= max_rx_in_use)
- return -EINVAL;
+ * indirection table/rxnfc settings */
+ if (ethtool_get_max_rxnfc_channel(dev, &max_rxnfc_in_use))
+ max_rxnfc_in_use = 0;
+ if (!netif_is_rxfh_configured(dev) ||
+ ethtool_get_max_rxfh_channel(dev, &max_rxfh_in_use))
+ max_rxfh_in_use = 0;
+ if (channels.combined_count + channels.rx_count <=
+ max_t(u64, max_rxnfc_in_use, max_rxfh_in_use))
+ return -EINVAL;
/* Disabling channels, query zero-copy AF_XDP sockets */
from_channel = channels.combined_count +