/*
 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
 *
 * Copyright (c) 2012, Intel Corporation.
 *
 *   Author: Zach Brown <zab@zabbo.net>
 *   Author: Peter J. Braam <braam@clusterfs.com>
 *   Author: Phil Schwan <phil@clusterfs.com>
 *   Author: Eric Barton <eric@bartonsoftware.com>
 *
 *   This file is part of Portals, http://www.sf.net/projects/sandiaportals/
 *
 *   Portals is free software; you can redistribute it and/or
 *   modify it under the terms of version 2 of the GNU General Public
 *   License as published by the Free Software Foundation.
 *
 *   Portals is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 */

#include "socklnd.h"

/*
 * Protocol entries :
 *   pro_send_hello       : send hello message
 *   pro_recv_hello       : receive hello message
 *   pro_pack	     : pack message header
 *   pro_unpack	   : unpack message header
 *   pro_queue_tx_zcack() : Called holding BH lock: kss_lock
 *			  return 1 if ACK is piggybacked, otherwise return 0
 *   pro_queue_tx_msg()   : Called holding BH lock: kss_lock
 *			  return the ACK that piggybacked by my message, or NULL
 *   pro_handle_zcreq()   : handler of incoming ZC-REQ
 *   pro_handle_zcack()   : handler of incoming ZC-ACK
 *   pro_match_tx()       : Called holding glock
 */

static struct ksock_tx *
ksocknal_queue_tx_msg_v1(struct ksock_conn *conn, struct ksock_tx *tx_msg)
{
	/* V1.x, just enqueue it */
	list_add_tail(&tx_msg->tx_list, &conn->ksnc_tx_queue);
	return NULL;
}

void
ksocknal_next_tx_carrier(struct ksock_conn *conn)
{
	struct ksock_tx *tx = conn->ksnc_tx_carrier;

	/* Called holding BH lock: conn->ksnc_scheduler->kss_lock */
	LASSERT(!list_empty(&conn->ksnc_tx_queue));
	LASSERT(tx);

	/* Next TX that can carry ZC-ACK or LNet message */
	if (tx->tx_list.next == &conn->ksnc_tx_queue) {
		/* no more packets queued */
		conn->ksnc_tx_carrier = NULL;
	} else {
		conn->ksnc_tx_carrier = list_next_entry(tx, tx_list);
		LASSERT(conn->ksnc_tx_carrier->tx_msg.ksm_type == tx->tx_msg.ksm_type);
	}
}

static int
ksocknal_queue_tx_zcack_v2(struct ksock_conn *conn,
			   struct ksock_tx *tx_ack, __u64 cookie)
{
	struct ksock_tx *tx = conn->ksnc_tx_carrier;

	LASSERT(!tx_ack ||
		tx_ack->tx_msg.ksm_type == KSOCK_MSG_NOOP);

	/*
	 * Enqueue or piggyback tx_ack / cookie
	 * . no tx can piggyback cookie of tx_ack (or cookie), just
	 *   enqueue the tx_ack (if tx_ack != NUL) and return NULL.
	 * . There is tx can piggyback cookie of tx_ack (or cookie),
	 *   piggyback the cookie and return the tx.
	 */
	if (!tx) {
		if (tx_ack) {
			list_add_tail(&tx_ack->tx_list,
				      &conn->ksnc_tx_queue);
			conn->ksnc_tx_carrier = tx_ack;
		}
		return 0;
	}

	if (tx->tx_msg.ksm_type == KSOCK_MSG_NOOP) {
		/* tx is noop zc-ack, can't piggyback zc-ack cookie */
		if (tx_ack)
			list_add_tail(&tx_ack->tx_list,
				      &conn->ksnc_tx_queue);
		return 0;
	}

	LASSERT(tx->tx_msg.ksm_type == KSOCK_MSG_LNET);
	LASSERT(!tx->tx_msg.ksm_zc_cookies[1]);

