// SPDX-License-Identifier: GPL-2.0
/*
 * Ceph msgr2 protocol implementation
 *
 * Copyright (C) 2020 Ilya Dryomov <idryomov@gmail.com>
 */

#include <linux/ceph/ceph_debug.h>

#include <crypto/aead.h>
#include <crypto/algapi.h>  /* for crypto_memneq() */
#include <crypto/hash.h>
#include <crypto/sha2.h>
#include <linux/bvec.h>
#include <linux/crc32c.h>
#include <linux/net.h>
#include <linux/scatterlist.h>
#include <linux/socket.h>
#include <linux/sched/mm.h>
#include <net/sock.h>
#include <net/tcp.h>

#include <linux/ceph/ceph_features.h>
#include <linux/ceph/decode.h>
#include <linux/ceph/libceph.h>
#include <linux/ceph/messenger.h>

#include "crypto.h"  /* for CEPH_KEY_LEN and CEPH_MAX_CON_SECRET_LEN */

#define FRAME_TAG_HELLO			1
#define FRAME_TAG_AUTH_REQUEST		2
#define FRAME_TAG_AUTH_BAD_METHOD	3
#define FRAME_TAG_AUTH_REPLY_MORE	4
#define FRAME_TAG_AUTH_REQUEST_MORE	5
#define FRAME_TAG_AUTH_DONE		6
#define FRAME_TAG_AUTH_SIGNATURE	7
#define FRAME_TAG_CLIENT_IDENT		8
#define FRAME_TAG_SERVER_IDENT		9
#define FRAME_TAG_IDENT_MISSING_FEATURES 10
#define FRAME_TAG_SESSION_RECONNECT	11
#define FRAME_TAG_SESSION_RESET		12
#define FRAME_TAG_SESSION_RETRY		13
#define FRAME_TAG_SESSION_RETRY_GLOBAL	14
#define FRAME_TAG_SESSION_RECONNECT_OK	15
#define FRAME_TAG_WAIT			16
#define FRAME_TAG_MESSAGE		17
#define FRAME_TAG_KEEPALIVE2		18
#define FRAME_TAG_KEEPALIVE2_ACK	19
#define FRAME_TAG_ACK			20

#define FRAME_LATE_STATUS_ABORTED	0x1
#define FRAME_LATE_STATUS_COMPLETE	0xe
#define FRAME_LATE_STATUS_ABORTED_MASK	0xf

#define IN_S_HANDLE_PREAMBLE		1
#define IN_S_HANDLE_CONTROL		2
#define IN_S_HANDLE_CONTROL_REMAINDER	3
#define IN_S_PREPARE_READ_DATA		4
#define IN_S_PREPARE_READ_DATA_CONT	5
#define IN_S_PREPARE_READ_ENC_PAGE	6
#define IN_S_HANDLE_EPILOGUE		7
#define IN_S_FINISH_SKIP		8

#define OUT_S_QUEUE_DATA		1
#define OUT_S_QUEUE_DATA_CONT		2
#define OUT_S_QUEUE_ENC_PAGE		3
#define OUT_S_QUEUE_ZEROS		4
#define OUT_S_FINISH_MESSAGE		5
#define OUT_S_GET_NEXT			6

#define CTRL_BODY(p)	((void *)(p) + CEPH_PREAMBLE_LEN)
#define FRONT_PAD(p)	((void *)(p) + CEPH_EPILOGUE_SECURE_LEN)
#define MIDDLE_PAD(p)	(FRONT_PAD(p) + CEPH_GCM_BLOCK_LEN)
#define DATA_PAD(p)	(MIDDLE_PAD(p) + CEPH_GCM_BLOCK_LEN)

#define CEPH_MSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL)

static int do_recvmsg(struct socket *sock, struct iov_iter *it)
{
	struct msghdr msg = { .msg_flags = CEPH_MSG_FLAGS };
	int ret;

	msg.msg_iter = *it;
	while (iov_iter_count(it)) {
		ret = sock_recvmsg(sock, &msg, msg.msg_flags);
		if (ret <= 0) {
			if (ret == -EAGAIN)
				ret = 0;
			return ret;
		}

		iov_iter_advance(it, ret);
	}

	WARN_ON(msg_data_left(&msg));
	return 1;
}

/*
 * Read as much as possible.
 *
 * Return:
 *   1 - done, nothing (else) to read
 *   0 - socket is empty, need to wait
 *  <0 - error
 */
static int ceph_tcp_recv(struct ceph_connection *con)
{
	int ret;

	dout("%s con %p %s %zu\n", __func__, con,
	     iov_iter_is_discard(&con->v2.in_iter) ? "discard" : "need",
	     iov_iter_count(&con->v2.in_iter));
	ret = do_recvmsg(con->sock, &con->v2.in_iter);
	dout("%s con %p ret %d left %zu\n", __func__, con, ret,
	     iov_iter_count(&con->v2.in_iter));
	return ret;
}

static int do_sendmsg(struct socket *sock, struct iov_iter *it)
{
	struct msghdr msg = { .msg_flags = CEPH_MSG_FLAGS };
	int ret;

	msg.msg_iter = *it;
	while (iov_iter_count(it)) {
		ret = sock_sendmsg(sock, &msg);
		if (ret <= 0) {
			if (ret == -EAGAIN)
				ret = 0;
			return ret;
		}

		iov_iter_advance(it, ret);
	}

	WARN_ON(msg_data_left(&msg));
	return 1;
}

static int do_try_sendpage(struct socket *sock, struct iov_iter *it)
{
	struct msghdr msg = { .msg_flags = CEPH_MSG_FLAGS };
	struct bio_vec bv;
	int ret;

	if (WARN_ON(!iov_iter_is_bvec(it)))
		return -EINVAL;

	while (iov_iter_count(it)) {
		/* iov_iter_iovec() for ITER_BVEC */
		bv.bv_page = it->bvec->bv_page;
		bv.bv_offset = it->bvec->bv_offset + it->iov_offset;
		bv.bv_len = min(iov_iter_count(it),
				it->bvec->bv_len - it->iov_offset);

		/*
		 * sendpage cannot properly handle pages with
		 * page_count == 0, we need to fall back to sendmsg if
		 * that's the case.
		 *
		 * Same goes for slab pages: skb_can_coalesce() allows
		 * coalescing neighboring slab objects into a single frag
		 * which triggers one of hardened usercopy checks.
		 */
		if (sendpage_ok(bv.bv_page)) {
			ret = sock->ops->sendpage(sock, bv.bv_page,
						  bv.bv_offset, bv.bv_len,
						  CEPH_MSG_FLAGS);
		} else {
			iov_iter_bvec(&msg.msg_iter, WRITE, &bv, 1, bv.bv_len);
			ret = sock_sendmsg(sock, &msg);
		}
		if (ret <= 0) {
			if (ret == -EAGAIN)
				ret = 0;
			return ret;
		}

		iov_iter_advance(it, ret);
	}

	return 1;
}

/*
 * Write as much as possible.  The socket is expected to be corked,
 * so we don't bother with MSG_MORE/MSG_SENDPAGE_NOTLAST here.
 *
 * Return:
 *   1 - done, nothing (else) to write
 *   0 - socket is full, need to wait
 *  <0 - error
 */
static int ceph_tcp_send(struct ceph_connection *con)
{
	int ret;

	dout("%s con %p have %zu try_sendpage %d\n", __func__, con,
	     iov_iter_count(&con->v2.out_iter), con->v2.out_iter_sendpage);
	if (con->v2.out_iter_sendpage)
		ret = do_try_sendpage(con->sock, &con->v2.out_iter);
	else
		ret = do_sendmsg(con->sock, &con->v2.out_iter);
	dout("%s con %p ret %d left %zu\n", __func__, con, ret,
	     iov_iter_count(&con->v2.out_iter));
	return ret;
}

static void add_in_kvec(struct ceph_connection *con, void *buf, int len)
{
	BUG_ON(con->v2.in_kvec_cnt >= ARRAY_SIZE(con->v2.in_kvecs));
	WARN_ON(!iov_iter_is_kvec(&con->v2.in_iter));

	con->v2.in_kvecs[con->v2.in_kvec_cnt].iov_base = buf;
	con->v2.in_kvecs[con->v2.in_kvec_cnt].iov_len = len;
	con->v2.in_kvec_cnt++;

	con->v2.in_iter.nr_segs++;
	con->v2.in_iter.count += len;
}

static void reset_in_kvecs(struct ceph_connection *con)
{
	WARN_ON(iov_iter_count(&con->v2.in_iter));

	con->v2.in_kvec_cnt = 0;
	iov_iter_kvec(&con->v2.in_iter, READ, con->v2.in_kvecs, 0, 0);
}

static void set_in_bvec(struct ceph_connection *con, const struct bio_vec *bv)
{
	WARN_ON(iov_iter_count(&con->v2.in_iter));

	con->v2.in_bvec = *bv;
	iov_iter_bvec(&con->v2.in_iter, READ, &con->v2.in_bvec, 1, bv->bv_len);
}

static void set_in_skip(struct ceph_connection *con, int len)
{
	WARN_ON(iov_iter_count(&con->v2.in_iter));

	dout("%s con %p len %d\n", __func__, con, len);
	iov_iter_discard(&con->v2.in_iter, READ, len);
}

static void add_out_kvec(struct ceph_connection *con, void *buf, int len)
{
	BUG_ON(con->v2.out_kvec_cnt >= ARRAY_SIZE(con->v2.out_kvecs));
	WARN_ON(!iov_iter_is_kvec(&con->v2.out_iter));
	WARN_ON(con->v2.out_zero);

	con->v2.out_kvecs[con->v2.out_kvec_cnt].iov_base = buf;
	con->v2.out_kvecs[con->v2.out_kvec_cnt].iov_len = len;
	con->v2.out_kvec_cnt++;

	con->v2.out_iter.nr_segs++;
	con->v2.out_iter.count += len;
}

static void reset_out_kvecs(struct ceph_connection *con)
{
	WARN_ON(iov_iter_count(&con->v2.out_iter));
	WARN_ON(con->v2.out_zero);

	con->v2.out_kvec_cnt = 0;

	iov_iter_kvec(&con->v2.out_iter, WRITE, con->v2.out_kvecs, 0, 0);
	con->v2.out_iter_sendpage = false;
}

static void set_out_bvec(struct ceph_connection *con, const struct bio_vec *bv,
			 bool zerocopy)
{
	WARN_ON(iov_iter_count(&con->v2.out_iter));
	WARN_ON(con->v2.out_zero);

	con->v2.out_bvec = *bv;
	con->v2.out_iter_sendpage = zerocopy;
	iov_iter_bvec(&con->v2.out_iter, WRITE, &con->v2.out_bvec, 1,
		      con->v2.out_bvec.bv_len);
}

static void set_out_bvec_zero(struct ceph_connection *con)
{
	WARN_ON(iov_iter_count(&con->v2.out_iter));
	WARN_ON(!con->v2.out_zero);

	con->v2.out_bvec.bv_page = ceph_zero_page;
	con->v2.out_bvec.bv_offset = 0;
	con->v2.out_bvec.bv_len = min(con->v2.out_zero, (int)PAGE_SIZE);
	con->v2.out_iter_sendpage = true;
	iov_iter_bvec(&con->v2.out_iter, WRITE, &con->v2.out_bvec, 1,
		      con->v2.out_bvec.bv_len);
}

static void out_zero_add(struct ceph_connection *con, int len)
{
	dout("%s con %p len %d\n", __func__, con, len);
	con->v2.out_zero += len;
}

static void *alloc_conn_buf(struct ceph_connection *con, int len)
{
	void *buf;

	dout("%s con %p len %d\n", __func__, con, len);

	if (WARN_ON(con->v2.conn_buf_cnt >= ARRAY_SIZE(con->v2.conn_bufs)))
		return NULL;

	buf = kvmalloc(len, GFP_NOIO);
	if (!buf)
		return NULL;

	con->v2.conn_bufs[con->v2.conn_buf_cnt++] = buf;
	return buf;
}

static void free_conn_bufs(struct ceph_connection *con)
{
	while (con->v2.conn_buf_cnt)
		kvfree(con->v2.conn_bufs[--con->v2.conn_buf_cnt]);
}

static void add_in_sign_kvec(struct ceph_connection *con, void *buf, int len)
{
	BUG_ON(con->v2.in_sign_kvec_cnt >= ARRAY_SIZE(con->v2.in_sign_kvecs));

	con->v2.in_sign_kvecs[con->v2.in_sign_kvec_cnt].iov_base = buf;
	con->v2.in_sign_kvecs[con->v2.in_sign_kvec_cnt].iov_len = len;
	con->v2.in_sign_kvec_cnt++;
}

static void clear_in_sign_kvecs(struct ceph_connection *con)
{
	con->v2.in_sign_kvec_cnt = 0;
}

static void add_out_sign_kvec(struct ceph_connection *con, void *buf, int len)
{
	BUG_ON(con->v2.out_sign_kvec_cnt >= ARRAY_SIZE(con->v2.out_sign_kvecs));

	con->v2.out_sign_kvecs[con->v2.out_sign_kvec_cnt].iov_base = buf;
	con->v2.out_sign_kvecs[con->v2.out_sign_kvec_cnt].iov_len = len;
	con->v2.out_sign_kvec_cnt++;
}

static void clear_out_sign_kvecs(struct ceph_connection *con)
{
	con->v2.out_sign_kvec_cnt = 0;
}

static bool con_secure(struct ceph_connection *con)
{
	return con->v2.con_mode == CEPH_CON_MODE_SECURE;
}

static int front_len(const struct ceph_msg *msg)
{
	return le32_to_cpu(msg->hdr.front_len);
}

static int middle_len(const struct ceph_msg *msg)
{
	return le32_to_cpu(msg->hdr.middle_len);
}

static int data_len(const struct ceph_msg *msg)
{
	return le32_to_cpu(msg->hdr.data_len);
}

static bool need_padding(int len)
{
	return !IS_ALIGNED(len, CEPH_GCM_BLOCK_LEN);
}

static int padded_len(int len)
{
	return ALIGN(len, CEPH_GCM_BLOCK_LEN);
}

static int padding_len(int len)
{
	return padded_len(len) - len;
}

/* preamble + control segment */
static int head_onwire_len(int ctrl_len, bool secure)
{
	int head_len;
	int rem_len;

	if (secure) {
		head_len = CEPH_PREAMBLE_SECURE_LEN;
		if (ctrl_len > CEPH_PREAMBLE_INLINE_LEN) {
			rem_len = ctrl_len - CEPH_PREAMBLE_INLINE_LEN;
			head_len += padded_len(rem_len) + CEPH_GCM_TAG_LEN;
		}
	} else {
		head_len = CEPH_PREAMBLE_PLAIN_LEN;
		if (ctrl_len)
			head_len += ctrl_len + CEPH_CRC_LEN;
	}
	return head_len;
}

/* front, middle and data segments + epilogue */
static int __tail_onwire_len(int front_len, int middle_len, int data_len,
			     bool secure)
{
	if (!front_len && !middle_len && !data_len)
		return 0;

	if (!secure)
		return front_len + middle_len + data_len +
		       CEPH_EPILOGUE_PLAIN_LEN;

	return padded_len(front_len) + padded_len(middle_len) +
	       padded_len(data_len) + CEPH_EPILOGUE_SECURE_LEN;
}

static int tail_onwire_len(const struct ceph_msg *msg, bool secure)
{
	return __tail_onwire_len(front_len(msg), middle_len(msg),
				 data_len(msg), secure);
}

/* head_onwire_len(sizeof(struct ceph_msg_header2), false) */
#define MESSAGE_HEAD_PLAIN_LEN	(CEPH_PREAMBLE_PLAIN_LEN +		\
				 sizeof(struct ceph_msg_header2) +	\
				 CEPH_CRC_LEN)

