// SPDX-License-Identifier: GPL-2.0-or-later
/* AFS Cache Manager Service
 *
 * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/ip.h>
#include "internal.h"
#include "afs_cm.h"
#include "protocol_yfs.h"
#define RXRPC_TRACE_ONLY_DEFINE_ENUMS
#include <trace/events/rxrpc.h>

static int afs_deliver_cb_init_call_back_state(struct afs_call *);
static int afs_deliver_cb_init_call_back_state3(struct afs_call *);
static int afs_deliver_cb_probe(struct afs_call *);
static int afs_deliver_cb_callback(struct afs_call *);
static int afs_deliver_cb_probe_uuid(struct afs_call *);
static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *);
static void afs_cm_destructor(struct afs_call *);
static void SRXAFSCB_CallBack(struct work_struct *);
static void SRXAFSCB_InitCallBackState(struct work_struct *);
static void SRXAFSCB_Probe(struct work_struct *);
static void SRXAFSCB_ProbeUuid(struct work_struct *);
static void SRXAFSCB_TellMeAboutYourself(struct work_struct *);

static int afs_deliver_yfs_cb_callback(struct afs_call *);

/*
 * CB.CallBack operation type
 */
static const struct afs_call_type afs_SRXCBCallBack = {
	.name		= "CB.CallBack",
	.deliver	= afs_deliver_cb_callback,
	.destructor	= afs_cm_destructor,
	.work		= SRXAFSCB_CallBack,
};

/*
 * CB.InitCallBackState operation type
 */
static const struct afs_call_type afs_SRXCBInitCallBackState = {
	.name		= "CB.InitCallBackState",
	.deliver	= afs_deliver_cb_init_call_back_state,
	.destructor	= afs_cm_destructor,
	.work		= SRXAFSCB_InitCallBackState,
};

/*
 * CB.InitCallBackState3 operation type
 */
static const struct afs_call_type afs_SRXCBInitCallBackState3 = {
	.name		= "CB.InitCallBackState3",
	.deliver	= afs_deliver_cb_init_call_back_state3,
	.destructor	= afs_cm_destructor,
	.work		= SRXAFSCB_InitCallBackState,
};

/*
 * CB.Probe operation type
 */
static const struct afs_call_type afs_SRXCBProbe = {
	.name		= "CB.Probe",
	.deliver	= afs_deliver_cb_probe,
	.destructor	= afs_cm_destructor,
	.work		= SRXAFSCB_Probe,
};

/*
 * CB.ProbeUuid operation type
 */
static const struct afs_call_type afs_SRXCBProbeUuid = {
	.name		= "CB.ProbeUuid",
	.deliver	= afs_deliver_cb_probe_uuid,
	.destructor	= afs_cm_destructor,
	.work		= SRXAFSCB_ProbeUuid,
};

/*
 * CB.TellMeAboutYourself operation type
 */
static const struct afs_call_type afs_SRXCBTellMeAboutYourself = {
	.name		= "CB.TellMeAboutYourself",
	.deliver	= afs_deliver_cb_tell_me_about_yourself,
	.destructor	= afs_cm_destructor,
	.work		= SRXAFSCB_TellMeAboutYourself,
};

/*
 * YFS CB.CallBack operation type
 */
static const struct afs_call_type afs_SRXYFSCB_CallBack = {
	.name		= "YFSCB.CallBack",
	.deliver	= afs_deliver_yfs_cb_callback,
	.destructor	= afs_cm_destructor,
	.work		= SRXAFSCB_CallBack,
};

/*
 * route an incoming cache manager call
 * - return T if supported, F if not
 */
bool afs_cm_incoming_call(struct afs_call *call)
{
	_enter("{%u, CB.OP %u}", call->service_id, call->operation_ID);

	switch (call->operation_ID) {
	case CBCallBack:
		call->type = &afs_SRXCBCallBack;
		return true;
	case CBInitCallBackState:
		call->type = &afs_SRXCBInitCallBackState;
		return true;
	case CBInitCallBackState3:
		call->type = &afs_SRXCBInitCallBackState3;
		return true;
	case CBProbe:
		call->type = &afs_SRXCBProbe;
		return true;
	case CBProbeUuid:
		call->type = &afs_SRXCBProbeUuid;
		return true;
	case CBTellMeAboutYourself:
		call->type = &afs_SRXCBTellMeAboutYourself;
		return true;
	case YFSCBCallBack:
		if (call->service_id != YFS_CM_SERVICE)
			return false;
		call->type = &afs_SRXYFSCB_CallBack;
		return true;
	default:
		return false;
	}
}

