// SPDX-License-Identifier: GPL-2.0
/*
 *  Shared Memory Communications over RDMA (SMC-R) and RoCE
 *
 *  CLC (connection layer control) handshake over initial TCP socket to
 *  prepare for RDMA traffic
 *
 *  Copyright IBM Corp. 2016, 2018
 *
 *  Author(s):  Ursula Braun <ubraun@linux.vnet.ibm.com>
 */

#include <linux/in.h>
#include <linux/inetdevice.h>
#include <linux/if_ether.h>
#include <linux/sched/signal.h>
#include <linux/utsname.h>
#include <linux/ctype.h>

#include <net/addrconf.h>
#include <net/sock.h>
#include <net/tcp.h>

#include "smc.h"
#include "smc_core.h"
#include "smc_clc.h"
#include "smc_ib.h"
#include "smc_ism.h"
#include "smc_netlink.h"

#define SMCR_CLC_ACCEPT_CONFIRM_LEN 68
#define SMCD_CLC_ACCEPT_CONFIRM_LEN 48
#define SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 78
#define SMCR_CLC_ACCEPT_CONFIRM_LEN_V2 108
#define SMC_CLC_RECV_BUF_LEN	100

/* eye catcher "SMCR" EBCDIC for CLC messages */
static const char SMC_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xd9'};
/* eye catcher "SMCD" EBCDIC for CLC messages */
static const char SMCD_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xc4'};

static u8 smc_hostname[SMC_MAX_HOSTNAME_LEN];

struct smc_clc_eid_table {
	rwlock_t lock;
	struct list_head list;
	u8 ueid_cnt;
	u8 seid_enabled;
};

static struct smc_clc_eid_table smc_clc_eid_table;

struct smc_clc_eid_entry {
	struct list_head list;
	u8 eid[SMC_MAX_EID_LEN];
};

/* The size of a user EID is 32 characters.
 * Valid characters should be (single-byte character set) A-Z, 0-9, '.' and '-'.
 * Blanks should only be used to pad to the expected size.
 * First character must be alphanumeric.
 */
static bool smc_clc_ueid_valid(char *ueid)
{
	char *end = ueid + SMC_MAX_EID_LEN;

	while (--end >= ueid && isspace(*end))
		;
	if (end < ueid)
		return false;
	if (!isalnum(*ueid) || islower(*ueid))
		return false;
	while (ueid <= end) {
		if ((!isalnum(*ueid) || islower(*ueid)) && *ueid != '.' &&
		    *ueid != '-')
			return false;
		ueid++;
	}
	return true;
}

static int smc_clc_ueid_add(char *ueid)
{
	struct smc_clc_eid_entry *new_ueid, *tmp_ueid;
	int rc;

	if (!smc_clc_ueid_valid(ueid))
		return -EINVAL;

	/* add a new ueid entry to the ueid table if there isn't one */
	new_ueid = kzalloc(sizeof(*new_ueid), GFP_KERNEL);
	if (!new_ueid)
		return -ENOMEM;
	memcpy(new_ueid->eid, ueid, SMC_MAX_EID_LEN);

	write_lock(&smc_clc_eid_table.lock);
	if (smc_clc_eid_table.ueid_cnt >= SMC_MAX_UEID) {
		rc = -ERANGE;
		goto err_out;
	}
	list_for_each_entry(tmp_ueid, &smc_clc_eid_table.list, list) {
		if (!memcmp(tmp_ueid->eid, ueid, SMC_MAX_EID_LEN)) {
			rc = -EEXIST;
			goto err_out;
		}
	}
	list_add_tail(&new_ueid->list, &smc_clc_eid_table.list);
	smc_clc_eid_table.ueid_cnt++;
	write_unlock(&smc_clc_eid_table.lock);
	return 0;

err_out:
	write_unlock(&smc_clc_eid_table.lock);
	kfree(new_ueid);
	return rc;
}

int smc_clc_ueid_count(void)
{
	int count;

	read_lock(&smc_clc_eid_table.lock);
	count = smc_clc_eid_table.ueid_cnt;
	read_unlock(&smc_clc_eid_table.lock);

	return count;
}

int smc_nl_add_ueid(struct sk_buff *skb, struct genl_info *info)
{
	struct nlattr *nla_ueid = info->attrs[SMC_NLA_EID_TABLE_ENTRY];
	char *ueid;

	if (!nla_ueid || nla_len(nla_ueid) != SMC_MAX_EID_LEN + 1)
		return -EINVAL;
	ueid = (char *)nla_data(nla_ueid);

	return smc_clc_ueid_add(ueid);
}

/* remove one or all ueid entries from the table */
static int smc_clc_ueid_remove(char *ueid)
{
	struct smc_clc_eid_entry *lst_ueid, *tmp_ueid;
	int rc = -ENOENT;

	/* remove table entry */
	write_lock(&smc_clc_eid_table.lock);
	list_for_each_entry_safe(lst_ueid, tmp_ueid, &smc_clc_eid_table.list,
				 list) {
		if (!ueid || !memcmp(lst_ueid->eid, ueid, SMC_MAX_EID_LEN)) {
			list_del(&lst_ueid->list);
			smc_clc_eid_table.ueid_cnt--;
			kfree(lst_ueid);
			rc = 0;
		}
	}
#if IS_ENABLED(CONFIG_S390)
	if (!rc && !smc_clc_eid_table.ueid_cnt) {
		smc_clc_eid_table.seid_enabled = 1;
		rc = -EAGAIN;	/* indicate success and enabling of seid */
	}
#endif
	write_unlock(&smc_clc_eid_table.lock);
	return rc;
}

int smc_nl_remove_ueid(struct sk_buff *skb, struct genl_info *info)
{
	struct nlattr *nla_ueid = info->attrs[SMC_NLA_EID_TABLE_ENTRY];
	char *ueid;

	if (!nla_ueid || nla_len(nla_ueid) != SMC_MAX_EID_LEN + 1)
		return -EINVAL;
	ueid = (char *)nla_data(nla_ueid);

	return smc_clc_ueid_remove(ueid);
}

int smc_nl_flush_ueid(struct sk_buff *skb, struct genl_info *info)
{
	smc_clc_ueid_remove(NULL);
	return 0;
}

static int smc_nl_ueid_dumpinfo(struct sk_buff *skb, u32 portid, u32 seq,
				u32 flags, char *ueid)
{
	char ueid_str[SMC_MAX_EID_LEN + 1];
	void *hdr;

	hdr = genlmsg_put(skb, portid, seq, &smc_gen_nl_family,
			  flags, SMC_NETLINK_DUMP_UEID);
	if (!hdr)
		return -ENOMEM;
	memcpy(ueid_str, ueid, SMC_MAX_EID_LEN);
	ueid_str[SMC_MAX_EID_LEN] = 0;
	if (nla_put_string(skb, SMC_NLA_EID_TABLE_ENTRY, ueid_str)) {
		genlmsg_cancel(skb, hdr);
		return -EMSGSIZE;
	}
	genlmsg_end(skb, hdr);
	return 0;
}