static const int frame_aligns[] = {
	sizeof(void *),
	sizeof(void *),
	sizeof(void *),
	PAGE_SIZE
};

/*
 * Discards trailing empty segments, unless there is just one segment.
 * A frame always has at least one (possibly empty) segment.
 */
static int calc_segment_count(const int *lens, int len_cnt)
{
	int i;

	for (i = len_cnt - 1; i >= 0; i--) {
		if (lens[i])
			return i + 1;
	}

	return 1;
}

static void init_frame_desc(struct ceph_frame_desc *desc, int tag,
			    const int *lens, int len_cnt)
{
	int i;

	memset(desc, 0, sizeof(*desc));

	desc->fd_tag = tag;
	desc->fd_seg_cnt = calc_segment_count(lens, len_cnt);
	BUG_ON(desc->fd_seg_cnt > CEPH_FRAME_MAX_SEGMENT_COUNT);
	for (i = 0; i < desc->fd_seg_cnt; i++) {
		desc->fd_lens[i] = lens[i];
		desc->fd_aligns[i] = frame_aligns[i];
	}
}

/*
 * Preamble crc covers everything up to itself (28 bytes) and
 * is calculated and verified irrespective of the connection mode
 * (i.e. even if the frame is encrypted).
 */
static void encode_preamble(const struct ceph_frame_desc *desc, void *p)
{
	void *crcp = p + CEPH_PREAMBLE_LEN - CEPH_CRC_LEN;
	void *start = p;
	int i;

	memset(p, 0, CEPH_PREAMBLE_LEN);

	ceph_encode_8(&p, desc->fd_tag);
	ceph_encode_8(&p, desc->fd_seg_cnt);
	for (i = 0; i < desc->fd_seg_cnt; i++) {
		ceph_encode_32(&p, desc->fd_lens[i]);
		ceph_encode_16(&p, desc->fd_aligns[i]);
	}

	put_unaligned_le32(crc32c(0, start, crcp - start), crcp);
}

static int decode_preamble(void *p, struct ceph_frame_desc *desc)
{
	void *crcp = p + CEPH_PREAMBLE_LEN - CEPH_CRC_LEN;
	u32 crc, expected_crc;
	int i;

	crc = crc32c(0, p, crcp - p);
	expected_crc = get_unaligned_le32(crcp);
	if (crc != expected_crc) {
		pr_err("bad preamble crc, calculated %u, expected %u\n",
		       crc, expected_crc);
		return -EBADMSG;
	}

	memset(desc, 0, sizeof(*desc));

	desc->fd_tag = ceph_decode_8(&p);
	desc->fd_seg_cnt = ceph_decode_8(&p);
	if (desc->fd_seg_cnt < 1 ||
	    desc->fd_seg_cnt > CEPH_FRAME_MAX_SEGMENT_COUNT) {
		pr_err("bad segment count %d\n", desc->fd_seg_cnt);
		return -EINVAL;
	}
	for (i = 0; i < desc->fd_seg_cnt; i++) {
		desc->fd_lens[i] = ceph_decode_32(&p);
		desc->fd_aligns[i] = ceph_decode_16(&p);
	}

	/*
	 * This would fire for FRAME_TAG_WAIT (it has one empty
	 * segment), but we should never get it as client.
	 */
	if (!desc->fd_lens[desc->fd_seg_cnt - 1]) {
		pr_err("last segment empty\n");
		return -EINVAL;
	}

	if (desc->fd_lens[0] > CEPH_MSG_MAX_CONTROL_LEN) {
		pr_err("control segment too big %d\n", desc->fd_lens[0]);
		return -EINVAL;
	}
	if (desc->fd_lens[1] > CEPH_MSG_MAX_FRONT_LEN) {
		pr_err("front segment too big %d\n", desc->fd_lens[1]);
		return -EINVAL;
	}
	if (desc->fd_lens[2] > CEPH_MSG_MAX_MIDDLE_LEN) {
		pr_err("middle segment too big %d\n", desc->fd_lens[2]);
		return -EINVAL;
	}
	if (desc->fd_lens[3] > CEPH_MSG_MAX_DATA_LEN) {
		pr_err("data segment too big %d\n", desc->fd_lens[3]);
		return -EINVAL;
	}

	return 0;
}

static void encode_epilogue_plain(struct ceph_connection *con, bool aborted)
{
	con->v2.out_epil.late_status = aborted ? FRAME_LATE_STATUS_ABORTED :
						 FRAME_LATE_STATUS_COMPLETE;
	cpu_to_le32s(&con->v2.out_epil.front_crc);
	cpu_to_le32s(&con->v2.out_epil.middle_crc);
	cpu_to_le32s(&con->v2.out_epil.data_crc);
}

static void encode_epilogue_secure(struct ceph_connection *con, bool aborted)
{
	memset(&con->v2.out_epil, 0, sizeof(con->v2.out_epil));
	con->v2.out_epil.late_status = aborted ? FRAME_LATE_STATUS_ABORTED :
						 FRAME_LATE_STATUS_COMPLETE;
}

static int decode_epilogue(void *p, u32 *front_crc, u32 *middle_crc,
			   u32 *data_crc)
{
	u8 late_status;

	late_status = ceph_decode_8(&p);
	if ((late_status & FRAME_LATE_STATUS_ABORTED_MASK) !=
			FRAME_LATE_STATUS_COMPLETE) {
		/* we should never get an aborted message as client */
		pr_err("bad late_status 0x%x\n", late_status);
		return -EINVAL;
	}

	if (front_crc && middle_crc && data_crc) {
		*front_crc = ceph_decode_32(&p);
		*middle_crc = ceph_decode_32(&p);
		*data_crc = ceph_decode_32(&p);
	}

	return 0;
}

static void fill_header(struct ceph_msg_header *hdr,
			const struct ceph_msg_header2 *hdr2,
			int front_len, int middle_len, int data_len,
			const struct ceph_entity_name *peer_name)
{
	hdr->seq = hdr2->seq;
	hdr->tid = hdr2->tid;
	hdr->type = hdr2->type;
	hdr->priority = hdr2->priority;
	hdr->version = hdr2->version;
	hdr->front_len = cpu_to_le32(front_len);
	hdr->middle_len = cpu_to_le32(middle_len);
	hdr->data_len = cpu_to_le32(data_len);
	hdr->data_off = hdr2->data_off;
	hdr->src = *peer_name;
	hdr->compat_version = hdr2->compat_version;
	hdr->reserved = 0;
	hdr->crc = 0;
}

static void fill_header2(struct ceph_msg_header2 *hdr2,
			 const struct ceph_msg_header *hdr, u64 ack_seq)
{
	hdr2->seq = hdr->seq;
	hdr2->tid = hdr->tid;
	hdr2->type = hdr->type;
	hdr2->priority = hdr->priority;
	hdr2->version = hdr->version;
	hdr2->data_pre_padding_len = 0;
	hdr2->data_off = hdr->data_off;
	hdr2->ack_seq = cpu_to_le64(ack_seq);
	hdr2->flags = 0;
	hdr2->compat_version = hdr->compat_version;
	hdr2->reserved = 0;
}

static int verify_control_crc(struct ceph_connection *con)
{
	int ctrl_len = con->v2.in_desc.fd_lens[0];
	u32 crc, expected_crc;

	WARN_ON(con->v2.in_kvecs[0].iov_len != ctrl_len);
	WARN_ON(con->v2.in_kvecs[1].iov_len != CEPH_CRC_LEN);

	crc = crc32c(-1, con->v2.in_kvecs[0].iov_base, ctrl_len);
	expected_crc = get_unaligned_le32(con->v2.in_kvecs[1].iov_base);
	if (crc != expected_crc) {
		pr_err("bad control crc, calculated %u, expected %u\n",
		       crc, expected_crc);
		return -EBADMSG;
	}

	return 0;
}

static int verify_epilogue_crcs(struct ceph_connection *con, u32 front_crc,
				u32 middle_crc, u32 data_crc)
{
	if (front_len(con->in_msg)) {
		con->in_front_crc = crc32c(-1, con->in_msg->front.iov_base,
					   front_len(con->in_msg));
	} else {
		WARN_ON(!middle_len(con->in_msg) && !data_len(con->in_msg));
		con->in_front_crc = -1;
	}

	if (middle_len(con->in_msg))
		con->in_middle_crc = crc32c(-1,
					    con->in_msg->middle->vec.iov_base,
					    middle_len(con->in_msg));
	else if (data_len(con->in_msg))
		con->in_middle_crc = -1;
	else
		con->in_middle_crc = 0;

	if (!data_len(con->in_msg))
		con->in_data_crc = 0;

	dout("%s con %p msg %p crcs %u %u %u\n", __func__, con, con->in_msg,
	     con->in_front_crc, con->in_middle_crc, con->in_data_crc);

	if (con->in_front_crc != front_crc) {
		pr_err("bad front crc, calculated %u, expected %u\n",
		       con->in_front_crc, front_crc);
		return -EBADMSG;
	}
	if (con->in_middle_crc != middle_crc) {
		pr_err("bad middle crc, calculated %u, expected %u\n",
		       con->in_middle_crc, middle_crc);
		return -EBADMSG;
	}
	if (con->in_data_crc != data_crc) {
		pr_err("bad data crc, calculated %u, expected %u\n",
		       con->in_data_crc, data_crc);
		return -EBADMSG;
	}

	return 0;
}

static int setup_crypto(struct ceph_connection *con,
			const u8 *session_key, int session_key_len,
			const u8 *con_secret, int con_secret_len)
{
	unsigned int noio_flag;
	int ret;

	dout("%s con %p con_mode %d session_key_len %d con_secret_len %d\n",
	     __func__, con, con->v2.con_mode, session_key_len, con_secret_len);
	WARN_ON(con->v2.hmac_tfm || con->v2.gcm_tfm || con->v2.gcm_req);

	if (con->v2.con_mode != CEPH_CON_MODE_CRC &&
	    con->v2.con_mode != CEPH_CON_MODE_SECURE) {
		pr_err("bad con_mode %d\n", con->v2.con_mode);
		return -EINVAL;
	}

	if (!session_key_len) {
		WARN_ON(con->v2.con_mode != CEPH_CON_MODE_CRC);
		WARN_ON(con_secret_len);
		return 0;  /* auth_none */
	}

	noio_flag = memalloc_noio_save();
	con->v2.hmac_tfm = crypto_alloc_shash("hmac(sha256)", 0, 0);
	memalloc_noio_restore(noio_flag);
	if (IS_ERR(con->v2.hmac_tfm)) {
		ret = PTR_ERR(con->v2.hmac_tfm);
		con->v2.hmac_tfm = NULL;
		pr_err("failed to allocate hmac tfm context: %d\n", ret);
		return ret;
	}

	WARN_ON((unsigned long)session_key &
		crypto_shash_alignmask(con->v2.hmac_tfm));
	ret = crypto_shash_setkey(con->v2.hmac_tfm, session_key,
				  session_key_len);
	if (ret) {
		pr_err("failed to set hmac key: %d\n", ret);
		return ret;
	}

	if (con->v2.con_mode == CEPH_CON_MODE_CRC) {
		WARN_ON(con_secret_len);
		return 0;  /* auth_x, plain mode */
	}

	if (con_secret_len < CEPH_GCM_KEY_LEN + 2 * CEPH_GCM_IV_LEN) {
		pr_err("con_secret too small %d\n", con_secret_len);
		return -EINVAL;
	}

	noio_flag = memalloc_noio_save();
	con->v2.gcm_tfm = crypto_alloc_aead("gcm(aes)", 0, 0);
	memalloc_noio_restore(noio_flag);
	if (IS_ERR(con->v2.gcm_tfm)) {
		ret = PTR_ERR(con->v2.gcm_tfm);
		con->v2.gcm_tfm = NULL;
		pr_err("failed to allocate gcm tfm context: %d\n", ret);
		return ret;
	}

	WARN_ON((unsigned long)con_secret &
		crypto_aead_alignmask(con->v2.gcm_tfm));
	ret = crypto_aead_setkey(con->v2.gcm_tfm, con_secret, CEPH_GCM_KEY_LEN);
	if (ret) {
		pr_err("failed to set gcm key: %d\n", ret);
		return ret;
	}

	WARN_ON(crypto_aead_ivsize(con->v2.gcm_tfm) != CEPH_GCM_IV_LEN);
	ret = crypto_aead_setauthsize(con->v2.gcm_tfm, CEPH_GCM_TAG_LEN);
	if (ret) {
		pr_err("failed to set gcm tag size: %d\n", ret);
		return ret;
	}

	con->v2.gcm_req = aead_request_alloc(con->v2.gcm_tfm, GFP_NOIO);
	if (!con->v2.gcm_req) {
		pr_err("failed to allocate gcm request\n");
		return -ENOMEM;
	}

	crypto_init_wait(&con->v2.gcm_wait);
	aead_request_set_callback(con->v2.gcm_req, CRYPTO_TFM_REQ_MAY_BACKLOG,
				  crypto_req_done, &con->v2.gcm_wait);

	memcpy(&con->v2.in_gcm_nonce, con_secret + CEPH_GCM_KEY_LEN,
	       CEPH_GCM_IV_LEN);
	memcpy(&con->v2.out_gcm_nonce,
	       con_secret + CEPH_GCM_KEY_LEN + CEPH_GCM_IV_LEN,
	       CEPH_GCM_IV_LEN);
	return 0;  /* auth_x, secure mode */
}

static int hmac_sha256(struct ceph_connection *con, const struct kvec *kvecs,
		       int kvec_cnt, u8 *hmac)
{
	SHASH_DESC_ON_STACK(desc, con->v2.hmac_tfm);  /* tfm arg is ignored */
	int ret;
	int i;

	dout("%s con %p hmac_tfm %p kvec_cnt %d\n", __func__, con,
	     con->v2.hmac_tfm, kvec_cnt);

	if (!con->v2.hmac_tfm) {
		memset(hmac, 0, SHA256_DIGEST_SIZE);
		return 0;  /* auth_none */
	}

	desc->tfm = con->v2.hmac_tfm;
	ret = crypto_shash_init(desc);
	if (ret)
		goto out;

	for (i = 0; i < kvec_cnt; i++) {
		WARN_ON((unsigned long)kvecs[i].iov_base &
			crypto_shash_alignmask(con->v2.hmac_tfm));
		ret = crypto_shash_update(desc, kvecs[i].iov_base,
					  kvecs[i].iov_len);
		if (ret)
			goto out;
	}

	ret = crypto_shash_final(desc, hmac);

out:
	shash_desc_zero(desc);
	return ret;  /* auth_x, both plain and secure modes */
}

static void gcm_inc_nonce(struct ceph_gcm_nonce *nonce)
{
	u64 counter;

	counter = le64_to_cpu(nonce->counter);
	nonce->counter = cpu_to_le64(counter + 1);
}

static int gcm_crypt(struct ceph_connection *con, bool encrypt,
		     struct scatterlist *src, struct scatterlist *dst,
		     int src_len)
{
	struct ceph_gcm_nonce *nonce;
	int ret;

	nonce = encrypt ? &con->v2.out_gcm_nonce : &con->v2.in_gcm_nonce;

	aead_request_set_ad(con->v2.gcm_req, 0);  /* no AAD */
	aead_request_set_crypt(con->v2.gcm_req, src, dst, src_len, (u8 *)nonce);
	ret = crypto_wait_req(encrypt ? crypto_aead_encrypt(con->v2.gcm_req) :
					crypto_aead_decrypt(con->v2.gcm_req),
			      &con->v2.gcm_wait);
	if (ret)
		return ret;

	gcm_inc_nonce(nonce);
	return 0;
}

