// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
 */

#include <net/genetlink.h>
#include <net/sock.h>

#include "devl_internal.h"

#define DEVLINK_NL_FLAG_NEED_PORT		BIT(0)
#define DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT	BIT(1)
#define DEVLINK_NL_FLAG_NEED_DEV_LOCK		BIT(2)
#define DEVLINK_NL_FLAG_OPTIONAL_PARENT_DEV	BIT(3)

static const struct genl_multicast_group devlink_nl_mcgrps[] = {
	[DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
};

struct devlink_nl_sock_priv {
	struct devlink_obj_desc __rcu *flt;
	spinlock_t flt_lock; /* Protects flt. */
};

static void devlink_nl_sock_priv_init(void *priv)
{
	struct devlink_nl_sock_priv *sk_priv = priv;

	spin_lock_init(&sk_priv->flt_lock);
}

static void devlink_nl_sock_priv_destroy(void *priv)
{
	struct devlink_nl_sock_priv *sk_priv = priv;
	struct devlink_obj_desc *flt;

	flt = rcu_dereference_protected(sk_priv->flt, true);
	kfree_rcu(flt, rcu);
}

int devlink_nl_notify_filter_set_doit(struct sk_buff *skb,
				      struct genl_info *info)
{
	struct devlink_nl_sock_priv *sk_priv;
	struct nlattr **attrs = info->attrs;
	struct devlink_obj_desc *flt;
	size_t data_offset = 0;
	size_t data_size = 0;
	char *pos;

	if (attrs[DEVLINK_ATTR_BUS_NAME])
		data_size = size_add(data_size,
				     nla_len(attrs[DEVLINK_ATTR_BUS_NAME]) + 1);
	if (attrs[DEVLINK_ATTR_DEV_NAME])
		data_size = size_add(data_size,
				     nla_len(attrs[DEVLINK_ATTR_DEV_NAME]) + 1);

	flt = kzalloc(size_add(sizeof(*flt), data_size), GFP_KERNEL);
	if (!flt)
		return -ENOMEM;

	pos = (char *) flt->data;
	if (attrs[DEVLINK_ATTR_BUS_NAME]) {
		data_offset += nla_strscpy(pos,
					   attrs[DEVLINK_ATTR_BUS_NAME],
					   data_size) + 1;
		flt->bus_name = pos;
		pos += data_offset;
	}
	if (attrs[DEVLINK_ATTR_DEV_NAME]) {
		nla_strscpy(pos, attrs[DEVLINK_ATTR_DEV_NAME],
			    data_size - data_offset);
		flt->dev_name = pos;
	}

	if (attrs[DEVLINK_ATTR_INDEX]) {
		flt->devlink_index = nla_get_uint(attrs[DEVLINK_ATTR_INDEX]);
		flt->devlink_index_valid = true;
	}

	if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
		flt->port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
		flt->port_index_valid = true;
	}

	/* Don't attach empty filter. */
	if (!flt->bus_name && !flt->dev_name &&
	    !flt->devlink_index_valid && !flt->port_index_valid) {
		kfree(flt);
		flt = NULL;
	}

	sk_priv = genl_sk_priv_get(&devlink_nl_family, NETLINK_CB(skb).sk);
	if (IS_ERR(sk_priv)) {
		kfree(flt);
		return PTR_ERR(sk_priv);
	}
	spin_lock(&sk_priv->flt_lock);
	flt = rcu_replace_pointer(sk_priv->flt, flt,
				  lockdep_is_held(&sk_priv->flt_lock));
	spin_unlock(&sk_priv->flt_lock);
	kfree_rcu(flt, rcu);
	return 0;
}

static bool devlink_obj_desc_match(const struct devlink_obj_desc *desc,
				   const struct devlink_obj_desc *flt)
{
	if (desc->devlink_index_valid && flt->devlink_index_valid &&
	    desc->devlink_index != flt->devlink_index)
		return false;
	if (desc->bus_name && flt->bus_name &&
	    strcmp(desc->bus_name, flt->bus_name))
		return false;
	if (desc->dev_name && flt->dev_name &&
	    strcmp(desc->dev_name, flt->dev_name))
		return false;
	if (desc->port_index_valid && flt->port_index_valid &&
	    desc->port_index != flt->port_index)
		return false;
	return true;
}