	if (tx_ack)
		cookie = tx_ack->tx_msg.ksm_zc_cookies[1];

	/* piggyback the zc-ack cookie */
	tx->tx_msg.ksm_zc_cookies[1] = cookie;
	/* move on to the next TX which can carry cookie */
	ksocknal_next_tx_carrier(conn);

	return 1;
}

static struct ksock_tx *
ksocknal_queue_tx_msg_v2(struct ksock_conn *conn, struct ksock_tx *tx_msg)
{
	struct ksock_tx *tx  = conn->ksnc_tx_carrier;

	/*
	 * Enqueue tx_msg:
	 * . If there is no NOOP on the connection, just enqueue
	 *   tx_msg and return NULL
	 * . If there is NOOP on the connection, piggyback the cookie
	 *   and replace the NOOP tx, and return the NOOP tx.
	 */
	if (!tx) { /* nothing on queue */
		list_add_tail(&tx_msg->tx_list, &conn->ksnc_tx_queue);
		conn->ksnc_tx_carrier = tx_msg;
		return NULL;
	}

	if (tx->tx_msg.ksm_type == KSOCK_MSG_LNET) { /* nothing to carry */
		list_add_tail(&tx_msg->tx_list, &conn->ksnc_tx_queue);
		return NULL;
	}

	LASSERT(tx->tx_msg.ksm_type == KSOCK_MSG_NOOP);

	/* There is a noop zc-ack can be piggybacked */
	tx_msg->tx_msg.ksm_zc_cookies[1] = tx->tx_msg.ksm_zc_cookies[1];
	ksocknal_next_tx_carrier(conn);

	/* use new_tx to replace the noop zc-ack packet */
	list_add(&tx_msg->tx_list, &tx->tx_list);
	list_del(&tx->tx_list);

	return tx;
}

static int
ksocknal_queue_tx_zcack_v3(struct ksock_conn *conn,
			   struct ksock_tx *tx_ack, __u64 cookie)
{
	struct ksock_tx *tx;

	if (conn->ksnc_type != SOCKLND_CONN_ACK)
		return ksocknal_queue_tx_zcack_v2(conn, tx_ack, cookie);

	/* non-blocking ZC-ACK (to router) */
	LASSERT(!tx_ack ||
		tx_ack->tx_msg.ksm_type == KSOCK_MSG_NOOP);

	tx = conn->ksnc_tx_carrier;
	if (!tx) {
		if (tx_ack) {
			list_add_tail(&tx_ack->tx_list,
				      &conn->ksnc_tx_queue);
			conn->ksnc_tx_carrier = tx_ack;
		}
		return 0;
	}

	/* conn->ksnc_tx_carrier */

	if (tx_ack)
		cookie = tx_ack->tx_msg.ksm_zc_cookies[1];

	if (cookie == SOCKNAL_KEEPALIVE_PING) /* ignore keepalive PING */
		return 1;

	if (tx->tx_msg.ksm_zc_cookies[1] == SOCKNAL_KEEPALIVE_PING) {
		/* replace the keepalive PING with a real ACK */
		LASSERT(!tx->tx_msg.ksm_zc_cookies[0]);
		tx->tx_msg.ksm_zc_cookies[1] = cookie;
		return 1;
	}

	if (cookie == tx->tx_msg.ksm_zc_cookies[0] ||
	    cookie == tx->tx_msg.ksm_zc_cookies[1]) {
		CWARN("%s: duplicated ZC cookie: %llu\n",
		      libcfs_id2str(conn->ksnc_peer->ksnp_id), cookie);
		return 1; /* XXX return error in the future */
	}