static int _smc_nl_ueid_dump(struct sk_buff *skb, u32 portid, u32 seq,
			     int start_idx)
{
	struct smc_clc_eid_entry *lst_ueid;
	int idx = 0;

	read_lock(&smc_clc_eid_table.lock);
	list_for_each_entry(lst_ueid, &smc_clc_eid_table.list, list) {
		if (idx++ < start_idx)
			continue;
		if (smc_nl_ueid_dumpinfo(skb, portid, seq, NLM_F_MULTI,
					 lst_ueid->eid)) {
			--idx;
			break;
		}
	}
	read_unlock(&smc_clc_eid_table.lock);
	return idx;
}

int smc_nl_dump_ueid(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct smc_nl_dmp_ctx *cb_ctx = smc_nl_dmp_ctx(cb);
	int idx;

	idx = _smc_nl_ueid_dump(skb, NETLINK_CB(cb->skb).portid,
				cb->nlh->nlmsg_seq, cb_ctx->pos[0]);

	cb_ctx->pos[0] = idx;
	return skb->len;
}

int smc_nl_dump_seid(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct smc_nl_dmp_ctx *cb_ctx = smc_nl_dmp_ctx(cb);
	char seid_str[SMC_MAX_EID_LEN + 1];
	u8 seid_enabled;
	void *hdr;
	u8 *seid;

	if (cb_ctx->pos[0])
		return skb->len;

	hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
			  &smc_gen_nl_family, NLM_F_MULTI,
			  SMC_NETLINK_DUMP_SEID);
	if (!hdr)
		return -ENOMEM;
	if (!smc_ism_is_v2_capable())
		goto end;

	smc_ism_get_system_eid(&seid);
	memcpy(seid_str, seid, SMC_MAX_EID_LEN);
	seid_str[SMC_MAX_EID_LEN] = 0;
	if (nla_put_string(skb, SMC_NLA_SEID_ENTRY, seid_str))
		goto err;
	read_lock(&smc_clc_eid_table.lock);
	seid_enabled = smc_clc_eid_table.seid_enabled;
	read_unlock(&smc_clc_eid_table.lock);
	if (nla_put_u8(skb, SMC_NLA_SEID_ENABLED, seid_enabled))
		goto err;
end:
	genlmsg_end(skb, hdr);
	cb_ctx->pos[0]++;
	return skb->len;
err:
	genlmsg_cancel(skb, hdr);
	return -EMSGSIZE;
}

int smc_nl_enable_seid(struct sk_buff *skb, struct genl_info *info)
{
#if IS_ENABLED(CONFIG_S390)
	write_lock(&smc_clc_eid_table.lock);
	smc_clc_eid_table.seid_enabled = 1;
	write_unlock(&smc_clc_eid_table.lock);
	return 0;
#else
	return -EOPNOTSUPP;
#endif
}

int smc_nl_disable_seid(struct sk_buff *skb, struct genl_info *info)
{
	int rc = 0;

#if IS_ENABLED(CONFIG_S390)
	write_lock(&smc_clc_eid_table.lock);
	if (!smc_clc_eid_table.ueid_cnt)
		rc = -ENOENT;
	else
		smc_clc_eid_table.seid_enabled = 0;
	write_unlock(&smc_clc_eid_table.lock);
#else
	rc = -EOPNOTSUPP;
#endif
	return rc;
}

static bool _smc_clc_match_ueid(u8 *peer_ueid)
{
	struct smc_clc_eid_entry *tmp_ueid;

	list_for_each_entry(tmp_ueid, &smc_clc_eid_table.list, list) {
		if (!memcmp(tmp_ueid->eid, peer_ueid, SMC_MAX_EID_LEN))
			return true;
	}
	return false;
}

bool smc_clc_match_eid(u8 *negotiated_eid,
		       struct smc_clc_v2_extension *smc_v2_ext,
		       u8 *peer_eid, u8 *local_eid)
{
	bool match = false;
	int i;

	negotiated_eid[0] = 0;
	read_lock(&smc_clc_eid_table.lock);
	if (peer_eid && local_eid &&
	    smc_clc_eid_table.seid_enabled &&
	    smc_v2_ext->hdr.flag.seid &&
	    !memcmp(peer_eid, local_eid, SMC_MAX_EID_LEN)) {
		memcpy(negotiated_eid, peer_eid, SMC_MAX_EID_LEN);
		match = true;
		goto out;
	}

	for (i = 0; i < smc_v2_ext->hdr.eid_cnt; i++) {
		if (_smc_clc_match_ueid(smc_v2_ext->user_eids[i])) {
			memcpy(negotiated_eid, smc_v2_ext->user_eids[i],
			       SMC_MAX_EID_LEN);
			match = true;
			goto out;
		}
	}
out:
	read_unlock(&smc_clc_eid_table.lock);
	return match;
}

/* check arriving CLC proposal */
static bool smc_clc_msg_prop_valid(struct smc_clc_msg_proposal *pclc)
{
	struct smc_clc_msg_proposal_prefix *pclc_prfx;
	struct smc_clc_smcd_v2_extension *smcd_v2_ext;
	struct smc_clc_msg_hdr *hdr = &pclc->hdr;
	struct smc_clc_v2_extension *v2_ext;

	pclc_prfx = smc_clc_proposal_get_prefix(pclc);
	if (!pclc_prfx ||
	    pclc_prfx->ipv6_prefixes_cnt > SMC_CLC_MAX_V6_PREFIX)
		return false;

	if (hdr->version == SMC_V1) {
		if (hdr->typev1 == SMC_TYPE_N)
			return false;
		if (ntohs(hdr->length) !=
			sizeof(*pclc) + ntohs(pclc->iparea_offset) +
			sizeof(*pclc_prfx) +
			pclc_prfx->ipv6_prefixes_cnt *
				sizeof(struct smc_clc_ipv6_prefix) +
			sizeof(struct smc_clc_msg_trail))
			return false;
	} else {
		v2_ext = smc_get_clc_v2_ext(pclc);
		if ((hdr->typev2 != SMC_TYPE_N &&
		     (!v2_ext || v2_ext->hdr.eid_cnt > SMC_CLC_MAX_UEID)) ||
		    (smcd_indicated(hdr->typev2) &&
		     v2_ext->hdr.ism_gid_cnt > SMCD_CLC_MAX_V2_GID_ENTRIES))
			return false;

		if (ntohs(hdr->length) !=
			sizeof(*pclc) +
			sizeof(struct smc_clc_msg_smcd) +
			(hdr->typev1 != SMC_TYPE_N ?
				sizeof(*pclc_prfx) +
				pclc_prfx->ipv6_prefixes_cnt *
				sizeof(struct smc_clc_ipv6_prefix) : 0) +
			(hdr->typev2 != SMC_TYPE_N ?
				sizeof(*v2_ext) +
				v2_ext->hdr.eid_cnt * SMC_MAX_EID_LEN : 0) +
			(smcd_indicated(hdr->typev2) ?
				sizeof(*smcd_v2_ext) + v2_ext->hdr.ism_gid_cnt *
					sizeof(struct smc_clc_smcd_gid_chid) :
				0) +
			sizeof(struct smc_clc_msg_trail))
			return false;
	}
	return true;
}

