// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
 */

#include <linux/jhash.h>
#include <linux/slab.h>
#include <linux/rwsem.h>
#include <linux/mutex.h>
#include <linux/wait.h>
#include <linux/hashtable.h>
#include <net/net_namespace.h>
#include <net/genetlink.h>
#include <linux/socket.h>
#include <linux/workqueue.h>

#include "vfs_cache.h"
#include "transport_ipc.h"
#include "server.h"
#include "smb_common.h"

#include "mgmt/user_config.h"
#include "mgmt/share_config.h"
#include "mgmt/user_session.h"
#include "mgmt/tree_connect.h"
#include "mgmt/ksmbd_ida.h"
#include "connection.h"
#include "transport_tcp.h"
#include "transport_rdma.h"

#define IPC_WAIT_TIMEOUT	(2 * HZ)

#define IPC_MSG_HASH_BITS	3
static DEFINE_HASHTABLE(ipc_msg_table, IPC_MSG_HASH_BITS);
static DECLARE_RWSEM(ipc_msg_table_lock);
static DEFINE_MUTEX(startup_lock);

static DEFINE_IDA(ipc_ida);

static unsigned int ksmbd_tools_pid;

static bool ksmbd_ipc_validate_version(struct genl_info *m)
{
	if (m->genlhdr->version != KSMBD_GENL_VERSION) {
		pr_err("%s. ksmbd: %d, kernel module: %d. %s.\n",
		       "Daemon and kernel module version mismatch",
		       m->genlhdr->version,
		       KSMBD_GENL_VERSION,
		       "User-space ksmbd should terminate");
		return false;
	}
	return true;
}

struct ksmbd_ipc_msg {
	unsigned int		type;
	unsigned int		sz;
	unsigned char		payload[];
};

struct ipc_msg_table_entry {
	unsigned int		handle;
	unsigned int		type;
	wait_queue_head_t	wait;
	struct hlist_node	ipc_table_hlist;

	void			*response;
	unsigned int		msg_sz;
};

static struct delayed_work ipc_timer_work;

static int handle_startup_event(struct sk_buff *skb, struct genl_info *info);
static int handle_unsupported_event(struct sk_buff *skb, struct genl_info *info);
static int handle_generic_event(struct sk_buff *skb, struct genl_info *info);
static int ksmbd_ipc_heartbeat_request(void);

static const struct nla_policy ksmbd_nl_policy[KSMBD_EVENT_MAX + 1] = {
	[KSMBD_EVENT_UNSPEC] = {
		.len = 0,
	},
	[KSMBD_EVENT_HEARTBEAT_REQUEST] = {
		.len = sizeof(struct ksmbd_heartbeat),
	},
	[KSMBD_EVENT_STARTING_UP] = {
		.len = sizeof(struct ksmbd_startup_request),
	},
	[KSMBD_EVENT_SHUTTING_DOWN] = {
		.len = sizeof(struct ksmbd_shutdown_request),
	},
	[KSMBD_EVENT_LOGIN_REQUEST] = {
		.len = sizeof(struct ksmbd_login_request),
	},
	[KSMBD_EVENT_LOGIN_RESPONSE] = {
		.len = sizeof(struct ksmbd_login_response),
	},
	[KSMBD_EVENT_SHARE_CONFIG_REQUEST] = {
		.len = sizeof(struct ksmbd_share_config_request),
	},
	[KSMBD_EVENT_SHARE_CONFIG_RESPONSE] = {
		.len = sizeof(struct ksmbd_share_config_response),
	},
	[KSMBD_EVENT_TREE_CONNECT_REQUEST] = {
		.len = sizeof(struct ksmbd_tree_connect_request),
	},
	[KSMBD_EVENT_TREE_CONNECT_RESPONSE] = {
		.len = sizeof(struct ksmbd_tree_connect_response),
	},
	[KSMBD_EVENT_TREE_DISCONNECT_REQUEST] = {
		.len = sizeof(struct ksmbd_tree_disconnect_request),
	},
	[KSMBD_EVENT_LOGOUT_REQUEST] = {
		.len = sizeof(struct ksmbd_logout_request),
	},
	[KSMBD_EVENT_RPC_REQUEST] = {
	},
	[KSMBD_EVENT_RPC_RESPONSE] = {
	},
	[KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST] = {
	},
	[KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE] = {
	},
};