	if (!tx->tx_msg.ksm_zc_cookies[0]) {
		/* NOOP tx has only one ZC-ACK cookie, can carry at least one more */
		if (tx->tx_msg.ksm_zc_cookies[1] > cookie) {
			tx->tx_msg.ksm_zc_cookies[0] = tx->tx_msg.ksm_zc_cookies[1];
			tx->tx_msg.ksm_zc_cookies[1] = cookie;
		} else {
			tx->tx_msg.ksm_zc_cookies[0] = cookie;
		}

		if (tx->tx_msg.ksm_zc_cookies[0] - tx->tx_msg.ksm_zc_cookies[1] > 2) {
			/* not likely to carry more ACKs, skip it to simplify logic */
			ksocknal_next_tx_carrier(conn);
		}

		return 1;
	}

	/* takes two or more cookies already */

	if (tx->tx_msg.ksm_zc_cookies[0] > tx->tx_msg.ksm_zc_cookies[1]) {
		__u64   tmp = 0;

		/* two separated cookies: (a+2, a) or (a+1, a) */
		LASSERT(tx->tx_msg.ksm_zc_cookies[0] -
			 tx->tx_msg.ksm_zc_cookies[1] <= 2);

		if (tx->tx_msg.ksm_zc_cookies[0] -
		    tx->tx_msg.ksm_zc_cookies[1] == 2) {
			if (cookie == tx->tx_msg.ksm_zc_cookies[1] + 1)
				tmp = cookie;
		} else if (cookie == tx->tx_msg.ksm_zc_cookies[1] - 1) {
			tmp = tx->tx_msg.ksm_zc_cookies[1];
		} else if (cookie == tx->tx_msg.ksm_zc_cookies[0] + 1) {
			tmp = tx->tx_msg.ksm_zc_cookies[0];
		}

		if (tmp) {
			/* range of cookies */
			tx->tx_msg.ksm_zc_cookies[0] = tmp - 1;
			tx->tx_msg.ksm_zc_cookies[1] = tmp + 1;
			return 1;
		}

	} else {
		/* ksm_zc_cookies[0] < ksm_zc_cookies[1], it is range of cookies */
		if (cookie >= tx->tx_msg.ksm_zc_cookies[0] &&
		    cookie <= tx->tx_msg.ksm_zc_cookies[1]) {
			CWARN("%s: duplicated ZC cookie: %llu\n",
			      libcfs_id2str(conn->ksnc_peer->ksnp_id), cookie);
			return 1; /* XXX: return error in the future */
		}

		if (cookie == tx->tx_msg.ksm_zc_cookies[1] + 1) {
			tx->tx_msg.ksm_zc_cookies[1] = cookie;
			return 1;
		}

		if (cookie == tx->tx_msg.ksm_zc_cookies[0] - 1) {
			tx->tx_msg.ksm_zc_cookies[0] = cookie;
			return 1;
		}
	}

	/* failed to piggyback ZC-ACK */
	if (tx_ack) {
		list_add_tail(&tx_ack->tx_list, &conn->ksnc_tx_queue);
		/* the next tx can piggyback at least 1 ACK */
		ksocknal_next_tx_carrier(conn);
	}

	return 0;
}

static int
ksocknal_match_tx(struct ksock_conn *conn, struct ksock_tx *tx, int nonblk)
{
	int nob;

#if SOCKNAL_VERSION_DEBUG
	if (!*ksocknal_tunables.ksnd_typed_conns)
		return SOCKNAL_MATCH_YES;
#endif

	if (!tx || !tx->tx_lnetmsg) {
		/* noop packet */
		nob = offsetof(ksock_msg_t, ksm_u);
	} else {
		nob = tx->tx_lnetmsg->msg_len +
		      ((conn->ksnc_proto == &ksocknal_protocol_v1x) ?
		       sizeof(lnet_hdr_t) : sizeof(ksock_msg_t));
	}

	/* default checking for typed connection */
	switch (conn->ksnc_type) {
	default:
		CERROR("ksnc_type bad: %u\n", conn->ksnc_type);
		LBUG();
	case SOCKLND_CONN_ANY:
		return SOCKNAL_MATCH_YES;

	case SOCKLND_CONN_BULK_IN:
		return SOCKNAL_MATCH_MAY;

	case SOCKLND_CONN_BULK_OUT:
		if (nob < *ksocknal_tunables.ksnd_min_bulk)
			return SOCKNAL_MATCH_MAY;
		else
			return SOCKNAL_MATCH_YES;

	case SOCKLND_CONN_CONTROL:
		if (nob >= *ksocknal_tunables.ksnd_min_bulk)
			return SOCKNAL_MATCH_MAY;
		else
			return SOCKNAL_MATCH_YES;
	}
}

