// 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_UDP_TUNNEL_TYPES] = {
		.per_dev	= false,
		.count		= __ETHTOOL_UDP_TUNNEL_TYPE_CNT,
		.strings	= udp_tunnel_type_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),
	[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 (!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,
			      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 && dev->phydev &&
	    !ops->get_ethtool_phy_stats && phy_ops &&
	    phy_ops->get_sset_count)
		ret = phy_ops->get_sset_count(dev->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 && dev->phydev &&
		    !ops->get_ethtool_phy_stats && phy_ops &&
		    phy_ops->get_strings)
			phy_ops->get_strings(dev->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,
			       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;
	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) {
				if (info)
					GENL_SET_ERR_MSG(info, "requested per device strings without dev");
				return -EINVAL;
			}
		}
		return 0;
	}

	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, 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;

	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,
};