static void get_bvec_at(struct ceph_msg_data_cursor *cursor,
			struct bio_vec *bv)
{
	struct page *page;
	size_t off, len;

	WARN_ON(!cursor->total_resid);

	/* skip zero-length data items */
	while (!cursor->resid)
		ceph_msg_data_advance(cursor, 0);

	/* get a piece of data, cursor isn't advanced */
	page = ceph_msg_data_next(cursor, &off, &len, NULL);

	bv->bv_page = page;
	bv->bv_offset = off;
	bv->bv_len = len;
}

static int calc_sg_cnt(void *buf, int buf_len)
{
	int sg_cnt;

	if (!buf_len)
		return 0;

	sg_cnt = need_padding(buf_len) ? 1 : 0;
	if (is_vmalloc_addr(buf)) {
		WARN_ON(offset_in_page(buf));
		sg_cnt += PAGE_ALIGN(buf_len) >> PAGE_SHIFT;
	} else {
		sg_cnt++;
	}

	return sg_cnt;
}

static int calc_sg_cnt_cursor(struct ceph_msg_data_cursor *cursor)
{
	int data_len = cursor->total_resid;
	struct bio_vec bv;
	int sg_cnt;

	if (!data_len)
		return 0;

	sg_cnt = need_padding(data_len) ? 1 : 0;
	do {
		get_bvec_at(cursor, &bv);
		sg_cnt++;

		ceph_msg_data_advance(cursor, bv.bv_len);
	} while (cursor->total_resid);

	return sg_cnt;
}

static void init_sgs(struct scatterlist **sg, void *buf, int buf_len, u8 *pad)
{
	void *end = buf + buf_len;
	struct page *page;
	int len;
	void *p;

	if (!buf_len)
		return;

	if (is_vmalloc_addr(buf)) {
		p = buf;
		do {
			page = vmalloc_to_page(p);
			len = min_t(int, end - p, PAGE_SIZE);
			WARN_ON(!page || !len || offset_in_page(p));
			sg_set_page(*sg, page, len, 0);
			*sg = sg_next(*sg);
			p += len;
		} while (p != end);
	} else {
		sg_set_buf(*sg, buf, buf_len);
		*sg = sg_next(*sg);
	}

	if (need_padding(buf_len)) {
		sg_set_buf(*sg, pad, padding_len(buf_len));
		*sg = sg_next(*sg);
	}
}

static void init_sgs_cursor(struct scatterlist **sg,
			    struct ceph_msg_data_cursor *cursor, u8 *pad)
{
	int data_len = cursor->total_resid;
	struct bio_vec bv;

	if (!data_len)
		return;

	do {
		get_bvec_at(cursor, &bv);
		sg_set_page(*sg, bv.bv_page, bv.bv_len, bv.bv_offset);
		*sg = sg_next(*sg);

		ceph_msg_data_advance(cursor, bv.bv_len);
	} while (cursor->total_resid);

	if (need_padding(data_len)) {
		sg_set_buf(*sg, pad, padding_len(data_len));
		*sg = sg_next(*sg);
	}
}

static int setup_message_sgs(struct sg_table *sgt, struct ceph_msg *msg,
			     u8 *front_pad, u8 *middle_pad, u8 *data_pad,
			     void *epilogue, bool add_tag)
{
	struct ceph_msg_data_cursor cursor;
	struct scatterlist *cur_sg;
	int sg_cnt;
	int ret;

	if (!front_len(msg) && !middle_len(msg) && !data_len(msg))
		return 0;

	sg_cnt = 1;  /* epilogue + [auth tag] */
	if (front_len(msg))
		sg_cnt += calc_sg_cnt(msg->front.iov_base,
				      front_len(msg));
	if (middle_len(msg))
		sg_cnt += calc_sg_cnt(msg->middle->vec.iov_base,
				      middle_len(msg));
	if (data_len(msg)) {
		ceph_msg_data_cursor_init(&cursor, msg, data_len(msg));
		sg_cnt += calc_sg_cnt_cursor(&cursor);
	}

	ret = sg_alloc_table(sgt, sg_cnt, GFP_NOIO);
	if (ret)
		return ret;

	cur_sg = sgt->sgl;
	if (front_len(msg))
		init_sgs(&cur_sg, msg->front.iov_base, front_len(msg),
			 front_pad);
	if (middle_len(msg))
		init_sgs(&cur_sg, msg->middle->vec.iov_base, middle_len(msg),
			 middle_pad);
	if (data_len(msg)) {
		ceph_msg_data_cursor_init(&cursor, msg, data_len(msg));
		init_sgs_cursor(&cur_sg, &cursor, data_pad);
	}

	WARN_ON(!sg_is_last(cur_sg));
	sg_set_buf(cur_sg, epilogue,
		   CEPH_GCM_BLOCK_LEN + (add_tag ? CEPH_GCM_TAG_LEN : 0));
	return 0;
}

static int decrypt_preamble(struct ceph_connection *con)
{
	struct scatterlist sg;

	sg_init_one(&sg, con->v2.in_buf, CEPH_PREAMBLE_SECURE_LEN);
	return gcm_crypt(con, false, &sg, &sg, CEPH_PREAMBLE_SECURE_LEN);
}

static int decrypt_control_remainder(struct ceph_connection *con)
{
	int ctrl_len = con->v2.in_desc.fd_lens[0];
	int rem_len = ctrl_len - CEPH_PREAMBLE_INLINE_LEN;
	int pt_len = padding_len(rem_len) + CEPH_GCM_TAG_LEN;
	struct scatterlist sgs[2];

	WARN_ON(con->v2.in_kvecs[0].iov_len != rem_len);
	WARN_ON(con->v2.in_kvecs[1].iov_len != pt_len);

	sg_init_table(sgs, 2);
	sg_set_buf(&sgs[0], con->v2.in_kvecs[0].iov_base, rem_len);
	sg_set_buf(&sgs[1], con->v2.in_buf, pt_len);

	return gcm_crypt(con, false, sgs, sgs,
			 padded_len(rem_len) + CEPH_GCM_TAG_LEN);
}

static int decrypt_tail(struct ceph_connection *con)
{
	struct sg_table enc_sgt = {};
	struct sg_table sgt = {};
	int tail_len;
	int ret;

	tail_len = tail_onwire_len(con->in_msg, true);
	ret = sg_alloc_table_from_pages(&enc_sgt, con->v2.in_enc_pages,
					con->v2.in_enc_page_cnt, 0, tail_len,
					GFP_NOIO);
	if (ret)
		goto out;

	ret = setup_message_sgs(&sgt, con->in_msg, FRONT_PAD(con->v2.in_buf),
			MIDDLE_PAD(con->v2.in_buf), DATA_PAD(con->v2.in_buf),
			con->v2.in_buf, true);
	if (ret)
		goto out;

	dout("%s con %p msg %p enc_page_cnt %d sg_cnt %d\n", __func__, con,
	     con->in_msg, con->v2.in_enc_page_cnt, sgt.orig_nents);
	ret = gcm_crypt(con, false, enc_sgt.sgl, sgt.sgl, tail_len);
	if (ret)
		goto out;

	WARN_ON(!con->v2.in_enc_page_cnt);
	ceph_release_page_vector(con->v2.in_enc_pages,
				 con->v2.in_enc_page_cnt);
	con->v2.in_enc_pages = NULL;
	con->v2.in_enc_page_cnt = 0;

out:
	sg_free_table(&sgt);
	sg_free_table(&enc_sgt);
	return ret;
}

static int prepare_banner(struct ceph_connection *con)
{
	int buf_len = CEPH_BANNER_V2_LEN + 2 + 8 + 8;
	void *buf, *p;

	buf = alloc_conn_buf(con, buf_len);
	if (!buf)
		return -ENOMEM;

	p = buf;
	ceph_encode_copy(&p, CEPH_BANNER_V2, CEPH_BANNER_V2_LEN);
	ceph_encode_16(&p, sizeof(u64) + sizeof(u64));
	ceph_encode_64(&p, CEPH_MSGR2_SUPPORTED_FEATURES);
	ceph_encode_64(&p, CEPH_MSGR2_REQUIRED_FEATURES);
	WARN_ON(p != buf + buf_len);

	add_out_kvec(con, buf, buf_len);
	add_out_sign_kvec(con, buf, buf_len);
	ceph_con_flag_set(con, CEPH_CON_F_WRITE_PENDING);
	return 0;
}

/*
 * base:
 *   preamble
 *   control body (ctrl_len bytes)
 *   space for control crc
 *
 * extdata (optional):
 *   control body (extdata_len bytes)
 *
 * Compute control crc and gather base and extdata into:
 *
 *   preamble
 *   control body (ctrl_len + extdata_len bytes)
 *   control crc
 *
 * Preamble should already be encoded at the start of base.
 */
static void prepare_head_plain(struct ceph_connection *con, void *base,
			       int ctrl_len, void *extdata, int extdata_len,
			       bool to_be_signed)
{
	int base_len = CEPH_PREAMBLE_LEN + ctrl_len + CEPH_CRC_LEN;
	void *crcp = base + base_len - CEPH_CRC_LEN;
	u32 crc;

	crc = crc32c(-1, CTRL_BODY(base), ctrl_len);
	if (extdata_len)
		crc = crc32c(crc, extdata, extdata_len);
	put_unaligned_le32(crc, crcp);

	if (!extdata_len) {
		add_out_kvec(con, base, base_len);
		if (to_be_signed)
			add_out_sign_kvec(con, base, base_len);
		return;
	}

	add_out_kvec(con, base, crcp - base);
	add_out_kvec(con, extdata, extdata_len);
	add_out_kvec(con, crcp, CEPH_CRC_LEN);
	if (to_be_signed) {
		add_out_sign_kvec(con, base, crcp - base);
		add_out_sign_kvec(con, extdata, extdata_len);
		add_out_sign_kvec(con, crcp, CEPH_CRC_LEN);
	}
}

static int prepare_head_secure_small(struct ceph_connection *con,
				     void *base, int ctrl_len)
{
	struct scatterlist sg;
	int ret;

	/* inline buffer padding? */
	if (ctrl_len < CEPH_PREAMBLE_INLINE_LEN)
		memset(CTRL_BODY(base) + ctrl_len, 0,
		       CEPH_PREAMBLE_INLINE_LEN - ctrl_len);

	sg_init_one(&sg, base, CEPH_PREAMBLE_SECURE_LEN);
	ret = gcm_crypt(con, true, &sg, &sg,
			CEPH_PREAMBLE_SECURE_LEN - CEPH_GCM_TAG_LEN);
	if (ret)
		return ret;

	add_out_kvec(con, base, CEPH_PREAMBLE_SECURE_LEN);
	return 0;
}

/*
 * base:
 *   preamble
 *   control body (ctrl_len bytes)
 *   space for padding, if needed
 *   space for control remainder auth tag
 *   space for preamble auth tag
 *
 * Encrypt preamble and the inline portion, then encrypt the remainder
 * and gather into:
 *
 *   preamble
 *   control body (48 bytes)
 *   preamble auth tag
 *   control body (ctrl_len - 48 bytes)
 *   zero padding, if needed
 *   control remainder auth tag
 *
 * Preamble should already be encoded at the start of base.
 */
static int prepare_head_secure_big(struct ceph_connection *con,
				   void *base, int ctrl_len)
{
	int rem_len = ctrl_len - CEPH_PREAMBLE_INLINE_LEN;
	void *rem = CTRL_BODY(base) + CEPH_PREAMBLE_INLINE_LEN;
	void *rem_tag = rem + padded_len(rem_len);
	void *pmbl_tag = rem_tag + CEPH_GCM_TAG_LEN;
	struct scatterlist sgs[2];
	int ret;

	sg_init_table(sgs, 2);
	sg_set_buf(&sgs[0], base, rem - base);
	sg_set_buf(&sgs[1], pmbl_tag, CEPH_GCM_TAG_LEN);
	ret = gcm_crypt(con, true, sgs, sgs, rem - base);
	if (ret)
		return ret;

	/* control remainder padding? */
	if (need_padding(rem_len))
		memset(rem + rem_len, 0, padding_len(rem_len));

	sg_init_one(&sgs[0], rem, pmbl_tag - rem);
	ret = gcm_crypt(con, true, sgs, sgs, rem_tag - rem);
	if (ret)
		return ret;

	add_out_kvec(con, base, rem - base);
	add_out_kvec(con, pmbl_tag, CEPH_GCM_TAG_LEN);
	add_out_kvec(con, rem, pmbl_tag - rem);
	return 0;
}

static int __prepare_control(struct ceph_connection *con, int tag,
			     void *base, int ctrl_len, void *extdata,
			     int extdata_len, bool to_be_signed)
{
	int total_len = ctrl_len + extdata_len;
	struct ceph_frame_desc desc;
	int ret;

	dout("%s con %p tag %d len %d (%d+%d)\n", __func__, con, tag,
	     total_len, ctrl_len, extdata_len);

	/* extdata may be vmalloc'ed but not base */
	if (WARN_ON(is_vmalloc_addr(base) || !ctrl_len))
		return -EINVAL;

	init_frame_desc(&desc, tag, &total_len, 1);
	encode_preamble(&desc, base);

	if (con_secure(con)) {
		if (WARN_ON(extdata_len || to_be_signed))
			return -EINVAL;

		if (ctrl_len <= CEPH_PREAMBLE_INLINE_LEN)
			/* fully inlined, inline buffer may need padding */
			ret = prepare_head_secure_small(con, base, ctrl_len);
		else
			/* partially inlined, inline buffer is full */
			ret = prepare_head_secure_big(con, base, ctrl_len);
		if (ret)
			return ret;
	} else {
		prepare_head_plain(con, base, ctrl_len, extdata, extdata_len,
				   to_be_signed);
	}

	ceph_con_flag_set(con, CEPH_CON_F_WRITE_PENDING);
	return 0;
}

static int prepare_control(struct ceph_connection *con, int tag,
			   void *base, int ctrl_len)
{
	return __prepare_control(con, tag, base, ctrl_len, NULL, 0, false);
}

static int prepare_hello(struct ceph_connection *con)
{
	void *buf, *p;
	int ctrl_len;

	ctrl_len = 1 + ceph_entity_addr_encoding_len(&con->peer_addr);
	buf = alloc_conn_buf(con, head_onwire_len(ctrl_len, false));
	if (!buf)
		return -ENOMEM;

	p = CTRL_BODY(buf);
	ceph_encode_8(&p, CEPH_ENTITY_TYPE_CLIENT);
	ceph_encode_entity_addr(&p, &con->peer_addr);
	WARN_ON(p != CTRL_BODY(buf) + ctrl_len);

	return __prepare_control(con, FRAME_TAG_HELLO, buf, ctrl_len,
				 NULL, 0, true);
}

/* so that head_onwire_len(AUTH_BUF_LEN, false) is 512 */
#define AUTH_BUF_LEN	(512 - CEPH_CRC_LEN - CEPH_PREAMBLE_PLAIN_LEN)

static int prepare_auth_request(struct ceph_connection *con)
{
	void *authorizer, *authorizer_copy;
	int ctrl_len, authorizer_len;
	void *buf;
	int ret;

	ctrl_len = AUTH_BUF_LEN;
	buf = alloc_conn_buf(con, head_onwire_len(ctrl_len, false));
	if (!buf)
		return -ENOMEM;

	mutex_unlock(&con->mutex);
	ret = con->ops->get_auth_request(con, CTRL_BODY(buf), &ctrl_len,
					 &authorizer, &authorizer_len);
	mutex_lock(&con->mutex);
	if (con->state != CEPH_CON_S_V2_HELLO) {
		dout("%s con %p state changed to %d\n", __func__, con,
		     con->state);
		return -EAGAIN;
	}

	dout("%s con %p get_auth_request ret %d\n", __func__, con, ret);
	if (ret)
		return ret;

	authorizer_copy = alloc_conn_buf(con, authorizer_len);
	if (!authorizer_copy)
		return -ENOMEM;

	memcpy(authorizer_copy, authorizer, authorizer_len);

	return __prepare_control(con, FRAME_TAG_AUTH_REQUEST, buf, ctrl_len,
				 authorizer_copy, authorizer_len, true);
}