static int
ksocknal_match_tx_v3(struct ksock_conn *conn, struct ksock_tx *tx, int nonblk)
{
	int nob;

	if (!tx || !tx->tx_lnetmsg)
		nob = offsetof(ksock_msg_t, ksm_u);
	else
		nob = tx->tx_lnetmsg->msg_len + sizeof(ksock_msg_t);

	switch (conn->ksnc_type) {
	default:
		CERROR("ksnc_type bad: %u\n", conn->ksnc_type);
		LBUG();
	case SOCKLND_CONN_ANY:
		return SOCKNAL_MATCH_NO;

	case SOCKLND_CONN_ACK:
		if (nonblk)
			return SOCKNAL_MATCH_YES;
		else if (!tx || !tx->tx_lnetmsg)
			return SOCKNAL_MATCH_MAY;
		else
			return SOCKNAL_MATCH_NO;

	case SOCKLND_CONN_BULK_OUT:
		if (nonblk)
			return SOCKNAL_MATCH_NO;
		else if (nob < *ksocknal_tunables.ksnd_min_bulk)
			return SOCKNAL_MATCH_MAY;
		else
			return SOCKNAL_MATCH_YES;

	case SOCKLND_CONN_CONTROL:
		if (nonblk)
			return SOCKNAL_MATCH_NO;
		else if (nob >= *ksocknal_tunables.ksnd_min_bulk)
			return SOCKNAL_MATCH_MAY;
		else
			return SOCKNAL_MATCH_YES;
	}
}

/* (Sink) handle incoming ZC request from sender */
static int
ksocknal_handle_zcreq(struct ksock_conn *c, __u64 cookie, int remote)
{
	struct ksock_peer *peer = c->ksnc_peer;
	struct ksock_conn *conn;
	struct ksock_tx *tx;
	int rc;

	read_lock(&ksocknal_data.ksnd_global_lock);

	conn = ksocknal_find_conn_locked(peer, NULL, !!remote);
	if (conn) {
		struct ksock_sched *sched = conn->ksnc_scheduler;

		LASSERT(conn->ksnc_proto->pro_queue_tx_zcack);

		spin_lock_bh(&sched->kss_lock);

		rc = conn->ksnc_proto->pro_queue_tx_zcack(conn, NULL, cookie);

		spin_unlock_bh(&sched->kss_lock);

		if (rc) { /* piggybacked */
			read_unlock(&ksocknal_data.ksnd_global_lock);
			return 0;
		}
	}

	read_unlock(&ksocknal_data.ksnd_global_lock);

	/* ACK connection is not ready, or can't piggyback the ACK */
	tx = ksocknal_alloc_tx_noop(cookie, !!remote);
	if (!tx)
		return -ENOMEM;

	rc = ksocknal_launch_packet(peer->ksnp_ni, tx, peer->ksnp_id);
	if (!rc)
		return 0;

	ksocknal_free_tx(tx);
	return rc;
}

