// SPDX-License-Identifier: GPL-2.0-only

#include <linux/ethtool.h>
#include <linux/phy.h>
#include "netlink.h"
#include "common.h"

struct strset_info {
	bool per_dev;
	bool free_strings;
	unsigned int count;
	const char (*strings)[ETH_GSTRING_LEN];
};

static const struct strset_info info_template[] = {
	[ETH_SS_TEST] = {
		.per_dev	= true,
	},
	[ETH_SS_STATS] = {
		.per_dev	= true,
	},
	[ETH_SS_PRIV_FLAGS] = {
		.per_dev	= true,
	},
	[ETH_SS_FEATURES] = {
		.per_dev	= false,
		.count		= ARRAY_SIZE(netdev_features_strings),
		.strings	= netdev_features_strings,
	},
	[ETH_SS_RSS_HASH_FUNCS] = {
		.per_dev	= false,
		.count		= ARRAY_SIZE(rss_hash_func_strings),
		.strings	= rss_hash_func_strings,
	},
	[ETH_SS_TUNABLES] = {
		.per_dev	= false,
		.count		= ARRAY_SIZE(tunable_strings),
		.strings	= tunable_strings,
	},
	[ETH_SS_PHY_STATS] = {
		.per_dev	= true,
	},
	[ETH_SS_PHY_TUNABLES] = {
		.per_dev	= false,
		.count		= ARRAY_SIZE(phy_tunable_strings),
		.strings	= phy_tunable_strings,
	},
	[ETH_SS_LINK_MODES] = {
		.per_dev	= false,
		.count		= __ETHTOOL_LINK_MODE_MASK_NBITS,
		.strings	= link_mode_names,
	},
	[ETH_SS_MSG_CLASSES] = {
		.per_dev	= false,
		.count		= NETIF_MSG_CLASS_COUNT,
		.strings	= netif_msg_class_names,
	},
	[ETH_SS_WOL_MODES] = {
		.per_dev	= false,
		.count		= WOL_MODE_COUNT,
		.strings	= wol_mode_names,
	},
	[ETH_SS_SOF_TIMESTAMPING] = {
		.per_dev	= false,
		.count		= __SOF_TIMESTAMPING_CNT,
		.strings	= sof_timestamping_names,
	},
	[ETH_SS_TS_TX_TYPES] = {
		.per_dev	= false,
		.count		= __HWTSTAMP_TX_CNT,
		.strings	= ts_tx_type_names,
	},
	[ETH_SS_TS_RX_FILTERS] = {
		.per_dev	= false,
		.count		= __HWTSTAMP_FILTER_CNT,
		.strings	= ts_rx_filter_names,
	},
	[ETH_SS_TS_FLAGS] = {
		.per_dev	= false,
		.count		= __HWTSTAMP_FLAG_CNT,
		.strings	= ts_flags_names,
	},
	[ETH_SS_UDP_TUNNEL_TYPES] = {
		.per_dev	= false,
		.count		= __ETHTOOL_UDP_TUNNEL_TYPE_CNT,
		.strings	= udp_tunnel_type_names,
	},
	[ETH_SS_STATS_STD] = {
		.per_dev	= false,
		.count		= __ETHTOOL_STATS_CNT,
		.strings	= stats_std_names,
	},
	[ETH_SS_STATS_ETH_PHY] = {
		.per_dev	= false,
		.count		= __ETHTOOL_A_STATS_ETH_PHY_CNT,
		.strings	= stats_eth_phy_names,
	},
	[ETH_SS_STATS_ETH_MAC] = {
		.per_dev	= false,
		.count		= __ETHTOOL_A_STATS_ETH_MAC_CNT,
		.strings	= stats_eth_mac_names,
	},
	[ETH_SS_STATS_ETH_CTRL] = {
		.per_dev	= false,
		.count		= __ETHTOOL_A_STATS_ETH_CTRL_CNT,
		.strings	= stats_eth_ctrl_names,
	},
	[ETH_SS_STATS_RMON] = {
		.per_dev	= false,
		.count		= __ETHTOOL_A_STATS_RMON_CNT,
		.strings	= stats_rmon_names,
	},
	[ETH_SS_STATS_PHY] = {
		.per_dev	= false,
		.count		= __ETHTOOL_A_STATS_PHY_CNT,
		.strings	= stats_phy_names,
	},
};