static struct genl_ops ksmbd_genl_ops[] = {
	{
		.cmd	= KSMBD_EVENT_UNSPEC,
		.doit	= handle_unsupported_event,
	},
	{
		.cmd	= KSMBD_EVENT_HEARTBEAT_REQUEST,
		.doit	= handle_unsupported_event,
	},
	{
		.cmd	= KSMBD_EVENT_STARTING_UP,
		.doit	= handle_startup_event,
	},
	{
		.cmd	= KSMBD_EVENT_SHUTTING_DOWN,
		.doit	= handle_unsupported_event,
	},
	{
		.cmd	= KSMBD_EVENT_LOGIN_REQUEST,
		.doit	= handle_unsupported_event,
	},
	{
		.cmd	= KSMBD_EVENT_LOGIN_RESPONSE,
		.doit	= handle_generic_event,
	},
	{
		.cmd	= KSMBD_EVENT_SHARE_CONFIG_REQUEST,
		.doit	= handle_unsupported_event,
	},
	{
		.cmd	= KSMBD_EVENT_SHARE_CONFIG_RESPONSE,
		.doit	= handle_generic_event,
	},
	{
		.cmd	= KSMBD_EVENT_TREE_CONNECT_REQUEST,
		.doit	= handle_unsupported_event,
	},
	{
		.cmd	= KSMBD_EVENT_TREE_CONNECT_RESPONSE,
		.doit	= handle_generic_event,
	},
	{
		.cmd	= KSMBD_EVENT_TREE_DISCONNECT_REQUEST,
		.doit	= handle_unsupported_event,
	},
	{
		.cmd	= KSMBD_EVENT_LOGOUT_REQUEST,
		.doit	= handle_unsupported_event,
	},
	{
		.cmd	= KSMBD_EVENT_RPC_REQUEST,
		.doit	= handle_unsupported_event,
	},
	{
		.cmd	= KSMBD_EVENT_RPC_RESPONSE,
		.doit	= handle_generic_event,
	},
	{
		.cmd	= KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST,
		.doit	= handle_unsupported_event,
	},
	{
		.cmd	= KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE,
		.doit	= handle_generic_event,
	},
};

static struct genl_family ksmbd_genl_family = {
	.name		= KSMBD_GENL_NAME,
	.version	= KSMBD_GENL_VERSION,
	.hdrsize	= 0,
	.maxattr	= KSMBD_EVENT_MAX,
	.netnsok	= true,
	.module		= THIS_MODULE,
	.ops		= ksmbd_genl_ops,
	.n_ops		= ARRAY_SIZE(ksmbd_genl_ops),
	.resv_start_op	= KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE + 1,
};

static void ksmbd_nl_init_fixup(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(ksmbd_genl_ops); i++)
		ksmbd_genl_ops[i].validate = GENL_DONT_VALIDATE_STRICT |
						GENL_DONT_VALIDATE_DUMP;

	ksmbd_genl_family.policy = ksmbd_nl_policy;
}

static int rpc_context_flags(struct ksmbd_session *sess)
{
	if (user_guest(sess->user))
		return KSMBD_RPC_RESTRICTED_CONTEXT;
	return 0;
}

static void ipc_update_last_active(void)
{
	if (server_conf.ipc_timeout)
		server_conf.ipc_last_active = jiffies;
}

static struct ksmbd_ipc_msg *ipc_msg_alloc(size_t sz)
{
	struct ksmbd_ipc_msg *msg;
	size_t msg_sz = sz + sizeof(struct ksmbd_ipc_msg);

	msg = kvzalloc(msg_sz, GFP_KERNEL);
	if (msg)
		msg->sz = sz;
	return msg;
}

static void ipc_msg_free(struct ksmbd_ipc_msg *msg)
{
	kvfree(msg);
}

static void ipc_msg_handle_free(int handle)
{
	if (handle >= 0)
		ksmbd_release_id(&ipc_ida, handle);
}

