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

#include <net/netdev_lock.h>

#include "netlink.h"
#include "common.h"

struct rss_req_info {
	struct ethnl_req_info		base;
	u32				rss_context;
};

struct rss_reply_data {
	struct ethnl_reply_data		base;
	bool				has_flow_hash;
	bool				no_key_fields;
	u32				indir_size;
	u32				hkey_size;
	u32				hfunc;
	u32				input_xfrm;
	u32				*indir_table;
	u8				*hkey;
	int				flow_hash[__ETHTOOL_A_FLOW_CNT];
};

static const u8 ethtool_rxfh_ft_nl2ioctl[] = {
	[ETHTOOL_A_FLOW_ETHER]		= ETHER_FLOW,
	[ETHTOOL_A_FLOW_IP4]		= IPV4_FLOW,
	[ETHTOOL_A_FLOW_IP6]		= IPV6_FLOW,
	[ETHTOOL_A_FLOW_TCP4]		= TCP_V4_FLOW,
	[ETHTOOL_A_FLOW_UDP4]		= UDP_V4_FLOW,
	[ETHTOOL_A_FLOW_SCTP4]		= SCTP_V4_FLOW,
	[ETHTOOL_A_FLOW_AH_ESP4]	= AH_ESP_V4_FLOW,
	[ETHTOOL_A_FLOW_TCP6]		= TCP_V6_FLOW,
	[ETHTOOL_A_FLOW_UDP6]		= UDP_V6_FLOW,
	[ETHTOOL_A_FLOW_SCTP6]		= SCTP_V6_FLOW,
	[ETHTOOL_A_FLOW_AH_ESP6]	= AH_ESP_V6_FLOW,
	[ETHTOOL_A_FLOW_AH4]		= AH_V4_FLOW,
	[ETHTOOL_A_FLOW_ESP4]		= ESP_V4_FLOW,
	[ETHTOOL_A_FLOW_AH6]		= AH_V6_FLOW,
	[ETHTOOL_A_FLOW_ESP6]		= ESP_V6_FLOW,
	[ETHTOOL_A_FLOW_GTPU4]		= GTPU_V4_FLOW,
	[ETHTOOL_A_FLOW_GTPU6]		= GTPU_V6_FLOW,
	[ETHTOOL_A_FLOW_GTPC4]		= GTPC_V4_FLOW,
	[ETHTOOL_A_FLOW_GTPC6]		= GTPC_V6_FLOW,
	[ETHTOOL_A_FLOW_GTPC_TEID4]	= GTPC_TEID_V4_FLOW,
	[ETHTOOL_A_FLOW_GTPC_TEID6]	= GTPC_TEID_V6_FLOW,
	[ETHTOOL_A_FLOW_GTPU_EH4]	= GTPU_EH_V4_FLOW,
	[ETHTOOL_A_FLOW_GTPU_EH6]	= GTPU_EH_V6_FLOW,
	[ETHTOOL_A_FLOW_GTPU_UL4]	= GTPU_UL_V4_FLOW,
	[ETHTOOL_A_FLOW_GTPU_UL6]	= GTPU_UL_V6_FLOW,
	[ETHTOOL_A_FLOW_GTPU_DL4]	= GTPU_DL_V4_FLOW,
	[ETHTOOL_A_FLOW_GTPU_DL6]	= GTPU_DL_V6_FLOW,
};

#define RSS_REQINFO(__req_base) \
	container_of(__req_base, struct rss_req_info, base)

#define RSS_REPDATA(__reply_base) \
	container_of(__reply_base, struct rss_reply_data, base)