/* (Sender) handle ZC_ACK from sink */
static int
ksocknal_handle_zcack(struct ksock_conn *conn, __u64 cookie1, __u64 cookie2)
{
	struct ksock_peer *peer = conn->ksnc_peer;
	struct ksock_tx *tx;
	struct ksock_tx *temp;
	struct ksock_tx *tmp;
	LIST_HEAD(zlist);
	int count;

	if (!cookie1)
		cookie1 = cookie2;

	count = (cookie1 > cookie2) ? 2 : (cookie2 - cookie1 + 1);

	if (cookie2 == SOCKNAL_KEEPALIVE_PING &&
	    conn->ksnc_proto == &ksocknal_protocol_v3x) {
		/* keepalive PING for V3.x, just ignore it */
		return count == 1 ? 0 : -EPROTO;
	}

	spin_lock(&peer->ksnp_lock);

	list_for_each_entry_safe(tx, tmp, &peer->ksnp_zc_req_list,
				 tx_zc_list) {
		__u64 c = tx->tx_msg.ksm_zc_cookies[0];

		if (c == cookie1 || c == cookie2 || (cookie1 < c && c < cookie2)) {
			tx->tx_msg.ksm_zc_cookies[0] = 0;
			list_del(&tx->tx_zc_list);
			list_add(&tx->tx_zc_list, &zlist);

			if (!--count)
				break;
		}
	}

	spin_unlock(&peer->ksnp_lock);

	list_for_each_entry_safe(tx, temp, &zlist, tx_zc_list) {
		list_del(&tx->tx_zc_list);
		ksocknal_tx_decref(tx);
	}

	return !count ? 0 : -EPROTO;
}

static int
ksocknal_send_hello_v1(struct ksock_conn *conn, ksock_hello_msg_t *hello)
{
	struct socket *sock = conn->ksnc_sock;
	lnet_hdr_t *hdr;
	lnet_magicversion_t *hmv;
	int rc;
	int i;

	CLASSERT(sizeof(lnet_magicversion_t) == offsetof(lnet_hdr_t, src_nid));

	LIBCFS_ALLOC(hdr, sizeof(*hdr));
	if (!hdr) {
		CERROR("Can't allocate lnet_hdr_t\n");
		return -ENOMEM;
	}

	hmv = (lnet_magicversion_t *)&hdr->dest_nid;

	/*
	 * Re-organize V2.x message header to V1.x (lnet_hdr_t)
	 * header and send out
	 */
	hmv->magic         = cpu_to_le32(LNET_PROTO_TCP_MAGIC);
	hmv->version_major = cpu_to_le16(KSOCK_PROTO_V1_MAJOR);
	hmv->version_minor = cpu_to_le16(KSOCK_PROTO_V1_MINOR);

	if (the_lnet.ln_testprotocompat) {
		/* single-shot proto check */
		LNET_LOCK();
		if (the_lnet.ln_testprotocompat & 1) {
			hmv->version_major++;   /* just different! */
			the_lnet.ln_testprotocompat &= ~1;
		}
		if (the_lnet.ln_testprotocompat & 2) {
			hmv->magic = LNET_PROTO_MAGIC;
			the_lnet.ln_testprotocompat &= ~2;
		}
		LNET_UNLOCK();
	}

	hdr->src_nid = cpu_to_le64(hello->kshm_src_nid);
	hdr->src_pid = cpu_to_le32(hello->kshm_src_pid);
	hdr->type = cpu_to_le32(LNET_MSG_HELLO);
	hdr->payload_length = cpu_to_le32(hello->kshm_nips * sizeof(__u32));
	hdr->msg.hello.type = cpu_to_le32(hello->kshm_ctype);
	hdr->msg.hello.incarnation = cpu_to_le64(hello->kshm_src_incarnation);

	rc = lnet_sock_write(sock, hdr, sizeof(*hdr), lnet_acceptor_timeout());
	if (rc) {
		CNETERR("Error %d sending HELLO hdr to %pI4h/%d\n",
			rc, &conn->ksnc_ipaddr, conn->ksnc_port);
		goto out;
	}

	if (!hello->kshm_nips)
		goto out;

	for (i = 0; i < (int)hello->kshm_nips; i++)
		hello->kshm_ips[i] = __cpu_to_le32(hello->kshm_ips[i]);

	rc = lnet_sock_write(sock, hello->kshm_ips,
			     hello->kshm_nips * sizeof(__u32),
			     lnet_acceptor_timeout());
	if (rc) {
		CNETERR("Error %d sending HELLO payload (%d) to %pI4h/%d\n",
			rc, hello->kshm_nips,
			&conn->ksnc_ipaddr, conn->ksnc_port);
	}
out:
	LIBCFS_FREE(hdr, sizeof(*hdr));

	return rc;
}

