// SPDX-License-Identifier: GPL-2.0-or-later
/* In-kernel rxperf server for testing purposes.
 *
 * Copyright (C) 2022 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */

#define pr_fmt(fmt) "rxperf: " fmt
#include <linux/module.h>
#include <linux/slab.h>
#include <crypto/krb5.h>
#include <net/sock.h>
#include <net/af_rxrpc.h>
#define RXRPC_TRACE_ONLY_DEFINE_ENUMS
#include <trace/events/rxrpc.h>

MODULE_DESCRIPTION("rxperf test server (afs)");
MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL");

#define RXPERF_PORT		7009
#define RX_PERF_SERVICE		147
#define RX_PERF_VERSION		3
#define RX_PERF_SEND		0
#define RX_PERF_RECV		1
#define RX_PERF_RPC		3
#define RX_PERF_FILE		4
#define RX_PERF_MAGIC_COOKIE	0x4711

struct rxperf_proto_params {
	__be32		version;
	__be32		type;
	__be32		rsize;
	__be32		wsize;
} __packed;

static const u8 rxperf_magic_cookie[] = { 0x00, 0x00, 0x47, 0x11 };
static const u8 secret[8] = { 0xa7, 0x83, 0x8a, 0xcb, 0xc7, 0x83, 0xec, 0x94 };

enum rxperf_call_state {
	RXPERF_CALL_SV_AWAIT_PARAMS,	/* Server: Awaiting parameter block */
	RXPERF_CALL_SV_AWAIT_REQUEST,	/* Server: Awaiting request data */
	RXPERF_CALL_SV_REPLYING,	/* Server: Replying */
	RXPERF_CALL_SV_AWAIT_ACK,	/* Server: Awaiting final ACK */
	RXPERF_CALL_COMPLETE,		/* Completed or failed */
};

struct rxperf_call {
	struct rxrpc_call	*rxcall;
	struct iov_iter		iter;
	struct kvec		kvec[1];
	struct work_struct	work;
	const char		*type;
	size_t			iov_len;
	size_t			req_len;	/* Size of request blob */
	size_t			reply_len;	/* Size of reply blob */
	unsigned int		debug_id;
	unsigned int		operation_id;
	struct rxperf_proto_params params;
	__be32			tmp[2];
	s32			abort_code;
	enum rxperf_call_state	state;
	short			error;
	unsigned short		unmarshal;
	u16			service_id;
	int (*deliver)(struct rxperf_call *call);
	void (*processor)(struct work_struct *work);
};

static struct socket *rxperf_socket;
static struct key *rxperf_sec_keyring;	/* Ring of security/crypto keys */
static struct workqueue_struct *rxperf_workqueue;

static void rxperf_deliver_to_call(struct work_struct *work);
static int rxperf_deliver_param_block(struct rxperf_call *call);
static int rxperf_deliver_request(struct rxperf_call *call);
static int rxperf_process_call(struct rxperf_call *call);
static void rxperf_charge_preallocation(struct work_struct *work);

static DECLARE_WORK(rxperf_charge_preallocation_work,
		    rxperf_charge_preallocation);

static inline void rxperf_set_call_state(struct rxperf_call *call,
					 enum rxperf_call_state to)
{
	call->state = to;
}

static inline void rxperf_set_call_complete(struct rxperf_call *call,
					    int error, s32 remote_abort)
{
	if (call->state != RXPERF_CALL_COMPLETE) {
		call->abort_code = remote_abort;
		call->error = error;
		call->state = RXPERF_CALL_COMPLETE;
	}
}

static void rxperf_rx_discard_new_call(struct rxrpc_call *rxcall,
				       unsigned long user_call_ID)
{
	kfree((struct rxperf_call *)user_call_ID);
}

static void rxperf_rx_new_call(struct sock *sk, struct rxrpc_call *rxcall,
			       unsigned long user_call_ID)
{
	queue_work(rxperf_workqueue, &rxperf_charge_preallocation_work);
}