const struct nla_policy ethnl_rss_get_policy[] = {
	[ETHTOOL_A_RSS_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
	[ETHTOOL_A_RSS_CONTEXT] = { .type = NLA_U32 },
	[ETHTOOL_A_RSS_START_CONTEXT] = { .type = NLA_U32 },
};

static int
rss_parse_request(struct ethnl_req_info *req_info, struct nlattr **tb,
		  struct netlink_ext_ack *extack)
{
	struct rss_req_info *request = RSS_REQINFO(req_info);

	if (tb[ETHTOOL_A_RSS_CONTEXT])
		request->rss_context = nla_get_u32(tb[ETHTOOL_A_RSS_CONTEXT]);
	if (tb[ETHTOOL_A_RSS_START_CONTEXT]) {
		NL_SET_BAD_ATTR(extack, tb[ETHTOOL_A_RSS_START_CONTEXT]);
		return -EINVAL;
	}

	return 0;
}

static void
rss_prepare_flow_hash(const struct rss_req_info *req, struct net_device *dev,
		      struct rss_reply_data *data, const struct genl_info *info)
{
	int i;

	data->has_flow_hash = false;

	if (!dev->ethtool_ops->get_rxfh_fields)
		return;
	if (req->rss_context && !dev->ethtool_ops->rxfh_per_ctx_fields)
		return;

	mutex_lock(&dev->ethtool->rss_lock);
	for (i = 1; i < __ETHTOOL_A_FLOW_CNT; i++) {
		struct ethtool_rxfh_fields fields = {
			.flow_type	= ethtool_rxfh_ft_nl2ioctl[i],
			.rss_context	= req->rss_context,
		};

		if (dev->ethtool_ops->get_rxfh_fields(dev, &fields)) {
			data->flow_hash[i] = -1; /* Unsupported */
			continue;
		}

		data->flow_hash[i] = fields.data;
		data->has_flow_hash = true;
	}
	mutex_unlock(&dev->ethtool->rss_lock);
}

static int
rss_get_data_alloc(struct net_device *dev, struct rss_reply_data *data)
{
	const struct ethtool_ops *ops = dev->ethtool_ops;
	u32 total_size, indir_bytes;
	u8 *rss_config;

	data->indir_size = 0;
	data->hkey_size = 0;
	if (ops->get_rxfh_indir_size)
		data->indir_size = ops->get_rxfh_indir_size(dev);
	if (ops->get_rxfh_key_size)
		data->hkey_size = ops->get_rxfh_key_size(dev);

	indir_bytes = data->indir_size * sizeof(u32);
	total_size = indir_bytes + data->hkey_size;
	rss_config = kzalloc(total_size, GFP_KERNEL);
	if (!rss_config)
		return -ENOMEM;

	if (data->indir_size)
		data->indir_table = (u32 *)rss_config;
	if (data->hkey_size)
		data->hkey = rss_config + indir_bytes;

	return 0;
}

static void rss_get_data_free(const struct rss_reply_data *data)
{
	kfree(data->indir_table);
}

static int
rss_prepare_get(const struct rss_req_info *request, struct net_device *dev,
		struct rss_reply_data *data, const struct genl_info *info)
{
	const struct ethtool_ops *ops = dev->ethtool_ops;
	struct ethtool_rxfh_param rxfh = {};
	int ret;

	ret = ethnl_ops_begin(dev);
	if (ret < 0)
		return ret;
	mutex_lock(&dev->ethtool->rss_lock);

	ret = rss_get_data_alloc(dev, data);
	if (ret)
		goto out_unlock;

	rxfh.indir_size = data->indir_size;
	rxfh.indir = data->indir_table;
	rxfh.key_size = data->hkey_size;
	rxfh.key = data->hkey;

	ret = ops->get_rxfh(dev, &rxfh);
	if (ret)
		goto out_unlock;

	data->hfunc = rxfh.hfunc;
	data->input_xfrm = rxfh.input_xfrm;
out_unlock:
	mutex_unlock(&dev->ethtool->rss_lock);
	ethnl_ops_complete(dev);
	return ret;
}

static void
__rss_prepare_ctx(struct net_device *dev, struct rss_reply_data *data,
		  struct ethtool_rxfh_context *ctx)
{
	if (WARN_ON_ONCE(data->indir_size != ctx->indir_size ||
			 data->hkey_size != ctx->key_size))
		return;

	data->no_key_fields = !dev->ethtool_ops->rxfh_per_ctx_key;

	data->hfunc = ctx->hfunc;
	data->input_xfrm = ctx->input_xfrm;
	memcpy(data->indir_table, ethtool_rxfh_context_indir(ctx),
	       data->indir_size * sizeof(u32));
	if (data->hkey_size)
		memcpy(data->hkey, ethtool_rxfh_context_key(ctx),
		       data->hkey_size);
}

static int
rss_prepare_ctx(const struct rss_req_info *request, struct net_device *dev,
		struct rss_reply_data *data, const struct genl_info *info)
{
	struct ethtool_rxfh_context *ctx;
	u32 total_size, indir_bytes;
	u8 *rss_config;
	int ret;

	mutex_lock(&dev->ethtool->rss_lock);
	ctx = xa_load(&dev->ethtool->rss_ctx, request->rss_context);
	if (!ctx) {
		ret = -ENOENT;
		goto out_unlock;
	}

	data->indir_size = ctx->indir_size;
	data->hkey_size = ctx->key_size;

	indir_bytes = data->indir_size * sizeof(u32);
	total_size = indir_bytes + data->hkey_size;
	rss_config = kzalloc(total_size, GFP_KERNEL);
	if (!rss_config) {
		ret = -ENOMEM;
		goto out_unlock;
	}

	data->indir_table = (u32 *)rss_config;
	if (data->hkey_size)
		data->hkey = rss_config + indir_bytes;

	__rss_prepare_ctx(dev, data, ctx);

	ret = 0;
out_unlock:
	mutex_unlock(&dev->ethtool->rss_lock);
	return ret;
}

static int
rss_prepare(const struct rss_req_info *request, struct net_device *dev,
	    struct rss_reply_data *data, const struct genl_info *info)
{
	rss_prepare_flow_hash(request, dev, data, info);

	/* Coming from RSS_SET, driver may only have flow_hash_fields ops */
	if (!dev->ethtool_ops->get_rxfh)
		return 0;

	if (request->rss_context)
		return rss_prepare_ctx(request, dev, data, info);
	return rss_prepare_get(request, dev, data, info);
}

static int
rss_prepare_data(const struct ethnl_req_info *req_base,
		 struct ethnl_reply_data *reply_base,
		 const struct genl_info *info)
{
	struct rss_reply_data *data = RSS_REPDATA(reply_base);
	struct rss_req_info *request = RSS_REQINFO(req_base);
	struct net_device *dev = reply_base->dev;
	const struct ethtool_ops *ops;

	ops = dev->ethtool_ops;
	if (!ops->get_rxfh)
		return -EOPNOTSUPP;

	/* Some drivers don't handle rss_context */
	if (request->rss_context && !ops->create_rxfh_context)
		return -EOPNOTSUPP;

	return rss_prepare(request, dev, data, info);
}

static int
rss_reply_size(const struct ethnl_req_info *req_base,
	       const struct ethnl_reply_data *reply_base)
{
	const struct rss_reply_data *data = RSS_REPDATA(reply_base);
	int len;

	len = nla_total_size(sizeof(u32)) +	/* _RSS_CONTEXT */
	      nla_total_size(sizeof(u32)) +	/* _RSS_HFUNC */
	      nla_total_size(sizeof(u32)) +	/* _RSS_INPUT_XFRM */
	      nla_total_size(sizeof(u32) * data->indir_size) + /* _RSS_INDIR */
	      nla_total_size(data->hkey_size) + /* _RSS_HKEY */
	      nla_total_size(0) +		/* _RSS_FLOW_HASH */
		nla_total_size(sizeof(u32)) * ETHTOOL_A_FLOW_MAX +
	      0;

	return len;
}

static int
rss_fill_reply(struct sk_buff *skb, const struct ethnl_req_info *req_base,
	       const struct ethnl_reply_data *reply_base)
{
	const struct rss_reply_data *data = RSS_REPDATA(reply_base);
	struct rss_req_info *request = RSS_REQINFO(req_base);

	if (request->rss_context &&
	    nla_put_u32(skb, ETHTOOL_A_RSS_CONTEXT, request->rss_context))
		return -EMSGSIZE;

	if ((data->indir_size &&
	     nla_put(skb, ETHTOOL_A_RSS_INDIR,
		     sizeof(u32) * data->indir_size, data->indir_table)))
		return -EMSGSIZE;

	if (!data->no_key_fields &&
	    ((data->hfunc &&
	      nla_put_u32(skb, ETHTOOL_A_RSS_HFUNC, data->hfunc)) ||
	     (data->input_xfrm &&
	      nla_put_u32(skb, ETHTOOL_A_RSS_INPUT_XFRM, data->input_xfrm)) ||
	     (data->hkey_size &&
	      nla_put(skb, ETHTOOL_A_RSS_HKEY, data->hkey_size, data->hkey))))
		return -EMSGSIZE;

	if (data->has_flow_hash) {
		struct nlattr *nest;
		int i;

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

		for (i = 1; i < __ETHTOOL_A_FLOW_CNT; i++) {
			if (data->flow_hash[i] >= 0 &&
			    nla_put_uint(skb, i, data->flow_hash[i])) {
				nla_nest_cancel(skb, nest);
				return -EMSGSIZE;
			}
		}

		nla_nest_end(skb, nest);
	}

	return 0;
}

static void rss_cleanup_data(struct ethnl_reply_data *reply_base)
{
	const struct rss_reply_data *data = RSS_REPDATA(reply_base);

	rss_get_data_free(data);
}

struct rss_nl_dump_ctx {
	unsigned long		ifindex;
	unsigned long		ctx_idx;

	/* User wants to only dump contexts from given ifindex */
	unsigned int		match_ifindex;
	unsigned int		start_ctx;
};

static struct rss_nl_dump_ctx *rss_dump_ctx(struct netlink_callback *cb)
{
	NL_ASSERT_CTX_FITS(struct rss_nl_dump_ctx);

	return (struct rss_nl_dump_ctx *)cb->ctx;
}

int ethnl_rss_dump_start(struct netlink_callback *cb)
{
	const struct genl_info *info = genl_info_dump(cb);
	struct rss_nl_dump_ctx *ctx = rss_dump_ctx(cb);
	struct ethnl_req_info req_info = {};
	struct nlattr **tb = info->attrs;
	int ret;

	/* Filtering by context not supported */
	if (tb[ETHTOOL_A_RSS_CONTEXT]) {
		NL_SET_BAD_ATTR(info->extack, tb[ETHTOOL_A_RSS_CONTEXT]);
		return -EINVAL;
	}
	if (tb[ETHTOOL_A_RSS_START_CONTEXT]) {
		ctx->start_ctx = nla_get_u32(tb[ETHTOOL_A_RSS_START_CONTEXT]);
		ctx->ctx_idx = ctx->start_ctx;
	}

	ret = ethnl_parse_header_dev_get(&req_info,
					 tb[ETHTOOL_A_RSS_HEADER],
					 sock_net(cb->skb->sk), cb->extack,
					 false);
	if (req_info.dev) {
		ctx->match_ifindex = req_info.dev->ifindex;
		ctx->ifindex = ctx->match_ifindex;
		ethnl_parse_header_dev_put(&req_info);
		req_info.dev = NULL;
	}

	return ret;
}

static int
rss_dump_one_ctx(struct sk_buff *skb, struct netlink_callback *cb,
		 struct net_device *dev, u32 rss_context)
{
	const struct genl_info *info = genl_info_dump(cb);
	struct rss_reply_data data = {};
	struct rss_req_info req = {};
	void *ehdr;
	int ret;

	req.rss_context = rss_context;

	ehdr = ethnl_dump_put(skb, cb, ETHTOOL_MSG_RSS_GET_REPLY);
	if (!ehdr)
		return -EMSGSIZE;

	ret = ethnl_fill_reply_header(skb, dev, ETHTOOL_A_RSS_HEADER);
	if (ret < 0)
		goto err_cancel;

	ret = rss_prepare(&req, dev, &data, info);
	if (ret)
		goto err_cancel;

	ret = rss_fill_reply(skb, &req.base, &data.base);
	if (ret)
		goto err_cleanup;
	genlmsg_end(skb, ehdr);

	rss_cleanup_data(&data.base);
	return 0;

err_cleanup:
	rss_cleanup_data(&data.base);
err_cancel:
	genlmsg_cancel(skb, ehdr);
	return ret;
}

static int
rss_dump_one_dev(struct sk_buff *skb, struct netlink_callback *cb,
		 struct net_device *dev)
{
	struct rss_nl_dump_ctx *ctx = rss_dump_ctx(cb);
	int ret;

	if (!dev->ethtool_ops->get_rxfh)
		return 0;

	if (!ctx->ctx_idx) {
		ret = rss_dump_one_ctx(skb, cb, dev, 0);
		if (ret)
			return ret;
		ctx->ctx_idx++;
	}

	for (; xa_find(&dev->ethtool->rss_ctx, &ctx->ctx_idx,
		       ULONG_MAX, XA_PRESENT); ctx->ctx_idx++) {
		ret = rss_dump_one_ctx(skb, cb, dev, ctx->ctx_idx);
		if (ret)
			return ret;
	}
	ctx->ctx_idx = ctx->start_ctx;

	return 0;
}

int ethnl_rss_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct rss_nl_dump_ctx *ctx = rss_dump_ctx(cb);
	struct net *net = sock_net(skb->sk);
	struct net_device *dev;
	int ret = 0;

	rtnl_lock();
	for_each_netdev_dump(net, dev, ctx->ifindex) {
		if (ctx->match_ifindex && ctx->match_ifindex != ctx->ifindex)
			break;

		netdev_lock_ops(dev);
		ret = rss_dump_one_dev(skb, cb, dev);
		netdev_unlock_ops(dev);
		if (ret)
			break;
	}
	rtnl_unlock();

	return ret;
}