static int
ksocknal_send_hello_v2(struct ksock_conn *conn, ksock_hello_msg_t *hello)
{
	struct socket *sock = conn->ksnc_sock;
	int rc;

	hello->kshm_magic   = LNET_PROTO_MAGIC;
	hello->kshm_version = conn->ksnc_proto->pro_version;

	if (the_lnet.ln_testprotocompat) {
		/* single-shot proto check */
		LNET_LOCK();
		if (the_lnet.ln_testprotocompat & 1) {
			hello->kshm_version++;   /* just different! */
			the_lnet.ln_testprotocompat &= ~1;
		}
		LNET_UNLOCK();
	}

	rc = lnet_sock_write(sock, hello, offsetof(ksock_hello_msg_t, kshm_ips),
			     lnet_acceptor_timeout());
	if (rc) {
		CNETERR("Error %d sending HELLO hdr to %pI4h/%d\n",
			rc, &conn->ksnc_ipaddr, conn->ksnc_port);
		return rc;
	}

	if (!hello->kshm_nips)
		return 0;

	rc = lnet_sock_write(sock, hello->kshm_ips,
			     hello->kshm_nips * sizeof(__u32),
			     lnet_acceptor_timeout());
	if (rc) {
		CNETERR("Error %d sending HELLO payload (%d) to %pI4h/%d\n",
			rc, hello->kshm_nips,
			&conn->ksnc_ipaddr, conn->ksnc_port);
	}

	return rc;
}

static int
ksocknal_recv_hello_v1(struct ksock_conn *conn, ksock_hello_msg_t *hello,
		       int timeout)
{
	struct socket *sock = conn->ksnc_sock;
	lnet_hdr_t *hdr;
	int rc;
	int i;

	LIBCFS_ALLOC(hdr, sizeof(*hdr));
	if (!hdr) {
		CERROR("Can't allocate lnet_hdr_t\n");
		return -ENOMEM;
	}

	rc = lnet_sock_read(sock, &hdr->src_nid,
			    sizeof(*hdr) - offsetof(lnet_hdr_t, src_nid),
			    timeout);
	if (rc) {
		CERROR("Error %d reading rest of HELLO hdr from %pI4h\n",
		       rc, &conn->ksnc_ipaddr);
		LASSERT(rc < 0 && rc != -EALREADY);
		goto out;
	}

	/* ...and check we got what we expected */
	if (hdr->type != cpu_to_le32(LNET_MSG_HELLO)) {
		CERROR("Expecting a HELLO hdr, but got type %d from %pI4h\n",
		       le32_to_cpu(hdr->type),
		       &conn->ksnc_ipaddr);
		rc = -EPROTO;
		goto out;
	}

	hello->kshm_src_nid         = le64_to_cpu(hdr->src_nid);
	hello->kshm_src_pid         = le32_to_cpu(hdr->src_pid);
	hello->kshm_src_incarnation = le64_to_cpu(hdr->msg.hello.incarnation);
	hello->kshm_ctype           = le32_to_cpu(hdr->msg.hello.type);
	hello->kshm_nips            = le32_to_cpu(hdr->payload_length) /
						  sizeof(__u32);

	if (hello->kshm_nips > LNET_MAX_INTERFACES) {
		CERROR("Bad nips %d from ip %pI4h\n",
		       hello->kshm_nips, &conn->ksnc_ipaddr);
		rc = -EPROTO;
		goto out;
	}

	if (!hello->kshm_nips)
		goto out;

	rc = lnet_sock_read(sock, hello->kshm_ips,
			    hello->kshm_nips * sizeof(__u32), timeout);
	if (rc) {
		CERROR("Error %d reading IPs from ip %pI4h\n",
		       rc, &conn->ksnc_ipaddr);
		LASSERT(rc < 0 && rc != -EALREADY);
		goto out;
	}

	for (i = 0; i < (int)hello->kshm_nips; i++) {
		hello->kshm_ips[i] = __le32_to_cpu(hello->kshm_ips[i]);

		if (!hello->kshm_ips[i]) {
			CERROR("Zero IP[%d] from ip %pI4h\n",
			       i, &conn->ksnc_ipaddr);
			rc = -EPROTO;
			break;
		}
	}
out:
	LIBCFS_FREE(hdr, sizeof(*hdr));

	return rc;
}