static int handle_response(int type, void *payload, size_t sz)
{
	unsigned int handle = *(unsigned int *)payload;
	struct ipc_msg_table_entry *entry;
	int ret = 0;

	ipc_update_last_active();
	down_read(&ipc_msg_table_lock);
	hash_for_each_possible(ipc_msg_table, entry, ipc_table_hlist, handle) {
		if (handle != entry->handle)
			continue;

		entry->response = NULL;
		/*
		 * Response message type value should be equal to
		 * request message type + 1.
		 */
		if (entry->type + 1 != type) {
			pr_err("Waiting for IPC type %d, got %d. Ignore.\n",
			       entry->type + 1, type);
		}

		entry->response = kvzalloc(sz, GFP_KERNEL);
		if (!entry->response) {
			ret = -ENOMEM;
			break;
		}

		memcpy(entry->response, payload, sz);
		entry->msg_sz = sz;
		wake_up_interruptible(&entry->wait);
		ret = 0;
		break;
	}
	up_read(&ipc_msg_table_lock);

	return ret;
}

static int ipc_server_config_on_startup(struct ksmbd_startup_request *req)
{
	int ret;

	ksmbd_set_fd_limit(req->file_max);
	server_conf.flags = req->flags;
	server_conf.signing = req->signing;
	server_conf.tcp_port = req->tcp_port;
	server_conf.ipc_timeout = req->ipc_timeout * HZ;
	server_conf.deadtime = req->deadtime * SMB_ECHO_INTERVAL;
	server_conf.share_fake_fscaps = req->share_fake_fscaps;
	ksmbd_init_domain(req->sub_auth);

	if (req->smb2_max_read)
		init_smb2_max_read_size(req->smb2_max_read);
	if (req->smb2_max_write)
		init_smb2_max_write_size(req->smb2_max_write);
	if (req->smb2_max_trans)
		init_smb2_max_trans_size(req->smb2_max_trans);
	if (req->smb2_max_credits) {
		init_smb2_max_credits(req->smb2_max_credits);
		server_conf.max_inflight_req =
			req->smb2_max_credits;
	}
	if (req->smbd_max_io_size)
		init_smbd_max_io_size(req->smbd_max_io_size);

	if (req->max_connections)
		server_conf.max_connections = req->max_connections;

	ret = ksmbd_set_netbios_name(req->netbios_name);
	ret |= ksmbd_set_server_string(req->server_string);
	ret |= ksmbd_set_work_group(req->work_group);
	ret |= ksmbd_tcp_set_interfaces(KSMBD_STARTUP_CONFIG_INTERFACES(req),
					req->ifc_list_sz);
	if (ret) {
		pr_err("Server configuration error: %s %s %s\n",
		       req->netbios_name, req->server_string,
		       req->work_group);
		return ret;
	}

	if (req->min_prot[0]) {
		ret = ksmbd_lookup_protocol_idx(req->min_prot);
		if (ret >= 0)
			server_conf.min_protocol = ret;
	}
	if (req->max_prot[0]) {
		ret = ksmbd_lookup_protocol_idx(req->max_prot);
		if (ret >= 0)
			server_conf.max_protocol = ret;
	}

	if (server_conf.ipc_timeout)
		schedule_delayed_work(&ipc_timer_work, server_conf.ipc_timeout);
	return 0;
}

static int handle_startup_event(struct sk_buff *skb, struct genl_info *info)
{
	int ret = 0;

#ifdef CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN
	if (!netlink_capable(skb, CAP_NET_ADMIN))
		return -EPERM;
#endif

	if (!ksmbd_ipc_validate_version(info))
		return -EINVAL;

	if (!info->attrs[KSMBD_EVENT_STARTING_UP])
		return -EINVAL;

	mutex_lock(&startup_lock);
	if (!ksmbd_server_configurable()) {
		mutex_unlock(&startup_lock);
		pr_err("Server reset is in progress, can't start daemon\n");
		return -EINVAL;
	}

	if (ksmbd_tools_pid) {
		if (ksmbd_ipc_heartbeat_request() == 0) {
			ret = -EINVAL;
			goto out;
		}

		pr_err("Reconnect to a new user space daemon\n");
	} else {
		struct ksmbd_startup_request *req;

		req = nla_data(info->attrs[info->genlhdr->cmd]);
		ret = ipc_server_config_on_startup(req);
		if (ret)
			goto out;
		server_queue_ctrl_init_work();
	}

	ksmbd_tools_pid = info->snd_portid;
	ipc_update_last_active();

out:
	mutex_unlock(&startup_lock);
	return ret;
}