static void rxperf_queue_call_work(struct rxperf_call *call)
{
	queue_work(rxperf_workqueue, &call->work);
}

static void rxperf_notify_rx(struct sock *sk, struct rxrpc_call *rxcall,
			     unsigned long call_user_ID)
{
	struct rxperf_call *call = (struct rxperf_call *)call_user_ID;

	if (call->state != RXPERF_CALL_COMPLETE)
		rxperf_queue_call_work(call);
}

static void rxperf_rx_attach(struct rxrpc_call *rxcall, unsigned long user_call_ID)
{
	struct rxperf_call *call = (struct rxperf_call *)user_call_ID;

	call->rxcall = rxcall;
}

static void rxperf_notify_end_reply_tx(struct sock *sock,
				       struct rxrpc_call *rxcall,
				       unsigned long call_user_ID)
{
	rxperf_set_call_state((struct rxperf_call *)call_user_ID,
			      RXPERF_CALL_SV_AWAIT_ACK);
}

static const struct rxrpc_kernel_ops rxperf_rxrpc_callback_ops = {
	.notify_new_call	= rxperf_rx_new_call,
	.discard_new_call	= rxperf_rx_discard_new_call,
	.user_attach_call	= rxperf_rx_attach,
};

/*
 * Charge the incoming call preallocation.
 */
static void rxperf_charge_preallocation(struct work_struct *work)
{
	struct rxperf_call *call;

	for (;;) {
		call = kzalloc(sizeof(*call), GFP_KERNEL);
		if (!call)
			break;

		call->type		= "unset";
		call->debug_id		= atomic_inc_return(&rxrpc_debug_id);
		call->deliver		= rxperf_deliver_param_block;
		call->state		= RXPERF_CALL_SV_AWAIT_PARAMS;
		call->service_id	= RX_PERF_SERVICE;
		call->iov_len		= sizeof(call->params);
		call->kvec[0].iov_len	= sizeof(call->params);
		call->kvec[0].iov_base	= &call->params;
		iov_iter_kvec(&call->iter, READ, call->kvec, 1, call->iov_len);
		INIT_WORK(&call->work, rxperf_deliver_to_call);

		if (rxrpc_kernel_charge_accept(rxperf_socket,
					       rxperf_notify_rx,
					       (unsigned long)call,
					       GFP_KERNEL,
					       call->debug_id) < 0)
			break;
		call = NULL;
	}

	kfree(call);
}

/*
 * Open an rxrpc socket and bind it to be a server for callback notifications
 * - the socket is left in blocking mode and non-blocking ops use MSG_DONTWAIT
 */
static int rxperf_open_socket(void)
{
	struct sockaddr_rxrpc srx;
	struct socket *socket;
	int ret;

	ret = sock_create_kern(&init_net, AF_RXRPC, SOCK_DGRAM, PF_INET6,
			       &socket);
	if (ret < 0)
		goto error_1;

	socket->sk->sk_allocation = GFP_NOFS;

	/* bind the callback manager's address to make this a server socket */
	memset(&srx, 0, sizeof(srx));
	srx.srx_family			= AF_RXRPC;
	srx.srx_service			= RX_PERF_SERVICE;
	srx.transport_type		= SOCK_DGRAM;
	srx.transport_len		= sizeof(srx.transport.sin6);
	srx.transport.sin6.sin6_family	= AF_INET6;
	srx.transport.sin6.sin6_port	= htons(RXPERF_PORT);

	ret = rxrpc_sock_set_min_security_level(socket->sk,
						RXRPC_SECURITY_ENCRYPT);
	if (ret < 0)
		goto error_2;

	ret = rxrpc_sock_set_security_keyring(socket->sk, rxperf_sec_keyring);

	ret = kernel_bind(socket, (struct sockaddr *)&srx, sizeof(srx));
	if (ret < 0)
		goto error_2;

	rxrpc_kernel_set_notifications(socket, &rxperf_rxrpc_callback_ops);

	ret = kernel_listen(socket, INT_MAX);
	if (ret < 0)
		goto error_2;

	rxperf_socket = socket;
	rxperf_charge_preallocation(&rxperf_charge_preallocation_work);
	return 0;

error_2:
	sock_release(socket);
error_1:
	pr_err("Can't set up rxperf socket: %d\n", ret);
	return ret;
}