/* RSS_NTF */

static void ethnl_rss_delete_notify(struct net_device *dev, u32 rss_context)
{
	struct sk_buff *ntf;
	size_t ntf_size;
	void *hdr;

	ntf_size = ethnl_reply_header_size() +
		nla_total_size(sizeof(u32));	/* _RSS_CONTEXT */

	ntf = genlmsg_new(ntf_size, GFP_KERNEL);
	if (!ntf)
		goto out_warn;

	hdr = ethnl_bcastmsg_put(ntf, ETHTOOL_MSG_RSS_DELETE_NTF);
	if (!hdr)
		goto out_free_ntf;

	if (ethnl_fill_reply_header(ntf, dev, ETHTOOL_A_RSS_HEADER) ||
	    nla_put_u32(ntf, ETHTOOL_A_RSS_CONTEXT, rss_context))
		goto out_free_ntf;

	genlmsg_end(ntf, hdr);
	if (ethnl_multicast(ntf, dev))
		goto out_warn;

	return;

out_free_ntf:
	nlmsg_free(ntf);
out_warn:
	pr_warn_once("Failed to send a RSS delete notification");
}

void ethtool_rss_notify(struct net_device *dev, u32 type, u32 rss_context)
{
	struct rss_req_info req_info = {
		.rss_context = rss_context,
	};

	if (type == ETHTOOL_MSG_RSS_DELETE_NTF)
		ethnl_rss_delete_notify(dev, rss_context);
	else
		ethnl_notify(dev, type, &req_info.base);
}