struct strset_req_info {
	struct ethnl_req_info		base;
	u32				req_ids;
	bool				counts_only;
};

#define STRSET_REQINFO(__req_base) \
	container_of(__req_base, struct strset_req_info, base)

struct strset_reply_data {
	struct ethnl_reply_data		base;
	struct strset_info		sets[ETH_SS_COUNT];
};

#define STRSET_REPDATA(__reply_base) \
	container_of(__reply_base, struct strset_reply_data, base)

const struct nla_policy ethnl_strset_get_policy[] = {
	[ETHTOOL_A_STRSET_HEADER]	=
		NLA_POLICY_NESTED(ethnl_header_policy_phy),
	[ETHTOOL_A_STRSET_STRINGSETS]	= { .type = NLA_NESTED },
	[ETHTOOL_A_STRSET_COUNTS_ONLY]	= { .type = NLA_FLAG },
};

static const struct nla_policy get_stringset_policy[] = {
	[ETHTOOL_A_STRINGSET_ID]	= { .type = NLA_U32 },
};

/**
 * strset_include() - test if a string set should be included in reply
 * @info: parsed client request
 * @data: pointer to request data structure
 * @id:   id of string set to check (ETH_SS_* constants)
 */
static bool strset_include(const struct strset_req_info *info,
			   const struct strset_reply_data *data, u32 id)
{
	bool per_dev;

	BUILD_BUG_ON(ETH_SS_COUNT >= BITS_PER_BYTE * sizeof(info->req_ids));

	if (info->req_ids)
		return info->req_ids & (1U << id);
	per_dev = data->sets[id].per_dev;
	if (!per_dev && !data->sets[id].strings)
		return false;

	return data->base.dev ? per_dev : !per_dev;
}

static int strset_get_id(const struct nlattr *nest, u32 *val,
			 struct netlink_ext_ack *extack)
{
	struct nlattr *tb[ARRAY_SIZE(get_stringset_policy)];
	int ret;

	ret = nla_parse_nested(tb, ARRAY_SIZE(get_stringset_policy) - 1, nest,
			       get_stringset_policy, extack);
	if (ret < 0)
		return ret;
	if (NL_REQ_ATTR_CHECK(extack, nest, tb, ETHTOOL_A_STRINGSET_ID))
		return -EINVAL;

	*val = nla_get_u32(tb[ETHTOOL_A_STRINGSET_ID]);
	return 0;
}

static const struct nla_policy strset_stringsets_policy[] = {
	[ETHTOOL_A_STRINGSETS_STRINGSET]	= { .type = NLA_NESTED },
};

static int strset_parse_request(struct ethnl_req_info *req_base,
				struct nlattr **tb,
				struct netlink_ext_ack *extack)
{
	struct strset_req_info *req_info = STRSET_REQINFO(req_base);
	struct nlattr *nest = tb[ETHTOOL_A_STRSET_STRINGSETS];
	struct nlattr *attr;
	int rem, ret;

	if (!nest)
		return 0;
	ret = nla_validate_nested(nest,
				  ARRAY_SIZE(strset_stringsets_policy) - 1,
				  strset_stringsets_policy, extack);
	if (ret < 0)
		return ret;

	req_info->counts_only = tb[ETHTOOL_A_STRSET_COUNTS_ONLY];
	nla_for_each_nested(attr, nest, rem) {
		u32 id;

		if (WARN_ONCE(nla_type(attr) != ETHTOOL_A_STRINGSETS_STRINGSET,
			      "unexpected attrtype %u in ETHTOOL_A_STRSET_STRINGSETS\n",
			      nla_type(attr)))
			return -EINVAL;

		ret = strset_get_id(attr, &id, extack);
		if (ret < 0)
			return ret;
		if (id >= ETH_SS_COUNT) {
			NL_SET_ERR_MSG_ATTR(extack, attr,
					    "unknown string set id");
			return -EOPNOTSUPP;
		}

		req_info->req_ids |= (1U << id);
	}

	return 0;
}

static void strset_cleanup_data(struct ethnl_reply_data *reply_base)
{
	struct strset_reply_data *data = STRSET_REPDATA(reply_base);
	unsigned int i;

	for (i = 0; i < ETH_SS_COUNT; i++)
		if (data->sets[i].free_strings) {
			kfree(data->sets[i].strings);
			data->sets[i].strings = NULL;
			data->sets[i].free_strings = false;
		}
}