static int
ksocknal_recv_hello_v2(struct ksock_conn *conn, ksock_hello_msg_t *hello, int timeout)
{
	struct socket *sock = conn->ksnc_sock;
	int rc;
	int i;

	if (hello->kshm_magic == LNET_PROTO_MAGIC)
		conn->ksnc_flip = 0;
	else
		conn->ksnc_flip = 1;

	rc = lnet_sock_read(sock, &hello->kshm_src_nid,
			    offsetof(ksock_hello_msg_t, kshm_ips) -
				     offsetof(ksock_hello_msg_t, kshm_src_nid),
			    timeout);
	if (rc) {
		CERROR("Error %d reading HELLO from %pI4h\n",
		       rc, &conn->ksnc_ipaddr);
		LASSERT(rc < 0 && rc != -EALREADY);
		return rc;
	}

	if (conn->ksnc_flip) {
		__swab32s(&hello->kshm_src_pid);
		__swab64s(&hello->kshm_src_nid);
		__swab32s(&hello->kshm_dst_pid);
		__swab64s(&hello->kshm_dst_nid);
		__swab64s(&hello->kshm_src_incarnation);
		__swab64s(&hello->kshm_dst_incarnation);
		__swab32s(&hello->kshm_ctype);
		__swab32s(&hello->kshm_nips);
	}

	if (hello->kshm_nips > LNET_MAX_INTERFACES) {
		CERROR("Bad nips %d from ip %pI4h\n",
		       hello->kshm_nips, &conn->ksnc_ipaddr);
		return -EPROTO;
	}

	if (!hello->kshm_nips)
		return 0;

	rc = lnet_sock_read(sock, hello->kshm_ips,
			    hello->kshm_nips * sizeof(__u32), timeout);
	if (rc) {
		CERROR("Error %d reading IPs from ip %pI4h\n",
		       rc, &conn->ksnc_ipaddr);
		LASSERT(rc < 0 && rc != -EALREADY);
		return rc;
	}

	for (i = 0; i < (int)hello->kshm_nips; i++) {
		if (conn->ksnc_flip)
			__swab32s(&hello->kshm_ips[i]);

		if (!hello->kshm_ips[i]) {
			CERROR("Zero IP[%d] from ip %pI4h\n",
			       i, &conn->ksnc_ipaddr);
			return -EPROTO;
		}
	}

	return 0;
}

static void
ksocknal_pack_msg_v1(struct ksock_tx *tx)
{
	/* V1.x has no KSOCK_MSG_NOOP */
	LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP);
	LASSERT(tx->tx_lnetmsg);

	tx->tx_iov[0].iov_base = &tx->tx_lnetmsg->msg_hdr;
	tx->tx_iov[0].iov_len  = sizeof(lnet_hdr_t);

	tx->tx_nob = tx->tx_lnetmsg->msg_len + sizeof(lnet_hdr_t);
	tx->tx_resid = tx->tx_lnetmsg->msg_len + sizeof(lnet_hdr_t);
}