/*
 * Clean up a cache manager call.
 */
static void afs_cm_destructor(struct afs_call *call)
{
	kfree(call->buffer);
	call->buffer = NULL;
}

/*
 * Abort a service call from within an action function.
 */
static void afs_abort_service_call(struct afs_call *call, u32 abort_code, int error,
				   enum rxrpc_abort_reason why)
{
	rxrpc_kernel_abort_call(call->net->socket, call->rxcall,
				abort_code, error, why);
	afs_set_call_complete(call, error, 0);
}

/*
 * The server supplied a list of callbacks that it wanted to break.
 */
static void SRXAFSCB_CallBack(struct work_struct *work)
{
	struct afs_call *call = container_of(work, struct afs_call, work);

	_enter("");

	/* We need to break the callbacks before sending the reply as the
	 * server holds up change visibility till it receives our reply so as
	 * to maintain cache coherency.
	 */
	if (call->server) {
		trace_afs_server(call->server->debug_id,
				 refcount_read(&call->server->ref),
				 atomic_read(&call->server->active),
				 afs_server_trace_callback);
		afs_break_callbacks(call->server, call->count, call->request);
	}

	afs_send_empty_reply(call);
	afs_put_call(call);
	_leave("");
}

/*
 * deliver request data to a CB.CallBack call
 */
static int afs_deliver_cb_callback(struct afs_call *call)
{
	struct afs_callback_break *cb;
	__be32 *bp;
	int ret, loop;

	_enter("{%u}", call->unmarshall);

	switch (call->unmarshall) {
	case 0:
		afs_extract_to_tmp(call);
		call->unmarshall++;

		/* extract the FID array and its count in two steps */
		fallthrough;
	case 1:
		_debug("extract FID count");
		ret = afs_extract_data(call, true);
		if (ret < 0)
			return ret;

		call->count = ntohl(call->tmp);
		_debug("FID count: %u", call->count);
		if (call->count > AFSCBMAX)
			return afs_protocol_error(call, afs_eproto_cb_fid_count);

		call->buffer = kmalloc(array3_size(call->count, 3, 4),
				       GFP_KERNEL);
		if (!call->buffer)
			return -ENOMEM;
		afs_extract_to_buf(call, call->count * 3 * 4);
		call->unmarshall++;

		fallthrough;
	case 2:
		_debug("extract FID array");
		ret = afs_extract_data(call, true);
		if (ret < 0)
			return ret;

		_debug("unmarshall FID array");
		call->request = kcalloc(call->count,
					sizeof(struct afs_callback_break),
					GFP_KERNEL);
		if (!call->request)
			return -ENOMEM;

		cb = call->request;
		bp = call->buffer;
		for (loop = call->count; loop > 0; loop--, cb++) {
			cb->fid.vid	= ntohl(*bp++);
			cb->fid.vnode	= ntohl(*bp++);
			cb->fid.unique	= ntohl(*bp++);
		}

		afs_extract_to_tmp(call);
		call->unmarshall++;

		/* extract the callback array and its count in two steps */
		fallthrough;
	case 3:
		_debug("extract CB count");
		ret = afs_extract_data(call, true);
		if (ret < 0)
			return ret;

		call->count2 = ntohl(call->tmp);
		_debug("CB count: %u", call->count2);
		if (call->count2 != call->count && call->count2 != 0)
			return afs_protocol_error(call, afs_eproto_cb_count);
		call->iter = &call->def_iter;
		iov_iter_discard(&call->def_iter, ITER_DEST, call->count2 * 3 * 4);
		call->unmarshall++;

		fallthrough;
	case 4:
		_debug("extract discard %zu/%u",
		       iov_iter_count(call->iter), call->count2 * 3 * 4);

		ret = afs_extract_data(call, false);
		if (ret < 0)
			return ret;

		call->unmarshall++;
		fallthrough;

	case 5:
		break;
	}

	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
		return afs_io_error(call, afs_io_error_cm_reply);
	return 0;
}

/*
 * allow the fileserver to request callback state (re-)initialisation
 */
static void SRXAFSCB_InitCallBackState(struct work_struct *work)
{
	struct afs_call *call = container_of(work, struct afs_call, work);

	_enter("{%p}", call->server);

	if (call->server)
		afs_init_callback_state(call->server);
	afs_send_empty_reply(call);
	afs_put_call(call);
	_leave("");
}