static int prepare_auth_request_more(struct ceph_connection *con,
				     void *reply, int reply_len)
{
	int ctrl_len, authorizer_len;
	void *authorizer;
	void *buf;
	int ret;

	ctrl_len = AUTH_BUF_LEN;
	buf = alloc_conn_buf(con, head_onwire_len(ctrl_len, false));
	if (!buf)
		return -ENOMEM;

	mutex_unlock(&con->mutex);
	ret = con->ops->handle_auth_reply_more(con, reply, reply_len,
					       CTRL_BODY(buf), &ctrl_len,
					       &authorizer, &authorizer_len);
	mutex_lock(&con->mutex);
	if (con->state != CEPH_CON_S_V2_AUTH) {
		dout("%s con %p state changed to %d\n", __func__, con,
		     con->state);
		return -EAGAIN;
	}

	dout("%s con %p handle_auth_reply_more ret %d\n", __func__, con, ret);
	if (ret)
		return ret;

	return __prepare_control(con, FRAME_TAG_AUTH_REQUEST_MORE, buf,
				 ctrl_len, authorizer, authorizer_len, true);
}

static int prepare_auth_signature(struct ceph_connection *con)
{
	void *buf;
	int ret;

	buf = alloc_conn_buf(con, head_onwire_len(SHA256_DIGEST_SIZE,
						  con_secure(con)));
	if (!buf)
		return -ENOMEM;

	ret = hmac_sha256(con, con->v2.in_sign_kvecs, con->v2.in_sign_kvec_cnt,
			  CTRL_BODY(buf));
	if (ret)
		return ret;

	return prepare_control(con, FRAME_TAG_AUTH_SIGNATURE, buf,
			       SHA256_DIGEST_SIZE);
}

static int prepare_client_ident(struct ceph_connection *con)
{
	struct ceph_entity_addr *my_addr = &con->msgr->inst.addr;
	struct ceph_client *client = from_msgr(con->msgr);
	u64 global_id = ceph_client_gid(client);
	void *buf, *p;
	int ctrl_len;

	WARN_ON(con->v2.server_cookie);
	WARN_ON(con->v2.connect_seq);
	WARN_ON(con->v2.peer_global_seq);

	if (!con->v2.client_cookie) {
		do {
			get_random_bytes(&con->v2.client_cookie,
					 sizeof(con->v2.client_cookie));
		} while (!con->v2.client_cookie);
		dout("%s con %p generated cookie 0x%llx\n", __func__, con,
		     con->v2.client_cookie);
	} else {
		dout("%s con %p cookie already set 0x%llx\n", __func__, con,
		     con->v2.client_cookie);
	}

	dout("%s con %p my_addr %s/%u peer_addr %s/%u global_id %llu global_seq %llu features 0x%llx required_features 0x%llx cookie 0x%llx\n",
	     __func__, con, ceph_pr_addr(my_addr), le32_to_cpu(my_addr->nonce),
	     ceph_pr_addr(&con->peer_addr), le32_to_cpu(con->peer_addr.nonce),
	     global_id, con->v2.global_seq, client->supported_features,
	     client->required_features, con->v2.client_cookie);

	ctrl_len = 1 + 4 + ceph_entity_addr_encoding_len(my_addr) +
		   ceph_entity_addr_encoding_len(&con->peer_addr) + 6 * 8;
	buf = alloc_conn_buf(con, head_onwire_len(ctrl_len, con_secure(con)));
	if (!buf)
		return -ENOMEM;

	p = CTRL_BODY(buf);
	ceph_encode_8(&p, 2);  /* addrvec marker */
	ceph_encode_32(&p, 1);  /* addr_cnt */
	ceph_encode_entity_addr(&p, my_addr);
	ceph_encode_entity_addr(&p, &con->peer_addr);
	ceph_encode_64(&p, global_id);
	ceph_encode_64(&p, con->v2.global_seq);
	ceph_encode_64(&p, client->supported_features);
	ceph_encode_64(&p, client->required_features);
	ceph_encode_64(&p, 0);  /* flags */
	ceph_encode_64(&p, con->v2.client_cookie);
	WARN_ON(p != CTRL_BODY(buf) + ctrl_len);

	return prepare_control(con, FRAME_TAG_CLIENT_IDENT, buf, ctrl_len);
}

static int prepare_session_reconnect(struct ceph_connection *con)
{
	struct ceph_entity_addr *my_addr = &con->msgr->inst.addr;
	void *buf, *p;
	int ctrl_len;

	WARN_ON(!con->v2.client_cookie);
	WARN_ON(!con->v2.server_cookie);
	WARN_ON(!con->v2.connect_seq);
	WARN_ON(!con->v2.peer_global_seq);

	dout("%s con %p my_addr %s/%u client_cookie 0x%llx server_cookie 0x%llx global_seq %llu connect_seq %llu in_seq %llu\n",
	     __func__, con, ceph_pr_addr(my_addr), le32_to_cpu(my_addr->nonce),
	     con->v2.client_cookie, con->v2.server_cookie, con->v2.global_seq,
	     con->v2.connect_seq, con->in_seq);

	ctrl_len = 1 + 4 + ceph_entity_addr_encoding_len(my_addr) + 5 * 8;
	buf = alloc_conn_buf(con, head_onwire_len(ctrl_len, con_secure(con)));
	if (!buf)
		return -ENOMEM;

	p = CTRL_BODY(buf);
	ceph_encode_8(&p, 2);  /* entity_addrvec_t marker */
	ceph_encode_32(&p, 1);  /* my_addrs len */
	ceph_encode_entity_addr(&p, my_addr);
	ceph_encode_64(&p, con->v2.client_cookie);
	ceph_encode_64(&p, con->v2.server_cookie);
	ceph_encode_64(&p, con->v2.global_seq);
	ceph_encode_64(&p, con->v2.connect_seq);
	ceph_encode_64(&p, con->in_seq);
	WARN_ON(p != CTRL_BODY(buf) + ctrl_len);

	return prepare_control(con, FRAME_TAG_SESSION_RECONNECT, buf, ctrl_len);
}

static int prepare_keepalive2(struct ceph_connection *con)
{
	struct ceph_timespec *ts = CTRL_BODY(con->v2.out_buf);
	struct timespec64 now;

	ktime_get_real_ts64(&now);
	dout("%s con %p timestamp %lld.%09ld\n", __func__, con, now.tv_sec,
	     now.tv_nsec);

	ceph_encode_timespec64(ts, &now);

	reset_out_kvecs(con);
	return prepare_control(con, FRAME_TAG_KEEPALIVE2, con->v2.out_buf,
			       sizeof(struct ceph_timespec));
}

static int prepare_ack(struct ceph_connection *con)
{
	void *p;

	dout("%s con %p in_seq_acked %llu -> %llu\n", __func__, con,
	     con->in_seq_acked, con->in_seq);
	con->in_seq_acked = con->in_seq;

	p = CTRL_BODY(con->v2.out_buf);
	ceph_encode_64(&p, con->in_seq_acked);

	reset_out_kvecs(con);
	return prepare_control(con, FRAME_TAG_ACK, con->v2.out_buf, 8);
}

static void prepare_epilogue_plain(struct ceph_connection *con, bool aborted)
{
	dout("%s con %p msg %p aborted %d crcs %u %u %u\n", __func__, con,
	     con->out_msg, aborted, con->v2.out_epil.front_crc,
	     con->v2.out_epil.middle_crc, con->v2.out_epil.data_crc);

	encode_epilogue_plain(con, aborted);
	add_out_kvec(con, &con->v2.out_epil, CEPH_EPILOGUE_PLAIN_LEN);
}

/*
 * For "used" empty segments, crc is -1.  For unused (trailing)
 * segments, crc is 0.
 */
static void prepare_message_plain(struct ceph_connection *con)
{
	struct ceph_msg *msg = con->out_msg;

	prepare_head_plain(con, con->v2.out_buf,
			   sizeof(struct ceph_msg_header2), NULL, 0, false);

	if (!front_len(msg) && !middle_len(msg)) {
		if (!data_len(msg)) {
			/*
			 * Empty message: once the head is written,
			 * we are done -- there is no epilogue.
			 */
			con->v2.out_state = OUT_S_FINISH_MESSAGE;
			return;
		}

		con->v2.out_epil.front_crc = -1;
		con->v2.out_epil.middle_crc = -1;
		con->v2.out_state = OUT_S_QUEUE_DATA;
		return;
	}

	if (front_len(msg)) {
		con->v2.out_epil.front_crc = crc32c(-1, msg->front.iov_base,
						    front_len(msg));
		add_out_kvec(con, msg->front.iov_base, front_len(msg));
	} else {
		/* middle (at least) is there, checked above */
		con->v2.out_epil.front_crc = -1;
	}

	if (middle_len(msg)) {
		con->v2.out_epil.middle_crc =
			crc32c(-1, msg->middle->vec.iov_base, middle_len(msg));
		add_out_kvec(con, msg->middle->vec.iov_base, middle_len(msg));
	} else {
		con->v2.out_epil.middle_crc = data_len(msg) ? -1 : 0;
	}

	if (data_len(msg)) {
		con->v2.out_state = OUT_S_QUEUE_DATA;
	} else {
		con->v2.out_epil.data_crc = 0;
		prepare_epilogue_plain(con, false);
		con->v2.out_state = OUT_S_FINISH_MESSAGE;
	}
}

/*
 * Unfortunately the kernel crypto API doesn't support streaming
 * (piecewise) operation for AEAD algorithms, so we can't get away
 * with a fixed size buffer and a couple sgs.  Instead, we have to
 * allocate pages for the entire tail of the message (currently up
 * to ~32M) and two sgs arrays (up to ~256K each)...
 */
static int prepare_message_secure(struct ceph_connection *con)
{
	void *zerop = page_address(ceph_zero_page);
	struct sg_table enc_sgt = {};
	struct sg_table sgt = {};
	struct page **enc_pages;
	int enc_page_cnt;
	int tail_len;
	int ret;

	ret = prepare_head_secure_small(con, con->v2.out_buf,
					sizeof(struct ceph_msg_header2));
	if (ret)
		return ret;

	tail_len = tail_onwire_len(con->out_msg, true);
	if (!tail_len) {
		/*
		 * Empty message: once the head is written,
		 * we are done -- there is no epilogue.
		 */
		con->v2.out_state = OUT_S_FINISH_MESSAGE;
		return 0;
	}

	encode_epilogue_secure(con, false);
	ret = setup_message_sgs(&sgt, con->out_msg, zerop, zerop, zerop,
				&con->v2.out_epil, false);
	if (ret)
		goto out;

	enc_page_cnt = calc_pages_for(0, tail_len);
	enc_pages = ceph_alloc_page_vector(enc_page_cnt, GFP_NOIO);
	if (IS_ERR(enc_pages)) {
		ret = PTR_ERR(enc_pages);
		goto out;
	}

	WARN_ON(con->v2.out_enc_pages || con->v2.out_enc_page_cnt);
	con->v2.out_enc_pages = enc_pages;
	con->v2.out_enc_page_cnt = enc_page_cnt;
	con->v2.out_enc_resid = tail_len;
	con->v2.out_enc_i = 0;

	ret = sg_alloc_table_from_pages(&enc_sgt, enc_pages, enc_page_cnt,
					0, tail_len, GFP_NOIO);
	if (ret)
		goto out;

	ret = gcm_crypt(con, true, sgt.sgl, enc_sgt.sgl,
			tail_len - CEPH_GCM_TAG_LEN);
	if (ret)
		goto out;

	dout("%s con %p msg %p sg_cnt %d enc_page_cnt %d\n", __func__, con,
	     con->out_msg, sgt.orig_nents, enc_page_cnt);
	con->v2.out_state = OUT_S_QUEUE_ENC_PAGE;

out:
	sg_free_table(&sgt);
	sg_free_table(&enc_sgt);
	return ret;
}

static int prepare_message(struct ceph_connection *con)
{
	int lens[] = {
		sizeof(struct ceph_msg_header2),
		front_len(con->out_msg),
		middle_len(con->out_msg),
		data_len(con->out_msg)
	};
	struct ceph_frame_desc desc;
	int ret;

	dout("%s con %p msg %p logical %d+%d+%d+%d\n", __func__, con,
	     con->out_msg, lens[0], lens[1], lens[2], lens[3]);

	if (con->in_seq > con->in_seq_acked) {
		dout("%s con %p in_seq_acked %llu -> %llu\n", __func__, con,
		     con->in_seq_acked, con->in_seq);
		con->in_seq_acked = con->in_seq;
	}

	reset_out_kvecs(con);
	init_frame_desc(&desc, FRAME_TAG_MESSAGE, lens, 4);
	encode_preamble(&desc, con->v2.out_buf);
	fill_header2(CTRL_BODY(con->v2.out_buf), &con->out_msg->hdr,
		     con->in_seq_acked);

	if (con_secure(con)) {
		ret = prepare_message_secure(con);
		if (ret)
			return ret;
	} else {
		prepare_message_plain(con);
	}

	ceph_con_flag_set(con, CEPH_CON_F_WRITE_PENDING);
	return 0;
}

static int prepare_read_banner_prefix(struct ceph_connection *con)
{
	void *buf;

	buf = alloc_conn_buf(con, CEPH_BANNER_V2_PREFIX_LEN);
	if (!buf)
		return -ENOMEM;

	reset_in_kvecs(con);
	add_in_kvec(con, buf, CEPH_BANNER_V2_PREFIX_LEN);
	add_in_sign_kvec(con, buf, CEPH_BANNER_V2_PREFIX_LEN);
	con->state = CEPH_CON_S_V2_BANNER_PREFIX;
	return 0;
}

static int prepare_read_banner_payload(struct ceph_connection *con,
				       int payload_len)
{
	void *buf;

	buf = alloc_conn_buf(con, payload_len);
	if (!buf)
		return -ENOMEM;

	reset_in_kvecs(con);
	add_in_kvec(con, buf, payload_len);
	add_in_sign_kvec(con, buf, payload_len);
	con->state = CEPH_CON_S_V2_BANNER_PAYLOAD;
	return 0;
}

static void prepare_read_preamble(struct ceph_connection *con)
{
	reset_in_kvecs(con);
	add_in_kvec(con, con->v2.in_buf,
		    con_secure(con) ? CEPH_PREAMBLE_SECURE_LEN :
				      CEPH_PREAMBLE_PLAIN_LEN);
	con->v2.in_state = IN_S_HANDLE_PREAMBLE;
}

static int prepare_read_control(struct ceph_connection *con)
{
	int ctrl_len = con->v2.in_desc.fd_lens[0];
	int head_len;
	void *buf;

	reset_in_kvecs(con);
	if (con->state == CEPH_CON_S_V2_HELLO ||
	    con->state == CEPH_CON_S_V2_AUTH) {
		head_len = head_onwire_len(ctrl_len, false);
		buf = alloc_conn_buf(con, head_len);
		if (!buf)
			return -ENOMEM;

		/* preserve preamble */
		memcpy(buf, con->v2.in_buf, CEPH_PREAMBLE_LEN);

		add_in_kvec(con, CTRL_BODY(buf), ctrl_len);
		add_in_kvec(con, CTRL_BODY(buf) + ctrl_len, CEPH_CRC_LEN);
		add_in_sign_kvec(con, buf, head_len);
	} else {
		if (ctrl_len > CEPH_PREAMBLE_INLINE_LEN) {
			buf = alloc_conn_buf(con, ctrl_len);
			if (!buf)
				return -ENOMEM;

			add_in_kvec(con, buf, ctrl_len);
		} else {
			add_in_kvec(con, CTRL_BODY(con->v2.in_buf), ctrl_len);
		}
		add_in_kvec(con, con->v2.in_buf, CEPH_CRC_LEN);
	}
	con->v2.in_state = IN_S_HANDLE_CONTROL;
	return 0;
}

