ethtool: Centralise validation of ETHTOOL_{G, S}RXFHINDIR parameters
Add a new ethtool operation (get_rxfh_indir_size) to get the indirectional table size. Use this to validate the user buffer size before calling get_rxfh_indir or set_rxfh_indir. Use get_rxnfc to get the number of RX rings, and validate the contents of the new indirection table before calling set_rxfh_indir. Remove this validation from drivers. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Acked-by: Dimitris Michailidis <dm@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
14596f7006
commit
7850f63f16
@@ -956,40 +956,28 @@ static int efx_ethtool_set_rx_ntuple(struct net_device *net_dev,
|
||||
return rc < 0 ? rc : 0;
|
||||
}
|
||||
|
||||
static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev,
|
||||
struct ethtool_rxfh_indir *indir)
|
||||
static u32 efx_ethtool_get_rxfh_indir_size(struct net_device *net_dev)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
size_t copy_size =
|
||||
min_t(size_t, indir->size, ARRAY_SIZE(efx->rx_indir_table));
|
||||
|
||||
if (efx_nic_rev(efx) < EFX_REV_FALCON_B0)
|
||||
return -EOPNOTSUPP;
|
||||
return (efx_nic_rev(efx) < EFX_REV_FALCON_B0 ?
|
||||
0 : ARRAY_SIZE(efx->rx_indir_table));
|
||||
}
|
||||
|
||||
indir->size = ARRAY_SIZE(efx->rx_indir_table);
|
||||
memcpy(indir->ring_index, efx->rx_indir_table,
|
||||
copy_size * sizeof(indir->ring_index[0]));
|
||||
static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev, u32 *indir)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
|
||||
memcpy(indir, efx->rx_indir_table, sizeof(efx->rx_indir_table));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int efx_ethtool_set_rxfh_indir(struct net_device *net_dev,
|
||||
const struct ethtool_rxfh_indir *indir)
|
||||
const u32 *indir)
|
||||
{
|
||||
struct efx_nic *efx = netdev_priv(net_dev);
|
||||
size_t i;
|
||||
|
||||
if (efx_nic_rev(efx) < EFX_REV_FALCON_B0)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Validate size and indices */
|
||||
if (indir->size != ARRAY_SIZE(efx->rx_indir_table))
|
||||
return -EINVAL;
|
||||
for (i = 0; i < ARRAY_SIZE(efx->rx_indir_table); i++)
|
||||
if (indir->ring_index[i] >= efx->n_rx_channels)
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(efx->rx_indir_table, indir->ring_index,
|
||||
sizeof(efx->rx_indir_table));
|
||||
memcpy(efx->rx_indir_table, indir, sizeof(efx->rx_indir_table));
|
||||
efx_nic_push_rx_indir_table(efx);
|
||||
return 0;
|
||||
}
|
||||
@@ -1020,6 +1008,7 @@ const struct ethtool_ops efx_ethtool_ops = {
|
||||
.reset = efx_ethtool_reset,
|
||||
.get_rxnfc = efx_ethtool_get_rxnfc,
|
||||
.set_rx_ntuple = efx_ethtool_set_rx_ntuple,
|
||||
.get_rxfh_indir_size = efx_ethtool_get_rxfh_indir_size,
|
||||
.get_rxfh_indir = efx_ethtool_get_rxfh_indir,
|
||||
.set_rxfh_indir = efx_ethtool_set_rxfh_indir,
|
||||
};
|
||||
|
Reference in New Issue
Block a user