/*
 * close the rxrpc socket rxperf was using
 */
static void rxperf_close_socket(void)
{
	kernel_listen(rxperf_socket, 0);
	kernel_sock_shutdown(rxperf_socket, SHUT_RDWR);
	flush_workqueue(rxperf_workqueue);
	sock_release(rxperf_socket);
}

/*
 * Log remote abort codes that indicate that we have a protocol disagreement
 * with the server.
 */
static void rxperf_log_error(struct rxperf_call *call, s32 remote_abort)
{
	static int max = 0;
	const char *msg;
	int m;

	switch (remote_abort) {
	case RX_EOF:		 msg = "unexpected EOF";	break;
	case RXGEN_CC_MARSHAL:	 msg = "client marshalling";	break;
	case RXGEN_CC_UNMARSHAL: msg = "client unmarshalling";	break;
	case RXGEN_SS_MARSHAL:	 msg = "server marshalling";	break;
	case RXGEN_SS_UNMARSHAL: msg = "server unmarshalling";	break;
	case RXGEN_DECODE:	 msg = "opcode decode";		break;
	case RXGEN_SS_XDRFREE:	 msg = "server XDR cleanup";	break;
	case RXGEN_CC_XDRFREE:	 msg = "client XDR cleanup";	break;
	case -32:		 msg = "insufficient data";	break;
	default:
		return;
	}

	m = max;
	if (m < 3) {
		max = m + 1;
		pr_info("Peer reported %s failure on %s\n", msg, call->type);
	}
}

/*
 * deliver messages to a call
 */
static void rxperf_deliver_to_call(struct work_struct *work)
{
	struct rxperf_call *call = container_of(work, struct rxperf_call, work);
	enum rxperf_call_state state;
	u32 abort_code, remote_abort = 0;
	int ret = 0;

	if (call->state == RXPERF_CALL_COMPLETE)
		return;

	while (state = call->state,
	       state == RXPERF_CALL_SV_AWAIT_PARAMS ||
	       state == RXPERF_CALL_SV_AWAIT_REQUEST ||
	       state == RXPERF_CALL_SV_AWAIT_ACK
	       ) {
		if (state == RXPERF_CALL_SV_AWAIT_ACK) {
			if (!rxrpc_kernel_check_life(rxperf_socket, call->rxcall))
				goto call_complete;
			return;
		}

		ret = call->deliver(call);
		if (ret == 0)
			ret = rxperf_process_call(call);

		switch (ret) {
		case 0:
			continue;
		case -EINPROGRESS:
		case -EAGAIN:
			return;
		case -ECONNABORTED:
			rxperf_log_error(call, call->abort_code);
			goto call_complete;
		case -EOPNOTSUPP:
			abort_code = RXGEN_OPCODE;
			rxrpc_kernel_abort_call(rxperf_socket, call->rxcall,
						abort_code, ret,
						rxperf_abort_op_not_supported);
			goto call_complete;
		case -ENOTSUPP:
			abort_code = RX_USER_ABORT;
			rxrpc_kernel_abort_call(rxperf_socket, call->rxcall,
						abort_code, ret,
						rxperf_abort_op_not_supported);
			goto call_complete;
		case -EIO:
			pr_err("Call %u in bad state %u\n",
			       call->debug_id, call->state);
			fallthrough;
		case -ENODATA:
		case -EBADMSG:
		case -EMSGSIZE:
		case -ENOMEM:
		case -EFAULT:
			rxrpc_kernel_abort_call(rxperf_socket, call->rxcall,
						RXGEN_SS_UNMARSHAL, ret,
						rxperf_abort_unmarshal_error);
			goto call_complete;
		default:
			rxrpc_kernel_abort_call(rxperf_socket, call->rxcall,
						RX_CALL_DEAD, ret,
						rxperf_abort_general_error);
			goto call_complete;
		}
	}

call_complete:
	rxperf_set_call_complete(call, ret, remote_abort);
	/* The call may have been requeued */
	rxrpc_kernel_shutdown_call(rxperf_socket, call->rxcall);
	rxrpc_kernel_put_call(rxperf_socket, call->rxcall);
	cancel_work(&call->work);
	kfree(call);
}