static int strset_prepare_set(struct strset_info *info, struct net_device *dev,
			      struct phy_device *phydev, unsigned int id,
			      bool counts_only)
{
	const struct ethtool_phy_ops *phy_ops = ethtool_phy_ops;
	const struct ethtool_ops *ops = dev->ethtool_ops;
	void *strings;
	int count, ret;

	if (id == ETH_SS_PHY_STATS && phydev &&
	    !ops->get_ethtool_phy_stats && phy_ops &&
	    phy_ops->get_sset_count)
		ret = phy_ops->get_sset_count(phydev);
	else if (ops->get_sset_count && ops->get_strings)
		ret = ops->get_sset_count(dev, id);
	else
		ret = -EOPNOTSUPP;
	if (ret <= 0) {
		info->count = 0;
		return 0;
	}

	count = ret;
	if (!counts_only) {
		strings = kcalloc(count, ETH_GSTRING_LEN, GFP_KERNEL);
		if (!strings)
			return -ENOMEM;
		if (id == ETH_SS_PHY_STATS && phydev &&
		    !ops->get_ethtool_phy_stats && phy_ops &&
		    phy_ops->get_strings)
			phy_ops->get_strings(phydev, strings);
		else
			ops->get_strings(dev, id, strings);
		info->strings = strings;
		info->free_strings = true;
	}
	info->count = count;

	return 0;
}

static int strset_prepare_data(const struct ethnl_req_info *req_base,
			       struct ethnl_reply_data *reply_base,
			       const struct genl_info *info)
{
	const struct strset_req_info *req_info = STRSET_REQINFO(req_base);
	struct strset_reply_data *data = STRSET_REPDATA(reply_base);
	struct net_device *dev = reply_base->dev;
	struct nlattr **tb = info->attrs;
	struct phy_device *phydev;
	unsigned int i;
	int ret;

	BUILD_BUG_ON(ARRAY_SIZE(info_template) != ETH_SS_COUNT);
	memcpy(&data->sets, &info_template, sizeof(data->sets));

	if (!dev) {
		for (i = 0; i < ETH_SS_COUNT; i++) {
			if ((req_info->req_ids & (1U << i)) &&
			    data->sets[i].per_dev) {
				GENL_SET_ERR_MSG(info, "requested per device strings without dev");
				return -EINVAL;
			}
		}
		return 0;
	}

	phydev = ethnl_req_get_phydev(req_base, tb, ETHTOOL_A_HEADER_FLAGS,
				      info->extack);

	/* phydev can be NULL, check for errors only */
	if (IS_ERR(phydev))
		return PTR_ERR(phydev);

	ret = ethnl_ops_begin(dev);
	if (ret < 0)
		goto err_strset;
	for (i = 0; i < ETH_SS_COUNT; i++) {
		if (!strset_include(req_info, data, i) ||
		    !data->sets[i].per_dev)
			continue;

		ret = strset_prepare_set(&data->sets[i], dev, phydev, i,
					 req_info->counts_only);
		if (ret < 0)
			goto err_ops;
	}
	ethnl_ops_complete(dev);

	return 0;
err_ops:
	ethnl_ops_complete(dev);
err_strset:
	strset_cleanup_data(reply_base);
	return ret;
}

/* calculate size of ETHTOOL_A_STRSET_STRINGSET nest for one string set */
static int strset_set_size(const struct strset_info *info, bool counts_only)
{
	unsigned int len = 0;
	unsigned int i;

	if (info->count == 0)
		return 0;
	if (counts_only)
		return nla_total_size(2 * nla_total_size(sizeof(u32)));

	for (i = 0; i < info->count; i++) {
		const char *str = info->strings[i];

		/* ETHTOOL_A_STRING_INDEX, ETHTOOL_A_STRING_VALUE, nest */
		len += nla_total_size(nla_total_size(sizeof(u32)) +
				      ethnl_strz_size(str));
	}
	/* ETHTOOL_A_STRINGSET_ID, ETHTOOL_A_STRINGSET_COUNT */
	len = 2 * nla_total_size(sizeof(u32)) + nla_total_size(len);

	return nla_total_size(len);
}