/* check arriving CLC accept or confirm */
static bool
smc_clc_msg_acc_conf_valid(struct smc_clc_msg_accept_confirm *clc)
{
	struct smc_clc_msg_hdr *hdr = &clc->hdr;

	if (hdr->typev1 != SMC_TYPE_R && hdr->typev1 != SMC_TYPE_D)
		return false;
	if (hdr->version == SMC_V1) {
		if ((hdr->typev1 == SMC_TYPE_R &&
		     ntohs(hdr->length) != SMCR_CLC_ACCEPT_CONFIRM_LEN) ||
		    (hdr->typev1 == SMC_TYPE_D &&
		     ntohs(hdr->length) != SMCD_CLC_ACCEPT_CONFIRM_LEN))
			return false;
	} else {
		if (hdr->typev1 == SMC_TYPE_D &&
		    ntohs(hdr->length) < SMCD_CLC_ACCEPT_CONFIRM_LEN_V2)
			return false;
		if (hdr->typev1 == SMC_TYPE_R &&
		    ntohs(hdr->length) < SMCR_CLC_ACCEPT_CONFIRM_LEN_V2)
			return false;
	}
	return true;
}

/* check arriving CLC decline */
static bool
smc_clc_msg_decl_valid(struct smc_clc_msg_decline *dclc)
{
	struct smc_clc_msg_hdr *hdr = &dclc->hdr;

	if (hdr->version == SMC_V1) {
		if (ntohs(hdr->length) != sizeof(struct smc_clc_msg_decline))
			return false;
	} else {
		if (ntohs(hdr->length) != sizeof(struct smc_clc_msg_decline_v2))
			return false;
	}
	return true;
}

static int smc_clc_fill_fce_v2x(struct smc_clc_first_contact_ext_v2x *fce_v2x,
				struct smc_init_info *ini)
{
	int ret = sizeof(*fce_v2x);

	memset(fce_v2x, 0, sizeof(*fce_v2x));
	fce_v2x->fce_v2_base.os_type = SMC_CLC_OS_LINUX;
	fce_v2x->fce_v2_base.release = ini->release_nr;
	memcpy(fce_v2x->fce_v2_base.hostname,
	       smc_hostname, sizeof(smc_hostname));
	if (ini->is_smcd && ini->release_nr < SMC_RELEASE_1) {
		ret = sizeof(struct smc_clc_first_contact_ext);
		goto out;
	}

	if (ini->release_nr >= SMC_RELEASE_1) {
		if (!ini->is_smcd) {
			fce_v2x->max_conns = ini->max_conns;
			fce_v2x->max_links = ini->max_links;
		}
		fce_v2x->feature_mask = htons(ini->feature_mask);
	}

out:
	return ret;
}

/* check if received message has a correct header length and contains valid
 * heading and trailing eyecatchers
 */