int devlink_nl_notify_filter(struct sock *dsk, struct sk_buff *skb, void *data)
{
	struct devlink_obj_desc *desc = data;
	struct devlink_nl_sock_priv *sk_priv;
	struct devlink_obj_desc *flt;
	int ret = 0;

	rcu_read_lock();
	sk_priv = __genl_sk_priv_get(&devlink_nl_family, dsk);
	if (!IS_ERR_OR_NULL(sk_priv)) {
		flt = rcu_dereference(sk_priv->flt);
		if (flt)
			ret = !devlink_obj_desc_match(desc, flt);
	}
	rcu_read_unlock();
	return ret;
}

int devlink_nl_put_nested_handle(struct sk_buff *msg, struct net *net,
				 struct devlink *devlink, int attrtype)
{
	struct nlattr *nested_attr;
	struct net *devl_net;

	nested_attr = nla_nest_start(msg, attrtype);
	if (!nested_attr)
		return -EMSGSIZE;
	if (devlink_nl_put_handle(msg, devlink))
		goto nla_put_failure;

	rcu_read_lock();
	devl_net = read_pnet_rcu(&devlink->_net);
	if (!net_eq(net, devl_net)) {
		int id = peernet2id_alloc(net, devl_net, GFP_ATOMIC);

		rcu_read_unlock();
		if (nla_put_s32(msg, DEVLINK_ATTR_NETNS_ID, id))
			return -EMSGSIZE;
	} else {
		rcu_read_unlock();
	}

	nla_nest_end(msg, nested_attr);
	return 0;

nla_put_failure:
	nla_nest_cancel(msg, nested_attr);
	return -EMSGSIZE;
}

int devlink_nl_msg_reply_and_new(struct sk_buff **msg, struct genl_info *info)
{
	int err;

	if (*msg) {
		err = genlmsg_reply(*msg, info);
		if (err)
			return err;
	}
	*msg = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!*msg)
		return -ENOMEM;
	return 0;
}

struct devlink *
devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs,
			    bool dev_lock)
{
	struct devlink *devlink;
	unsigned long index;
	char *busname;
	char *devname;

	if (attrs[DEVLINK_ATTR_INDEX]) {
		if (attrs[DEVLINK_ATTR_BUS_NAME] ||
		    attrs[DEVLINK_ATTR_DEV_NAME])
			return ERR_PTR(-EINVAL);
		index = nla_get_u32(attrs[DEVLINK_ATTR_INDEX]);
		devlink = devlinks_xa_lookup_get(net, index);
		if (!devlink)
			return ERR_PTR(-ENODEV);
		goto found;
	}

	if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
		return ERR_PTR(-EINVAL);

	busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
	devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);

	if (!strcmp(busname, DEVLINK_INDEX_BUS_NAME)) {
		if (kstrtoul(devname, 10, &index))
			return ERR_PTR(-ENODEV);
		devlink = devlinks_xa_lookup_get(net, index);
		if (!devlink)
			return ERR_PTR(-ENODEV);
		goto found;
	}

	devlinks_xa_for_each_registered_get(net, index, devlink) {
		if (strcmp(devlink_bus_name(devlink), busname) == 0 &&
		    strcmp(devlink_dev_name(devlink), devname) == 0)
			goto found;
		devlink_put(devlink);
	}

	return ERR_PTR(-ENODEV);

found:
	devl_dev_lock(devlink, dev_lock);
	if (devl_is_registered(devlink))
		return devlink;
	devl_dev_unlock(devlink, dev_lock);
	devlink_put(devlink);
	return ERR_PTR(-ENODEV);
}