/* RSS_SET */

#define RFH_MASK (RXH_L2DA | RXH_VLAN | RXH_IP_SRC | RXH_IP_DST | \
		  RXH_L3_PROTO | RXH_L4_B_0_1 | RXH_L4_B_2_3 |	  \
		  RXH_GTP_TEID | RXH_DISCARD)

static const struct nla_policy ethnl_rss_flows_policy[] = {
	[ETHTOOL_A_FLOW_ETHER]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_IP4]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_IP6]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_TCP4]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_UDP4]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_SCTP4]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_AH_ESP4]	= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_TCP6]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_UDP6]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_SCTP6]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_AH_ESP6]	= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_AH4]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_ESP4]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_AH6]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_ESP6]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_GTPU4]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_GTPU6]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_GTPC4]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_GTPC6]		= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_GTPC_TEID4]	= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_GTPC_TEID6]	= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_GTPU_EH4]	= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_GTPU_EH6]	= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_GTPU_UL4]	= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_GTPU_UL6]	= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_GTPU_DL4]	= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
	[ETHTOOL_A_FLOW_GTPU_DL6]	= NLA_POLICY_MASK(NLA_UINT, RFH_MASK),
};

const struct nla_policy ethnl_rss_set_policy[ETHTOOL_A_RSS_FLOW_HASH + 1] = {
	[ETHTOOL_A_RSS_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
	[ETHTOOL_A_RSS_CONTEXT] = { .type = NLA_U32, },
	[ETHTOOL_A_RSS_HFUNC] = NLA_POLICY_MIN(NLA_U32, 1),
	[ETHTOOL_A_RSS_INDIR] = { .type = NLA_BINARY, },
	[ETHTOOL_A_RSS_HKEY] = NLA_POLICY_MIN(NLA_BINARY, 1),
	[ETHTOOL_A_RSS_INPUT_XFRM] =
		NLA_POLICY_MAX(NLA_U32, RXH_XFRM_SYM_OR_XOR),
	[ETHTOOL_A_RSS_FLOW_HASH] = NLA_POLICY_NESTED(ethnl_rss_flows_policy),
};

static int
ethnl_rss_set_validate(struct ethnl_req_info *req_info, struct genl_info *info)
{
	const struct ethtool_ops *ops = req_info->dev->ethtool_ops;
	struct rss_req_info *request = RSS_REQINFO(req_info);
	struct nlattr **tb = info->attrs;
	struct nlattr *bad_attr = NULL;
	u32 input_xfrm;

	if (request->rss_context && !ops->create_rxfh_context)
		bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_CONTEXT];

	if (request->rss_context && !ops->rxfh_per_ctx_key) {
		bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_HFUNC];
		bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_HKEY];
		bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_INPUT_XFRM];
	}

	input_xfrm = nla_get_u32_default(tb[ETHTOOL_A_RSS_INPUT_XFRM], 0);
	if (input_xfrm & ~ops->supported_input_xfrm)
		bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_INPUT_XFRM];

	if (tb[ETHTOOL_A_RSS_FLOW_HASH] && !ops->set_rxfh_fields)
		bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_FLOW_HASH];
	if (request->rss_context &&
	    tb[ETHTOOL_A_RSS_FLOW_HASH] && !ops->rxfh_per_ctx_fields)
		bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_FLOW_HASH];

	if (bad_attr) {
		NL_SET_BAD_ATTR(info->extack, bad_attr);
		return -EOPNOTSUPP;
	}

	return 1;
}