static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm, bool check_trl)
{
	struct smc_clc_msg_accept_confirm *clc;
	struct smc_clc_msg_proposal *pclc;
	struct smc_clc_msg_decline *dclc;
	struct smc_clc_msg_trail *trl;

	if (memcmp(clcm->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&
	    memcmp(clcm->eyecatcher, SMCD_EYECATCHER, sizeof(SMCD_EYECATCHER)))
		return false;
	switch (clcm->type) {
	case SMC_CLC_PROPOSAL:
		pclc = (struct smc_clc_msg_proposal *)clcm;
		if (!smc_clc_msg_prop_valid(pclc))
			return false;
		trl = (struct smc_clc_msg_trail *)
			((u8 *)pclc + ntohs(pclc->hdr.length) - sizeof(*trl));
		break;
	case SMC_CLC_ACCEPT:
	case SMC_CLC_CONFIRM:
		clc = (struct smc_clc_msg_accept_confirm *)clcm;
		if (!smc_clc_msg_acc_conf_valid(clc))
			return false;
		trl = (struct smc_clc_msg_trail *)
			((u8 *)clc + ntohs(clc->hdr.length) - sizeof(*trl));
		break;
	case SMC_CLC_DECLINE:
		dclc = (struct smc_clc_msg_decline *)clcm;
		if (!smc_clc_msg_decl_valid(dclc))
			return false;
		check_trl = false;
		break;
	default:
		return false;
	}
	if (check_trl &&
	    memcmp(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&
	    memcmp(trl->eyecatcher, SMCD_EYECATCHER, sizeof(SMCD_EYECATCHER)))
		return false;
	return true;
}

/* find ipv4 addr on device and get the prefix len, fill CLC proposal msg */
static int smc_clc_prfx_set4_rcu(struct dst_entry *dst, __be32 ipv4,
				 struct smc_clc_msg_proposal_prefix *prop)
{
	struct in_device *in_dev = __in_dev_get_rcu(dst->dev);
	const struct in_ifaddr *ifa;

	if (!in_dev)
		return -ENODEV;

	in_dev_for_each_ifa_rcu(ifa, in_dev) {
		if (!inet_ifa_match(ipv4, ifa))
			continue;
		prop->prefix_len = inet_mask_len(ifa->ifa_mask);
		prop->outgoing_subnet = ifa->ifa_address & ifa->ifa_mask;
		/* prop->ipv6_prefixes_cnt = 0; already done by memset before */
		return 0;
	}
	return -ENOENT;
}

/* fill CLC proposal msg with ipv6 prefixes from device */
static int smc_clc_prfx_set6_rcu(struct dst_entry *dst,
				 struct smc_clc_msg_proposal_prefix *prop,
				 struct smc_clc_ipv6_prefix *ipv6_prfx)
{
#if IS_ENABLED(CONFIG_IPV6)
	struct inet6_dev *in6_dev = __in6_dev_get(dst->dev);
	struct inet6_ifaddr *ifa;
	int cnt = 0;

	if (!in6_dev)
		return -ENODEV;
	/* use a maximum of 8 IPv6 prefixes from device */
	list_for_each_entry(ifa, &in6_dev->addr_list, if_list) {
		if (ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)
			continue;
		ipv6_addr_prefix(&ipv6_prfx[cnt].prefix,
				 &ifa->addr, ifa->prefix_len);
		ipv6_prfx[cnt].prefix_len = ifa->prefix_len;
		cnt++;
		if (cnt == SMC_CLC_MAX_V6_PREFIX)
			break;
	}
	prop->ipv6_prefixes_cnt = cnt;
	if (cnt)
		return 0;
#endif
	return -ENOENT;
}

/* retrieve and set prefixes in CLC proposal msg */
static int smc_clc_prfx_set(struct socket *clcsock,
			    struct smc_clc_msg_proposal_prefix *prop,
			    struct smc_clc_ipv6_prefix *ipv6_prfx)
{
	struct dst_entry *dst = sk_dst_get(clcsock->sk);
	struct sockaddr_storage addrs;
	struct sockaddr_in6 *addr6;
	struct sockaddr_in *addr;
	int rc = -ENOENT;

	if (!dst) {
		rc = -ENOTCONN;
		goto out;
	}
	if (!dst->dev) {
		rc = -ENODEV;
		goto out_rel;
	}
	/* get address to which the internal TCP socket is bound */
	if (kernel_getsockname(clcsock, (struct sockaddr *)&addrs) < 0)
		goto out_rel;
	/* analyze IP specific data of net_device belonging to TCP socket */
	addr6 = (struct sockaddr_in6 *)&addrs;
	rcu_read_lock();
	if (addrs.ss_family == PF_INET) {
		/* IPv4 */
		addr = (struct sockaddr_in *)&addrs;
		rc = smc_clc_prfx_set4_rcu(dst, addr->sin_addr.s_addr, prop);
	} else if (ipv6_addr_v4mapped(&addr6->sin6_addr)) {
		/* mapped IPv4 address - peer is IPv4 only */
		rc = smc_clc_prfx_set4_rcu(dst, addr6->sin6_addr.s6_addr32[3],
					   prop);
	} else {
		/* IPv6 */
		rc = smc_clc_prfx_set6_rcu(dst, prop, ipv6_prfx);
	}
	rcu_read_unlock();
out_rel:
	dst_release(dst);
out:
	return rc;
}

/* match ipv4 addrs of dev against addr in CLC proposal */
static int smc_clc_prfx_match4_rcu(struct net_device *dev,
				   struct smc_clc_msg_proposal_prefix *prop)
{
	struct in_device *in_dev = __in_dev_get_rcu(dev);
	const struct in_ifaddr *ifa;

	if (!in_dev)
		return -ENODEV;
	in_dev_for_each_ifa_rcu(ifa, in_dev) {
		if (prop->prefix_len == inet_mask_len(ifa->ifa_mask) &&
		    inet_ifa_match(prop->outgoing_subnet, ifa))
			return 0;
	}

	return -ENOENT;
}

/* match ipv6 addrs of dev against addrs in CLC proposal */
static int smc_clc_prfx_match6_rcu(struct net_device *dev,
				   struct smc_clc_msg_proposal_prefix *prop)
{
#if IS_ENABLED(CONFIG_IPV6)
	struct inet6_dev *in6_dev = __in6_dev_get(dev);
	struct smc_clc_ipv6_prefix *ipv6_prfx;
	struct inet6_ifaddr *ifa;
	int i, max;

	if (!in6_dev)
		return -ENODEV;
	/* ipv6 prefix list starts behind smc_clc_msg_proposal_prefix */
	ipv6_prfx = (struct smc_clc_ipv6_prefix *)((u8 *)prop + sizeof(*prop));
	max = min_t(u8, prop->ipv6_prefixes_cnt, SMC_CLC_MAX_V6_PREFIX);
	list_for_each_entry(ifa, &in6_dev->addr_list, if_list) {
		if (ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)
			continue;
		for (i = 0; i < max; i++) {
			if (ifa->prefix_len == ipv6_prfx[i].prefix_len &&
			    ipv6_prefix_equal(&ifa->addr, &ipv6_prfx[i].prefix,
					      ifa->prefix_len))
				return 0;
		}
	}
#endif
	return -ENOENT;
}

/* check if proposed prefixes match one of our device prefixes */
int smc_clc_prfx_match(struct socket *clcsock,
		       struct smc_clc_msg_proposal_prefix *prop)
{
	struct dst_entry *dst = sk_dst_get(clcsock->sk);
	int rc;

	if (!dst) {
		rc = -ENOTCONN;
		goto out;
	}
	if (!dst->dev) {
		rc = -ENODEV;
		goto out_rel;
	}
	rcu_read_lock();
	if (!prop->ipv6_prefixes_cnt)
		rc = smc_clc_prfx_match4_rcu(dst->dev, prop);
	else
		rc = smc_clc_prfx_match6_rcu(dst->dev, prop);
	rcu_read_unlock();
out_rel:
	dst_release(dst);
out:
	return rc;
}

/* Wait for data on the tcp-socket, analyze received data
 * Returns:
 * 0 if success and it was not a decline that we received.
 * SMC_CLC_DECL_REPLY if decline received for fallback w/o another decl send.
 * clcsock error, -EINTR, -ECONNRESET, -EPROTO otherwise.
 */
int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
		     u8 expected_type, unsigned long timeout)
{
	long rcvtimeo = READ_ONCE(smc->clcsock->sk->sk_rcvtimeo);
	struct sock *clc_sk = smc->clcsock->sk;
	struct smc_clc_msg_hdr *clcm = buf;
	struct msghdr msg = {NULL, 0};
	int reason_code = 0;
	struct kvec vec = {buf, buflen};
	int len, datlen, recvlen;
	bool check_trl = true;
	int krflags;

	/* peek the first few bytes to determine length of data to receive
	 * so we don't consume any subsequent CLC message or payload data
	 * in the TCP byte stream
	 */
	/*
	 * Caller must make sure that buflen is no less than
	 * sizeof(struct smc_clc_msg_hdr)
	 */
	krflags = MSG_PEEK | MSG_WAITALL;
	WRITE_ONCE(clc_sk->sk_rcvtimeo, timeout);
	iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1,
			sizeof(struct smc_clc_msg_hdr));
	len = sock_recvmsg(smc->clcsock, &msg, krflags);
	if (signal_pending(current)) {
		reason_code = -EINTR;
		clc_sk->sk_err = EINTR;
		smc->sk.sk_err = EINTR;
		goto out;
	}
	if (clc_sk->sk_err) {
		reason_code = -clc_sk->sk_err;
		if (clc_sk->sk_err == EAGAIN &&
		    expected_type == SMC_CLC_DECLINE)
			clc_sk->sk_err = 0; /* reset for fallback usage */
		else
			smc->sk.sk_err = clc_sk->sk_err;
		goto out;
	}
	if (!len) { /* peer has performed orderly shutdown */
		smc->sk.sk_err = ECONNRESET;
		reason_code = -ECONNRESET;
		goto out;
	}
	if (len < 0) {
		if (len != -EAGAIN || expected_type != SMC_CLC_DECLINE)
			smc->sk.sk_err = -len;
		reason_code = len;
		goto out;
	}
	datlen = ntohs(clcm->length);
	if ((len < sizeof(struct smc_clc_msg_hdr)) ||
	    (clcm->version < SMC_V1) ||
	    ((clcm->type != SMC_CLC_DECLINE) &&
	     (clcm->type != expected_type))) {
		smc->sk.sk_err = EPROTO;
		reason_code = -EPROTO;
		goto out;
	}

	/* receive the complete CLC message */
	memset(&msg, 0, sizeof(struct msghdr));
	if (datlen > buflen) {
		check_trl = false;
		recvlen = buflen;
	} else {
		recvlen = datlen;
	}
	iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, recvlen);
	krflags = MSG_WAITALL;
	len = sock_recvmsg(smc->clcsock, &msg, krflags);
	if (len < recvlen || !smc_clc_msg_hdr_valid(clcm, check_trl)) {
		smc->sk.sk_err = EPROTO;
		reason_code = -EPROTO;
		goto out;
	}
	datlen -= len;
	while (datlen) {
		u8 tmp[SMC_CLC_RECV_BUF_LEN];

		vec.iov_base = &tmp;
		vec.iov_len = SMC_CLC_RECV_BUF_LEN;
		/* receive remaining proposal message */
		recvlen = datlen > SMC_CLC_RECV_BUF_LEN ?
						SMC_CLC_RECV_BUF_LEN : datlen;
		iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, recvlen);
		len = sock_recvmsg(smc->clcsock, &msg, krflags);
		if (len < recvlen) {
			smc->sk.sk_err = EPROTO;
			reason_code = -EPROTO;
			goto out;
		}
		datlen -= len;
	}
	if (clcm->type == SMC_CLC_DECLINE) {
		struct smc_clc_msg_decline *dclc;

		dclc = (struct smc_clc_msg_decline *)clcm;
		reason_code = SMC_CLC_DECL_PEERDECL;
		smc->peer_diagnosis = ntohl(dclc->peer_diagnosis);
		if (((struct smc_clc_msg_decline *)buf)->hdr.typev2 &
						SMC_FIRST_CONTACT_MASK) {
			smc->conn.lgr->sync_err = 1;
			smc_lgr_terminate_sched(smc->conn.lgr);
		}
	}