static void
ksocknal_pack_msg_v2(struct ksock_tx *tx)
{
	tx->tx_iov[0].iov_base = &tx->tx_msg;

	if (tx->tx_lnetmsg) {
		LASSERT(tx->tx_msg.ksm_type != KSOCK_MSG_NOOP);

		tx->tx_msg.ksm_u.lnetmsg.ksnm_hdr = tx->tx_lnetmsg->msg_hdr;
		tx->tx_iov[0].iov_len = sizeof(ksock_msg_t);
		tx->tx_nob = sizeof(ksock_msg_t) + tx->tx_lnetmsg->msg_len;
		tx->tx_resid = sizeof(ksock_msg_t) + tx->tx_lnetmsg->msg_len;
	} else {
		LASSERT(tx->tx_msg.ksm_type == KSOCK_MSG_NOOP);

		tx->tx_iov[0].iov_len = offsetof(ksock_msg_t, ksm_u.lnetmsg.ksnm_hdr);
		tx->tx_nob = offsetof(ksock_msg_t,  ksm_u.lnetmsg.ksnm_hdr);
		tx->tx_resid = offsetof(ksock_msg_t,  ksm_u.lnetmsg.ksnm_hdr);
	}
	/* Don't checksum before start sending, because packet can be piggybacked with ACK */
}

static void
ksocknal_unpack_msg_v1(ksock_msg_t *msg)
{
	msg->ksm_csum = 0;
	msg->ksm_type = KSOCK_MSG_LNET;
	msg->ksm_zc_cookies[0] = 0;
	msg->ksm_zc_cookies[1] = 0;
}

static void
ksocknal_unpack_msg_v2(ksock_msg_t *msg)
{
	return;  /* Do nothing */
}

struct ksock_proto ksocknal_protocol_v1x = {
	.pro_version        = KSOCK_PROTO_V1,
	.pro_send_hello     = ksocknal_send_hello_v1,
	.pro_recv_hello     = ksocknal_recv_hello_v1,
	.pro_pack           = ksocknal_pack_msg_v1,
	.pro_unpack         = ksocknal_unpack_msg_v1,
	.pro_queue_tx_msg   = ksocknal_queue_tx_msg_v1,
	.pro_handle_zcreq   = NULL,
	.pro_handle_zcack   = NULL,
	.pro_queue_tx_zcack = NULL,
	.pro_match_tx       = ksocknal_match_tx
};

struct ksock_proto ksocknal_protocol_v2x = {
	.pro_version        = KSOCK_PROTO_V2,
	.pro_send_hello     = ksocknal_send_hello_v2,
	.pro_recv_hello     = ksocknal_recv_hello_v2,
	.pro_pack           = ksocknal_pack_msg_v2,
	.pro_unpack         = ksocknal_unpack_msg_v2,
	.pro_queue_tx_msg   = ksocknal_queue_tx_msg_v2,
	.pro_queue_tx_zcack = ksocknal_queue_tx_zcack_v2,
	.pro_handle_zcreq   = ksocknal_handle_zcreq,
	.pro_handle_zcack   = ksocknal_handle_zcack,
	.pro_match_tx       = ksocknal_match_tx
};

struct ksock_proto ksocknal_protocol_v3x = {
	.pro_version        = KSOCK_PROTO_V3,
	.pro_send_hello     = ksocknal_send_hello_v2,
	.pro_recv_hello     = ksocknal_recv_hello_v2,
	.pro_pack           = ksocknal_pack_msg_v2,
	.pro_unpack         = ksocknal_unpack_msg_v2,
	.pro_queue_tx_msg   = ksocknal_queue_tx_msg_v2,
	.pro_queue_tx_zcack = ksocknal_queue_tx_zcack_v3,
	.pro_handle_zcreq   = ksocknal_handle_zcreq,
	.pro_handle_zcack   = ksocknal_handle_zcack,
	.pro_match_tx       = ksocknal_match_tx_v3
};