/*
 * Extract a piece of data from the received data socket buffers.
 */
static int rxperf_extract_data(struct rxperf_call *call, bool want_more)
{
	u32 remote_abort = 0;
	int ret;

	ret = rxrpc_kernel_recv_data(rxperf_socket, call->rxcall, &call->iter,
				     &call->iov_len, want_more, &remote_abort,
				     &call->service_id);
	pr_debug("Extract i=%zu l=%zu m=%u ret=%d\n",
		 iov_iter_count(&call->iter), call->iov_len, want_more, ret);
	if (ret == 0 || ret == -EAGAIN)
		return ret;

	if (ret == 1) {
		switch (call->state) {
		case RXPERF_CALL_SV_AWAIT_REQUEST:
			rxperf_set_call_state(call, RXPERF_CALL_SV_REPLYING);
			break;
		case RXPERF_CALL_COMPLETE:
			pr_debug("premature completion %d", call->error);
			return call->error;
		default:
			break;
		}
		return 0;
	}

	rxperf_set_call_complete(call, ret, remote_abort);
	return ret;
}

/*
 * Grab the operation ID from an incoming manager call.
 */
static int rxperf_deliver_param_block(struct rxperf_call *call)
{
	u32 version;
	int ret;

	/* Extract the parameter block */
	ret = rxperf_extract_data(call, true);
	if (ret < 0)
		return ret;

	version			= ntohl(call->params.version);
	call->operation_id	= ntohl(call->params.type);
	call->deliver		= rxperf_deliver_request;

	if (version != RX_PERF_VERSION) {
		pr_info("Version mismatch %x\n", version);
		return -ENOTSUPP;
	}

	switch (call->operation_id) {
	case RX_PERF_SEND:
		call->type = "send";
		call->reply_len = 0;
		call->iov_len = 4;	/* Expect req size */
		break;
	case RX_PERF_RECV:
		call->type = "recv";
		call->req_len = 0;
		call->iov_len = 4;	/* Expect reply size */
		break;
	case RX_PERF_RPC:
		call->type = "rpc";
		call->iov_len = 8;	/* Expect req size and reply size */
		break;
	case RX_PERF_FILE:
		call->type = "file";
		fallthrough;
	default:
		return -EOPNOTSUPP;
	}

	rxperf_set_call_state(call, RXPERF_CALL_SV_AWAIT_REQUEST);
	return call->deliver(call);
}

/*
 * Deliver the request data.
 */