struct devlink *
devlink_get_parent_from_attrs_lock(struct net *net, struct nlattr **attrs)
{
	unsigned int maxtype = ARRAY_SIZE(devlink_dl_parent_dev_nl_policy) - 1;
	struct devlink *devlink;
	struct nlattr **tb;
	int err;

	if (!attrs[DEVLINK_ATTR_PARENT_DEV])
		return ERR_PTR(-EINVAL);

	tb = kzalloc_objs(*tb, maxtype + 1);
	if (!tb)
		return ERR_PTR(-ENOMEM);

	err = nla_parse_nested(tb, maxtype, attrs[DEVLINK_ATTR_PARENT_DEV],
			       devlink_dl_parent_dev_nl_policy, NULL);
	if (err)
		goto out;

	devlink = devlink_get_from_attrs_lock(net, tb, false);
	kfree(tb);
	return devlink;
out:
	kfree(tb);
	return ERR_PTR(err);
}

static int __devlink_nl_pre_doit(struct sk_buff *skb, struct genl_info *info,
				 u8 flags)
{
	bool parent_dev = flags & DEVLINK_NL_FLAG_OPTIONAL_PARENT_DEV;
	bool dev_lock = flags & DEVLINK_NL_FLAG_NEED_DEV_LOCK;
	struct devlink *devlink, *parent_devlink = NULL;
	struct net *net = genl_info_net(info);
	struct nlattr **attrs = info->attrs;
	struct devlink_port *devlink_port;
	int err;

	if (parent_dev && attrs[DEVLINK_ATTR_PARENT_DEV]) {
		parent_devlink = devlink_get_parent_from_attrs_lock(net, attrs);
		if (IS_ERR(parent_devlink))
			return PTR_ERR(parent_devlink);
		devlink_nl_ctx(info)->parent_devlink = parent_devlink;
		/* Drop the parent devlink lock but don't release the reference.
		 * This will keep it alive until the end of the request.
		 */
		devl_unlock(parent_devlink);
	}

	devlink = devlink_get_from_attrs_lock(net, attrs, dev_lock);
	if (IS_ERR(devlink)) {
		err = PTR_ERR(devlink);
		goto parent_put;
	}
	devlink_nl_ctx(info)->devlink = devlink;
	if (flags & DEVLINK_NL_FLAG_NEED_PORT) {
		devlink_port = devlink_port_get_from_info(devlink, info);
		if (IS_ERR(devlink_port)) {
			err = PTR_ERR(devlink_port);
			goto unlock;
		}
		devlink_nl_ctx(info)->devlink_port = devlink_port;
	} else if (flags & DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT) {
		devlink_port = devlink_port_get_from_info(devlink, info);
		if (!IS_ERR(devlink_port))
			devlink_nl_ctx(info)->devlink_port = devlink_port;
	}
	return 0;

unlock:
	devl_dev_unlock(devlink, dev_lock);
	devlink_put(devlink);
parent_put:
	if (parent_dev && parent_devlink)
		devlink_put(parent_devlink);
	return err;
}

int devlink_nl_pre_doit(const struct genl_split_ops *ops,
			struct sk_buff *skb, struct genl_info *info)
{
	return __devlink_nl_pre_doit(skb, info, 0);
}

int devlink_nl_pre_doit_port(const struct genl_split_ops *ops,
			     struct sk_buff *skb, struct genl_info *info)
{
	return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_PORT);
}

int devlink_nl_pre_doit_dev_lock(const struct genl_split_ops *ops,
				 struct sk_buff *skb, struct genl_info *info)
{
	return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_DEV_LOCK);
}

int devlink_nl_pre_doit_port_optional(const struct genl_split_ops *ops,
				      struct sk_buff *skb,
				      struct genl_info *info)
{
	return __devlink_nl_pre_doit(skb, info, DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT);
}

int devlink_nl_pre_doit_parent_dev_optional(const struct genl_split_ops *ops,
					    struct sk_buff *skb,
					    struct genl_info *info)
{
	return __devlink_nl_pre_doit(skb, info,
				     DEVLINK_NL_FLAG_OPTIONAL_PARENT_DEV);
}

static void __devlink_nl_post_doit(struct sk_buff *skb, struct genl_info *info,
				   u8 flags)
{
	bool dev_lock = flags & DEVLINK_NL_FLAG_NEED_DEV_LOCK;
	struct devlink *devlink;

	devlink = devlink_nl_ctx(info)->devlink;
	devl_dev_unlock(devlink, dev_lock);
	devlink_put(devlink);
	if (devlink_nl_ctx(info)->parent_devlink)
		devlink_put(devlink_nl_ctx(info)->parent_devlink);
}