out:
	WRITE_ONCE(clc_sk->sk_rcvtimeo, rcvtimeo);
	return reason_code;
}

/* send CLC DECLINE message across internal TCP socket */
int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, u8 version)
{
	struct smc_clc_msg_decline *dclc_v1;
	struct smc_clc_msg_decline_v2 dclc;
	struct msghdr msg;
	int len, send_len;
	struct kvec vec;

	dclc_v1 = (struct smc_clc_msg_decline *)&dclc;
	memset(&dclc, 0, sizeof(dclc));
	memcpy(dclc.hdr.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
	dclc.hdr.type = SMC_CLC_DECLINE;
	dclc.hdr.version = version;
	dclc.os_type = version == SMC_V1 ? 0 : SMC_CLC_OS_LINUX;
	dclc.hdr.typev2 = (peer_diag_info == SMC_CLC_DECL_SYNCERR) ?
						SMC_FIRST_CONTACT_MASK : 0;
	if ((!smc_conn_lgr_valid(&smc->conn) || !smc->conn.lgr->is_smcd) &&
	    smc_ib_is_valid_local_systemid())
		memcpy(dclc.id_for_peer, local_systemid,
		       sizeof(local_systemid));
	dclc.peer_diagnosis = htonl(peer_diag_info);
	if (version == SMC_V1) {
		memcpy(dclc_v1->trl.eyecatcher, SMC_EYECATCHER,
		       sizeof(SMC_EYECATCHER));
		send_len = sizeof(*dclc_v1);
	} else {
		memcpy(dclc.trl.eyecatcher, SMC_EYECATCHER,
		       sizeof(SMC_EYECATCHER));
		send_len = sizeof(dclc);
	}
	dclc.hdr.length = htons(send_len);

	memset(&msg, 0, sizeof(msg));
	vec.iov_base = &dclc;
	vec.iov_len = send_len;
	len = kernel_sendmsg(smc->clcsock, &msg, &vec, 1, send_len);
	if (len < 0 || len < send_len)
		len = -EPROTO;
	return len > 0 ? 0 : len;
}

/* send CLC PROPOSAL message across internal TCP socket */
int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
{
	struct smc_clc_smcd_v2_extension *smcd_v2_ext;
	struct smc_clc_msg_proposal_prefix *pclc_prfx;
	struct smc_clc_msg_proposal *pclc_base;
	struct smc_clc_smcd_gid_chid *gidchids;
	struct smc_clc_msg_proposal_area *pclc;
	struct smc_clc_ipv6_prefix *ipv6_prfx;
	struct net *net = sock_net(&smc->sk);
	struct smc_clc_v2_extension *v2_ext;
	struct smc_clc_msg_smcd *pclc_smcd;
	struct smc_clc_msg_trail *trl;
	struct smcd_dev *smcd;
	int len, i, plen, rc;
	int reason_code = 0;
	struct kvec vec[8];
	struct msghdr msg;

	pclc = kzalloc(sizeof(*pclc), GFP_KERNEL);
	if (!pclc)
		return -ENOMEM;

	pclc_base = &pclc->pclc_base;
	pclc_smcd = &pclc->pclc_smcd;
	pclc_prfx = &pclc->pclc_prfx;
	ipv6_prfx = pclc->pclc_prfx_ipv6;
	v2_ext = container_of(&pclc->pclc_v2_ext,
			      struct smc_clc_v2_extension, fixed);
	smcd_v2_ext = container_of(&pclc->pclc_smcd_v2_ext,
				   struct smc_clc_smcd_v2_extension, fixed);
	gidchids = pclc->pclc_gidchids;
	trl = &pclc->pclc_trl;

	pclc_base->hdr.version = SMC_V2;
	pclc_base->hdr.typev1 = ini->smc_type_v1;
	pclc_base->hdr.typev2 = ini->smc_type_v2;
	plen = sizeof(*pclc_base) + sizeof(*pclc_smcd) + sizeof(*trl);

	/* retrieve ip prefixes for CLC proposal msg */
	if (ini->smc_type_v1 != SMC_TYPE_N) {
		rc = smc_clc_prfx_set(smc->clcsock, pclc_prfx, ipv6_prfx);
		if (rc) {
			if (ini->smc_type_v2 == SMC_TYPE_N) {
				kfree(pclc);
				return SMC_CLC_DECL_CNFERR;
			}
			pclc_base->hdr.typev1 = SMC_TYPE_N;
		} else {
			pclc_base->iparea_offset = htons(sizeof(*pclc_smcd));
			plen += sizeof(*pclc_prfx) +
					pclc_prfx->ipv6_prefixes_cnt *
					sizeof(ipv6_prfx[0]);
		}
	}

	/* build SMC Proposal CLC message */
	memcpy(pclc_base->hdr.eyecatcher, SMC_EYECATCHER,
	       sizeof(SMC_EYECATCHER));
	pclc_base->hdr.type = SMC_CLC_PROPOSAL;
	if (smcr_indicated(ini->smc_type_v1)) {
		/* add SMC-R specifics */
		memcpy(pclc_base->lcl.id_for_peer, local_systemid,
		       sizeof(local_systemid));
		memcpy(pclc_base->lcl.gid, ini->ib_gid, SMC_GID_SIZE);
		memcpy(pclc_base->lcl.mac, &ini->ib_dev->mac[ini->ib_port - 1],
		       ETH_ALEN);
	}
	if (smcd_indicated(ini->smc_type_v1)) {
		struct smcd_gid smcd_gid;

		/* add SMC-D specifics */
		if (ini->ism_dev[0]) {
			smcd = ini->ism_dev[0];
			smcd->ops->get_local_gid(smcd, &smcd_gid);
			pclc_smcd->ism.gid = htonll(smcd_gid.gid);
			pclc_smcd->ism.chid =
				htons(smc_ism_get_chid(ini->ism_dev[0]));
		}
	}
	if (ini->smc_type_v2 == SMC_TYPE_N) {
		pclc_smcd->v2_ext_offset = 0;
	} else {
		struct smc_clc_eid_entry *ueident;
		u16 v2_ext_offset;

		v2_ext->hdr.flag.release = SMC_RELEASE;
		v2_ext_offset = sizeof(*pclc_smcd) -
			offsetofend(struct smc_clc_msg_smcd, v2_ext_offset);
		if (ini->smc_type_v1 != SMC_TYPE_N)
			v2_ext_offset += sizeof(*pclc_prfx) +
						pclc_prfx->ipv6_prefixes_cnt *
						sizeof(ipv6_prfx[0]);
		pclc_smcd->v2_ext_offset = htons(v2_ext_offset);
		plen += sizeof(*v2_ext);

		v2_ext->feature_mask = htons(SMC_FEATURE_MASK);
		read_lock(&smc_clc_eid_table.lock);
		v2_ext->hdr.eid_cnt = smc_clc_eid_table.ueid_cnt;
		plen += smc_clc_eid_table.ueid_cnt * SMC_MAX_EID_LEN;
		i = 0;
		list_for_each_entry(ueident, &smc_clc_eid_table.list, list) {
			memcpy(v2_ext->user_eids[i++], ueident->eid,
			       sizeof(ueident->eid));
		}
		read_unlock(&smc_clc_eid_table.lock);
	}
	if (smcd_indicated(ini->smc_type_v2)) {
		struct smcd_gid smcd_gid;
		u8 *eid = NULL;
		int entry = 0;

		v2_ext->hdr.flag.seid = smc_clc_eid_table.seid_enabled;
		v2_ext->hdr.smcd_v2_ext_offset = htons(sizeof(*v2_ext) -
				offsetofend(struct smc_clnt_opts_area_hdr,
					    smcd_v2_ext_offset) +
				v2_ext->hdr.eid_cnt * SMC_MAX_EID_LEN);
		smc_ism_get_system_eid(&eid);
		if (eid && v2_ext->hdr.flag.seid)
			memcpy(smcd_v2_ext->system_eid, eid, SMC_MAX_EID_LEN);
		plen += sizeof(*smcd_v2_ext);
		if (ini->ism_offered_cnt) {
			for (i = 1; i <= ini->ism_offered_cnt; i++) {
				smcd = ini->ism_dev[i];
				smcd->ops->get_local_gid(smcd, &smcd_gid);
				gidchids[entry].chid =
					htons(smc_ism_get_chid(ini->ism_dev[i]));
				gidchids[entry].gid = htonll(smcd_gid.gid);
				if (smc_ism_is_emulated(smcd)) {
					/* an Emulated-ISM device takes two
					 * entries. CHID of the second entry
					 * repeats that of the first entry.
					 */
					gidchids[entry + 1].chid =
						gidchids[entry].chid;
					gidchids[entry + 1].gid =
						htonll(smcd_gid.gid_ext);
					entry++;
				}
				entry++;
			}
			plen += entry * sizeof(struct smc_clc_smcd_gid_chid);
		}
		v2_ext->hdr.ism_gid_cnt = entry;
	}
	if (smcr_indicated(ini->smc_type_v2)) {
		memcpy(v2_ext->roce, ini->smcrv2.ib_gid_v2, SMC_GID_SIZE);
		v2_ext->max_conns = net->smc.sysctl_max_conns_per_lgr;
		v2_ext->max_links = net->smc.sysctl_max_links_per_lgr;
	}

	pclc_base->hdr.length = htons(plen);
	memcpy(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));

	/* send SMC Proposal CLC message */
	memset(&msg, 0, sizeof(msg));
	i = 0;
	vec[i].iov_base = pclc_base;
	vec[i++].iov_len = sizeof(*pclc_base);
	vec[i].iov_base = pclc_smcd;
	vec[i++].iov_len = sizeof(*pclc_smcd);
	if (ini->smc_type_v1 != SMC_TYPE_N) {
		vec[i].iov_base = pclc_prfx;
		vec[i++].iov_len = sizeof(*pclc_prfx);
		if (pclc_prfx->ipv6_prefixes_cnt > 0) {
			vec[i].iov_base = ipv6_prfx;
			vec[i++].iov_len = pclc_prfx->ipv6_prefixes_cnt *
					   sizeof(ipv6_prfx[0]);
		}
	}
	if (ini->smc_type_v2 != SMC_TYPE_N) {
		vec[i].iov_base = v2_ext;
		vec[i++].iov_len = sizeof(*v2_ext) +
				   (v2_ext->hdr.eid_cnt * SMC_MAX_EID_LEN);
		if (smcd_indicated(ini->smc_type_v2)) {
			vec[i].iov_base = smcd_v2_ext;
			vec[i++].iov_len = sizeof(*smcd_v2_ext);
			if (ini->ism_offered_cnt) {
				vec[i].iov_base = gidchids;
				vec[i++].iov_len = v2_ext->hdr.ism_gid_cnt *
					sizeof(struct smc_clc_smcd_gid_chid);
			}
		}
	}
	vec[i].iov_base = trl;
	vec[i++].iov_len = sizeof(*trl);
	/* due to the few bytes needed for clc-handshake this cannot block */
	len = kernel_sendmsg(smc->clcsock, &msg, vec, i, plen);
	if (len < 0) {
		smc->sk.sk_err = smc->clcsock->sk->sk_err;
		reason_code = -smc->sk.sk_err;
	} else if (len < ntohs(pclc_base->hdr.length)) {
		reason_code = -ENETUNREACH;
		smc->sk.sk_err = -reason_code;
	}

	kfree(pclc);
	return reason_code;
}