static int
rss_set_prep_indir(struct net_device *dev, struct genl_info *info,
		   struct rss_reply_data *data, struct ethtool_rxfh_param *rxfh,
		   bool *reset, bool *mod)
{
	const struct ethtool_ops *ops = dev->ethtool_ops;
	struct netlink_ext_ack *extack = info->extack;
	struct nlattr **tb = info->attrs;
	struct ethtool_rxnfc rx_rings;
	size_t alloc_size;
	u32 user_size;
	int i, err;

	if (!tb[ETHTOOL_A_RSS_INDIR])
		return 0;
	if (!data->indir_size || !ops->get_rxnfc)
		return -EOPNOTSUPP;

	rx_rings.cmd = ETHTOOL_GRXRINGS;
	err = ops->get_rxnfc(dev, &rx_rings, NULL);
	if (err)
		return err;

	if (nla_len(tb[ETHTOOL_A_RSS_INDIR]) % 4) {
		NL_SET_BAD_ATTR(info->extack, tb[ETHTOOL_A_RSS_INDIR]);
		return -EINVAL;
	}
	user_size = nla_len(tb[ETHTOOL_A_RSS_INDIR]) / 4;
	if (!user_size) {
		if (rxfh->rss_context) {
			NL_SET_ERR_MSG_ATTR(extack, tb[ETHTOOL_A_RSS_INDIR],
					    "can't reset table for a context");
			return -EINVAL;
		}
		*reset = true;
	} else if (data->indir_size % user_size) {
		NL_SET_ERR_MSG_ATTR_FMT(extack, tb[ETHTOOL_A_RSS_INDIR],
					"size (%d) mismatch with device indir table (%d)",
					user_size, data->indir_size);
		return -EINVAL;
	}

	rxfh->indir_size = data->indir_size;
	alloc_size = array_size(data->indir_size, sizeof(rxfh->indir[0]));
	rxfh->indir = kzalloc(alloc_size, GFP_KERNEL);
	if (!rxfh->indir)
		return -ENOMEM;

	nla_memcpy(rxfh->indir, tb[ETHTOOL_A_RSS_INDIR], alloc_size);
	for (i = 0; i < user_size; i++) {
		if (rxfh->indir[i] < rx_rings.data)
			continue;

		NL_SET_ERR_MSG_ATTR_FMT(extack, tb[ETHTOOL_A_RSS_INDIR],
					"entry %d: queue out of range (%d)",
					i, rxfh->indir[i]);
		err = -EINVAL;
		goto err_free;
	}

	if (user_size) {
		/* Replicate the user-provided table to fill the device table */
		for (i = user_size; i < data->indir_size; i++)
			rxfh->indir[i] = rxfh->indir[i % user_size];
	} else {
		for (i = 0; i < data->indir_size; i++)
			rxfh->indir[i] =
				ethtool_rxfh_indir_default(i, rx_rings.data);
	}

	*mod |= memcmp(rxfh->indir, data->indir_table, data->indir_size);

	return 0;

err_free:
	kfree(rxfh->indir);
	rxfh->indir = NULL;
	return err;
}

static int
rss_set_prep_hkey(struct net_device *dev, struct genl_info *info,
		  struct rss_reply_data *data, struct ethtool_rxfh_param *rxfh,
		  bool *mod)
{
	struct nlattr **tb = info->attrs;

	if (!tb[ETHTOOL_A_RSS_HKEY])
		return 0;

	if (nla_len(tb[ETHTOOL_A_RSS_HKEY]) != data->hkey_size) {
		NL_SET_BAD_ATTR(info->extack, tb[ETHTOOL_A_RSS_HKEY]);
		return -EINVAL;
	}

	rxfh->key_size = data->hkey_size;
	rxfh->key = kmemdup(data->hkey, data->hkey_size, GFP_KERNEL);
	if (!rxfh->key)
		return -ENOMEM;

	ethnl_update_binary(rxfh->key, rxfh->key_size, tb[ETHTOOL_A_RSS_HKEY],
			    mod);
	return 0;
}

static int
rss_check_rxfh_fields_sym(struct net_device *dev, struct genl_info *info,
			  struct rss_reply_data *data, bool xfrm_sym)
{
	struct nlattr **tb = info->attrs;
	int i;

	if (!xfrm_sym)
		return 0;
	if (!data->has_flow_hash) {
		NL_SET_ERR_MSG_ATTR(info->extack, tb[ETHTOOL_A_RSS_INPUT_XFRM],
				    "hash field config not reported");
		return -EINVAL;
	}

	for (i = 1; i < __ETHTOOL_A_FLOW_CNT; i++)
		if (data->flow_hash[i] >= 0 &&
		    !ethtool_rxfh_config_is_sym(data->flow_hash[i])) {
			NL_SET_ERR_MSG_ATTR(info->extack,
					    tb[ETHTOOL_A_RSS_INPUT_XFRM],
					    "hash field config is not symmetric");
			return -EINVAL;
		}

	return 0;
}