/*
 * deliver request data to a CB.InitCallBackState call
 */
static int afs_deliver_cb_init_call_back_state(struct afs_call *call)
{
	_enter("");

	afs_extract_discard(call, 0);
	return afs_extract_data(call, false);
}

/*
 * deliver request data to a CB.InitCallBackState3 call
 */
static int afs_deliver_cb_init_call_back_state3(struct afs_call *call)
{
	struct afs_uuid *r;
	unsigned loop;
	__be32 *b;
	int ret;

	_enter("{%u}", call->unmarshall);

	switch (call->unmarshall) {
	case 0:
		call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL);
		if (!call->buffer)
			return -ENOMEM;
		afs_extract_to_buf(call, 11 * sizeof(__be32));
		call->unmarshall++;

		fallthrough;
	case 1:
		_debug("extract UUID");
		ret = afs_extract_data(call, false);
		switch (ret) {
		case 0:		break;
		case -EAGAIN:	return 0;
		default:	return ret;
		}

		_debug("unmarshall UUID");
		call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
		if (!call->request)
			return -ENOMEM;

		b = call->buffer;
		r = call->request;
		r->time_low			= b[0];
		r->time_mid			= htons(ntohl(b[1]));
		r->time_hi_and_version		= htons(ntohl(b[2]));
		r->clock_seq_hi_and_reserved 	= ntohl(b[3]);
		r->clock_seq_low		= ntohl(b[4]);

		for (loop = 0; loop < 6; loop++)
			r->node[loop] = ntohl(b[loop + 5]);

		call->unmarshall++;
		fallthrough;

	case 2:
		break;
	}

	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
		return afs_io_error(call, afs_io_error_cm_reply);

	if (memcmp(call->request, &call->server->_uuid, sizeof(call->server->_uuid)) != 0) {
		pr_notice("Callback UUID does not match fileserver UUID\n");
		trace_afs_cm_no_server_u(call, call->request);
		return 0;
	}

	return 0;
}

/*
 * allow the fileserver to see if the cache manager is still alive
 */
static void SRXAFSCB_Probe(struct work_struct *work)
{
	struct afs_call *call = container_of(work, struct afs_call, work);

	_enter("");
	afs_send_empty_reply(call);
	afs_put_call(call);
	_leave("");
}

/*
 * deliver request data to a CB.Probe call
 */
static int afs_deliver_cb_probe(struct afs_call *call)
{
	int ret;

	_enter("");

	afs_extract_discard(call, 0);
	ret = afs_extract_data(call, false);
	if (ret < 0)
		return ret;

	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
		return afs_io_error(call, afs_io_error_cm_reply);
	return 0;
}

/*
 * Allow the fileserver to quickly find out if the cache manager has been
 * rebooted.
 */
static void SRXAFSCB_ProbeUuid(struct work_struct *work)
{
	struct afs_call *call = container_of(work, struct afs_call, work);
	struct afs_uuid *r = call->request;

	_enter("");

	if (memcmp(r, &call->net->uuid, sizeof(call->net->uuid)) == 0)
		afs_send_empty_reply(call);
	else
		afs_abort_service_call(call, 1, 1, afs_abort_probeuuid_negative);

	afs_put_call(call);
	_leave("");
}

/*
 * deliver request data to a CB.ProbeUuid call
 */
static int afs_deliver_cb_probe_uuid(struct afs_call *call)
{
	struct afs_uuid *r;
	unsigned loop;
	__be32 *b;
	int ret;

	_enter("{%u}", call->unmarshall);

	switch (call->unmarshall) {
	case 0:
		call->buffer = kmalloc_array(11, sizeof(__be32), GFP_KERNEL);
		if (!call->buffer)
			return -ENOMEM;
		afs_extract_to_buf(call, 11 * sizeof(__be32));
		call->unmarshall++;

		fallthrough;
	case 1:
		_debug("extract UUID");
		ret = afs_extract_data(call, false);
		switch (ret) {
		case 0:		break;
		case -EAGAIN:	return 0;
		default:	return ret;
		}

		_debug("unmarshall UUID");
		call->request = kmalloc(sizeof(struct afs_uuid), GFP_KERNEL);
		if (!call->request)
			return -ENOMEM;

		b = call->buffer;
		r = call->request;
		r->time_low			= b[0];
		r->time_mid			= htons(ntohl(b[1]));
		r->time_hi_and_version		= htons(ntohl(b[2]));
		r->clock_seq_hi_and_reserved 	= ntohl(b[3]);
		r->clock_seq_low		= ntohl(b[4]);

		for (loop = 0; loop < 6; loop++)
			r->node[loop] = ntohl(b[loop + 5]);

		call->unmarshall++;
		fallthrough;

	case 2:
		break;
	}

	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
		return afs_io_error(call, afs_io_error_cm_reply);
	return 0;
}

