Unverified Commit 306a08f9 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!15103 ethtool: fail closed if we can't get max channel used in indirection tables

parents f9012a3c 2b15e449
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -171,11 +171,9 @@ ethnl_set_channels(struct ethnl_req_info *req_info, struct genl_info *info)
	 */
	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;
	max_rxfh_in_use = ethtool_get_max_rxfh_channel(dev);
	if (channels.combined_count + channels.rx_count <= max_rxfh_in_use) {
		GENL_SET_ERR_MSG(info, "requested channel counts are too low for existing indirection table settings");
		GENL_SET_ERR_MSG_FMT(info, "requested channel counts are too low for existing indirection table (%d)", max_rxfh_in_use);
		return -EINVAL;
	}
	if (channels.combined_count + channels.rx_count <= max_rxnfc_in_use) {
+15 −11
Original line number Diff line number Diff line
@@ -587,35 +587,39 @@ int ethtool_get_max_rxnfc_channel(struct net_device *dev, u64 *max)
	return err;
}

int ethtool_get_max_rxfh_channel(struct net_device *dev, u32 *max)
u32 ethtool_get_max_rxfh_channel(struct net_device *dev)
{
	u32 dev_size, current_max = 0;
	u32 dev_size, current_max;
	u32 *indir;
	int ret;

	if (!netif_is_rxfh_configured(dev))
		return 0;

	if (!dev->ethtool_ops->get_rxfh_indir_size ||
	    !dev->ethtool_ops->get_rxfh)
		return -EOPNOTSUPP;
		return 0;
	dev_size = dev->ethtool_ops->get_rxfh_indir_size(dev);
	if (dev_size == 0)
		return -EOPNOTSUPP;
		return 0;

	indir = kcalloc(dev_size, sizeof(indir[0]), GFP_USER);
	if (!indir)
		return -ENOMEM;
		return U32_MAX;

	ret = dev->ethtool_ops->get_rxfh(dev, indir, NULL, NULL);
	if (ret)
		goto out;
	if (ret) {
		current_max = U32_MAX;
		goto out_free;
	}

	current_max = 0;
	while (dev_size--)
		current_max = max(current_max, indir[dev_size]);

	*max = current_max;

out:
out_free:
	kfree(indir);
	return ret;
	return current_max;
}

int ethtool_check_ops(const struct ethtool_ops *ops)
+1 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ int __ethtool_get_link(struct net_device *dev);
bool convert_legacy_settings_to_link_ksettings(
	struct ethtool_link_ksettings *link_ksettings,
	const struct ethtool_cmd *legacy_settings);
int ethtool_get_max_rxfh_channel(struct net_device *dev, u32 *max);
u32 ethtool_get_max_rxfh_channel(struct net_device *dev);
int ethtool_get_max_rxnfc_channel(struct net_device *dev, u64 *max);
int __ethtool_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info);

+1 −3
Original line number Diff line number Diff line
@@ -1847,9 +1847,7 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
	 * 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;
	max_rxfh_in_use = ethtool_get_max_rxfh_channel(dev);
	if (channels.combined_count + channels.rx_count <=
	    max_t(u64, max_rxnfc_in_use, max_rxfh_in_use))
		return -EINVAL;