static void
smcd_clc_prep_confirm_accept(struct smc_connection *conn,
			     struct smc_clc_msg_accept_confirm *clc,
			     int first_contact, u8 version,
			     u8 *eid, struct smc_init_info *ini,
			     int *fce_len,
			     struct smc_clc_first_contact_ext_v2x *fce_v2x,
			     struct smc_clc_msg_trail *trl)
{
	struct smcd_dev *smcd = conn->lgr->smcd;
	struct smcd_gid smcd_gid;
	u16 chid;
	int len;

	/* SMC-D specific settings */
	memcpy(clc->hdr.eyecatcher, SMCD_EYECATCHER,
	       sizeof(SMCD_EYECATCHER));
	smcd->ops->get_local_gid(smcd, &smcd_gid);
	clc->hdr.typev1 = SMC_TYPE_D;
	clc->d0.gid = htonll(smcd_gid.gid);
	clc->d0.token = htonll(conn->rmb_desc->token);
	clc->d0.dmbe_size = conn->rmbe_size_comp;
	clc->d0.dmbe_idx = 0;
	memcpy(&clc->d0.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
	if (version == SMC_V1) {
		clc->hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
	} else {
		chid = smc_ism_get_chid(smcd);
		clc->d1.chid = htons(chid);
		if (eid && eid[0])
			memcpy(clc->d1.eid, eid, SMC_MAX_EID_LEN);
		if (__smc_ism_is_emulated(chid))
			clc->d1.gid_ext = htonll(smcd_gid.gid_ext);
		len = SMCD_CLC_ACCEPT_CONFIRM_LEN_V2;
		if (first_contact) {
			*fce_len = smc_clc_fill_fce_v2x(fce_v2x, ini);
			len += *fce_len;
		}
		clc->hdr.length = htons(len);
	}
	memcpy(trl->eyecatcher, SMCD_EYECATCHER,
	       sizeof(SMCD_EYECATCHER));
}

static void
smcr_clc_prep_confirm_accept(struct smc_connection *conn,
			     struct smc_clc_msg_accept_confirm *clc,
			     int first_contact, u8 version,
			     u8 *eid, struct smc_init_info *ini,
			     int *fce_len,
			     struct smc_clc_first_contact_ext_v2x *fce_v2x,
			     struct smc_clc_fce_gid_ext *gle,
			     struct smc_clc_msg_trail *trl)
{
	struct smc_link *link = conn->lnk;
	int len;