static int rxperf_deliver_request(struct rxperf_call *call)
{
	int ret;

	switch (call->unmarshal) {
	case 0:
		call->kvec[0].iov_len	= call->iov_len;
		call->kvec[0].iov_base	= call->tmp;
		iov_iter_kvec(&call->iter, READ, call->kvec, 1, call->iov_len);
		call->unmarshal++;
		fallthrough;
	case 1:
		ret = rxperf_extract_data(call, true);
		if (ret < 0)
			return ret;

		switch (call->operation_id) {
		case RX_PERF_SEND:
			call->type = "send";
			call->req_len	= ntohl(call->tmp[0]);
			call->reply_len	= 0;
			break;
		case RX_PERF_RECV:
			call->type = "recv";
			call->req_len = 0;
			call->reply_len	= ntohl(call->tmp[0]);
			break;
		case RX_PERF_RPC:
			call->type = "rpc";
			call->req_len	= ntohl(call->tmp[0]);
			call->reply_len	= ntohl(call->tmp[1]);
			break;
		default:
			pr_info("Can't parse extra params\n");
			return -EIO;
		}

		pr_debug("CALL op=%s rq=%zx rp=%zx\n",
			 call->type, call->req_len, call->reply_len);

		call->iov_len = call->req_len;
		iov_iter_discard(&call->iter, READ, call->req_len);
		call->unmarshal++;
		fallthrough;
	case 2:
		ret = rxperf_extract_data(call, true);
		if (ret < 0)
			return ret;

		/* Deal with the terminal magic cookie. */
		call->iov_len = 4;
		call->kvec[0].iov_len	= call->iov_len;
		call->kvec[0].iov_base	= call->tmp;
		iov_iter_kvec(&call->iter, READ, call->kvec, 1, call->iov_len);
		call->unmarshal++;
		fallthrough;
	case 3:
		ret = rxperf_extract_data(call, false);
		if (ret < 0)
			return ret;
		call->unmarshal++;
		fallthrough;
	default:
		return 0;
	}
}

/*
 * Process a call for which we've received the request.
 */
static int rxperf_process_call(struct rxperf_call *call)
{
	struct msghdr msg = {};
	struct bio_vec bv;
	struct kvec iov[1];
	ssize_t n;
	size_t reply_len = call->reply_len, len;

	rxrpc_kernel_set_tx_length(rxperf_socket, call->rxcall,
				   reply_len + sizeof(rxperf_magic_cookie));

	while (reply_len > 0) {
		len = umin(reply_len, PAGE_SIZE);
		bvec_set_page(&bv, ZERO_PAGE(0), len, 0);
		iov_iter_bvec(&msg.msg_iter, WRITE, &bv, 1, len);
		msg.msg_flags = MSG_MORE;
		n = rxrpc_kernel_send_data(rxperf_socket, call->rxcall, &msg,
					   len, rxperf_notify_end_reply_tx);
		if (n < 0)
			return n;
		if (n == 0)
			return -EIO;
		reply_len -= n;
	}

	len = sizeof(rxperf_magic_cookie);
	iov[0].iov_base	= (void *)rxperf_magic_cookie;
	iov[0].iov_len	= len;
	iov_iter_kvec(&msg.msg_iter, WRITE, iov, 1, len);
	msg.msg_flags = 0;
	n = rxrpc_kernel_send_data(rxperf_socket, call->rxcall, &msg, len,
				   rxperf_notify_end_reply_tx);
	if (n >= 0)
		return 0; /* Success */

	if (n == -ENOMEM)
		rxrpc_kernel_abort_call(rxperf_socket, call->rxcall,
					RXGEN_SS_MARSHAL, -ENOMEM,
					rxperf_abort_oom);
	return n;
}

/*
 * Add an rxkad key to the security keyring.
 */
static int rxperf_add_rxkad_key(struct key *keyring)
{
	key_ref_t kref;
	int ret;

	kref = key_create_or_update(make_key_ref(keyring, true),
				    "rxrpc_s",
				    __stringify(RX_PERF_SERVICE) ":2",
				    secret,
				    sizeof(secret),
				    KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH
				    | KEY_USR_VIEW,
				    KEY_ALLOC_NOT_IN_QUOTA);

	if (IS_ERR(kref)) {
		pr_err("Can't allocate rxperf server key: %ld\n", PTR_ERR(kref));
		return PTR_ERR(kref);
	}

	ret = key_link(keyring, key_ref_to_ptr(kref));
	if (ret < 0)
		pr_err("Can't link rxperf server key: %d\n", ret);
	key_ref_put(kref);
	return ret;
}

#ifdef CONFIG_RXGK
/*
 * Add a yfs-rxgk key to the security keyring.
 */