static int prepare_read_control_remainder(struct ceph_connection *con)
{
	int ctrl_len = con->v2.in_desc.fd_lens[0];
	int rem_len = ctrl_len - CEPH_PREAMBLE_INLINE_LEN;
	void *buf;

	buf = alloc_conn_buf(con, ctrl_len);
	if (!buf)
		return -ENOMEM;

	memcpy(buf, CTRL_BODY(con->v2.in_buf), CEPH_PREAMBLE_INLINE_LEN);

	reset_in_kvecs(con);
	add_in_kvec(con, buf + CEPH_PREAMBLE_INLINE_LEN, rem_len);
	add_in_kvec(con, con->v2.in_buf,
		    padding_len(rem_len) + CEPH_GCM_TAG_LEN);
	con->v2.in_state = IN_S_HANDLE_CONTROL_REMAINDER;
	return 0;
}

static int prepare_read_data(struct ceph_connection *con)
{
	struct bio_vec bv;

	con->in_data_crc = -1;
	ceph_msg_data_cursor_init(&con->v2.in_cursor, con->in_msg,
				  data_len(con->in_msg));

	get_bvec_at(&con->v2.in_cursor, &bv);
	if (ceph_test_opt(from_msgr(con->msgr), RXBOUNCE)) {
		if (unlikely(!con->bounce_page)) {
			con->bounce_page = alloc_page(GFP_NOIO);
			if (!con->bounce_page) {
				pr_err("failed to allocate bounce page\n");
				return -ENOMEM;
			}
		}

		bv.bv_page = con->bounce_page;
		bv.bv_offset = 0;
	}
	set_in_bvec(con, &bv);
	con->v2.in_state = IN_S_PREPARE_READ_DATA_CONT;
	return 0;
}

static void prepare_read_data_cont(struct ceph_connection *con)
{
	struct bio_vec bv;

	if (ceph_test_opt(from_msgr(con->msgr), RXBOUNCE)) {
		con->in_data_crc = crc32c(con->in_data_crc,
					  page_address(con->bounce_page),
					  con->v2.in_bvec.bv_len);

		get_bvec_at(&con->v2.in_cursor, &bv);
		memcpy_to_page(bv.bv_page, bv.bv_offset,
			       page_address(con->bounce_page),
			       con->v2.in_bvec.bv_len);
	} else {
		con->in_data_crc = ceph_crc32c_page(con->in_data_crc,
						    con->v2.in_bvec.bv_page,
						    con->v2.in_bvec.bv_offset,
						    con->v2.in_bvec.bv_len);
	}

	ceph_msg_data_advance(&con->v2.in_cursor, con->v2.in_bvec.bv_len);
	if (con->v2.in_cursor.total_resid) {
		get_bvec_at(&con->v2.in_cursor, &bv);
		if (ceph_test_opt(from_msgr(con->msgr), RXBOUNCE)) {
			bv.bv_page = con->bounce_page;
			bv.bv_offset = 0;
		}
		set_in_bvec(con, &bv);
		WARN_ON(con->v2.in_state != IN_S_PREPARE_READ_DATA_CONT);
		return;
	}

	/*
	 * We've read all data.  Prepare to read epilogue.
	 */
	reset_in_kvecs(con);
	add_in_kvec(con, con->v2.in_buf, CEPH_EPILOGUE_PLAIN_LEN);
	con->v2.in_state = IN_S_HANDLE_EPILOGUE;
}

static int prepare_read_tail_plain(struct ceph_connection *con)
{
	struct ceph_msg *msg = con->in_msg;

	if (!front_len(msg) && !middle_len(msg)) {
		WARN_ON(!data_len(msg));
		return prepare_read_data(con);
	}

	reset_in_kvecs(con);
	if (front_len(msg)) {
		add_in_kvec(con, msg->front.iov_base, front_len(msg));
		WARN_ON(msg->front.iov_len != front_len(msg));
	}
	if (middle_len(msg)) {
		add_in_kvec(con, msg->middle->vec.iov_base, middle_len(msg));
		WARN_ON(msg->middle->vec.iov_len != middle_len(msg));
	}

	if (data_len(msg)) {
		con->v2.in_state = IN_S_PREPARE_READ_DATA;
	} else {
		add_in_kvec(con, con->v2.in_buf, CEPH_EPILOGUE_PLAIN_LEN);
		con->v2.in_state = IN_S_HANDLE_EPILOGUE;
	}
	return 0;
}

static void prepare_read_enc_page(struct ceph_connection *con)
{
	struct bio_vec bv;

	dout("%s con %p i %d resid %d\n", __func__, con, con->v2.in_enc_i,
	     con->v2.in_enc_resid);
	WARN_ON(!con->v2.in_enc_resid);

	bv.bv_page = con->v2.in_enc_pages[con->v2.in_enc_i];
	bv.bv_offset = 0;
	bv.bv_len = min(con->v2.in_enc_resid, (int)PAGE_SIZE);

	set_in_bvec(con, &bv);
	con->v2.in_enc_i++;
	con->v2.in_enc_resid -= bv.bv_len;

	if (con->v2.in_enc_resid) {
		con->v2.in_state = IN_S_PREPARE_READ_ENC_PAGE;
		return;
	}

	/*
	 * We are set to read the last piece of ciphertext (ending
	 * with epilogue) + auth tag.
	 */
	WARN_ON(con->v2.in_enc_i != con->v2.in_enc_page_cnt);
	con->v2.in_state = IN_S_HANDLE_EPILOGUE;
}

static int prepare_read_tail_secure(struct ceph_connection *con)
{
	struct page **enc_pages;
	int enc_page_cnt;
	int tail_len;

	tail_len = tail_onwire_len(con->in_msg, true);
	WARN_ON(!tail_len);

	enc_page_cnt = calc_pages_for(0, tail_len);
	enc_pages = ceph_alloc_page_vector(enc_page_cnt, GFP_NOIO);
	if (IS_ERR(enc_pages))
		return PTR_ERR(enc_pages);

	WARN_ON(con->v2.in_enc_pages || con->v2.in_enc_page_cnt);
	con->v2.in_enc_pages = enc_pages;
	con->v2.in_enc_page_cnt = enc_page_cnt;
	con->v2.in_enc_resid = tail_len;
	con->v2.in_enc_i = 0;

	prepare_read_enc_page(con);
	return 0;
}

static void __finish_skip(struct ceph_connection *con)
{
	con->in_seq++;
	prepare_read_preamble(con);
}

static void prepare_skip_message(struct ceph_connection *con)
{
	struct ceph_frame_desc *desc = &con->v2.in_desc;
	int tail_len;

	dout("%s con %p %d+%d+%d\n", __func__, con, desc->fd_lens[1],
	     desc->fd_lens[2], desc->fd_lens[3]);

	tail_len = __tail_onwire_len(desc->fd_lens[1], desc->fd_lens[2],
				     desc->fd_lens[3], con_secure(con));
	if (!tail_len) {
		__finish_skip(con);
	} else {
		set_in_skip(con, tail_len);
		con->v2.in_state = IN_S_FINISH_SKIP;
	}
}

static int process_banner_prefix(struct ceph_connection *con)
{
	int payload_len;
	void *p;

	WARN_ON(con->v2.in_kvecs[0].iov_len != CEPH_BANNER_V2_PREFIX_LEN);

	p = con->v2.in_kvecs[0].iov_base;
	if (memcmp(p, CEPH_BANNER_V2, CEPH_BANNER_V2_LEN)) {
		if (!memcmp(p, CEPH_BANNER, CEPH_BANNER_LEN))
			con->error_msg = "server is speaking msgr1 protocol";
		else
			con->error_msg = "protocol error, bad banner";
		return -EINVAL;
	}

	p += CEPH_BANNER_V2_LEN;
	payload_len = ceph_decode_16(&p);
	dout("%s con %p payload_len %d\n", __func__, con, payload_len);

	return prepare_read_banner_payload(con, payload_len);
}

static int process_banner_payload(struct ceph_connection *con)
{
	void *end = con->v2.in_kvecs[0].iov_base + con->v2.in_kvecs[0].iov_len;
	u64 feat = CEPH_MSGR2_SUPPORTED_FEATURES;
	u64 req_feat = CEPH_MSGR2_REQUIRED_FEATURES;
	u64 server_feat, server_req_feat;
	void *p;
	int ret;

	p = con->v2.in_kvecs[0].iov_base;
	ceph_decode_64_safe(&p, end, server_feat, bad);
	ceph_decode_64_safe(&p, end, server_req_feat, bad);

	dout("%s con %p server_feat 0x%llx server_req_feat 0x%llx\n",
	     __func__, con, server_feat, server_req_feat);

	if (req_feat & ~server_feat) {
		pr_err("msgr2 feature set mismatch: my required > server's supported 0x%llx, need 0x%llx\n",
		       server_feat, req_feat & ~server_feat);
		con->error_msg = "missing required protocol features";
		return -EINVAL;
	}
	if (server_req_feat & ~feat) {
		pr_err("msgr2 feature set mismatch: server's required > my supported 0x%llx, missing 0x%llx\n",
		       feat, server_req_feat & ~feat);
		con->error_msg = "missing required protocol features";
		return -EINVAL;
	}

	/* no reset_out_kvecs() as our banner may still be pending */
	ret = prepare_hello(con);
	if (ret) {
		pr_err("prepare_hello failed: %d\n", ret);
		return ret;
	}

	con->state = CEPH_CON_S_V2_HELLO;
	prepare_read_preamble(con);
	return 0;

bad:
	pr_err("failed to decode banner payload\n");
	return -EINVAL;
}

static int process_hello(struct ceph_connection *con, void *p, void *end)
{
	struct ceph_entity_addr *my_addr = &con->msgr->inst.addr;
	struct ceph_entity_addr addr_for_me;
	u8 entity_type;
	int ret;

	if (con->state != CEPH_CON_S_V2_HELLO) {
		con->error_msg = "protocol error, unexpected hello";
		return -EINVAL;
	}

	ceph_decode_8_safe(&p, end, entity_type, bad);
	ret = ceph_decode_entity_addr(&p, end, &addr_for_me);
	if (ret) {
		pr_err("failed to decode addr_for_me: %d\n", ret);
		return ret;
	}

	dout("%s con %p entity_type %d addr_for_me %s\n", __func__, con,
	     entity_type, ceph_pr_addr(&addr_for_me));

	if (entity_type != con->peer_name.type) {
		pr_err("bad peer type, want %d, got %d\n",
		       con->peer_name.type, entity_type);
		con->error_msg = "wrong peer at address";
		return -EINVAL;
	}

	/*
	 * Set our address to the address our first peer (i.e. monitor)
	 * sees that we are connecting from.  If we are behind some sort
	 * of NAT and want to be identified by some private (not NATed)
	 * address, ip option should be used.
	 */
	if (ceph_addr_is_blank(my_addr)) {
		memcpy(&my_addr->in_addr, &addr_for_me.in_addr,
		       sizeof(my_addr->in_addr));
		ceph_addr_set_port(my_addr, 0);
		dout("%s con %p set my addr %s, as seen by peer %s\n",
		     __func__, con, ceph_pr_addr(my_addr),
		     ceph_pr_addr(&con->peer_addr));
	} else {
		dout("%s con %p my addr already set %s\n",
		     __func__, con, ceph_pr_addr(my_addr));
	}

	WARN_ON(ceph_addr_is_blank(my_addr) || ceph_addr_port(my_addr));
	WARN_ON(my_addr->type != CEPH_ENTITY_ADDR_TYPE_ANY);
	WARN_ON(!my_addr->nonce);

	/* no reset_out_kvecs() as our hello may still be pending */
	ret = prepare_auth_request(con);
	if (ret) {
		if (ret != -EAGAIN)
			pr_err("prepare_auth_request failed: %d\n", ret);
		return ret;
	}

	con->state = CEPH_CON_S_V2_AUTH;
	return 0;

bad:
	pr_err("failed to decode hello\n");
	return -EINVAL;
}

static int process_auth_bad_method(struct ceph_connection *con,
				   void *p, void *end)
{
	int allowed_protos[8], allowed_modes[8];
	int allowed_proto_cnt, allowed_mode_cnt;
	int used_proto, result;
	int ret;
	int i;

	if (con->state != CEPH_CON_S_V2_AUTH) {
		con->error_msg = "protocol error, unexpected auth_bad_method";
		return -EINVAL;
	}

	ceph_decode_32_safe(&p, end, used_proto, bad);
	ceph_decode_32_safe(&p, end, result, bad);
	dout("%s con %p used_proto %d result %d\n", __func__, con, used_proto,
	     result);

	ceph_decode_32_safe(&p, end, allowed_proto_cnt, bad);
	if (allowed_proto_cnt > ARRAY_SIZE(allowed_protos)) {
		pr_err("allowed_protos too big %d\n", allowed_proto_cnt);
		return -EINVAL;
	}
	for (i = 0; i < allowed_proto_cnt; i++) {
		ceph_decode_32_safe(&p, end, allowed_protos[i], bad);
		dout("%s con %p allowed_protos[%d] %d\n", __func__, con,
		     i, allowed_protos[i]);
	}

	ceph_decode_32_safe(&p, end, allowed_mode_cnt, bad);
	if (allowed_mode_cnt > ARRAY_SIZE(allowed_modes)) {
		pr_err("allowed_modes too big %d\n", allowed_mode_cnt);
		return -EINVAL;
	}
	for (i = 0; i < allowed_mode_cnt; i++) {
		ceph_decode_32_safe(&p, end, allowed_modes[i], bad);
		dout("%s con %p allowed_modes[%d] %d\n", __func__, con,
		     i, allowed_modes[i]);
	}

	mutex_unlock(&con->mutex);
	ret = con->ops->handle_auth_bad_method(con, used_proto, result,
					       allowed_protos,
					       allowed_proto_cnt,
					       allowed_modes,
					       allowed_mode_cnt);
	mutex_lock(&con->mutex);
	if (con->state != CEPH_CON_S_V2_AUTH) {
		dout("%s con %p state changed to %d\n", __func__, con,
		     con->state);
		return -EAGAIN;
	}

	dout("%s con %p handle_auth_bad_method ret %d\n", __func__, con, ret);
	return ret;

bad:
	pr_err("failed to decode auth_bad_method\n");
	return -EINVAL;
}

static int process_auth_reply_more(struct ceph_connection *con,
				   void *p, void *end)
{
	int payload_len;
	int ret;

	if (con->state != CEPH_CON_S_V2_AUTH) {
		con->error_msg = "protocol error, unexpected auth_reply_more";
		return -EINVAL;
	}

	ceph_decode_32_safe(&p, end, payload_len, bad);
	ceph_decode_need(&p, end, payload_len, bad);

	dout("%s con %p payload_len %d\n", __func__, con, payload_len);

	reset_out_kvecs(con);
	ret = prepare_auth_request_more(con, p, payload_len);
	if (ret) {
		if (ret != -EAGAIN)
			pr_err("prepare_auth_request_more failed: %d\n", ret);
		return ret;
	}

	return 0;

bad:
	pr_err("failed to decode auth_reply_more\n");
	return -EINVAL;
}