	/* SMC-R specific settings */
	memcpy(clc->hdr.eyecatcher, SMC_EYECATCHER,
	       sizeof(SMC_EYECATCHER));
	clc->hdr.typev1 = SMC_TYPE_R;
	memcpy(clc->r0.lcl.id_for_peer, local_systemid,
	       sizeof(local_systemid));
	memcpy(&clc->r0.lcl.gid, link->gid, SMC_GID_SIZE);
	memcpy(&clc->r0.lcl.mac, &link->smcibdev->mac[link->ibport - 1],
	       ETH_ALEN);
	hton24(clc->r0.qpn, link->roce_qp->qp_num);
	clc->r0.rmb_rkey =
		htonl(conn->rmb_desc->mr[link->link_idx]->rkey);
	clc->r0.rmbe_idx = 1; /* for now: 1 RMB = 1 RMBE */
	clc->r0.rmbe_alert_token = htonl(conn->alert_token_local);
	switch (clc->hdr.type) {
	case SMC_CLC_ACCEPT:
		clc->r0.qp_mtu = link->path_mtu;
		break;
	case SMC_CLC_CONFIRM:
		clc->r0.qp_mtu = min(link->path_mtu, link->peer_mtu);
		break;
	}
	clc->r0.rmbe_size = conn->rmbe_size_comp;
	clc->r0.rmb_dma_addr = conn->rmb_desc->is_vm ?
		cpu_to_be64((uintptr_t)conn->rmb_desc->cpu_addr) :
		cpu_to_be64((u64)sg_dma_address
			    (conn->rmb_desc->sgt[link->link_idx].sgl));
	hton24(clc->r0.psn, link->psn_initial);
	if (version == SMC_V1) {
		clc->hdr.length = htons(SMCR_CLC_ACCEPT_CONFIRM_LEN);
	} else {
		if (eid && eid[0])
			memcpy(clc->r1.eid, eid, SMC_MAX_EID_LEN);
		len = SMCR_CLC_ACCEPT_CONFIRM_LEN_V2;
		if (first_contact) {
			*fce_len = smc_clc_fill_fce_v2x(fce_v2x, ini);
			len += *fce_len;
			fce_v2x->fce_v2_base.v2_direct =
				!link->lgr->uses_gateway;
			if (clc->hdr.type == SMC_CLC_CONFIRM) {
				memset(gle, 0, sizeof(*gle));
				gle->gid_cnt = ini->smcrv2.gidlist.len;
				len += sizeof(*gle);
				len += gle->gid_cnt * sizeof(gle->gid[0]);
			}
		}
		clc->hdr.length = htons(len);
	}
	memcpy(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
}

/* build and send CLC CONFIRM / ACCEPT message */
static int smc_clc_send_confirm_accept(struct smc_sock *smc,
				       struct smc_clc_msg_accept_confirm *clc,
				       int first_contact, u8 version,
				       u8 *eid, struct smc_init_info *ini)
{
	struct smc_clc_first_contact_ext_v2x fce_v2x;
	struct smc_connection *conn = &smc->conn;
	struct smc_clc_fce_gid_ext gle;
	struct smc_clc_msg_trail trl;
	int i, fce_len;
	struct kvec vec[5];
	struct msghdr msg;

	/* send SMC Confirm CLC msg */
	clc->hdr.version = version;	/* SMC version */
	if (first_contact)
		clc->hdr.typev2 |= SMC_FIRST_CONTACT_MASK;
	if (conn->lgr->is_smcd)
		smcd_clc_prep_confirm_accept(conn, clc, first_contact,
					     version, eid, ini, &fce_len,
					     &fce_v2x, &trl);
	else
		smcr_clc_prep_confirm_accept(conn, clc, first_contact,
					     version, eid, ini, &fce_len,
					     &fce_v2x, &gle, &trl);
	memset(&msg, 0, sizeof(msg));
	i = 0;
	vec[i].iov_base = clc;
	if (version > SMC_V1)
		vec[i++].iov_len = (clc->hdr.typev1 == SMC_TYPE_D ?
					SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 :
					SMCR_CLC_ACCEPT_CONFIRM_LEN_V2) -
				   sizeof(trl);
	else
		vec[i++].iov_len = (clc->hdr.typev1 == SMC_TYPE_D ?
						SMCD_CLC_ACCEPT_CONFIRM_LEN :
						SMCR_CLC_ACCEPT_CONFIRM_LEN) -
				   sizeof(trl);
	if (version > SMC_V1 && first_contact) {
		vec[i].iov_base = &fce_v2x;
		vec[i++].iov_len = fce_len;
		if (!conn->lgr->is_smcd) {
			if (clc->hdr.type == SMC_CLC_CONFIRM) {
				vec[i].iov_base = &gle;
				vec[i++].iov_len = sizeof(gle);
				vec[i].iov_base = &ini->smcrv2.gidlist.list;
				vec[i++].iov_len = gle.gid_cnt *
						   sizeof(gle.gid[0]);
			}
		}
	}
	vec[i].iov_base = &trl;
	vec[i++].iov_len = sizeof(trl);
	return kernel_sendmsg(smc->clcsock, &msg, vec, 1,
			      ntohs(clc->hdr.length));
}

/* send CLC CONFIRM message across internal TCP socket */
int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact,
			 u8 version, u8 *eid, struct smc_init_info *ini)
{
	struct smc_clc_msg_accept_confirm cclc;
	int reason_code = 0;
	int len;

	/* send SMC Confirm CLC msg */
	memset(&cclc, 0, sizeof(cclc));
	cclc.hdr.type = SMC_CLC_CONFIRM;
	len = smc_clc_send_confirm_accept(smc, &cclc, clnt_first_contact,
					  version, eid, ini);
	if (len < ntohs(cclc.hdr.length)) {
		if (len >= 0) {
			reason_code = -ENETUNREACH;
			smc->sk.sk_err = -reason_code;
		} else {
			smc->sk.sk_err = smc->clcsock->sk->sk_err;
			reason_code = -smc->sk.sk_err;
		}
	}
	return reason_code;
}

/* send CLC ACCEPT message across internal TCP socket */
int smc_clc_send_accept(struct smc_sock *new_smc, bool srv_first_contact,
			u8 version, u8 *negotiated_eid, struct smc_init_info *ini)
{
	struct smc_clc_msg_accept_confirm aclc;
	int len;

	memset(&aclc, 0, sizeof(aclc));
	aclc.hdr.type = SMC_CLC_ACCEPT;
	len = smc_clc_send_confirm_accept(new_smc, &aclc, srv_first_contact,
					  version, negotiated_eid, ini);
	if (len < ntohs(aclc.hdr.length))
		len = len >= 0 ? -EPROTO : -new_smc->clcsock->sk->sk_err;

	return len > 0 ? 0 : len;
}

int smc_clc_srv_v2x_features_validate(struct smc_sock *smc,
				      struct smc_clc_msg_proposal *pclc,
				      struct smc_init_info *ini)
{
	struct smc_clc_v2_extension *pclc_v2_ext;
	struct net *net = sock_net(&smc->sk);