static int rxperf_add_yfs_rxgk_key(struct key *keyring, u32 enctype)
{
	const struct krb5_enctype *krb5 = crypto_krb5_find_enctype(enctype);
	key_ref_t kref;
	char name[64];
	int ret;
	u8 key[32];

	if (!krb5 || krb5->key_len > sizeof(key))
		return 0;

	/* The key is just { 0, 1, 2, 3, 4, ... } */
	for (int i = 0; i < krb5->key_len; i++)
		key[i] = i;

	sprintf(name, "%u:6:1:%u", RX_PERF_SERVICE, enctype);

	kref = key_create_or_update(make_key_ref(keyring, true),
				    "rxrpc_s", name,
				    key, krb5->key_len,
				    KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
				    KEY_USR_VIEW,
				    KEY_ALLOC_NOT_IN_QUOTA);

	if (IS_ERR(kref)) {
		pr_err("Can't allocate rxperf server key: %ld\n", PTR_ERR(kref));
		return PTR_ERR(kref);
	}

	ret = key_link(keyring, key_ref_to_ptr(kref));
	if (ret < 0)
		pr_err("Can't link rxperf server key: %d\n", ret);
	key_ref_put(kref);
	return ret;
}
#endif

/*
 * Initialise the rxperf server.
 */
static int __init rxperf_init(void)
{
	struct key *keyring;
	int ret = -ENOMEM;

	pr_info("Server registering\n");

	rxperf_workqueue = alloc_workqueue("rxperf", WQ_PERCPU, 0);
	if (!rxperf_workqueue)
		goto error_workqueue;

	keyring = keyring_alloc("rxperf_server",
				GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, current_cred(),
				KEY_POS_VIEW | KEY_POS_READ | KEY_POS_SEARCH |
				KEY_POS_WRITE |
				KEY_USR_VIEW | KEY_USR_READ | KEY_USR_SEARCH |
				KEY_USR_WRITE |
				KEY_OTH_VIEW | KEY_OTH_READ | KEY_OTH_SEARCH,
				KEY_ALLOC_NOT_IN_QUOTA,
				NULL, NULL);
	if (IS_ERR(keyring)) {
		pr_err("Can't allocate rxperf server keyring: %ld\n",
		       PTR_ERR(keyring));
		goto error_keyring;
	}
	rxperf_sec_keyring = keyring;
	ret = rxperf_add_rxkad_key(keyring);
	if (ret < 0)
		goto error_key;
#ifdef CONFIG_RXGK
	ret = rxperf_add_yfs_rxgk_key(keyring, KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96);
	if (ret < 0)
		goto error_key;
	ret = rxperf_add_yfs_rxgk_key(keyring, KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96);
	if (ret < 0)
		goto error_key;
	ret = rxperf_add_yfs_rxgk_key(keyring, KRB5_ENCTYPE_AES128_CTS_HMAC_SHA256_128);
	if (ret < 0)
		goto error_key;
	ret = rxperf_add_yfs_rxgk_key(keyring, KRB5_ENCTYPE_AES256_CTS_HMAC_SHA384_192);
	if (ret < 0)
		goto error_key;
	ret = rxperf_add_yfs_rxgk_key(keyring, KRB5_ENCTYPE_CAMELLIA128_CTS_CMAC);
	if (ret < 0)
		goto error_key;
	ret = rxperf_add_yfs_rxgk_key(keyring, KRB5_ENCTYPE_CAMELLIA256_CTS_CMAC);
	if (ret < 0)
		goto error_key;
#endif

	ret = rxperf_open_socket();
	if (ret < 0)
		goto error_socket;
	return 0;

error_socket:
error_key:
	key_put(rxperf_sec_keyring);
error_keyring:
	destroy_workqueue(rxperf_workqueue);
	rcu_barrier();
error_workqueue:
	pr_err("Failed to register: %d\n", ret);
	return ret;
}
late_initcall(rxperf_init); /* Must be called after net/ to create socket */

static void __exit rxperf_exit(void)
{
	pr_info("Server unregistering.\n");

	rxperf_close_socket();
	key_put(rxperf_sec_keyring);
	destroy_workqueue(rxperf_workqueue);
	rcu_barrier();
}
module_exit(rxperf_exit);