static int strset_reply_size(const struct ethnl_req_info *req_base,
			     const struct ethnl_reply_data *reply_base)
{
	const struct strset_req_info *req_info = STRSET_REQINFO(req_base);
	const struct strset_reply_data *data = STRSET_REPDATA(reply_base);
	unsigned int i;
	int len = 0;
	int ret;

	len += nla_total_size(0); /* ETHTOOL_A_STRSET_STRINGSETS */

	for (i = 0; i < ETH_SS_COUNT; i++) {
		const struct strset_info *set_info = &data->sets[i];

		if (!strset_include(req_info, data, i))
			continue;

		ret = strset_set_size(set_info, req_info->counts_only);
		if (ret < 0)
			return ret;
		len += ret;
	}

	return len;
}

/* fill one string into reply */
static int strset_fill_string(struct sk_buff *skb,
			      const struct strset_info *set_info, u32 idx)
{
	struct nlattr *string_attr;
	const char *value;

	value = set_info->strings[idx];

	string_attr = nla_nest_start(skb, ETHTOOL_A_STRINGS_STRING);
	if (!string_attr)
		return -EMSGSIZE;
	if (nla_put_u32(skb, ETHTOOL_A_STRING_INDEX, idx) ||
	    ethnl_put_strz(skb, ETHTOOL_A_STRING_VALUE, value))
		goto nla_put_failure;
	nla_nest_end(skb, string_attr);

	return 0;
nla_put_failure:
	nla_nest_cancel(skb, string_attr);
	return -EMSGSIZE;
}

/* fill one string set into reply */
static int strset_fill_set(struct sk_buff *skb,
			   const struct strset_info *set_info, u32 id,
			   bool counts_only)
{
	struct nlattr *stringset_attr;
	struct nlattr *strings_attr;
	unsigned int i;

	if (!set_info->per_dev && !set_info->strings)
		return -EOPNOTSUPP;
	if (set_info->count == 0)
		return 0;
	stringset_attr = nla_nest_start(skb, ETHTOOL_A_STRINGSETS_STRINGSET);
	if (!stringset_attr)
		return -EMSGSIZE;

	if (nla_put_u32(skb, ETHTOOL_A_STRINGSET_ID, id) ||
	    nla_put_u32(skb, ETHTOOL_A_STRINGSET_COUNT, set_info->count))
		goto nla_put_failure;

	if (!counts_only) {
		strings_attr = nla_nest_start(skb, ETHTOOL_A_STRINGSET_STRINGS);
		if (!strings_attr)
			goto nla_put_failure;
		for (i = 0; i < set_info->count; i++) {
			if (strset_fill_string(skb, set_info, i) < 0)
				goto nla_put_failure;
		}
		nla_nest_end(skb, strings_attr);
	}

	nla_nest_end(skb, stringset_attr);
	return 0;

nla_put_failure:
	nla_nest_cancel(skb, stringset_attr);
	return -EMSGSIZE;
}

static int strset_fill_reply(struct sk_buff *skb,
			     const struct ethnl_req_info *req_base,
			     const struct ethnl_reply_data *reply_base)
{
	const struct strset_req_info *req_info = STRSET_REQINFO(req_base);
	const struct strset_reply_data *data = STRSET_REPDATA(reply_base);
	struct nlattr *nest;
	unsigned int i;
	int ret;

	nest = nla_nest_start(skb, ETHTOOL_A_STRSET_STRINGSETS);
	if (!nest)
		return -EMSGSIZE;

	for (i = 0; i < ETH_SS_COUNT; i++) {
		if (strset_include(req_info, data, i)) {
			ret = strset_fill_set(skb, &data->sets[i], i,
					      req_info->counts_only);
			if (ret < 0)
				goto nla_put_failure;
		}
	}

	nla_nest_end(skb, nest);
	return 0;

nla_put_failure:
	nla_nest_cancel(skb, nest);
	return ret;
}

const struct ethnl_request_ops ethnl_strset_request_ops = {
	.request_cmd		= ETHTOOL_MSG_STRSET_GET,
	.reply_cmd		= ETHTOOL_MSG_STRSET_GET_REPLY,
	.hdr_attr		= ETHTOOL_A_STRSET_HEADER,
	.req_info_size		= sizeof(struct strset_req_info),
	.reply_data_size	= sizeof(struct strset_reply_data),
	.allow_nodev_do		= true,

	.parse_request		= strset_parse_request,
	.prepare_data		= strset_prepare_data,
	.reply_size		= strset_reply_size,
	.fill_reply		= strset_fill_reply,
	.cleanup_data		= strset_cleanup_data,
};