/*
 * Align session_key and con_secret to avoid GFP_ATOMIC allocation
 * inside crypto_shash_setkey() and crypto_aead_setkey() called from
 * setup_crypto().  __aligned(16) isn't guaranteed to work for stack
 * objects, so do it by hand.
 */
static int process_auth_done(struct ceph_connection *con, void *p, void *end)
{
	u8 session_key_buf[CEPH_KEY_LEN + 16];
	u8 con_secret_buf[CEPH_MAX_CON_SECRET_LEN + 16];
	u8 *session_key = PTR_ALIGN(&session_key_buf[0], 16);
	u8 *con_secret = PTR_ALIGN(&con_secret_buf[0], 16);
	int session_key_len, con_secret_len;
	int payload_len;
	u64 global_id;
	int ret;

	if (con->state != CEPH_CON_S_V2_AUTH) {
		con->error_msg = "protocol error, unexpected auth_done";
		return -EINVAL;
	}

	ceph_decode_64_safe(&p, end, global_id, bad);
	ceph_decode_32_safe(&p, end, con->v2.con_mode, bad);
	ceph_decode_32_safe(&p, end, payload_len, bad);

	dout("%s con %p global_id %llu con_mode %d payload_len %d\n",
	     __func__, con, global_id, con->v2.con_mode, payload_len);

	mutex_unlock(&con->mutex);
	session_key_len = 0;
	con_secret_len = 0;
	ret = con->ops->handle_auth_done(con, global_id, p, payload_len,
					 session_key, &session_key_len,
					 con_secret, &con_secret_len);
	mutex_lock(&con->mutex);
	if (con->state != CEPH_CON_S_V2_AUTH) {
		dout("%s con %p state changed to %d\n", __func__, con,
		     con->state);
		ret = -EAGAIN;
		goto out;
	}

	dout("%s con %p handle_auth_done ret %d\n", __func__, con, ret);
	if (ret)
		goto out;

	ret = setup_crypto(con, session_key, session_key_len, con_secret,
			   con_secret_len);
	if (ret)
		goto out;

	reset_out_kvecs(con);
	ret = prepare_auth_signature(con);
	if (ret) {
		pr_err("prepare_auth_signature failed: %d\n", ret);
		goto out;
	}

	con->state = CEPH_CON_S_V2_AUTH_SIGNATURE;

out:
	memzero_explicit(session_key_buf, sizeof(session_key_buf));
	memzero_explicit(con_secret_buf, sizeof(con_secret_buf));
	return ret;

bad:
	pr_err("failed to decode auth_done\n");
	return -EINVAL;
}

static int process_auth_signature(struct ceph_connection *con,
				  void *p, void *end)
{
	u8 hmac[SHA256_DIGEST_SIZE];
	int ret;

	if (con->state != CEPH_CON_S_V2_AUTH_SIGNATURE) {
		con->error_msg = "protocol error, unexpected auth_signature";
		return -EINVAL;
	}

	ret = hmac_sha256(con, con->v2.out_sign_kvecs,
			  con->v2.out_sign_kvec_cnt, hmac);
	if (ret)
		return ret;

	ceph_decode_need(&p, end, SHA256_DIGEST_SIZE, bad);
	if (crypto_memneq(p, hmac, SHA256_DIGEST_SIZE)) {
		con->error_msg = "integrity error, bad auth signature";
		return -EBADMSG;
	}

	dout("%s con %p auth signature ok\n", __func__, con);

	/* no reset_out_kvecs() as our auth_signature may still be pending */
	if (!con->v2.server_cookie) {
		ret = prepare_client_ident(con);
		if (ret) {
			pr_err("prepare_client_ident failed: %d\n", ret);
			return ret;
		}

		con->state = CEPH_CON_S_V2_SESSION_CONNECT;
	} else {
		ret = prepare_session_reconnect(con);
		if (ret) {
			pr_err("prepare_session_reconnect failed: %d\n", ret);
			return ret;
		}

		con->state = CEPH_CON_S_V2_SESSION_RECONNECT;
	}

	return 0;

bad:
	pr_err("failed to decode auth_signature\n");
	return -EINVAL;
}

static int process_server_ident(struct ceph_connection *con,
				void *p, void *end)
{
	struct ceph_client *client = from_msgr(con->msgr);
	u64 features, required_features;
	struct ceph_entity_addr addr;
	u64 global_seq;
	u64 global_id;
	u64 cookie;
	u64 flags;
	int ret;

	if (con->state != CEPH_CON_S_V2_SESSION_CONNECT) {
		con->error_msg = "protocol error, unexpected server_ident";
		return -EINVAL;
	}

	ret = ceph_decode_entity_addrvec(&p, end, true, &addr);
	if (ret) {
		pr_err("failed to decode server addrs: %d\n", ret);
		return ret;
	}

	ceph_decode_64_safe(&p, end, global_id, bad);
	ceph_decode_64_safe(&p, end, global_seq, bad);
	ceph_decode_64_safe(&p, end, features, bad);
	ceph_decode_64_safe(&p, end, required_features, bad);
	ceph_decode_64_safe(&p, end, flags, bad);
	ceph_decode_64_safe(&p, end, cookie, bad);

	dout("%s con %p addr %s/%u global_id %llu global_seq %llu features 0x%llx required_features 0x%llx flags 0x%llx cookie 0x%llx\n",
	     __func__, con, ceph_pr_addr(&addr), le32_to_cpu(addr.nonce),
	     global_id, global_seq, features, required_features, flags, cookie);

	/* is this who we intended to talk to? */
	if (memcmp(&addr, &con->peer_addr, sizeof(con->peer_addr))) {
		pr_err("bad peer addr/nonce, want %s/%u, got %s/%u\n",
		       ceph_pr_addr(&con->peer_addr),
		       le32_to_cpu(con->peer_addr.nonce),
		       ceph_pr_addr(&addr), le32_to_cpu(addr.nonce));
		con->error_msg = "wrong peer at address";
		return -EINVAL;
	}

	if (client->required_features & ~features) {
		pr_err("RADOS feature set mismatch: my required > server's supported 0x%llx, need 0x%llx\n",
		       features, client->required_features & ~features);
		con->error_msg = "missing required protocol features";
		return -EINVAL;
	}

	/*
	 * Both name->type and name->num are set in ceph_con_open() but
	 * name->num may be bogus in the initial monmap.  name->type is
	 * verified in handle_hello().
	 */
	WARN_ON(!con->peer_name.type);
	con->peer_name.num = cpu_to_le64(global_id);
	con->v2.peer_global_seq = global_seq;
	con->peer_features = features;
	WARN_ON(required_features & ~client->supported_features);
	con->v2.server_cookie = cookie;

	if (flags & CEPH_MSG_CONNECT_LOSSY) {
		ceph_con_flag_set(con, CEPH_CON_F_LOSSYTX);
		WARN_ON(con->v2.server_cookie);
	} else {
		WARN_ON(!con->v2.server_cookie);
	}

	clear_in_sign_kvecs(con);
	clear_out_sign_kvecs(con);
	free_conn_bufs(con);
	con->delay = 0;  /* reset backoff memory */

	con->state = CEPH_CON_S_OPEN;
	con->v2.out_state = OUT_S_GET_NEXT;
	return 0;

bad:
	pr_err("failed to decode server_ident\n");
	return -EINVAL;
}

static int process_ident_missing_features(struct ceph_connection *con,
					  void *p, void *end)
{
	struct ceph_client *client = from_msgr(con->msgr);
	u64 missing_features;

	if (con->state != CEPH_CON_S_V2_SESSION_CONNECT) {
		con->error_msg = "protocol error, unexpected ident_missing_features";
		return -EINVAL;
	}

	ceph_decode_64_safe(&p, end, missing_features, bad);
	pr_err("RADOS feature set mismatch: server's required > my supported 0x%llx, missing 0x%llx\n",
	       client->supported_features, missing_features);
	con->error_msg = "missing required protocol features";
	return -EINVAL;

bad:
	pr_err("failed to decode ident_missing_features\n");
	return -EINVAL;
}

static int process_session_reconnect_ok(struct ceph_connection *con,
					void *p, void *end)
{
	u64 seq;

	if (con->state != CEPH_CON_S_V2_SESSION_RECONNECT) {
		con->error_msg = "protocol error, unexpected session_reconnect_ok";
		return -EINVAL;
	}

	ceph_decode_64_safe(&p, end, seq, bad);

	dout("%s con %p seq %llu\n", __func__, con, seq);
	ceph_con_discard_requeued(con, seq);

	clear_in_sign_kvecs(con);
	clear_out_sign_kvecs(con);
	free_conn_bufs(con);
	con->delay = 0;  /* reset backoff memory */

	con->state = CEPH_CON_S_OPEN;
	con->v2.out_state = OUT_S_GET_NEXT;
	return 0;

bad:
	pr_err("failed to decode session_reconnect_ok\n");
	return -EINVAL;
}

static int process_session_retry(struct ceph_connection *con,
				 void *p, void *end)
{
	u64 connect_seq;
	int ret;

	if (con->state != CEPH_CON_S_V2_SESSION_RECONNECT) {
		con->error_msg = "protocol error, unexpected session_retry";
		return -EINVAL;
	}

	ceph_decode_64_safe(&p, end, connect_seq, bad);

	dout("%s con %p connect_seq %llu\n", __func__, con, connect_seq);
	WARN_ON(connect_seq <= con->v2.connect_seq);
	con->v2.connect_seq = connect_seq + 1;

	free_conn_bufs(con);

	reset_out_kvecs(con);
	ret = prepare_session_reconnect(con);
	if (ret) {
		pr_err("prepare_session_reconnect (cseq) failed: %d\n", ret);
		return ret;
	}

	return 0;

bad:
	pr_err("failed to decode session_retry\n");
	return -EINVAL;
}

static int process_session_retry_global(struct ceph_connection *con,
					void *p, void *end)
{
	u64 global_seq;
	int ret;

	if (con->state != CEPH_CON_S_V2_SESSION_RECONNECT) {
		con->error_msg = "protocol error, unexpected session_retry_global";
		return -EINVAL;
	}

	ceph_decode_64_safe(&p, end, global_seq, bad);

	dout("%s con %p global_seq %llu\n", __func__, con, global_seq);
	WARN_ON(global_seq <= con->v2.global_seq);
	con->v2.global_seq = ceph_get_global_seq(con->msgr, global_seq);

	free_conn_bufs(con);

	reset_out_kvecs(con);
	ret = prepare_session_reconnect(con);
	if (ret) {
		pr_err("prepare_session_reconnect (gseq) failed: %d\n", ret);
		return ret;
	}

	return 0;

bad:
	pr_err("failed to decode session_retry_global\n");
	return -EINVAL;
}

static int process_session_reset(struct ceph_connection *con,
				 void *p, void *end)
{
	bool full;
	int ret;

	if (con->state != CEPH_CON_S_V2_SESSION_RECONNECT) {
		con->error_msg = "protocol error, unexpected session_reset";
		return -EINVAL;
	}

	ceph_decode_8_safe(&p, end, full, bad);
	if (!full) {
		con->error_msg = "protocol error, bad session_reset";
		return -EINVAL;
	}

	pr_info("%s%lld %s session reset\n", ENTITY_NAME(con->peer_name),
		ceph_pr_addr(&con->peer_addr));
	ceph_con_reset_session(con);

	mutex_unlock(&con->mutex);
	if (con->ops->peer_reset)
		con->ops->peer_reset(con);
	mutex_lock(&con->mutex);
	if (con->state != CEPH_CON_S_V2_SESSION_RECONNECT) {
		dout("%s con %p state changed to %d\n", __func__, con,
		     con->state);
		return -EAGAIN;
	}

	free_conn_bufs(con);

	reset_out_kvecs(con);
	ret = prepare_client_ident(con);
	if (ret) {
		pr_err("prepare_client_ident (rst) failed: %d\n", ret);
		return ret;
	}

	con->state = CEPH_CON_S_V2_SESSION_CONNECT;
	return 0;

bad:
	pr_err("failed to decode session_reset\n");
	return -EINVAL;
}

static int process_keepalive2_ack(struct ceph_connection *con,
				  void *p, void *end)
{
	if (con->state != CEPH_CON_S_OPEN) {
		con->error_msg = "protocol error, unexpected keepalive2_ack";
		return -EINVAL;
	}

	ceph_decode_need(&p, end, sizeof(struct ceph_timespec), bad);
	ceph_decode_timespec64(&con->last_keepalive_ack, p);

	dout("%s con %p timestamp %lld.%09ld\n", __func__, con,
	     con->last_keepalive_ack.tv_sec, con->last_keepalive_ack.tv_nsec);

	return 0;

bad:
	pr_err("failed to decode keepalive2_ack\n");
	return -EINVAL;
}

static int process_ack(struct ceph_connection *con, void *p, void *end)
{
	u64 seq;

	if (con->state != CEPH_CON_S_OPEN) {
		con->error_msg = "protocol error, unexpected ack";
		return -EINVAL;
	}

	ceph_decode_64_safe(&p, end, seq, bad);

	dout("%s con %p seq %llu\n", __func__, con, seq);
	ceph_con_discard_sent(con, seq);
	return 0;

bad:
	pr_err("failed to decode ack\n");
	return -EINVAL;
}

static int process_control(struct ceph_connection *con, void *p, void *end)
{
	int tag = con->v2.in_desc.fd_tag;
	int ret;

	dout("%s con %p tag %d len %d\n", __func__, con, tag, (int)(end - p));

	switch (tag) {
	case FRAME_TAG_HELLO:
		ret = process_hello(con, p, end);
		break;
	case FRAME_TAG_AUTH_BAD_METHOD:
		ret = process_auth_bad_method(con, p, end);
		break;
	case FRAME_TAG_AUTH_REPLY_MORE:
		ret = process_auth_reply_more(con, p, end);
		break;
	case FRAME_TAG_AUTH_DONE:
		ret = process_auth_done(con, p, end);
		break;
	case FRAME_TAG_AUTH_SIGNATURE:
		ret = process_auth_signature(con, p, end);
		break;
	case FRAME_TAG_SERVER_IDENT:
		ret = process_server_ident(con, p, end);
		break;
	case FRAME_TAG_IDENT_MISSING_FEATURES:
		ret = process_ident_missing_features(con, p, end);
		break;
	case FRAME_TAG_SESSION_RECONNECT_OK:
		ret = process_session_reconnect_ok(con, p, end);
		break;
	case FRAME_TAG_SESSION_RETRY:
		ret = process_session_retry(con, p, end);
		break;
	case FRAME_TAG_SESSION_RETRY_GLOBAL:
		ret = process_session_retry_global(con, p, end);
		break;
	case FRAME_TAG_SESSION_RESET:
		ret = process_session_reset(con, p, end);
		break;
	case FRAME_TAG_KEEPALIVE2_ACK:
		ret = process_keepalive2_ack(con, p, end);
		break;
	case FRAME_TAG_ACK:
		ret = process_ack(con, p, end);
		break;
	default:
		pr_err("bad tag %d\n", tag);
		con->error_msg = "protocol error, bad tag";
		return -EINVAL;
	}
	if (ret) {
		dout("%s con %p error %d\n", __func__, con, ret);
		return ret;
	}

	prepare_read_preamble(con);
	return 0;
}

/*
 * Return:
 *   1 - con->in_msg set, read message
 *   0 - skip message
 *  <0 - error
 */