static int handle_unsupported_event(struct sk_buff *skb, struct genl_info *info)
{
	pr_err("Unknown IPC event: %d, ignore.\n", info->genlhdr->cmd);
	return -EINVAL;
}

static int handle_generic_event(struct sk_buff *skb, struct genl_info *info)
{
	void *payload;
	int sz;
	int type = info->genlhdr->cmd;

#ifdef CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN
	if (!netlink_capable(skb, CAP_NET_ADMIN))
		return -EPERM;
#endif

	if (type > KSMBD_EVENT_MAX) {
		WARN_ON(1);
		return -EINVAL;
	}

	if (!ksmbd_ipc_validate_version(info))
		return -EINVAL;

	if (!info->attrs[type])
		return -EINVAL;

	payload = nla_data(info->attrs[info->genlhdr->cmd]);
	sz = nla_len(info->attrs[info->genlhdr->cmd]);
	return handle_response(type, payload, sz);
}

static int ipc_msg_send(struct ksmbd_ipc_msg *msg)
{
	struct genlmsghdr *nlh;
	struct sk_buff *skb;
	int ret = -EINVAL;

	if (!ksmbd_tools_pid)
		return ret;

	skb = genlmsg_new(msg->sz, GFP_KERNEL);
	if (!skb)
		return -ENOMEM;

	nlh = genlmsg_put(skb, 0, 0, &ksmbd_genl_family, 0, msg->type);
	if (!nlh)
		goto out;

	ret = nla_put(skb, msg->type, msg->sz, msg->payload);
	if (ret) {
		genlmsg_cancel(skb, nlh);
		goto out;
	}

	genlmsg_end(skb, nlh);
	ret = genlmsg_unicast(&init_net, skb, ksmbd_tools_pid);
	if (!ret)
		ipc_update_last_active();
	return ret;

out:
	nlmsg_free(skb);
	return ret;
}

static int ipc_validate_msg(struct ipc_msg_table_entry *entry)
{
	unsigned int msg_sz = entry->msg_sz;

	if (entry->type == KSMBD_EVENT_RPC_REQUEST) {
		struct ksmbd_rpc_command *resp = entry->response;

		msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz;
	} else if (entry->type == KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST) {
		struct ksmbd_spnego_authen_response *resp = entry->response;

		msg_sz = sizeof(struct ksmbd_spnego_authen_response) +
				resp->session_key_len + resp->spnego_blob_len;
	} else if (entry->type == KSMBD_EVENT_SHARE_CONFIG_REQUEST) {
		struct ksmbd_share_config_response *resp = entry->response;

		if (resp->payload_sz) {
			if (resp->payload_sz < resp->veto_list_sz)
				return -EINVAL;

			msg_sz = sizeof(struct ksmbd_share_config_response) +
					resp->payload_sz;
		}
	}

	return entry->msg_sz != msg_sz ? -EINVAL : 0;
}

static void *ipc_msg_send_request(struct ksmbd_ipc_msg *msg, unsigned int handle)
{
	struct ipc_msg_table_entry entry;
	int ret;

	if ((int)handle < 0)
		return NULL;

	entry.type = msg->type;
	entry.response = NULL;
	init_waitqueue_head(&entry.wait);

	down_write(&ipc_msg_table_lock);
	entry.handle = handle;
	hash_add(ipc_msg_table, &entry.ipc_table_hlist, entry.handle);
	up_write(&ipc_msg_table_lock);

	ret = ipc_msg_send(msg);
	if (ret)
		goto out;

	ret = wait_event_interruptible_timeout(entry.wait,
					       entry.response != NULL,
					       IPC_WAIT_TIMEOUT);
	if (entry.response) {
		ret = ipc_validate_msg(&entry);
		if (ret) {
			kvfree(entry.response);
			entry.response = NULL;
		}
	}
out:
	down_write(&ipc_msg_table_lock);
	hash_del(&entry.ipc_table_hlist);
	up_write(&ipc_msg_table_lock);
	return entry.response;
}

static int ksmbd_ipc_heartbeat_request(void)
{
	struct ksmbd_ipc_msg *msg;
	int ret;

	msg = ipc_msg_alloc(sizeof(struct ksmbd_heartbeat));
	if (!msg)
		return -EINVAL;

	msg->type = KSMBD_EVENT_HEARTBEAT_REQUEST;
	ret = ipc_msg_send(msg);
	ipc_msg_free(msg);
	return ret;
}