	ini->max_conns = SMC_CONN_PER_LGR_MAX;
	ini->max_links = SMC_LINKS_ADD_LNK_MAX;
	ini->feature_mask = SMC_FEATURE_MASK;

	if ((!(ini->smcd_version & SMC_V2) && !(ini->smcr_version & SMC_V2)) ||
	    ini->release_nr < SMC_RELEASE_1)
		return 0;

	pclc_v2_ext = smc_get_clc_v2_ext(pclc);
	if (!pclc_v2_ext)
		return SMC_CLC_DECL_NOV2EXT;

	if (ini->smcr_version & SMC_V2) {
		ini->max_conns = min_t(u8, pclc_v2_ext->max_conns,
				       net->smc.sysctl_max_conns_per_lgr);
		if (ini->max_conns < SMC_CONN_PER_LGR_MIN)
			return SMC_CLC_DECL_MAXCONNERR;

		ini->max_links = min_t(u8, pclc_v2_ext->max_links,
				       net->smc.sysctl_max_links_per_lgr);
		if (ini->max_links < SMC_LINKS_ADD_LNK_MIN)
			return SMC_CLC_DECL_MAXLINKERR;
	}

	return 0;
}

int smc_clc_clnt_v2x_features_validate(struct smc_clc_first_contact_ext *fce,
				       struct smc_init_info *ini)
{
	struct smc_clc_first_contact_ext_v2x *fce_v2x =
		(struct smc_clc_first_contact_ext_v2x *)fce;

	if (ini->release_nr < SMC_RELEASE_1)
		return 0;

	if (!ini->is_smcd) {
		if (fce_v2x->max_conns < SMC_CONN_PER_LGR_MIN)
			return SMC_CLC_DECL_MAXCONNERR;
		ini->max_conns = fce_v2x->max_conns;

		if (fce_v2x->max_links > SMC_LINKS_ADD_LNK_MAX ||
		    fce_v2x->max_links < SMC_LINKS_ADD_LNK_MIN)
			return SMC_CLC_DECL_MAXLINKERR;
		ini->max_links = fce_v2x->max_links;
	}
	/* common supplemental features of server and client */
	ini->feature_mask = ntohs(fce_v2x->feature_mask) & SMC_FEATURE_MASK;

	return 0;
}

int smc_clc_v2x_features_confirm_check(struct smc_clc_msg_accept_confirm *cclc,
				       struct smc_init_info *ini)
{
	struct smc_clc_first_contact_ext *fce =
		smc_get_clc_first_contact_ext(cclc, ini->is_smcd);
	struct smc_clc_first_contact_ext_v2x *fce_v2x =
		(struct smc_clc_first_contact_ext_v2x *)fce;

	if (cclc->hdr.version == SMC_V1 ||
	    !(cclc->hdr.typev2 & SMC_FIRST_CONTACT_MASK))
		return 0;

	if (ini->release_nr != fce->release)
		return SMC_CLC_DECL_RELEASEERR;

	if (fce->release < SMC_RELEASE_1)
		return 0;

	if (!ini->is_smcd) {
		if (fce_v2x->max_conns != ini->max_conns)
			return SMC_CLC_DECL_MAXCONNERR;
		if (fce_v2x->max_links != ini->max_links)
			return SMC_CLC_DECL_MAXLINKERR;
	}
	/* common supplemental features returned by client */
	ini->feature_mask = ntohs(fce_v2x->feature_mask);

	return 0;
}

void smc_clc_get_hostname(u8 **host)
{
	*host = &smc_hostname[0];
}

void __init smc_clc_init(void)
{
	struct new_utsname *u;

	memset(smc_hostname, _S, sizeof(smc_hostname)); /* ASCII blanks */
	u = utsname();
	memcpy(smc_hostname, u->nodename,
	       min_t(size_t, strlen(u->nodename), sizeof(smc_hostname)));

	INIT_LIST_HEAD(&smc_clc_eid_table.list);
	rwlock_init(&smc_clc_eid_table.lock);
	smc_clc_eid_table.ueid_cnt = 0;
#if IS_ENABLED(CONFIG_S390)
	smc_clc_eid_table.seid_enabled = 1;
#else
	smc_clc_eid_table.seid_enabled = 0;
#endif
}

void smc_clc_exit(void)
{
	smc_clc_ueid_remove(NULL);
}