static int process_message_header(struct ceph_connection *con,
				  void *p, void *end)
{
	struct ceph_frame_desc *desc = &con->v2.in_desc;
	struct ceph_msg_header2 *hdr2 = p;
	struct ceph_msg_header hdr;
	int skip;
	int ret;
	u64 seq;

	/* verify seq# */
	seq = le64_to_cpu(hdr2->seq);
	if ((s64)seq - (s64)con->in_seq < 1) {
		pr_info("%s%lld %s skipping old message: seq %llu, expected %llu\n",
			ENTITY_NAME(con->peer_name),
			ceph_pr_addr(&con->peer_addr),
			seq, con->in_seq + 1);
		return 0;
	}
	if ((s64)seq - (s64)con->in_seq > 1) {
		pr_err("bad seq %llu, expected %llu\n", seq, con->in_seq + 1);
		con->error_msg = "bad message sequence # for incoming message";
		return -EBADE;
	}

	ceph_con_discard_sent(con, le64_to_cpu(hdr2->ack_seq));

	fill_header(&hdr, hdr2, desc->fd_lens[1], desc->fd_lens[2],
		    desc->fd_lens[3], &con->peer_name);
	ret = ceph_con_in_msg_alloc(con, &hdr, &skip);
	if (ret)
		return ret;

	WARN_ON(!con->in_msg ^ skip);
	if (skip)
		return 0;

	WARN_ON(!con->in_msg);
	WARN_ON(con->in_msg->con != con);
	return 1;
}

static int process_message(struct ceph_connection *con)
{
	ceph_con_process_message(con);

	/*
	 * We could have been closed by ceph_con_close() because
	 * ceph_con_process_message() temporarily drops con->mutex.
	 */
	if (con->state != CEPH_CON_S_OPEN) {
		dout("%s con %p state changed to %d\n", __func__, con,
		     con->state);
		return -EAGAIN;
	}

	prepare_read_preamble(con);
	return 0;
}

static int __handle_control(struct ceph_connection *con, void *p)
{
	void *end = p + con->v2.in_desc.fd_lens[0];
	struct ceph_msg *msg;
	int ret;

	if (con->v2.in_desc.fd_tag != FRAME_TAG_MESSAGE)
		return process_control(con, p, end);

	ret = process_message_header(con, p, end);
	if (ret < 0)
		return ret;
	if (ret == 0) {
		prepare_skip_message(con);
		return 0;
	}

	msg = con->in_msg;  /* set in process_message_header() */
	if (front_len(msg)) {
		WARN_ON(front_len(msg) > msg->front_alloc_len);
		msg->front.iov_len = front_len(msg);
	} else {
		msg->front.iov_len = 0;
	}
	if (middle_len(msg)) {
		WARN_ON(middle_len(msg) > msg->middle->alloc_len);
		msg->middle->vec.iov_len = middle_len(msg);
	} else if (msg->middle) {
		msg->middle->vec.iov_len = 0;
	}

	if (!front_len(msg) && !middle_len(msg) && !data_len(msg))
		return process_message(con);

	if (con_secure(con))
		return prepare_read_tail_secure(con);

	return prepare_read_tail_plain(con);
}

static int handle_preamble(struct ceph_connection *con)
{
	struct ceph_frame_desc *desc = &con->v2.in_desc;
	int ret;

	if (con_secure(con)) {
		ret = decrypt_preamble(con);
		if (ret) {
			if (ret == -EBADMSG)
				con->error_msg = "integrity error, bad preamble auth tag";
			return ret;
		}
	}

	ret = decode_preamble(con->v2.in_buf, desc);
	if (ret) {
		if (ret == -EBADMSG)
			con->error_msg = "integrity error, bad crc";
		else
			con->error_msg = "protocol error, bad preamble";
		return ret;
	}

	dout("%s con %p tag %d seg_cnt %d %d+%d+%d+%d\n", __func__,
	     con, desc->fd_tag, desc->fd_seg_cnt, desc->fd_lens[0],
	     desc->fd_lens[1], desc->fd_lens[2], desc->fd_lens[3]);

	if (!con_secure(con))
		return prepare_read_control(con);

	if (desc->fd_lens[0] > CEPH_PREAMBLE_INLINE_LEN)
		return prepare_read_control_remainder(con);

	return __handle_control(con, CTRL_BODY(con->v2.in_buf));
}

static int handle_control(struct ceph_connection *con)
{
	int ctrl_len = con->v2.in_desc.fd_lens[0];
	void *buf;
	int ret;

	WARN_ON(con_secure(con));

	ret = verify_control_crc(con);
	if (ret) {
		con->error_msg = "integrity error, bad crc";
		return ret;
	}

	if (con->state == CEPH_CON_S_V2_AUTH) {
		buf = alloc_conn_buf(con, ctrl_len);
		if (!buf)
			return -ENOMEM;

		memcpy(buf, con->v2.in_kvecs[0].iov_base, ctrl_len);
		return __handle_control(con, buf);
	}

	return __handle_control(con, con->v2.in_kvecs[0].iov_base);
}

static int handle_control_remainder(struct ceph_connection *con)
{
	int ret;

	WARN_ON(!con_secure(con));

	ret = decrypt_control_remainder(con);
	if (ret) {
		if (ret == -EBADMSG)
			con->error_msg = "integrity error, bad control remainder auth tag";
		return ret;
	}

	return __handle_control(con, con->v2.in_kvecs[0].iov_base -
				     CEPH_PREAMBLE_INLINE_LEN);
}

static int handle_epilogue(struct ceph_connection *con)
{
	u32 front_crc, middle_crc, data_crc;
	int ret;

	if (con_secure(con)) {
		ret = decrypt_tail(con);
		if (ret) {
			if (ret == -EBADMSG)
				con->error_msg = "integrity error, bad epilogue auth tag";
			return ret;
		}

		/* just late_status */
		ret = decode_epilogue(con->v2.in_buf, NULL, NULL, NULL);
		if (ret) {
			con->error_msg = "protocol error, bad epilogue";
			return ret;
		}
	} else {
		ret = decode_epilogue(con->v2.in_buf, &front_crc,
				      &middle_crc, &data_crc);
		if (ret) {
			con->error_msg = "protocol error, bad epilogue";
			return ret;
		}

		ret = verify_epilogue_crcs(con, front_crc, middle_crc,
					   data_crc);
		if (ret) {
			con->error_msg = "integrity error, bad crc";
			return ret;
		}
	}

	return process_message(con);
}

static void finish_skip(struct ceph_connection *con)
{
	dout("%s con %p\n", __func__, con);

	if (con_secure(con))
		gcm_inc_nonce(&con->v2.in_gcm_nonce);

	__finish_skip(con);
}

static int populate_in_iter(struct ceph_connection *con)
{
	int ret;

	dout("%s con %p state %d in_state %d\n", __func__, con, con->state,
	     con->v2.in_state);
	WARN_ON(iov_iter_count(&con->v2.in_iter));

	if (con->state == CEPH_CON_S_V2_BANNER_PREFIX) {
		ret = process_banner_prefix(con);
	} else if (con->state == CEPH_CON_S_V2_BANNER_PAYLOAD) {
		ret = process_banner_payload(con);
	} else if ((con->state >= CEPH_CON_S_V2_HELLO &&
		    con->state <= CEPH_CON_S_V2_SESSION_RECONNECT) ||
		   con->state == CEPH_CON_S_OPEN) {
		switch (con->v2.in_state) {
		case IN_S_HANDLE_PREAMBLE:
			ret = handle_preamble(con);
			break;
		case IN_S_HANDLE_CONTROL:
			ret = handle_control(con);
			break;
		case IN_S_HANDLE_CONTROL_REMAINDER:
			ret = handle_control_remainder(con);
			break;
		case IN_S_PREPARE_READ_DATA:
			ret = prepare_read_data(con);
			break;
		case IN_S_PREPARE_READ_DATA_CONT:
			prepare_read_data_cont(con);
			ret = 0;
			break;
		case IN_S_PREPARE_READ_ENC_PAGE:
			prepare_read_enc_page(con);
			ret = 0;
			break;
		case IN_S_HANDLE_EPILOGUE:
			ret = handle_epilogue(con);
			break;
		case IN_S_FINISH_SKIP:
			finish_skip(con);
			ret = 0;
			break;
		default:
			WARN(1, "bad in_state %d", con->v2.in_state);
			return -EINVAL;
		}
	} else {
		WARN(1, "bad state %d", con->state);
		return -EINVAL;
	}
	if (ret) {
		dout("%s con %p error %d\n", __func__, con, ret);
		return ret;
	}

	if (WARN_ON(!iov_iter_count(&con->v2.in_iter)))
		return -ENODATA;
	dout("%s con %p populated %zu\n", __func__, con,
	     iov_iter_count(&con->v2.in_iter));
	return 1;
}

int ceph_con_v2_try_read(struct ceph_connection *con)
{
	int ret;

	dout("%s con %p state %d need %zu\n", __func__, con, con->state,
	     iov_iter_count(&con->v2.in_iter));

	if (con->state == CEPH_CON_S_PREOPEN)
		return 0;

	/*
	 * We should always have something pending here.  If not,
	 * avoid calling populate_in_iter() as if we read something
	 * (ceph_tcp_recv() would immediately return 1).
	 */
	if (WARN_ON(!iov_iter_count(&con->v2.in_iter)))
		return -ENODATA;

	for (;;) {
		ret = ceph_tcp_recv(con);
		if (ret <= 0)
			return ret;

		ret = populate_in_iter(con);
		if (ret <= 0) {
			if (ret && ret != -EAGAIN && !con->error_msg)
				con->error_msg = "read processing error";
			return ret;
		}
	}
}

static void queue_data(struct ceph_connection *con)
{
	struct bio_vec bv;

	con->v2.out_epil.data_crc = -1;
	ceph_msg_data_cursor_init(&con->v2.out_cursor, con->out_msg,
				  data_len(con->out_msg));

	get_bvec_at(&con->v2.out_cursor, &bv);
	set_out_bvec(con, &bv, true);
	con->v2.out_state = OUT_S_QUEUE_DATA_CONT;
}

static void queue_data_cont(struct ceph_connection *con)
{
	struct bio_vec bv;

	con->v2.out_epil.data_crc = ceph_crc32c_page(
		con->v2.out_epil.data_crc, con->v2.out_bvec.bv_page,
		con->v2.out_bvec.bv_offset, con->v2.out_bvec.bv_len);

	ceph_msg_data_advance(&con->v2.out_cursor, con->v2.out_bvec.bv_len);
	if (con->v2.out_cursor.total_resid) {
		get_bvec_at(&con->v2.out_cursor, &bv);
		set_out_bvec(con, &bv, true);
		WARN_ON(con->v2.out_state != OUT_S_QUEUE_DATA_CONT);
		return;
	}

	/*
	 * We've written all data.  Queue epilogue.  Once it's written,
	 * we are done.
	 */
	reset_out_kvecs(con);
	prepare_epilogue_plain(con, false);
	con->v2.out_state = OUT_S_FINISH_MESSAGE;
}

static void queue_enc_page(struct ceph_connection *con)
{
	struct bio_vec bv;

	dout("%s con %p i %d resid %d\n", __func__, con, con->v2.out_enc_i,
	     con->v2.out_enc_resid);
	WARN_ON(!con->v2.out_enc_resid);

	bv.bv_page = con->v2.out_enc_pages[con->v2.out_enc_i];
	bv.bv_offset = 0;
	bv.bv_len = min(con->v2.out_enc_resid, (int)PAGE_SIZE);

	set_out_bvec(con, &bv, false);
	con->v2.out_enc_i++;
	con->v2.out_enc_resid -= bv.bv_len;

	if (con->v2.out_enc_resid) {
		WARN_ON(con->v2.out_state != OUT_S_QUEUE_ENC_PAGE);
		return;
	}

	/*
	 * We've queued the last piece of ciphertext (ending with
	 * epilogue) + auth tag.  Once it's written, we are done.
	 */
	WARN_ON(con->v2.out_enc_i != con->v2.out_enc_page_cnt);
	con->v2.out_state = OUT_S_FINISH_MESSAGE;
}

static void queue_zeros(struct ceph_connection *con)
{
	dout("%s con %p out_zero %d\n", __func__, con, con->v2.out_zero);

	if (con->v2.out_zero) {
		set_out_bvec_zero(con);
		con->v2.out_zero -= con->v2.out_bvec.bv_len;
		con->v2.out_state = OUT_S_QUEUE_ZEROS;
		return;
	}

	/*
	 * We've zero-filled everything up to epilogue.  Queue epilogue
	 * with late_status set to ABORTED and crcs adjusted for zeros.
	 * Once it's written, we are done patching up for the revoke.
	 */
	reset_out_kvecs(con);
	prepare_epilogue_plain(con, true);
	con->v2.out_state = OUT_S_FINISH_MESSAGE;
}

static void finish_message(struct ceph_connection *con)
{
	dout("%s con %p msg %p\n", __func__, con, con->out_msg);

	/* we end up here both plain and secure modes */
	if (con->v2.out_enc_pages) {
		WARN_ON(!con->v2.out_enc_page_cnt);
		ceph_release_page_vector(con->v2.out_enc_pages,
					 con->v2.out_enc_page_cnt);
		con->v2.out_enc_pages = NULL;
		con->v2.out_enc_page_cnt = 0;
	}
	/* message may have been revoked */
	if (con->out_msg) {
		ceph_msg_put(con->out_msg);
		con->out_msg = NULL;
	}

	con->v2.out_state = OUT_S_GET_NEXT;
}

static int populate_out_iter(struct ceph_connection *con)
{
	int ret;

	dout("%s con %p state %d out_state %d\n", __func__, con, con->state,
	     con->v2.out_state);
	WARN_ON(iov_iter_count(&con->v2.out_iter));

	if (con->state != CEPH_CON_S_OPEN) {
		WARN_ON(con->state < CEPH_CON_S_V2_BANNER_PREFIX ||
			con->state > CEPH_CON_S_V2_SESSION_RECONNECT);
		goto nothing_pending;
	}

	switch (con->v2.out_state) {
	case OUT_S_QUEUE_DATA:
		WARN_ON(!con->out_msg);
		queue_data(con);
		goto populated;
	case OUT_S_QUEUE_DATA_CONT:
		WARN_ON(!con->out_msg);
		queue_data_cont(con);
		goto populated;
	case OUT_S_QUEUE_ENC_PAGE:
		queue_enc_page(con);
		goto populated;
	case OUT_S_QUEUE_ZEROS:
		WARN_ON(con->out_msg);  /* revoked */
		queue_zeros(con);
		goto populated;
	case OUT_S_FINISH_MESSAGE:
		finish_message(con);
		break;
	case OUT_S_GET_NEXT:
		break;
	default:
		WARN(1, "bad out_state %d", con->v2.out_state);
		return -EINVAL;
	}

	WARN_ON(con->v2.out_state != OUT_S_GET_NEXT);
	if (ceph_con_flag_test_and_clear(con, CEPH_CON_F_KEEPALIVE_PENDING)) {
		ret = prepare_keepalive2(con);
		if (ret) {
			pr_err("prepare_keepalive2 failed: %d\n", ret);
			return ret;
		}
	} else if (!list_empty(&con->out_queue)) {
		ceph_con_get_out_msg(con);
		ret = prepare_message(con);
		if (ret) {
			pr_err("prepare_message failed: %d\n", ret);
			return ret;
		}
	} else if (con->in_seq > con->in_seq_acked) {
		ret = prepare_ack(con);
		if (ret) {
			pr_err("prepare_ack failed: %d\n", ret);
			return ret;
		}
	} else {
		goto nothing_pending;
	}

populated:
	if (WARN_ON(!iov_iter_count(&con->v2.out_iter)))
		return -ENODATA;
	dout("%s con %p populated %zu\n", __func__, con,
	     iov_iter_count(&con->v2.out_iter));
	return 1;

nothing_pending:
	WARN_ON(iov_iter_count(&con->v2.out_iter));
	dout("%s con %p nothing pending\n", __func__, con);
	ceph_con_flag_clear(con, CEPH_CON_F_WRITE_PENDING);
	return 0;
}