struct ksmbd_login_response *ksmbd_ipc_login_request(const char *account)
{
	struct ksmbd_ipc_msg *msg;
	struct ksmbd_login_request *req;
	struct ksmbd_login_response *resp;

	if (strlen(account) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ)
		return NULL;

	msg = ipc_msg_alloc(sizeof(struct ksmbd_login_request));
	if (!msg)
		return NULL;

	msg->type = KSMBD_EVENT_LOGIN_REQUEST;
	req = (struct ksmbd_login_request *)msg->payload;
	req->handle = ksmbd_acquire_id(&ipc_ida);
	strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ);

	resp = ipc_msg_send_request(msg, req->handle);
	ipc_msg_handle_free(req->handle);
	ipc_msg_free(msg);
	return resp;
}

struct ksmbd_spnego_authen_response *
ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len)
{
	struct ksmbd_ipc_msg *msg;
	struct ksmbd_spnego_authen_request *req;
	struct ksmbd_spnego_authen_response *resp;

	msg = ipc_msg_alloc(sizeof(struct ksmbd_spnego_authen_request) +
			blob_len + 1);
	if (!msg)
		return NULL;

	msg->type = KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST;
	req = (struct ksmbd_spnego_authen_request *)msg->payload;
	req->handle = ksmbd_acquire_id(&ipc_ida);
	req->spnego_blob_len = blob_len;
	memcpy(req->spnego_blob, spnego_blob, blob_len);

	resp = ipc_msg_send_request(msg, req->handle);
	ipc_msg_handle_free(req->handle);
	ipc_msg_free(msg);
	return resp;
}

struct ksmbd_tree_connect_response *
ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess,
			       struct ksmbd_share_config *share,
			       struct ksmbd_tree_connect *tree_conn,
			       struct sockaddr *peer_addr)
{
	struct ksmbd_ipc_msg *msg;
	struct ksmbd_tree_connect_request *req;
	struct ksmbd_tree_connect_response *resp;

	if (strlen(user_name(sess->user)) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ)
		return NULL;

	if (strlen(share->name) >= KSMBD_REQ_MAX_SHARE_NAME)
		return NULL;

	msg = ipc_msg_alloc(sizeof(struct ksmbd_tree_connect_request));
	if (!msg)
		return NULL;

	msg->type = KSMBD_EVENT_TREE_CONNECT_REQUEST;
	req = (struct ksmbd_tree_connect_request *)msg->payload;

	req->handle = ksmbd_acquire_id(&ipc_ida);
	req->account_flags = sess->user->flags;
	req->session_id = sess->id;
	req->connect_id = tree_conn->id;
	strscpy(req->account, user_name(sess->user), KSMBD_REQ_MAX_ACCOUNT_NAME_SZ);
	strscpy(req->share, share->name, KSMBD_REQ_MAX_SHARE_NAME);
	snprintf(req->peer_addr, sizeof(req->peer_addr), "%pIS", peer_addr);

	if (peer_addr->sa_family == AF_INET6)
		req->flags |= KSMBD_TREE_CONN_FLAG_REQUEST_IPV6;
	if (test_session_flag(sess, CIFDS_SESSION_FLAG_SMB2))
		req->flags |= KSMBD_TREE_CONN_FLAG_REQUEST_SMB2;

	resp = ipc_msg_send_request(msg, req->handle);
	ipc_msg_handle_free(req->handle);
	ipc_msg_free(msg);
	return resp;
}

int ksmbd_ipc_tree_disconnect_request(unsigned long long session_id,
				      unsigned long long connect_id)
{
	struct ksmbd_ipc_msg *msg;
	struct ksmbd_tree_disconnect_request *req;
	int ret;

	msg = ipc_msg_alloc(sizeof(struct ksmbd_tree_disconnect_request));
	if (!msg)
		return -ENOMEM;

	msg->type = KSMBD_EVENT_TREE_DISCONNECT_REQUEST;
	req = (struct ksmbd_tree_disconnect_request *)msg->payload;
	req->session_id = session_id;
	req->connect_id = connect_id;

	ret = ipc_msg_send(msg);
	ipc_msg_free(msg);
	return ret;
}