/*
 * allow the fileserver to ask about the cache manager's capabilities
 */
static void SRXAFSCB_TellMeAboutYourself(struct work_struct *work)
{
	struct afs_call *call = container_of(work, struct afs_call, work);
	int loop;

	struct {
		struct /* InterfaceAddr */ {
			__be32 nifs;
			__be32 uuid[11];
			__be32 ifaddr[32];
			__be32 netmask[32];
			__be32 mtu[32];
		} ia;
		struct /* Capabilities */ {
			__be32 capcount;
			__be32 caps[1];
		} cap;
	} reply;

	_enter("");

	memset(&reply, 0, sizeof(reply));

	reply.ia.uuid[0] = call->net->uuid.time_low;
	reply.ia.uuid[1] = htonl(ntohs(call->net->uuid.time_mid));
	reply.ia.uuid[2] = htonl(ntohs(call->net->uuid.time_hi_and_version));
	reply.ia.uuid[3] = htonl((s8) call->net->uuid.clock_seq_hi_and_reserved);
	reply.ia.uuid[4] = htonl((s8) call->net->uuid.clock_seq_low);
	for (loop = 0; loop < 6; loop++)
		reply.ia.uuid[loop + 5] = htonl((s8) call->net->uuid.node[loop]);

	reply.cap.capcount = htonl(1);
	reply.cap.caps[0] = htonl(AFS_CAP_ERROR_TRANSLATION);
	afs_send_simple_reply(call, &reply, sizeof(reply));
	afs_put_call(call);
	_leave("");
}

/*
 * deliver request data to a CB.TellMeAboutYourself call
 */
static int afs_deliver_cb_tell_me_about_yourself(struct afs_call *call)
{
	int ret;

	_enter("");

	afs_extract_discard(call, 0);
	ret = afs_extract_data(call, false);
	if (ret < 0)
		return ret;

	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
		return afs_io_error(call, afs_io_error_cm_reply);
	return 0;
}

/*
 * deliver request data to a YFS CB.CallBack call
 */
static int afs_deliver_yfs_cb_callback(struct afs_call *call)
{
	struct afs_callback_break *cb;
	struct yfs_xdr_YFSFid *bp;
	size_t size;
	int ret, loop;

	_enter("{%u}", call->unmarshall);

	switch (call->unmarshall) {
	case 0:
		afs_extract_to_tmp(call);
		call->unmarshall++;

		/* extract the FID array and its count in two steps */
		fallthrough;
	case 1:
		_debug("extract FID count");
		ret = afs_extract_data(call, true);
		if (ret < 0)
			return ret;

		call->count = ntohl(call->tmp);
		_debug("FID count: %u", call->count);
		if (call->count > YFSCBMAX)
			return afs_protocol_error(call, afs_eproto_cb_fid_count);

		size = array_size(call->count, sizeof(struct yfs_xdr_YFSFid));
		call->buffer = kmalloc(size, GFP_KERNEL);
		if (!call->buffer)
			return -ENOMEM;
		afs_extract_to_buf(call, size);
		call->unmarshall++;

		fallthrough;
	case 2:
		_debug("extract FID array");
		ret = afs_extract_data(call, false);
		if (ret < 0)
			return ret;

		_debug("unmarshall FID array");
		call->request = kcalloc(call->count,
					sizeof(struct afs_callback_break),
					GFP_KERNEL);
		if (!call->request)
			return -ENOMEM;

		cb = call->request;
		bp = call->buffer;
		for (loop = call->count; loop > 0; loop--, cb++) {
			cb->fid.vid	= xdr_to_u64(bp->volume);
			cb->fid.vnode	= xdr_to_u64(bp->vnode.lo);
			cb->fid.vnode_hi = ntohl(bp->vnode.hi);
			cb->fid.unique	= ntohl(bp->vnode.unique);
			bp++;
		}

		afs_extract_to_tmp(call);
		call->unmarshall++;
		fallthrough;

	case 3:
		break;
	}

	if (!afs_check_call_state(call, AFS_CALL_SV_REPLYING))
		return afs_io_error(call, afs_io_error_cm_reply);
	return 0;
}