int ceph_con_v2_try_write(struct ceph_connection *con)
{
	int ret;

	dout("%s con %p state %d have %zu\n", __func__, con, con->state,
	     iov_iter_count(&con->v2.out_iter));

	/* open the socket first? */
	if (con->state == CEPH_CON_S_PREOPEN) {
		WARN_ON(con->peer_addr.type != CEPH_ENTITY_ADDR_TYPE_MSGR2);

		/*
		 * Always bump global_seq.  Bump connect_seq only if
		 * there is a session (i.e. we are reconnecting and will
		 * send session_reconnect instead of client_ident).
		 */
		con->v2.global_seq = ceph_get_global_seq(con->msgr, 0);
		if (con->v2.server_cookie)
			con->v2.connect_seq++;

		ret = prepare_read_banner_prefix(con);
		if (ret) {
			pr_err("prepare_read_banner_prefix failed: %d\n", ret);
			con->error_msg = "connect error";
			return ret;
		}

		reset_out_kvecs(con);
		ret = prepare_banner(con);
		if (ret) {
			pr_err("prepare_banner failed: %d\n", ret);
			con->error_msg = "connect error";
			return ret;
		}

		ret = ceph_tcp_connect(con);
		if (ret) {
			pr_err("ceph_tcp_connect failed: %d\n", ret);
			con->error_msg = "connect error";
			return ret;
		}
	}

	if (!iov_iter_count(&con->v2.out_iter)) {
		ret = populate_out_iter(con);
		if (ret <= 0) {
			if (ret && ret != -EAGAIN && !con->error_msg)
				con->error_msg = "write processing error";
			return ret;
		}
	}

	tcp_sock_set_cork(con->sock->sk, true);
	for (;;) {
		ret = ceph_tcp_send(con);
		if (ret <= 0)
			break;

		ret = populate_out_iter(con);
		if (ret <= 0) {
			if (ret && ret != -EAGAIN && !con->error_msg)
				con->error_msg = "write processing error";
			break;
		}
	}

	tcp_sock_set_cork(con->sock->sk, false);
	return ret;
}

static u32 crc32c_zeros(u32 crc, int zero_len)
{
	int len;

	while (zero_len) {
		len = min(zero_len, (int)PAGE_SIZE);
		crc = crc32c(crc, page_address(ceph_zero_page), len);
		zero_len -= len;
	}

	return crc;
}

static void prepare_zero_front(struct ceph_connection *con, int resid)
{
	int sent;

	WARN_ON(!resid || resid > front_len(con->out_msg));
	sent = front_len(con->out_msg) - resid;
	dout("%s con %p sent %d resid %d\n", __func__, con, sent, resid);

	if (sent) {
		con->v2.out_epil.front_crc =
			crc32c(-1, con->out_msg->front.iov_base, sent);
		con->v2.out_epil.front_crc =
			crc32c_zeros(con->v2.out_epil.front_crc, resid);
	} else {
		con->v2.out_epil.front_crc = crc32c_zeros(-1, resid);
	}

	con->v2.out_iter.count -= resid;
	out_zero_add(con, resid);
}

static void prepare_zero_middle(struct ceph_connection *con, int resid)
{
	int sent;

	WARN_ON(!resid || resid > middle_len(con->out_msg));
	sent = middle_len(con->out_msg) - resid;
	dout("%s con %p sent %d resid %d\n", __func__, con, sent, resid);

	if (sent) {
		con->v2.out_epil.middle_crc =
			crc32c(-1, con->out_msg->middle->vec.iov_base, sent);
		con->v2.out_epil.middle_crc =
			crc32c_zeros(con->v2.out_epil.middle_crc, resid);
	} else {
		con->v2.out_epil.middle_crc = crc32c_zeros(-1, resid);
	}

	con->v2.out_iter.count -= resid;
	out_zero_add(con, resid);
}

static void prepare_zero_data(struct ceph_connection *con)
{
	dout("%s con %p\n", __func__, con);
	con->v2.out_epil.data_crc = crc32c_zeros(-1, data_len(con->out_msg));
	out_zero_add(con, data_len(con->out_msg));
}

static void revoke_at_queue_data(struct ceph_connection *con)
{
	int boundary;
	int resid;

	WARN_ON(!data_len(con->out_msg));
	WARN_ON(!iov_iter_is_kvec(&con->v2.out_iter));
	resid = iov_iter_count(&con->v2.out_iter);

	boundary = front_len(con->out_msg) + middle_len(con->out_msg);
	if (resid > boundary) {
		resid -= boundary;
		WARN_ON(resid > MESSAGE_HEAD_PLAIN_LEN);
		dout("%s con %p was sending head\n", __func__, con);
		if (front_len(con->out_msg))
			prepare_zero_front(con, front_len(con->out_msg));
		if (middle_len(con->out_msg))
			prepare_zero_middle(con, middle_len(con->out_msg));
		prepare_zero_data(con);
		WARN_ON(iov_iter_count(&con->v2.out_iter) != resid);
		con->v2.out_state = OUT_S_QUEUE_ZEROS;
		return;
	}

	boundary = middle_len(con->out_msg);
	if (resid > boundary) {
		resid -= boundary;
		dout("%s con %p was sending front\n", __func__, con);
		prepare_zero_front(con, resid);
		if (middle_len(con->out_msg))
			prepare_zero_middle(con, middle_len(con->out_msg));
		prepare_zero_data(con);
		queue_zeros(con);
		return;
	}

	WARN_ON(!resid);
	dout("%s con %p was sending middle\n", __func__, con);
	prepare_zero_middle(con, resid);
	prepare_zero_data(con);
	queue_zeros(con);
}

static void revoke_at_queue_data_cont(struct ceph_connection *con)
{
	int sent, resid;  /* current piece of data */

	WARN_ON(!data_len(con->out_msg));
	WARN_ON(!iov_iter_is_bvec(&con->v2.out_iter));
	resid = iov_iter_count(&con->v2.out_iter);
	WARN_ON(!resid || resid > con->v2.out_bvec.bv_len);
	sent = con->v2.out_bvec.bv_len - resid;
	dout("%s con %p sent %d resid %d\n", __func__, con, sent, resid);

	if (sent) {
		con->v2.out_epil.data_crc = ceph_crc32c_page(
			con->v2.out_epil.data_crc, con->v2.out_bvec.bv_page,
			con->v2.out_bvec.bv_offset, sent);
		ceph_msg_data_advance(&con->v2.out_cursor, sent);
	}
	WARN_ON(resid > con->v2.out_cursor.total_resid);
	con->v2.out_epil.data_crc = crc32c_zeros(con->v2.out_epil.data_crc,
						con->v2.out_cursor.total_resid);

	con->v2.out_iter.count -= resid;
	out_zero_add(con, con->v2.out_cursor.total_resid);
	queue_zeros(con);
}

static void revoke_at_finish_message(struct ceph_connection *con)
{
	int boundary;
	int resid;

	WARN_ON(!iov_iter_is_kvec(&con->v2.out_iter));
	resid = iov_iter_count(&con->v2.out_iter);

	if (!front_len(con->out_msg) && !middle_len(con->out_msg) &&
	    !data_len(con->out_msg)) {
		WARN_ON(!resid || resid > MESSAGE_HEAD_PLAIN_LEN);
		dout("%s con %p was sending head (empty message) - noop\n",
		     __func__, con);
		return;
	}

	boundary = front_len(con->out_msg) + middle_len(con->out_msg) +
		   CEPH_EPILOGUE_PLAIN_LEN;
	if (resid > boundary) {
		resid -= boundary;
		WARN_ON(resid > MESSAGE_HEAD_PLAIN_LEN);
		dout("%s con %p was sending head\n", __func__, con);
		if (front_len(con->out_msg))
			prepare_zero_front(con, front_len(con->out_msg));
		if (middle_len(con->out_msg))
			prepare_zero_middle(con, middle_len(con->out_msg));
		con->v2.out_iter.count -= CEPH_EPILOGUE_PLAIN_LEN;
		WARN_ON(iov_iter_count(&con->v2.out_iter) != resid);
		con->v2.out_state = OUT_S_QUEUE_ZEROS;
		return;
	}

	boundary = middle_len(con->out_msg) + CEPH_EPILOGUE_PLAIN_LEN;
	if (resid > boundary) {
		resid -= boundary;
		dout("%s con %p was sending front\n", __func__, con);
		prepare_zero_front(con, resid);
		if (middle_len(con->out_msg))
			prepare_zero_middle(con, middle_len(con->out_msg));
		con->v2.out_iter.count -= CEPH_EPILOGUE_PLAIN_LEN;
		queue_zeros(con);
		return;
	}

	boundary = CEPH_EPILOGUE_PLAIN_LEN;
	if (resid > boundary) {
		resid -= boundary;
		dout("%s con %p was sending middle\n", __func__, con);
		prepare_zero_middle(con, resid);
		con->v2.out_iter.count -= CEPH_EPILOGUE_PLAIN_LEN;
		queue_zeros(con);
		return;
	}

	WARN_ON(!resid);
	dout("%s con %p was sending epilogue - noop\n", __func__, con);
}

void ceph_con_v2_revoke(struct ceph_connection *con)
{
	WARN_ON(con->v2.out_zero);

	if (con_secure(con)) {
		WARN_ON(con->v2.out_state != OUT_S_QUEUE_ENC_PAGE &&
			con->v2.out_state != OUT_S_FINISH_MESSAGE);
		dout("%s con %p secure - noop\n", __func__, con);
		return;
	}

	switch (con->v2.out_state) {
	case OUT_S_QUEUE_DATA:
		revoke_at_queue_data(con);
		break;
	case OUT_S_QUEUE_DATA_CONT:
		revoke_at_queue_data_cont(con);
		break;
	case OUT_S_FINISH_MESSAGE:
		revoke_at_finish_message(con);
		break;
	default:
		WARN(1, "bad out_state %d", con->v2.out_state);
		break;
	}
}

static void revoke_at_prepare_read_data(struct ceph_connection *con)
{
	int remaining;
	int resid;

	WARN_ON(con_secure(con));
	WARN_ON(!data_len(con->in_msg));
	WARN_ON(!iov_iter_is_kvec(&con->v2.in_iter));
	resid = iov_iter_count(&con->v2.in_iter);
	WARN_ON(!resid);

	remaining = data_len(con->in_msg) + CEPH_EPILOGUE_PLAIN_LEN;
	dout("%s con %p resid %d remaining %d\n", __func__, con, resid,
	     remaining);
	con->v2.in_iter.count -= resid;
	set_in_skip(con, resid + remaining);
	con->v2.in_state = IN_S_FINISH_SKIP;
}

static void revoke_at_prepare_read_data_cont(struct ceph_connection *con)
{
	int recved, resid;  /* current piece of data */
	int remaining;

	WARN_ON(con_secure(con));
	WARN_ON(!data_len(con->in_msg));
	WARN_ON(!iov_iter_is_bvec(&con->v2.in_iter));
	resid = iov_iter_count(&con->v2.in_iter);
	WARN_ON(!resid || resid > con->v2.in_bvec.bv_len);
	recved = con->v2.in_bvec.bv_len - resid;
	dout("%s con %p recved %d resid %d\n", __func__, con, recved, resid);

	if (recved)
		ceph_msg_data_advance(&con->v2.in_cursor, recved);
	WARN_ON(resid > con->v2.in_cursor.total_resid);

	remaining = CEPH_EPILOGUE_PLAIN_LEN;
	dout("%s con %p total_resid %zu remaining %d\n", __func__, con,
	     con->v2.in_cursor.total_resid, remaining);
	con->v2.in_iter.count -= resid;
	set_in_skip(con, con->v2.in_cursor.total_resid + remaining);
	con->v2.in_state = IN_S_FINISH_SKIP;
}

static void revoke_at_prepare_read_enc_page(struct ceph_connection *con)
{
	int resid;  /* current enc page (not necessarily data) */

	WARN_ON(!con_secure(con));
	WARN_ON(!iov_iter_is_bvec(&con->v2.in_iter));
	resid = iov_iter_count(&con->v2.in_iter);
	WARN_ON(!resid || resid > con->v2.in_bvec.bv_len);

	dout("%s con %p resid %d enc_resid %d\n", __func__, con, resid,
	     con->v2.in_enc_resid);
	con->v2.in_iter.count -= resid;
	set_in_skip(con, resid + con->v2.in_enc_resid);
	con->v2.in_state = IN_S_FINISH_SKIP;
}

static void revoke_at_handle_epilogue(struct ceph_connection *con)
{
	int resid;

	resid = iov_iter_count(&con->v2.in_iter);
	WARN_ON(!resid);

	dout("%s con %p resid %d\n", __func__, con, resid);
	con->v2.in_iter.count -= resid;
	set_in_skip(con, resid);
	con->v2.in_state = IN_S_FINISH_SKIP;
}

void ceph_con_v2_revoke_incoming(struct ceph_connection *con)
{
	switch (con->v2.in_state) {
	case IN_S_PREPARE_READ_DATA:
		revoke_at_prepare_read_data(con);
		break;
	case IN_S_PREPARE_READ_DATA_CONT:
		revoke_at_prepare_read_data_cont(con);
		break;
	case IN_S_PREPARE_READ_ENC_PAGE:
		revoke_at_prepare_read_enc_page(con);
		break;
	case IN_S_HANDLE_EPILOGUE:
		revoke_at_handle_epilogue(con);
		break;
	default:
		WARN(1, "bad in_state %d", con->v2.in_state);
		break;
	}
}

bool ceph_con_v2_opened(struct ceph_connection *con)
{
	return con->v2.peer_global_seq;
}

void ceph_con_v2_reset_session(struct ceph_connection *con)
{
	con->v2.client_cookie = 0;
	con->v2.server_cookie = 0;
	con->v2.global_seq = 0;
	con->v2.connect_seq = 0;
	con->v2.peer_global_seq = 0;
}

void ceph_con_v2_reset_protocol(struct ceph_connection *con)
{
	iov_iter_truncate(&con->v2.in_iter, 0);
	iov_iter_truncate(&con->v2.out_iter, 0);
	con->v2.out_zero = 0;

	clear_in_sign_kvecs(con);
	clear_out_sign_kvecs(con);
	free_conn_bufs(con);

	if (con->v2.in_enc_pages) {
		WARN_ON(!con->v2.in_enc_page_cnt);
		ceph_release_page_vector(con->v2.in_enc_pages,
					 con->v2.in_enc_page_cnt);
		con->v2.in_enc_pages = NULL;
		con->v2.in_enc_page_cnt = 0;
	}
	if (con->v2.out_enc_pages) {
		WARN_ON(!con->v2.out_enc_page_cnt);
		ceph_release_page_vector(con->v2.out_enc_pages,
					 con->v2.out_enc_page_cnt);
		con->v2.out_enc_pages = NULL;
		con->v2.out_enc_page_cnt = 0;
	}

	con->v2.con_mode = CEPH_CON_MODE_UNKNOWN;
	memzero_explicit(&con->v2.in_gcm_nonce, CEPH_GCM_IV_LEN);
	memzero_explicit(&con->v2.out_gcm_nonce, CEPH_GCM_IV_LEN);

	if (con->v2.hmac_tfm) {
		crypto_free_shash(con->v2.hmac_tfm);
		con->v2.hmac_tfm = NULL;
	}
	if (con->v2.gcm_req) {
		aead_request_free(con->v2.gcm_req);
		con->v2.gcm_req = NULL;
	}
	if (con->v2.gcm_tfm) {
		crypto_free_aead(con->v2.gcm_tfm);
		con->v2.gcm_tfm = NULL;
	}
}