int ksmbd_ipc_logout_request(const char *account, int flags)
{
	struct ksmbd_ipc_msg *msg;
	struct ksmbd_logout_request *req;
	int ret;

	if (strlen(account) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ)
		return -EINVAL;

	msg = ipc_msg_alloc(sizeof(struct ksmbd_logout_request));
	if (!msg)
		return -ENOMEM;

	msg->type = KSMBD_EVENT_LOGOUT_REQUEST;
	req = (struct ksmbd_logout_request *)msg->payload;
	req->account_flags = flags;
	strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ);

	ret = ipc_msg_send(msg);
	ipc_msg_free(msg);
	return ret;
}

struct ksmbd_share_config_response *
ksmbd_ipc_share_config_request(const char *name)
{
	struct ksmbd_ipc_msg *msg;
	struct ksmbd_share_config_request *req;
	struct ksmbd_share_config_response *resp;

	if (strlen(name) >= KSMBD_REQ_MAX_SHARE_NAME)
		return NULL;

	msg = ipc_msg_alloc(sizeof(struct ksmbd_share_config_request));
	if (!msg)
		return NULL;

	msg->type = KSMBD_EVENT_SHARE_CONFIG_REQUEST;
	req = (struct ksmbd_share_config_request *)msg->payload;
	req->handle = ksmbd_acquire_id(&ipc_ida);
	strscpy(req->share_name, name, KSMBD_REQ_MAX_SHARE_NAME);

	resp = ipc_msg_send_request(msg, req->handle);
	ipc_msg_handle_free(req->handle);
	ipc_msg_free(msg);
	return resp;
}

struct ksmbd_rpc_command *ksmbd_rpc_open(struct ksmbd_session *sess, int handle)
{
	struct ksmbd_ipc_msg *msg;
	struct ksmbd_rpc_command *req;
	struct ksmbd_rpc_command *resp;

	msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command));
	if (!msg)
		return NULL;

	msg->type = KSMBD_EVENT_RPC_REQUEST;
	req = (struct ksmbd_rpc_command *)msg->payload;
	req->handle = handle;
	req->flags = ksmbd_session_rpc_method(sess, handle);
	req->flags |= KSMBD_RPC_OPEN_METHOD;
	req->payload_sz = 0;

	resp = ipc_msg_send_request(msg, req->handle);
	ipc_msg_free(msg);
	return resp;
}

struct ksmbd_rpc_command *ksmbd_rpc_close(struct ksmbd_session *sess, int handle)
{
	struct ksmbd_ipc_msg *msg;
	struct ksmbd_rpc_command *req;
	struct ksmbd_rpc_command *resp;

	msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command));
	if (!msg)
		return NULL;

	msg->type = KSMBD_EVENT_RPC_REQUEST;
	req = (struct ksmbd_rpc_command *)msg->payload;
	req->handle = handle;
	req->flags = ksmbd_session_rpc_method(sess, handle);
	req->flags |= KSMBD_RPC_CLOSE_METHOD;
	req->payload_sz = 0;

	resp = ipc_msg_send_request(msg, req->handle);
	ipc_msg_free(msg);
	return resp;
}

struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle,
					  void *payload, size_t payload_sz)
{
	struct ksmbd_ipc_msg *msg;
	struct ksmbd_rpc_command *req;
	struct ksmbd_rpc_command *resp;

	msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1);
	if (!msg)
		return NULL;

	msg->type = KSMBD_EVENT_RPC_REQUEST;
	req = (struct ksmbd_rpc_command *)msg->payload;
	req->handle = handle;
	req->flags = ksmbd_session_rpc_method(sess, handle);
	req->flags |= rpc_context_flags(sess);
	req->flags |= KSMBD_RPC_WRITE_METHOD;
	req->payload_sz = payload_sz;
	memcpy(req->payload, payload, payload_sz);

	resp = ipc_msg_send_request(msg, req->handle);
	ipc_msg_free(msg);
	return resp;
}

struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle)
{
	struct ksmbd_ipc_msg *msg;
	struct ksmbd_rpc_command *req;
	struct ksmbd_rpc_command *resp;

	msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command));
	if (!msg)
		return NULL;

	msg->type = KSMBD_EVENT_RPC_REQUEST;
	req = (struct ksmbd_rpc_command *)msg->payload;
	req->handle = handle;
	req->flags = ksmbd_session_rpc_method(sess, handle);
	req->flags |= rpc_context_flags(sess);
	req->flags |= KSMBD_RPC_READ_METHOD;
	req->payload_sz = 0;

	resp = ipc_msg_send_request(msg, req->handle);
	ipc_msg_free(msg);
	return resp;
}

struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle,
					  void *payload, size_t payload_sz)
{
	struct ksmbd_ipc_msg *msg;
	struct ksmbd_rpc_command *req;
	struct ksmbd_rpc_command *resp;

	msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1);
	if (!msg)
		return NULL;

	msg->type = KSMBD_EVENT_RPC_REQUEST;
	req = (struct ksmbd_rpc_command *)msg->payload;
	req->handle = handle;
	req->flags = ksmbd_session_rpc_method(sess, handle);
	req->flags |= rpc_context_flags(sess);
	req->flags |= KSMBD_RPC_IOCTL_METHOD;
	req->payload_sz = payload_sz;
	memcpy(req->payload, payload, payload_sz);

	resp = ipc_msg_send_request(msg, req->handle);
	ipc_msg_free(msg);
	return resp;
}

struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess, void *payload,
					size_t payload_sz)
{
	struct ksmbd_ipc_msg *msg;
	struct ksmbd_rpc_command *req;
	struct ksmbd_rpc_command *resp;

	msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1);
	if (!msg)
		return NULL;

	msg->type = KSMBD_EVENT_RPC_REQUEST;
	req = (struct ksmbd_rpc_command *)msg->payload;
	req->handle = ksmbd_acquire_id(&ipc_ida);
	req->flags = rpc_context_flags(sess);
	req->flags |= KSMBD_RPC_RAP_METHOD;
	req->payload_sz = payload_sz;
	memcpy(req->payload, payload, payload_sz);

	resp = ipc_msg_send_request(msg, req->handle);
	ipc_msg_handle_free(req->handle);
	ipc_msg_free(msg);
	return resp;
}

static int __ipc_heartbeat(void)
{
	unsigned long delta;

	if (!ksmbd_server_running())
		return 0;

	if (time_after(jiffies, server_conf.ipc_last_active)) {
		delta = (jiffies - server_conf.ipc_last_active);
	} else {
		ipc_update_last_active();
		schedule_delayed_work(&ipc_timer_work,
				      server_conf.ipc_timeout);
		return 0;
	}

	if (delta < server_conf.ipc_timeout) {
		schedule_delayed_work(&ipc_timer_work,
				      server_conf.ipc_timeout - delta);
		return 0;
	}

	if (ksmbd_ipc_heartbeat_request() == 0) {
		schedule_delayed_work(&ipc_timer_work,
				      server_conf.ipc_timeout);
		return 0;
	}

	mutex_lock(&startup_lock);
	WRITE_ONCE(server_conf.state, SERVER_STATE_RESETTING);
	server_conf.ipc_last_active = 0;
	ksmbd_tools_pid = 0;
	pr_err("No IPC daemon response for %lus\n", delta / HZ);
	mutex_unlock(&startup_lock);
	return -EINVAL;
}

static void ipc_timer_heartbeat(struct work_struct *w)
{
	if (__ipc_heartbeat())
		server_queue_ctrl_reset_work();
}

int ksmbd_ipc_id_alloc(void)
{
	return ksmbd_acquire_id(&ipc_ida);
}

void ksmbd_rpc_id_free(int handle)
{
	ksmbd_release_id(&ipc_ida, handle);
}

void ksmbd_ipc_release(void)
{
	cancel_delayed_work_sync(&ipc_timer_work);
	genl_unregister_family(&ksmbd_genl_family);
}

void ksmbd_ipc_soft_reset(void)
{
	mutex_lock(&startup_lock);
	ksmbd_tools_pid = 0;
	cancel_delayed_work_sync(&ipc_timer_work);
	mutex_unlock(&startup_lock);
}

int ksmbd_ipc_init(void)
{
	int ret = 0;

	ksmbd_nl_init_fixup();
	INIT_DELAYED_WORK(&ipc_timer_work, ipc_timer_heartbeat);

	ret = genl_register_family(&ksmbd_genl_family);
	if (ret) {
		pr_err("Failed to register KSMBD netlink interface %d\n", ret);
		cancel_delayed_work_sync(&ipc_timer_work);
	}

	return ret;
}