static int
ethnl_set_rss_fields(struct net_device *dev, struct genl_info *info,
		     u32 rss_context, struct rss_reply_data *data,
		     bool xfrm_sym, bool *mod)
{
	struct nlattr *flow_nest = info->attrs[ETHTOOL_A_RSS_FLOW_HASH];
	struct nlattr *flows[ETHTOOL_A_FLOW_MAX + 1];
	const struct ethtool_ops *ops;
	int i, ret;

	ops = dev->ethtool_ops;

	ret = rss_check_rxfh_fields_sym(dev, info, data, xfrm_sym);
	if (ret)
		return ret;

	if (!flow_nest)
		return 0;

	ret = nla_parse_nested(flows, ARRAY_SIZE(ethnl_rss_flows_policy) - 1,
			       flow_nest, ethnl_rss_flows_policy, info->extack);
	if (ret < 0)
		return ret;

	for (i = 1; i < __ETHTOOL_A_FLOW_CNT; i++) {
		struct ethtool_rxfh_fields fields = {
			.flow_type	= ethtool_rxfh_ft_nl2ioctl[i],
			.rss_context	= rss_context,
		};

		if (!flows[i])
			continue;

		fields.data = nla_get_u32(flows[i]);
		if (data->has_flow_hash && data->flow_hash[i] == fields.data)
			continue;

		if (xfrm_sym && !ethtool_rxfh_config_is_sym(fields.data)) {
			NL_SET_ERR_MSG_ATTR(info->extack, flows[i],
					    "conflict with xfrm-input");
			return -EINVAL;
		}

		ret = ops->set_rxfh_fields(dev, &fields, info->extack);
		if (ret)
			return ret;

		*mod = true;
	}

	return 0;
}

static void
rss_set_ctx_update(struct ethtool_rxfh_context *ctx, struct nlattr **tb,
		   struct rss_reply_data *data, struct ethtool_rxfh_param *rxfh)
{
	int i;

	if (rxfh->indir) {
		for (i = 0; i < data->indir_size; i++)
			ethtool_rxfh_context_indir(ctx)[i] = rxfh->indir[i];
		ctx->indir_configured = !!nla_len(tb[ETHTOOL_A_RSS_INDIR]);
	}
	if (rxfh->key) {
		memcpy(ethtool_rxfh_context_key(ctx), rxfh->key,
		       data->hkey_size);
		ctx->key_configured = !!rxfh->key_size;
	}
	if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE)
		ctx->hfunc = rxfh->hfunc;
	if (rxfh->input_xfrm != RXH_XFRM_NO_CHANGE)
		ctx->input_xfrm = rxfh->input_xfrm;
}

static int
ethnl_rss_set(struct ethnl_req_info *req_info, struct genl_info *info)
{
	bool indir_reset = false, indir_mod, xfrm_sym = false;
	struct rss_req_info *request = RSS_REQINFO(req_info);
	struct ethtool_rxfh_context *ctx = NULL;
	struct net_device *dev = req_info->dev;
	bool mod = false, fields_mod = false;
	struct ethtool_rxfh_param rxfh = {};
	struct nlattr **tb = info->attrs;
	struct rss_reply_data data = {};
	const struct ethtool_ops *ops;
	int ret;

	ops = dev->ethtool_ops;
	data.base.dev = dev;

	ret = rss_prepare(request, dev, &data, info);
	if (ret)
		return ret;

	rxfh.rss_context = request->rss_context;

	ret = rss_set_prep_indir(dev, info, &data, &rxfh, &indir_reset, &mod);
	if (ret)
		goto exit_clean_data;
	indir_mod = !!tb[ETHTOOL_A_RSS_INDIR];

	rxfh.hfunc = data.hfunc;
	ethnl_update_u8(&rxfh.hfunc, tb[ETHTOOL_A_RSS_HFUNC], &mod);
	if (rxfh.hfunc == data.hfunc)
		rxfh.hfunc = ETH_RSS_HASH_NO_CHANGE;

	ret = rss_set_prep_hkey(dev, info, &data, &rxfh, &mod);
	if (ret)
		goto exit_free_indir;

	rxfh.input_xfrm = data.input_xfrm;
	ethnl_update_u8(&rxfh.input_xfrm, tb[ETHTOOL_A_RSS_INPUT_XFRM], &mod);
	/* For drivers which don't support input_xfrm it will be set to 0xff
	 * in the RSS context info. In all other case input_xfrm != 0 means
	 * symmetric hashing is requested.
	 */
	if (!request->rss_context || ops->rxfh_per_ctx_key)
		xfrm_sym = rxfh.input_xfrm || data.input_xfrm;
	if (rxfh.input_xfrm == data.input_xfrm)
		rxfh.input_xfrm = RXH_XFRM_NO_CHANGE;

	mutex_lock(&dev->ethtool->rss_lock);
	if (request->rss_context) {
		ctx = xa_load(&dev->ethtool->rss_ctx, request->rss_context);
		if (!ctx) {
			ret = -ENOENT;
			goto exit_unlock;
		}
	}

	ret = ethnl_set_rss_fields(dev, info, request->rss_context,
				   &data, xfrm_sym, &fields_mod);
	if (ret)
		goto exit_unlock;

	if (!mod)
		ret = 0; /* nothing to tell the driver */
	else if (!ops->set_rxfh)
		ret = -EOPNOTSUPP;
	else if (!rxfh.rss_context)
		ret = ops->set_rxfh(dev, &rxfh, info->extack);
	else
		ret = ops->modify_rxfh_context(dev, ctx, &rxfh, info->extack);
	if (ret)
		goto exit_unlock;

	if (ctx)
		rss_set_ctx_update(ctx, tb, &data, &rxfh);
	else if (indir_reset)
		dev->priv_flags &= ~IFF_RXFH_CONFIGURED;
	else if (indir_mod)
		dev->priv_flags |= IFF_RXFH_CONFIGURED;

exit_unlock:
	mutex_unlock(&dev->ethtool->rss_lock);
	kfree(rxfh.key);
exit_free_indir:
	kfree(rxfh.indir);
exit_clean_data:
	rss_cleanup_data(&data.base);

	return ret ?: mod || fields_mod;
}

