/*
 * 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.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with Portals; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#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 ksock_tx_t *
ksocknal_queue_tx_msg_v1(ksock_conn_t *conn, ksock_tx_t *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(ksock_conn_t *conn)
{
	ksock_tx_t     *tx = conn->ksnc_tx_carrier;

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

	/* 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_entry(tx->tx_list.next,
						       ksock_tx_t, tx_list);
		LASSERT (conn->ksnc_tx_carrier->tx_msg.ksm_type == tx->tx_msg.ksm_type);
	}
}

static int
ksocknal_queue_tx_zcack_v2(ksock_conn_t *conn,
			   ksock_tx_t *tx_ack, __u64 cookie)
{
	ksock_tx_t *tx = conn->ksnc_tx_carrier;

	LASSERT (tx_ack == NULL ||
		 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 == NULL) {
		if (tx_ack != NULL) {
			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 != NULL)
			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] == 0);

	if (tx_ack != NULL)
		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 ksock_tx_t *
ksocknal_queue_tx_msg_v2(ksock_conn_t *conn, ksock_tx_t *tx_msg)
{
	ksock_tx_t  *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 == NULL) { /* 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(ksock_conn_t *conn,
			   ksock_tx_t *tx_ack, __u64 cookie)
{
	ksock_tx_t *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 == NULL ||
		 tx_ack->tx_msg.ksm_type == KSOCK_MSG_NOOP);

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

	/* conn->ksnc_tx_carrier != NULL */

	if (tx_ack != NULL)
		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] == 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: "LPU64"\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] == 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 != 0) {
			/* 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: "LPU64"\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 != NULL) {
		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(ksock_conn_t *conn, ksock_tx_t *tx, int nonblk)
{
	int nob;

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

	if (tx == NULL || tx->tx_lnetmsg == NULL) {
		/* 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(ksock_conn_t *conn, ksock_tx_t *tx, int nonblk)
{
	int nob;

	if (tx == NULL || tx->tx_lnetmsg == NULL)
		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 == NULL || tx->tx_lnetmsg == NULL)
			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(ksock_conn_t *c, __u64 cookie, int remote)
{
	ksock_peer_t   *peer = c->ksnc_peer;
	ksock_conn_t   *conn;
	ksock_tx_t     *tx;
	int	     rc;

	read_lock(&ksocknal_data.ksnd_global_lock);

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

		LASSERT(conn->ksnc_proto->pro_queue_tx_zcack != NULL);

		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 == NULL)
		return -ENOMEM;

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

	ksocknal_free_tx(tx);
	return rc;
}

/* (Sender) handle ZC_ACK from sink */
static int
ksocknal_handle_zcack(ksock_conn_t *conn, __u64 cookie1, __u64 cookie2)
{
	ksock_peer_t      *peer = conn->ksnc_peer;
	ksock_tx_t	*tx;
	ksock_tx_t	*tmp;
	LIST_HEAD     (zlist);
	int		count;

	if (cookie1 == 0)
		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 == 0)
				break;
		}
	}

	spin_unlock(&peer->ksnp_lock);

	while (!list_empty(&zlist)) {
		tx = list_entry(zlist.next, ksock_tx_t, tx_zc_list);
		list_del(&tx->tx_zc_list);
		ksocknal_tx_decref(tx);
	}

	return count == 0 ? 0 : -EPROTO;
}

static int
ksocknal_send_hello_v1 (ksock_conn_t *conn, ksock_hello_msg_t *hello)
{
	socket_t	*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 == NULL) {
		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 != 0) {
		/* single-shot proto check */
		LNET_LOCK();
		if ((the_lnet.ln_testprotocompat & 1) != 0) {
			hmv->version_major++;   /* just different! */
			the_lnet.ln_testprotocompat &= ~1;
		}
		if ((the_lnet.ln_testprotocompat & 2) != 0) {
			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 = libcfs_sock_write(sock, hdr, sizeof(*hdr),lnet_acceptor_timeout());

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

	if (hello->kshm_nips == 0)
		goto out;

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

	rc = libcfs_sock_write(sock, hello->kshm_ips,
			       hello->kshm_nips * sizeof(__u32),
			       lnet_acceptor_timeout());
	if (rc != 0) {
		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 (ksock_conn_t *conn, ksock_hello_msg_t *hello)
{
	socket_t   *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 != 0) {
		/* single-shot proto check */
		LNET_LOCK();
		if ((the_lnet.ln_testprotocompat & 1) != 0) {
			hello->kshm_version++;   /* just different! */
			the_lnet.ln_testprotocompat &= ~1;
		}
		LNET_UNLOCK();
	}

	rc = libcfs_sock_write(sock, hello, offsetof(ksock_hello_msg_t, kshm_ips),
			       lnet_acceptor_timeout());

	if (rc != 0) {
		CNETERR("Error %d sending HELLO hdr to %pI4h/%d\n",
			rc, &conn->ksnc_ipaddr, conn->ksnc_port);
		return rc;
	}

	if (hello->kshm_nips == 0)
		return 0;

	rc = libcfs_sock_write(sock, hello->kshm_ips,
			       hello->kshm_nips * sizeof(__u32),
			       lnet_acceptor_timeout());
	if (rc != 0) {
		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(ksock_conn_t *conn, ksock_hello_msg_t *hello,int timeout)
{
	socket_t	*sock = conn->ksnc_sock;
	lnet_hdr_t	  *hdr;
	int		  rc;
	int		  i;

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

	rc = libcfs_sock_read(sock, &hdr->src_nid,
			      sizeof (*hdr) - offsetof (lnet_hdr_t, src_nid),
			      timeout);
	if (rc != 0) {
		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 == 0)
		goto out;

	rc = libcfs_sock_read(sock, hello->kshm_ips,
			      hello->kshm_nips * sizeof(__u32), timeout);
	if (rc != 0) {
		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] == 0) {
			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 (ksock_conn_t *conn, ksock_hello_msg_t *hello, int timeout)
{
	socket_t      *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 = libcfs_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 != 0) {
		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 == 0)
		return 0;

	rc = libcfs_sock_read(sock, hello->kshm_ips,
			      hello->kshm_nips * sizeof(__u32), timeout);
	if (rc != 0) {
		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] == 0) {
			CERROR("Zero IP[%d] from ip %pI4h\n",
			       i, &conn->ksnc_ipaddr);
			return -EPROTO;
		}
	}

	return 0;
}

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

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

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

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

	if (tx->tx_lnetmsg != NULL) {
		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_resid = tx->tx_nob = 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_resid = tx->tx_nob = 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]  = msg->ksm_zc_cookies[1]  = 0;
}

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

ksock_proto_t  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
};

ksock_proto_t  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
};

ksock_proto_t  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
};