void devlink_nl_post_doit(const struct genl_split_ops *ops,
			  struct sk_buff *skb, struct genl_info *info)
{
	__devlink_nl_post_doit(skb, info, 0);
}

void
devlink_nl_post_doit_dev_lock(const struct genl_split_ops *ops,
			      struct sk_buff *skb, struct genl_info *info)
{
	__devlink_nl_post_doit(skb, info, DEVLINK_NL_FLAG_NEED_DEV_LOCK);
}

void
devlink_nl_post_doit_parent_dev_optional(const struct genl_split_ops *ops,
					 struct sk_buff *skb,
					 struct genl_info *info)
{
	__devlink_nl_post_doit(skb, info, DEVLINK_NL_FLAG_OPTIONAL_PARENT_DEV);
}

static int devlink_nl_inst_single_dumpit(struct sk_buff *msg,
					 struct netlink_callback *cb, int flags,
					 devlink_nl_dump_one_func_t *dump_one,
					 struct nlattr **attrs)
{
	struct devlink *devlink;
	int err;

	devlink = devlink_get_from_attrs_lock(sock_net(msg->sk), attrs, false);
	if (IS_ERR(devlink))
		return PTR_ERR(devlink);
	err = dump_one(msg, devlink, cb, flags | NLM_F_DUMP_FILTERED);

	devl_unlock(devlink);
	devlink_put(devlink);

	if (err != -EMSGSIZE)
		return err;
	return msg->len;
}

static int devlink_nl_inst_iter_dumpit(struct sk_buff *msg,
				       struct netlink_callback *cb, int flags,
				       devlink_nl_dump_one_func_t *dump_one)
{
	struct devlink_nl_dump_state *state = devlink_dump_state(cb);
	struct devlink *devlink;
	int err = 0;

	while ((devlink = devlinks_xa_find_get(sock_net(msg->sk),
					       &state->instance))) {
		devl_lock(devlink);

		if (devl_is_registered(devlink))
			err = dump_one(msg, devlink, cb, flags);
		else
			err = 0;

		devl_unlock(devlink);
		devlink_put(devlink);

		if (err)
			break;

		state->instance++;

		/* restart sub-object walk for the next instance */
		state->idx = 0;
		state->port_ctx.index = 0;
		state->port_ctx.index_valid = false;
	}

	if (err != -EMSGSIZE)
		return err;
	return msg->len;
}

int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb,
		      devlink_nl_dump_one_func_t *dump_one)
{
	const struct genl_info *info = genl_info_dump(cb);
	struct nlattr **attrs = info->attrs;
	int flags = NLM_F_MULTI;

	if (attrs &&
	    (attrs[DEVLINK_ATTR_BUS_NAME] || attrs[DEVLINK_ATTR_DEV_NAME] ||
	     attrs[DEVLINK_ATTR_INDEX]))
		return devlink_nl_inst_single_dumpit(msg, cb, flags, dump_one,
						     attrs);
	else
		return devlink_nl_inst_iter_dumpit(msg, cb, flags, dump_one);
}

struct genl_family devlink_nl_family __ro_after_init = {
	.name		= DEVLINK_GENL_NAME,
	.version	= DEVLINK_GENL_VERSION,
	.netnsok	= true,
	.parallel_ops	= true,
	.module		= THIS_MODULE,
	.split_ops	= devlink_nl_ops,
	.n_split_ops	= ARRAY_SIZE(devlink_nl_ops),
	.resv_start_op	= DEVLINK_CMD_SELFTESTS_RUN + 1,
	.mcgrps		= devlink_nl_mcgrps,
	.n_mcgrps	= ARRAY_SIZE(devlink_nl_mcgrps),
	.sock_priv_size		= sizeof(struct devlink_nl_sock_priv),
	.sock_priv_init		= devlink_nl_sock_priv_init,
	.sock_priv_destroy	= devlink_nl_sock_priv_destroy,
};