const struct ethnl_request_ops ethnl_rss_request_ops = {
	.request_cmd		= ETHTOOL_MSG_RSS_GET,
	.reply_cmd		= ETHTOOL_MSG_RSS_GET_REPLY,
	.hdr_attr		= ETHTOOL_A_RSS_HEADER,
	.req_info_size		= sizeof(struct rss_req_info),
	.reply_data_size	= sizeof(struct rss_reply_data),

	.parse_request		= rss_parse_request,
	.prepare_data		= rss_prepare_data,
	.reply_size		= rss_reply_size,
	.fill_reply		= rss_fill_reply,
	.cleanup_data		= rss_cleanup_data,

	.set_validate		= ethnl_rss_set_validate,
	.set			= ethnl_rss_set,
	.set_ntf_cmd		= ETHTOOL_MSG_RSS_NTF,
};

/* RSS_CREATE */

const struct nla_policy ethnl_rss_create_policy[ETHTOOL_A_RSS_INPUT_XFRM + 1] = {
	[ETHTOOL_A_RSS_HEADER]	= NLA_POLICY_NESTED(ethnl_header_policy),
	[ETHTOOL_A_RSS_CONTEXT]	= NLA_POLICY_MIN(NLA_U32, 1),
	[ETHTOOL_A_RSS_HFUNC]	= NLA_POLICY_MIN(NLA_U32, 1),
	[ETHTOOL_A_RSS_INDIR]	= NLA_POLICY_MIN(NLA_BINARY, 1),
	[ETHTOOL_A_RSS_HKEY]	= NLA_POLICY_MIN(NLA_BINARY, 1),
	[ETHTOOL_A_RSS_INPUT_XFRM] =
		NLA_POLICY_MAX(NLA_U32, RXH_XFRM_SYM_OR_XOR),
};

static int
ethnl_rss_create_validate(struct net_device *dev, struct genl_info *info)
{
	const struct ethtool_ops *ops = dev->ethtool_ops;
	struct nlattr **tb = info->attrs;
	struct nlattr *bad_attr = NULL;
	u32 rss_context, input_xfrm;

	if (!ops->create_rxfh_context)
		return -EOPNOTSUPP;

	rss_context = nla_get_u32_default(tb[ETHTOOL_A_RSS_CONTEXT], 0);
	if (ops->rxfh_max_num_contexts &&
	    ops->rxfh_max_num_contexts <= rss_context) {
		NL_SET_BAD_ATTR(info->extack, tb[ETHTOOL_A_RSS_CONTEXT]);
		return -ERANGE;
	}

	if (!ops->rxfh_per_ctx_key) {
		bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_HFUNC];
		bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_HKEY];
		bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_INPUT_XFRM];
	}

	input_xfrm = nla_get_u32_default(tb[ETHTOOL_A_RSS_INPUT_XFRM], 0);
	if (input_xfrm & ~ops->supported_input_xfrm)
		bad_attr = bad_attr ?: tb[ETHTOOL_A_RSS_INPUT_XFRM];

	if (bad_attr) {
		NL_SET_BAD_ATTR(info->extack, bad_attr);
		return -EOPNOTSUPP;
	}

	return 0;
}

static void
ethnl_rss_create_send_ntf(struct sk_buff *rsp, struct net_device *dev)
{
	struct nlmsghdr *nlh = (void *)rsp->data;
	struct genlmsghdr *genl_hdr;

	/* Convert the reply into a notification */
	nlh->nlmsg_pid = 0;
	nlh->nlmsg_seq = ethnl_bcast_seq_next();

	genl_hdr = nlmsg_data(nlh);
	genl_hdr->cmd =	ETHTOOL_MSG_RSS_CREATE_NTF;

	ethnl_multicast(rsp, dev);
}

int ethnl_rss_create_doit(struct sk_buff *skb, struct genl_info *info)
{
	bool indir_dflt = false, mod = false, ntf_fail = false;
	struct ethtool_rxfh_param rxfh = {};
	struct ethtool_rxfh_context *ctx;
	struct nlattr **tb = info->attrs;
	struct rss_reply_data data = {};
	const struct ethtool_ops *ops;
	struct rss_req_info req = {};
	struct net_device *dev;
	struct sk_buff *rsp;
	void *hdr;
	u32 limit;
	int ret;

	rsp = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
	if (!rsp)
		return -ENOMEM;

	ret = ethnl_parse_header_dev_get(&req.base, tb[ETHTOOL_A_RSS_HEADER],
					 genl_info_net(info), info->extack,
					 true);
	if (ret < 0)
		goto exit_free_rsp;

	dev = req.base.dev;
	ops = dev->ethtool_ops;

	req.rss_context = nla_get_u32_default(tb[ETHTOOL_A_RSS_CONTEXT], 0);

	ret = ethnl_rss_create_validate(dev, info);
	if (ret)
		goto exit_free_dev;

	rtnl_lock();
	netdev_lock_ops(dev);

	ret = ethnl_ops_begin(dev);
	if (ret < 0)
		goto exit_dev_unlock;

	ret = rss_get_data_alloc(dev, &data);
	if (ret)
		goto exit_ops;

	ret = rss_set_prep_indir(dev, info, &data, &rxfh, &indir_dflt, &mod);
	if (ret)
		goto exit_clean_data;

	ethnl_update_u8(&rxfh.hfunc, tb[ETHTOOL_A_RSS_HFUNC], &mod);

	ret = rss_set_prep_hkey(dev, info, &data, &rxfh, &mod);
	if (ret)
		goto exit_free_indir;

	rxfh.input_xfrm = RXH_XFRM_NO_CHANGE;
	ethnl_update_u8(&rxfh.input_xfrm, tb[ETHTOOL_A_RSS_INPUT_XFRM], &mod);

	ctx = ethtool_rxfh_ctx_alloc(ops, data.indir_size, data.hkey_size);
	if (!ctx) {
		ret = -ENOMEM;
		goto exit_free_hkey;
	}

	mutex_lock(&dev->ethtool->rss_lock);
	if (!req.rss_context) {
		limit = ops->rxfh_max_num_contexts ?: U32_MAX;
		ret = xa_alloc(&dev->ethtool->rss_ctx, &req.rss_context, ctx,
			       XA_LIMIT(1, limit - 1), GFP_KERNEL_ACCOUNT);
	} else {
		ret = xa_insert(&dev->ethtool->rss_ctx,
				req.rss_context, ctx, GFP_KERNEL_ACCOUNT);
	}
	if (ret < 0) {
		NL_SET_ERR_MSG_ATTR(info->extack, tb[ETHTOOL_A_RSS_CONTEXT],
				    "error allocating context ID");
		goto err_unlock_free_ctx;
	}
	rxfh.rss_context = req.rss_context;

	ret = ops->create_rxfh_context(dev, ctx, &rxfh, info->extack);
	if (ret)
		goto err_ctx_id_free;

	/* Make sure driver populates defaults */
	WARN_ON_ONCE(!rxfh.key && ops->rxfh_per_ctx_key &&
		     !memchr_inv(ethtool_rxfh_context_key(ctx), 0,
				 ctx->key_size));

	/* Store the config from rxfh to Xarray.. */
	rss_set_ctx_update(ctx, tb, &data, &rxfh);
	/* .. copy from Xarray to data. */
	__rss_prepare_ctx(dev, &data, ctx);

	hdr = ethnl_unicast_put(rsp, info->snd_portid, info->snd_seq,
				ETHTOOL_MSG_RSS_CREATE_ACT_REPLY);
	ntf_fail = ethnl_fill_reply_header(rsp, dev, ETHTOOL_A_RSS_HEADER);
	ntf_fail |= rss_fill_reply(rsp, &req.base, &data.base);
	if (WARN_ON(!hdr || ntf_fail)) {
		ret = -EMSGSIZE;
		goto exit_unlock;
	}

	genlmsg_end(rsp, hdr);

	/* Use the same skb for the response and the notification,
	 * genlmsg_reply() will copy the skb if it has elevated user count.
	 */
	skb_get(rsp);
	ret = genlmsg_reply(rsp, info);
	ethnl_rss_create_send_ntf(rsp, dev);
	rsp = NULL;

exit_unlock:
	mutex_unlock(&dev->ethtool->rss_lock);
exit_free_hkey:
	kfree(rxfh.key);
exit_free_indir:
	kfree(rxfh.indir);
exit_clean_data:
	rss_get_data_free(&data);
exit_ops:
	ethnl_ops_complete(dev);
exit_dev_unlock:
	netdev_unlock_ops(dev);
	rtnl_unlock();
exit_free_dev:
	ethnl_parse_header_dev_put(&req.base);
exit_free_rsp:
	nlmsg_free(rsp);
	return ret;

err_ctx_id_free:
	xa_erase(&dev->ethtool->rss_ctx, req.rss_context);
err_unlock_free_ctx:
	kfree(ctx);
	goto exit_unlock;
}

/* RSS_DELETE */

const struct nla_policy ethnl_rss_delete_policy[ETHTOOL_A_RSS_CONTEXT + 1] = {
	[ETHTOOL_A_RSS_HEADER]	= NLA_POLICY_NESTED(ethnl_header_policy),
	[ETHTOOL_A_RSS_CONTEXT]	= NLA_POLICY_MIN(NLA_U32, 1),
};

int ethnl_rss_delete_doit(struct sk_buff *skb, struct genl_info *info)
{
	struct ethtool_rxfh_context *ctx;
	struct nlattr **tb = info->attrs;
	struct ethnl_req_info req = {};
	const struct ethtool_ops *ops;
	struct net_device *dev;
	u32 rss_context;
	int ret;

	if (GENL_REQ_ATTR_CHECK(info, ETHTOOL_A_RSS_CONTEXT))
		return -EINVAL;
	rss_context = nla_get_u32(tb[ETHTOOL_A_RSS_CONTEXT]);

	ret = ethnl_parse_header_dev_get(&req, tb[ETHTOOL_A_RSS_HEADER],
					 genl_info_net(info), info->extack,
					 true);
	if (ret < 0)
		return ret;

	dev = req.dev;
	ops = dev->ethtool_ops;

	if (!ops->create_rxfh_context)
		goto exit_free_dev;

	rtnl_lock();
	netdev_lock_ops(dev);

	ret = ethnl_ops_begin(dev);
	if (ret < 0)
		goto exit_dev_unlock;

	mutex_lock(&dev->ethtool->rss_lock);
	ret = ethtool_check_rss_ctx_busy(dev, rss_context);
	if (ret)
		goto exit_unlock;

	ctx = xa_load(&dev->ethtool->rss_ctx, rss_context);
	if (!ctx) {
		ret = -ENOENT;
		goto exit_unlock;
	}

	ret = ops->remove_rxfh_context(dev, ctx, rss_context, info->extack);
	if (ret)
		goto exit_unlock;

	WARN_ON(xa_erase(&dev->ethtool->rss_ctx, rss_context) != ctx);
	kfree(ctx);

	ethnl_rss_delete_notify(dev, rss_context);

exit_unlock:
	mutex_unlock(&dev->ethtool->rss_lock);
	ethnl_ops_complete(dev);
exit_dev_unlock:
	netdev_unlock_ops(dev);
	rtnl_unlock();
exit_free_dev:
	ethnl_parse_header_dev_put(&req);
	return ret;
}
