1// SPDX-License-Identifier: GPL-2.0
2/*
3 *  Shared Memory Communications over RDMA (SMC-R) and RoCE
4 *
5 *  CLC (connection layer control) handshake over initial TCP socket to
6 *  prepare for RDMA traffic
7 *
8 *  Copyright IBM Corp. 2016, 2018
9 *
10 *  Author(s):  Ursula Braun <ubraun@linux.vnet.ibm.com>
11 */
12
13#include <linux/in.h>
14#include <linux/inetdevice.h>
15#include <linux/if_ether.h>
16#include <linux/sched/signal.h>
17#include <linux/utsname.h>
18#include <linux/ctype.h>
19
20#include <net/addrconf.h>
21#include <net/sock.h>
22#include <net/tcp.h>
23
24#include "smc.h"
25#include "smc_core.h"
26#include "smc_clc.h"
27#include "smc_ib.h"
28#include "smc_ism.h"
29#include "smc_netlink.h"
30
31#define SMCR_CLC_ACCEPT_CONFIRM_LEN 68
32#define SMCD_CLC_ACCEPT_CONFIRM_LEN 48
33#define SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 78
34#define SMCR_CLC_ACCEPT_CONFIRM_LEN_V2 108
35#define SMC_CLC_RECV_BUF_LEN	100
36
37/* eye catcher "SMCR" EBCDIC for CLC messages */
38static const char SMC_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xd9'};
39/* eye catcher "SMCD" EBCDIC for CLC messages */
40static const char SMCD_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xc4'};
41
42static u8 smc_hostname[SMC_MAX_HOSTNAME_LEN];
43
44struct smc_clc_eid_table {
45	rwlock_t lock;
46	struct list_head list;
47	u8 ueid_cnt;
48	u8 seid_enabled;
49};
50
51static struct smc_clc_eid_table smc_clc_eid_table;
52
53struct smc_clc_eid_entry {
54	struct list_head list;
55	u8 eid[SMC_MAX_EID_LEN];
56};
57
58/* The size of a user EID is 32 characters.
59 * Valid characters should be (single-byte character set) A-Z, 0-9, '.' and '-'.
60 * Blanks should only be used to pad to the expected size.
61 * First character must be alphanumeric.
62 */
63static bool smc_clc_ueid_valid(char *ueid)
64{
65	char *end = ueid + SMC_MAX_EID_LEN;
66
67	while (--end >= ueid && isspace(*end))
68		;
69	if (end < ueid)
70		return false;
71	if (!isalnum(*ueid) || islower(*ueid))
72		return false;
73	while (ueid <= end) {
74		if ((!isalnum(*ueid) || islower(*ueid)) && *ueid != '.' &&
75		    *ueid != '-')
76			return false;
77		ueid++;
78	}
79	return true;
80}
81
82static int smc_clc_ueid_add(char *ueid)
83{
84	struct smc_clc_eid_entry *new_ueid, *tmp_ueid;
85	int rc;
86
87	if (!smc_clc_ueid_valid(ueid))
88		return -EINVAL;
89
90	/* add a new ueid entry to the ueid table if there isn't one */
91	new_ueid = kzalloc(sizeof(*new_ueid), GFP_KERNEL);
92	if (!new_ueid)
93		return -ENOMEM;
94	memcpy(new_ueid->eid, ueid, SMC_MAX_EID_LEN);
95
96	write_lock(&smc_clc_eid_table.lock);
97	if (smc_clc_eid_table.ueid_cnt >= SMC_MAX_UEID) {
98		rc = -ERANGE;
99		goto err_out;
100	}
101	list_for_each_entry(tmp_ueid, &smc_clc_eid_table.list, list) {
102		if (!memcmp(tmp_ueid->eid, ueid, SMC_MAX_EID_LEN)) {
103			rc = -EEXIST;
104			goto err_out;
105		}
106	}
107	list_add_tail(&new_ueid->list, &smc_clc_eid_table.list);
108	smc_clc_eid_table.ueid_cnt++;
109	write_unlock(&smc_clc_eid_table.lock);
110	return 0;
111
112err_out:
113	write_unlock(&smc_clc_eid_table.lock);
114	kfree(new_ueid);
115	return rc;
116}
117
118int smc_clc_ueid_count(void)
119{
120	int count;
121
122	read_lock(&smc_clc_eid_table.lock);
123	count = smc_clc_eid_table.ueid_cnt;
124	read_unlock(&smc_clc_eid_table.lock);
125
126	return count;
127}
128
129int smc_nl_add_ueid(struct sk_buff *skb, struct genl_info *info)
130{
131	struct nlattr *nla_ueid = info->attrs[SMC_NLA_EID_TABLE_ENTRY];
132	char *ueid;
133
134	if (!nla_ueid || nla_len(nla_ueid) != SMC_MAX_EID_LEN + 1)
135		return -EINVAL;
136	ueid = (char *)nla_data(nla_ueid);
137
138	return smc_clc_ueid_add(ueid);
139}
140
141/* remove one or all ueid entries from the table */
142static int smc_clc_ueid_remove(char *ueid)
143{
144	struct smc_clc_eid_entry *lst_ueid, *tmp_ueid;
145	int rc = -ENOENT;
146
147	/* remove table entry */
148	write_lock(&smc_clc_eid_table.lock);
149	list_for_each_entry_safe(lst_ueid, tmp_ueid, &smc_clc_eid_table.list,
150				 list) {
151		if (!ueid || !memcmp(lst_ueid->eid, ueid, SMC_MAX_EID_LEN)) {
152			list_del(&lst_ueid->list);
153			smc_clc_eid_table.ueid_cnt--;
154			kfree(lst_ueid);
155			rc = 0;
156		}
157	}
158#if IS_ENABLED(CONFIG_S390)
159	if (!rc && !smc_clc_eid_table.ueid_cnt) {
160		smc_clc_eid_table.seid_enabled = 1;
161		rc = -EAGAIN;	/* indicate success and enabling of seid */
162	}
163#endif
164	write_unlock(&smc_clc_eid_table.lock);
165	return rc;
166}
167
168int smc_nl_remove_ueid(struct sk_buff *skb, struct genl_info *info)
169{
170	struct nlattr *nla_ueid = info->attrs[SMC_NLA_EID_TABLE_ENTRY];
171	char *ueid;
172
173	if (!nla_ueid || nla_len(nla_ueid) != SMC_MAX_EID_LEN + 1)
174		return -EINVAL;
175	ueid = (char *)nla_data(nla_ueid);
176
177	return smc_clc_ueid_remove(ueid);
178}
179
180int smc_nl_flush_ueid(struct sk_buff *skb, struct genl_info *info)
181{
182	smc_clc_ueid_remove(NULL);
183	return 0;
184}
185
186static int smc_nl_ueid_dumpinfo(struct sk_buff *skb, u32 portid, u32 seq,
187				u32 flags, char *ueid)
188{
189	char ueid_str[SMC_MAX_EID_LEN + 1];
190	void *hdr;
191
192	hdr = genlmsg_put(skb, portid, seq, &smc_gen_nl_family,
193			  flags, SMC_NETLINK_DUMP_UEID);
194	if (!hdr)
195		return -ENOMEM;
196	memcpy(ueid_str, ueid, SMC_MAX_EID_LEN);
197	ueid_str[SMC_MAX_EID_LEN] = 0;
198	if (nla_put_string(skb, SMC_NLA_EID_TABLE_ENTRY, ueid_str)) {
199		genlmsg_cancel(skb, hdr);
200		return -EMSGSIZE;
201	}
202	genlmsg_end(skb, hdr);
203	return 0;
204}
205
206static int _smc_nl_ueid_dump(struct sk_buff *skb, u32 portid, u32 seq,
207			     int start_idx)
208{
209	struct smc_clc_eid_entry *lst_ueid;
210	int idx = 0;
211
212	read_lock(&smc_clc_eid_table.lock);
213	list_for_each_entry(lst_ueid, &smc_clc_eid_table.list, list) {
214		if (idx++ < start_idx)
215			continue;
216		if (smc_nl_ueid_dumpinfo(skb, portid, seq, NLM_F_MULTI,
217					 lst_ueid->eid)) {
218			--idx;
219			break;
220		}
221	}
222	read_unlock(&smc_clc_eid_table.lock);
223	return idx;
224}
225
226int smc_nl_dump_ueid(struct sk_buff *skb, struct netlink_callback *cb)
227{
228	struct smc_nl_dmp_ctx *cb_ctx = smc_nl_dmp_ctx(cb);
229	int idx;
230
231	idx = _smc_nl_ueid_dump(skb, NETLINK_CB(cb->skb).portid,
232				cb->nlh->nlmsg_seq, cb_ctx->pos[0]);
233
234	cb_ctx->pos[0] = idx;
235	return skb->len;
236}
237
238int smc_nl_dump_seid(struct sk_buff *skb, struct netlink_callback *cb)
239{
240	struct smc_nl_dmp_ctx *cb_ctx = smc_nl_dmp_ctx(cb);
241	char seid_str[SMC_MAX_EID_LEN + 1];
242	u8 seid_enabled;
243	void *hdr;
244	u8 *seid;
245
246	if (cb_ctx->pos[0])
247		return skb->len;
248
249	hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
250			  &smc_gen_nl_family, NLM_F_MULTI,
251			  SMC_NETLINK_DUMP_SEID);
252	if (!hdr)
253		return -ENOMEM;
254	if (!smc_ism_is_v2_capable())
255		goto end;
256
257	smc_ism_get_system_eid(&seid);
258	memcpy(seid_str, seid, SMC_MAX_EID_LEN);
259	seid_str[SMC_MAX_EID_LEN] = 0;
260	if (nla_put_string(skb, SMC_NLA_SEID_ENTRY, seid_str))
261		goto err;
262	read_lock(&smc_clc_eid_table.lock);
263	seid_enabled = smc_clc_eid_table.seid_enabled;
264	read_unlock(&smc_clc_eid_table.lock);
265	if (nla_put_u8(skb, SMC_NLA_SEID_ENABLED, seid_enabled))
266		goto err;
267end:
268	genlmsg_end(skb, hdr);
269	cb_ctx->pos[0]++;
270	return skb->len;
271err:
272	genlmsg_cancel(skb, hdr);
273	return -EMSGSIZE;
274}
275
276int smc_nl_enable_seid(struct sk_buff *skb, struct genl_info *info)
277{
278#if IS_ENABLED(CONFIG_S390)
279	write_lock(&smc_clc_eid_table.lock);
280	smc_clc_eid_table.seid_enabled = 1;
281	write_unlock(&smc_clc_eid_table.lock);
282	return 0;
283#else
284	return -EOPNOTSUPP;
285#endif
286}
287
288int smc_nl_disable_seid(struct sk_buff *skb, struct genl_info *info)
289{
290	int rc = 0;
291
292#if IS_ENABLED(CONFIG_S390)
293	write_lock(&smc_clc_eid_table.lock);
294	if (!smc_clc_eid_table.ueid_cnt)
295		rc = -ENOENT;
296	else
297		smc_clc_eid_table.seid_enabled = 0;
298	write_unlock(&smc_clc_eid_table.lock);
299#else
300	rc = -EOPNOTSUPP;
301#endif
302	return rc;
303}
304
305static bool _smc_clc_match_ueid(u8 *peer_ueid)
306{
307	struct smc_clc_eid_entry *tmp_ueid;
308
309	list_for_each_entry(tmp_ueid, &smc_clc_eid_table.list, list) {
310		if (!memcmp(tmp_ueid->eid, peer_ueid, SMC_MAX_EID_LEN))
311			return true;
312	}
313	return false;
314}
315
316bool smc_clc_match_eid(u8 *negotiated_eid,
317		       struct smc_clc_v2_extension *smc_v2_ext,
318		       u8 *peer_eid, u8 *local_eid)
319{
320	bool match = false;
321	int i;
322
323	negotiated_eid[0] = 0;
324	read_lock(&smc_clc_eid_table.lock);
325	if (peer_eid && local_eid &&
326	    smc_clc_eid_table.seid_enabled &&
327	    smc_v2_ext->hdr.flag.seid &&
328	    !memcmp(peer_eid, local_eid, SMC_MAX_EID_LEN)) {
329		memcpy(negotiated_eid, peer_eid, SMC_MAX_EID_LEN);
330		match = true;
331		goto out;
332	}
333
334	for (i = 0; i < smc_v2_ext->hdr.eid_cnt; i++) {
335		if (_smc_clc_match_ueid(smc_v2_ext->user_eids[i])) {
336			memcpy(negotiated_eid, smc_v2_ext->user_eids[i],
337			       SMC_MAX_EID_LEN);
338			match = true;
339			goto out;
340		}
341	}
342out:
343	read_unlock(&smc_clc_eid_table.lock);
344	return match;
345}
346
347/* check arriving CLC proposal */
348static bool smc_clc_msg_prop_valid(struct smc_clc_msg_proposal *pclc)
349{
350	struct smc_clc_msg_proposal_prefix *pclc_prfx;
351	struct smc_clc_smcd_v2_extension *smcd_v2_ext;
352	struct smc_clc_msg_hdr *hdr = &pclc->hdr;
353	struct smc_clc_v2_extension *v2_ext;
354
355	v2_ext = smc_get_clc_v2_ext(pclc);
356	pclc_prfx = smc_clc_proposal_get_prefix(pclc);
357	if (hdr->version == SMC_V1) {
358		if (hdr->typev1 == SMC_TYPE_N)
359			return false;
360		if (ntohs(hdr->length) !=
361			sizeof(*pclc) + ntohs(pclc->iparea_offset) +
362			sizeof(*pclc_prfx) +
363			pclc_prfx->ipv6_prefixes_cnt *
364				sizeof(struct smc_clc_ipv6_prefix) +
365			sizeof(struct smc_clc_msg_trail))
366			return false;
367	} else {
368		if (ntohs(hdr->length) !=
369			sizeof(*pclc) +
370			sizeof(struct smc_clc_msg_smcd) +
371			(hdr->typev1 != SMC_TYPE_N ?
372				sizeof(*pclc_prfx) +
373				pclc_prfx->ipv6_prefixes_cnt *
374				sizeof(struct smc_clc_ipv6_prefix) : 0) +
375			(hdr->typev2 != SMC_TYPE_N ?
376				sizeof(*v2_ext) +
377				v2_ext->hdr.eid_cnt * SMC_MAX_EID_LEN : 0) +
378			(smcd_indicated(hdr->typev2) ?
379				sizeof(*smcd_v2_ext) + v2_ext->hdr.ism_gid_cnt *
380					sizeof(struct smc_clc_smcd_gid_chid) :
381				0) +
382			sizeof(struct smc_clc_msg_trail))
383			return false;
384	}
385	return true;
386}
387
388/* check arriving CLC accept or confirm */
389static bool
390smc_clc_msg_acc_conf_valid(struct smc_clc_msg_accept_confirm *clc)
391{
392	struct smc_clc_msg_hdr *hdr = &clc->hdr;
393
394	if (hdr->typev1 != SMC_TYPE_R && hdr->typev1 != SMC_TYPE_D)
395		return false;
396	if (hdr->version == SMC_V1) {
397		if ((hdr->typev1 == SMC_TYPE_R &&
398		     ntohs(hdr->length) != SMCR_CLC_ACCEPT_CONFIRM_LEN) ||
399		    (hdr->typev1 == SMC_TYPE_D &&
400		     ntohs(hdr->length) != SMCD_CLC_ACCEPT_CONFIRM_LEN))
401			return false;
402	} else {
403		if (hdr->typev1 == SMC_TYPE_D &&
404		    ntohs(hdr->length) < SMCD_CLC_ACCEPT_CONFIRM_LEN_V2)
405			return false;
406		if (hdr->typev1 == SMC_TYPE_R &&
407		    ntohs(hdr->length) < SMCR_CLC_ACCEPT_CONFIRM_LEN_V2)
408			return false;
409	}
410	return true;
411}
412
413/* check arriving CLC decline */
414static bool
415smc_clc_msg_decl_valid(struct smc_clc_msg_decline *dclc)
416{
417	struct smc_clc_msg_hdr *hdr = &dclc->hdr;
418
419	if (hdr->typev1 != SMC_TYPE_R && hdr->typev1 != SMC_TYPE_D)
420		return false;
421	if (hdr->version == SMC_V1) {
422		if (ntohs(hdr->length) != sizeof(struct smc_clc_msg_decline))
423			return false;
424	} else {
425		if (ntohs(hdr->length) != sizeof(struct smc_clc_msg_decline_v2))
426			return false;
427	}
428	return true;
429}
430
431static int smc_clc_fill_fce_v2x(struct smc_clc_first_contact_ext_v2x *fce_v2x,
432				struct smc_init_info *ini)
433{
434	int ret = sizeof(*fce_v2x);
435
436	memset(fce_v2x, 0, sizeof(*fce_v2x));
437	fce_v2x->fce_v2_base.os_type = SMC_CLC_OS_LINUX;
438	fce_v2x->fce_v2_base.release = ini->release_nr;
439	memcpy(fce_v2x->fce_v2_base.hostname,
440	       smc_hostname, sizeof(smc_hostname));
441	if (ini->is_smcd && ini->release_nr < SMC_RELEASE_1) {
442		ret = sizeof(struct smc_clc_first_contact_ext);
443		goto out;
444	}
445
446	if (ini->release_nr >= SMC_RELEASE_1) {
447		if (!ini->is_smcd) {
448			fce_v2x->max_conns = ini->max_conns;
449			fce_v2x->max_links = ini->max_links;
450		}
451		fce_v2x->feature_mask = htons(ini->feature_mask);
452	}
453
454out:
455	return ret;
456}
457
458/* check if received message has a correct header length and contains valid
459 * heading and trailing eyecatchers
460 */
461static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm, bool check_trl)
462{
463	struct smc_clc_msg_accept_confirm *clc;
464	struct smc_clc_msg_proposal *pclc;
465	struct smc_clc_msg_decline *dclc;
466	struct smc_clc_msg_trail *trl;
467
468	if (memcmp(clcm->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&
469	    memcmp(clcm->eyecatcher, SMCD_EYECATCHER, sizeof(SMCD_EYECATCHER)))
470		return false;
471	switch (clcm->type) {
472	case SMC_CLC_PROPOSAL:
473		pclc = (struct smc_clc_msg_proposal *)clcm;
474		if (!smc_clc_msg_prop_valid(pclc))
475			return false;
476		trl = (struct smc_clc_msg_trail *)
477			((u8 *)pclc + ntohs(pclc->hdr.length) - sizeof(*trl));
478		break;
479	case SMC_CLC_ACCEPT:
480	case SMC_CLC_CONFIRM:
481		clc = (struct smc_clc_msg_accept_confirm *)clcm;
482		if (!smc_clc_msg_acc_conf_valid(clc))
483			return false;
484		trl = (struct smc_clc_msg_trail *)
485			((u8 *)clc + ntohs(clc->hdr.length) - sizeof(*trl));
486		break;
487	case SMC_CLC_DECLINE:
488		dclc = (struct smc_clc_msg_decline *)clcm;
489		if (!smc_clc_msg_decl_valid(dclc))
490			return false;
491		check_trl = false;
492		break;
493	default:
494		return false;
495	}
496	if (check_trl &&
497	    memcmp(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&
498	    memcmp(trl->eyecatcher, SMCD_EYECATCHER, sizeof(SMCD_EYECATCHER)))
499		return false;
500	return true;
501}
502
503/* find ipv4 addr on device and get the prefix len, fill CLC proposal msg */
504static int smc_clc_prfx_set4_rcu(struct dst_entry *dst, __be32 ipv4,
505				 struct smc_clc_msg_proposal_prefix *prop)
506{
507	struct in_device *in_dev = __in_dev_get_rcu(dst->dev);
508	const struct in_ifaddr *ifa;
509
510	if (!in_dev)
511		return -ENODEV;
512
513	in_dev_for_each_ifa_rcu(ifa, in_dev) {
514		if (!inet_ifa_match(ipv4, ifa))
515			continue;
516		prop->prefix_len = inet_mask_len(ifa->ifa_mask);
517		prop->outgoing_subnet = ifa->ifa_address & ifa->ifa_mask;
518		/* prop->ipv6_prefixes_cnt = 0; already done by memset before */
519		return 0;
520	}
521	return -ENOENT;
522}
523
524/* fill CLC proposal msg with ipv6 prefixes from device */
525static int smc_clc_prfx_set6_rcu(struct dst_entry *dst,
526				 struct smc_clc_msg_proposal_prefix *prop,
527				 struct smc_clc_ipv6_prefix *ipv6_prfx)
528{
529#if IS_ENABLED(CONFIG_IPV6)
530	struct inet6_dev *in6_dev = __in6_dev_get(dst->dev);
531	struct inet6_ifaddr *ifa;
532	int cnt = 0;
533
534	if (!in6_dev)
535		return -ENODEV;
536	/* use a maximum of 8 IPv6 prefixes from device */
537	list_for_each_entry(ifa, &in6_dev->addr_list, if_list) {
538		if (ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)
539			continue;
540		ipv6_addr_prefix(&ipv6_prfx[cnt].prefix,
541				 &ifa->addr, ifa->prefix_len);
542		ipv6_prfx[cnt].prefix_len = ifa->prefix_len;
543		cnt++;
544		if (cnt == SMC_CLC_MAX_V6_PREFIX)
545			break;
546	}
547	prop->ipv6_prefixes_cnt = cnt;
548	if (cnt)
549		return 0;
550#endif
551	return -ENOENT;
552}
553
554/* retrieve and set prefixes in CLC proposal msg */
555static int smc_clc_prfx_set(struct socket *clcsock,
556			    struct smc_clc_msg_proposal_prefix *prop,
557			    struct smc_clc_ipv6_prefix *ipv6_prfx)
558{
559	struct dst_entry *dst = sk_dst_get(clcsock->sk);
560	struct sockaddr_storage addrs;
561	struct sockaddr_in6 *addr6;
562	struct sockaddr_in *addr;
563	int rc = -ENOENT;
564
565	if (!dst) {
566		rc = -ENOTCONN;
567		goto out;
568	}
569	if (!dst->dev) {
570		rc = -ENODEV;
571		goto out_rel;
572	}
573	/* get address to which the internal TCP socket is bound */
574	if (kernel_getsockname(clcsock, (struct sockaddr *)&addrs) < 0)
575		goto out_rel;
576	/* analyze IP specific data of net_device belonging to TCP socket */
577	addr6 = (struct sockaddr_in6 *)&addrs;
578	rcu_read_lock();
579	if (addrs.ss_family == PF_INET) {
580		/* IPv4 */
581		addr = (struct sockaddr_in *)&addrs;
582		rc = smc_clc_prfx_set4_rcu(dst, addr->sin_addr.s_addr, prop);
583	} else if (ipv6_addr_v4mapped(&addr6->sin6_addr)) {
584		/* mapped IPv4 address - peer is IPv4 only */
585		rc = smc_clc_prfx_set4_rcu(dst, addr6->sin6_addr.s6_addr32[3],
586					   prop);
587	} else {
588		/* IPv6 */
589		rc = smc_clc_prfx_set6_rcu(dst, prop, ipv6_prfx);
590	}
591	rcu_read_unlock();
592out_rel:
593	dst_release(dst);
594out:
595	return rc;
596}
597
598/* match ipv4 addrs of dev against addr in CLC proposal */
599static int smc_clc_prfx_match4_rcu(struct net_device *dev,
600				   struct smc_clc_msg_proposal_prefix *prop)
601{
602	struct in_device *in_dev = __in_dev_get_rcu(dev);
603	const struct in_ifaddr *ifa;
604
605	if (!in_dev)
606		return -ENODEV;
607	in_dev_for_each_ifa_rcu(ifa, in_dev) {
608		if (prop->prefix_len == inet_mask_len(ifa->ifa_mask) &&
609		    inet_ifa_match(prop->outgoing_subnet, ifa))
610			return 0;
611	}
612
613	return -ENOENT;
614}
615
616/* match ipv6 addrs of dev against addrs in CLC proposal */
617static int smc_clc_prfx_match6_rcu(struct net_device *dev,
618				   struct smc_clc_msg_proposal_prefix *prop)
619{
620#if IS_ENABLED(CONFIG_IPV6)
621	struct inet6_dev *in6_dev = __in6_dev_get(dev);
622	struct smc_clc_ipv6_prefix *ipv6_prfx;
623	struct inet6_ifaddr *ifa;
624	int i, max;
625
626	if (!in6_dev)
627		return -ENODEV;
628	/* ipv6 prefix list starts behind smc_clc_msg_proposal_prefix */
629	ipv6_prfx = (struct smc_clc_ipv6_prefix *)((u8 *)prop + sizeof(*prop));
630	max = min_t(u8, prop->ipv6_prefixes_cnt, SMC_CLC_MAX_V6_PREFIX);
631	list_for_each_entry(ifa, &in6_dev->addr_list, if_list) {
632		if (ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)
633			continue;
634		for (i = 0; i < max; i++) {
635			if (ifa->prefix_len == ipv6_prfx[i].prefix_len &&
636			    ipv6_prefix_equal(&ifa->addr, &ipv6_prfx[i].prefix,
637					      ifa->prefix_len))
638				return 0;
639		}
640	}
641#endif
642	return -ENOENT;
643}
644
645/* check if proposed prefixes match one of our device prefixes */
646int smc_clc_prfx_match(struct socket *clcsock,
647		       struct smc_clc_msg_proposal_prefix *prop)
648{
649	struct dst_entry *dst = sk_dst_get(clcsock->sk);
650	int rc;
651
652	if (!dst) {
653		rc = -ENOTCONN;
654		goto out;
655	}
656	if (!dst->dev) {
657		rc = -ENODEV;
658		goto out_rel;
659	}
660	rcu_read_lock();
661	if (!prop->ipv6_prefixes_cnt)
662		rc = smc_clc_prfx_match4_rcu(dst->dev, prop);
663	else
664		rc = smc_clc_prfx_match6_rcu(dst->dev, prop);
665	rcu_read_unlock();
666out_rel:
667	dst_release(dst);
668out:
669	return rc;
670}
671
672/* Wait for data on the tcp-socket, analyze received data
673 * Returns:
674 * 0 if success and it was not a decline that we received.
675 * SMC_CLC_DECL_REPLY if decline received for fallback w/o another decl send.
676 * clcsock error, -EINTR, -ECONNRESET, -EPROTO otherwise.
677 */
678int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
679		     u8 expected_type, unsigned long timeout)
680{
681	long rcvtimeo = smc->clcsock->sk->sk_rcvtimeo;
682	struct sock *clc_sk = smc->clcsock->sk;
683	struct smc_clc_msg_hdr *clcm = buf;
684	struct msghdr msg = {NULL, 0};
685	int reason_code = 0;
686	struct kvec vec = {buf, buflen};
687	int len, datlen, recvlen;
688	bool check_trl = true;
689	int krflags;
690
691	/* peek the first few bytes to determine length of data to receive
692	 * so we don't consume any subsequent CLC message or payload data
693	 * in the TCP byte stream
694	 */
695	/*
696	 * Caller must make sure that buflen is no less than
697	 * sizeof(struct smc_clc_msg_hdr)
698	 */
699	krflags = MSG_PEEK | MSG_WAITALL;
700	clc_sk->sk_rcvtimeo = timeout;
701	iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1,
702			sizeof(struct smc_clc_msg_hdr));
703	len = sock_recvmsg(smc->clcsock, &msg, krflags);
704	if (signal_pending(current)) {
705		reason_code = -EINTR;
706		clc_sk->sk_err = EINTR;
707		smc->sk.sk_err = EINTR;
708		goto out;
709	}
710	if (clc_sk->sk_err) {
711		reason_code = -clc_sk->sk_err;
712		if (clc_sk->sk_err == EAGAIN &&
713		    expected_type == SMC_CLC_DECLINE)
714			clc_sk->sk_err = 0; /* reset for fallback usage */
715		else
716			smc->sk.sk_err = clc_sk->sk_err;
717		goto out;
718	}
719	if (!len) { /* peer has performed orderly shutdown */
720		smc->sk.sk_err = ECONNRESET;
721		reason_code = -ECONNRESET;
722		goto out;
723	}
724	if (len < 0) {
725		if (len != -EAGAIN || expected_type != SMC_CLC_DECLINE)
726			smc->sk.sk_err = -len;
727		reason_code = len;
728		goto out;
729	}
730	datlen = ntohs(clcm->length);
731	if ((len < sizeof(struct smc_clc_msg_hdr)) ||
732	    (clcm->version < SMC_V1) ||
733	    ((clcm->type != SMC_CLC_DECLINE) &&
734	     (clcm->type != expected_type))) {
735		smc->sk.sk_err = EPROTO;
736		reason_code = -EPROTO;
737		goto out;
738	}
739
740	/* receive the complete CLC message */
741	memset(&msg, 0, sizeof(struct msghdr));
742	if (datlen > buflen) {
743		check_trl = false;
744		recvlen = buflen;
745	} else {
746		recvlen = datlen;
747	}
748	iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, recvlen);
749	krflags = MSG_WAITALL;
750	len = sock_recvmsg(smc->clcsock, &msg, krflags);
751	if (len < recvlen || !smc_clc_msg_hdr_valid(clcm, check_trl)) {
752		smc->sk.sk_err = EPROTO;
753		reason_code = -EPROTO;
754		goto out;
755	}
756	datlen -= len;
757	while (datlen) {
758		u8 tmp[SMC_CLC_RECV_BUF_LEN];
759
760		vec.iov_base = &tmp;
761		vec.iov_len = SMC_CLC_RECV_BUF_LEN;
762		/* receive remaining proposal message */
763		recvlen = datlen > SMC_CLC_RECV_BUF_LEN ?
764						SMC_CLC_RECV_BUF_LEN : datlen;
765		iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, recvlen);
766		len = sock_recvmsg(smc->clcsock, &msg, krflags);
767		datlen -= len;
768	}
769	if (clcm->type == SMC_CLC_DECLINE) {
770		struct smc_clc_msg_decline *dclc;
771
772		dclc = (struct smc_clc_msg_decline *)clcm;
773		reason_code = SMC_CLC_DECL_PEERDECL;
774		smc->peer_diagnosis = ntohl(dclc->peer_diagnosis);
775		if (((struct smc_clc_msg_decline *)buf)->hdr.typev2 &
776						SMC_FIRST_CONTACT_MASK) {
777			smc->conn.lgr->sync_err = 1;
778			smc_lgr_terminate_sched(smc->conn.lgr);
779		}
780	}
781
782out:
783	clc_sk->sk_rcvtimeo = rcvtimeo;
784	return reason_code;
785}
786
787/* send CLC DECLINE message across internal TCP socket */
788int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, u8 version)
789{
790	struct smc_clc_msg_decline *dclc_v1;
791	struct smc_clc_msg_decline_v2 dclc;
792	struct msghdr msg;
793	int len, send_len;
794	struct kvec vec;
795
796	dclc_v1 = (struct smc_clc_msg_decline *)&dclc;
797	memset(&dclc, 0, sizeof(dclc));
798	memcpy(dclc.hdr.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
799	dclc.hdr.type = SMC_CLC_DECLINE;
800	dclc.hdr.version = version;
801	dclc.os_type = version == SMC_V1 ? 0 : SMC_CLC_OS_LINUX;
802	dclc.hdr.typev2 = (peer_diag_info == SMC_CLC_DECL_SYNCERR) ?
803						SMC_FIRST_CONTACT_MASK : 0;
804	if ((!smc_conn_lgr_valid(&smc->conn) || !smc->conn.lgr->is_smcd) &&
805	    smc_ib_is_valid_local_systemid())
806		memcpy(dclc.id_for_peer, local_systemid,
807		       sizeof(local_systemid));
808	dclc.peer_diagnosis = htonl(peer_diag_info);
809	if (version == SMC_V1) {
810		memcpy(dclc_v1->trl.eyecatcher, SMC_EYECATCHER,
811		       sizeof(SMC_EYECATCHER));
812		send_len = sizeof(*dclc_v1);
813	} else {
814		memcpy(dclc.trl.eyecatcher, SMC_EYECATCHER,
815		       sizeof(SMC_EYECATCHER));
816		send_len = sizeof(dclc);
817	}
818	dclc.hdr.length = htons(send_len);
819
820	memset(&msg, 0, sizeof(msg));
821	vec.iov_base = &dclc;
822	vec.iov_len = send_len;
823	len = kernel_sendmsg(smc->clcsock, &msg, &vec, 1, send_len);
824	if (len < 0 || len < send_len)
825		len = -EPROTO;
826	return len > 0 ? 0 : len;
827}
828
829/* send CLC PROPOSAL message across internal TCP socket */
830int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
831{
832	struct smc_clc_smcd_v2_extension *smcd_v2_ext;
833	struct smc_clc_msg_proposal_prefix *pclc_prfx;
834	struct smc_clc_msg_proposal *pclc_base;
835	struct smc_clc_smcd_gid_chid *gidchids;
836	struct smc_clc_msg_proposal_area *pclc;
837	struct smc_clc_ipv6_prefix *ipv6_prfx;
838	struct net *net = sock_net(&smc->sk);
839	struct smc_clc_v2_extension *v2_ext;
840	struct smc_clc_msg_smcd *pclc_smcd;
841	struct smc_clc_msg_trail *trl;
842	struct smcd_dev *smcd;
843	int len, i, plen, rc;
844	int reason_code = 0;
845	struct kvec vec[8];
846	struct msghdr msg;
847
848	pclc = kzalloc(sizeof(*pclc), GFP_KERNEL);
849	if (!pclc)
850		return -ENOMEM;
851
852	pclc_base = &pclc->pclc_base;
853	pclc_smcd = &pclc->pclc_smcd;
854	pclc_prfx = &pclc->pclc_prfx;
855	ipv6_prfx = pclc->pclc_prfx_ipv6;
856	v2_ext = &pclc->pclc_v2_ext;
857	smcd_v2_ext = &pclc->pclc_smcd_v2_ext;
858	gidchids = pclc->pclc_gidchids;
859	trl = &pclc->pclc_trl;
860
861	pclc_base->hdr.version = SMC_V2;
862	pclc_base->hdr.typev1 = ini->smc_type_v1;
863	pclc_base->hdr.typev2 = ini->smc_type_v2;
864	plen = sizeof(*pclc_base) + sizeof(*pclc_smcd) + sizeof(*trl);
865
866	/* retrieve ip prefixes for CLC proposal msg */
867	if (ini->smc_type_v1 != SMC_TYPE_N) {
868		rc = smc_clc_prfx_set(smc->clcsock, pclc_prfx, ipv6_prfx);
869		if (rc) {
870			if (ini->smc_type_v2 == SMC_TYPE_N) {
871				kfree(pclc);
872				return SMC_CLC_DECL_CNFERR;
873			}
874			pclc_base->hdr.typev1 = SMC_TYPE_N;
875		} else {
876			pclc_base->iparea_offset = htons(sizeof(*pclc_smcd));
877			plen += sizeof(*pclc_prfx) +
878					pclc_prfx->ipv6_prefixes_cnt *
879					sizeof(ipv6_prfx[0]);
880		}
881	}
882
883	/* build SMC Proposal CLC message */
884	memcpy(pclc_base->hdr.eyecatcher, SMC_EYECATCHER,
885	       sizeof(SMC_EYECATCHER));
886	pclc_base->hdr.type = SMC_CLC_PROPOSAL;
887	if (smcr_indicated(ini->smc_type_v1)) {
888		/* add SMC-R specifics */
889		memcpy(pclc_base->lcl.id_for_peer, local_systemid,
890		       sizeof(local_systemid));
891		memcpy(pclc_base->lcl.gid, ini->ib_gid, SMC_GID_SIZE);
892		memcpy(pclc_base->lcl.mac, &ini->ib_dev->mac[ini->ib_port - 1],
893		       ETH_ALEN);
894	}
895	if (smcd_indicated(ini->smc_type_v1)) {
896		struct smcd_gid smcd_gid;
897
898		/* add SMC-D specifics */
899		if (ini->ism_dev[0]) {
900			smcd = ini->ism_dev[0];
901			smcd->ops->get_local_gid(smcd, &smcd_gid);
902			pclc_smcd->ism.gid = htonll(smcd_gid.gid);
903			pclc_smcd->ism.chid =
904				htons(smc_ism_get_chid(ini->ism_dev[0]));
905		}
906	}
907	if (ini->smc_type_v2 == SMC_TYPE_N) {
908		pclc_smcd->v2_ext_offset = 0;
909	} else {
910		struct smc_clc_eid_entry *ueident;
911		u16 v2_ext_offset;
912
913		v2_ext->hdr.flag.release = SMC_RELEASE;
914		v2_ext_offset = sizeof(*pclc_smcd) -
915			offsetofend(struct smc_clc_msg_smcd, v2_ext_offset);
916		if (ini->smc_type_v1 != SMC_TYPE_N)
917			v2_ext_offset += sizeof(*pclc_prfx) +
918						pclc_prfx->ipv6_prefixes_cnt *
919						sizeof(ipv6_prfx[0]);
920		pclc_smcd->v2_ext_offset = htons(v2_ext_offset);
921		plen += sizeof(*v2_ext);
922
923		v2_ext->feature_mask = htons(SMC_FEATURE_MASK);
924		read_lock(&smc_clc_eid_table.lock);
925		v2_ext->hdr.eid_cnt = smc_clc_eid_table.ueid_cnt;
926		plen += smc_clc_eid_table.ueid_cnt * SMC_MAX_EID_LEN;
927		i = 0;
928		list_for_each_entry(ueident, &smc_clc_eid_table.list, list) {
929			memcpy(v2_ext->user_eids[i++], ueident->eid,
930			       sizeof(ueident->eid));
931		}
932		read_unlock(&smc_clc_eid_table.lock);
933	}
934	if (smcd_indicated(ini->smc_type_v2)) {
935		struct smcd_gid smcd_gid;
936		u8 *eid = NULL;
937		int entry = 0;
938
939		v2_ext->hdr.flag.seid = smc_clc_eid_table.seid_enabled;
940		v2_ext->hdr.smcd_v2_ext_offset = htons(sizeof(*v2_ext) -
941				offsetofend(struct smc_clnt_opts_area_hdr,
942					    smcd_v2_ext_offset) +
943				v2_ext->hdr.eid_cnt * SMC_MAX_EID_LEN);
944		smc_ism_get_system_eid(&eid);
945		if (eid && v2_ext->hdr.flag.seid)
946			memcpy(smcd_v2_ext->system_eid, eid, SMC_MAX_EID_LEN);
947		plen += sizeof(*smcd_v2_ext);
948		if (ini->ism_offered_cnt) {
949			for (i = 1; i <= ini->ism_offered_cnt; i++) {
950				smcd = ini->ism_dev[i];
951				smcd->ops->get_local_gid(smcd, &smcd_gid);
952				gidchids[entry].chid =
953					htons(smc_ism_get_chid(ini->ism_dev[i]));
954				gidchids[entry].gid = htonll(smcd_gid.gid);
955				if (smc_ism_is_emulated(smcd)) {
956					/* an Emulated-ISM device takes two
957					 * entries. CHID of the second entry
958					 * repeats that of the first entry.
959					 */
960					gidchids[entry + 1].chid =
961						gidchids[entry].chid;
962					gidchids[entry + 1].gid =
963						htonll(smcd_gid.gid_ext);
964					entry++;
965				}
966				entry++;
967			}
968			plen += entry * sizeof(struct smc_clc_smcd_gid_chid);
969		}
970		v2_ext->hdr.ism_gid_cnt = entry;
971	}
972	if (smcr_indicated(ini->smc_type_v2)) {
973		memcpy(v2_ext->roce, ini->smcrv2.ib_gid_v2, SMC_GID_SIZE);
974		v2_ext->max_conns = net->smc.sysctl_max_conns_per_lgr;
975		v2_ext->max_links = net->smc.sysctl_max_links_per_lgr;
976	}
977
978	pclc_base->hdr.length = htons(plen);
979	memcpy(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
980
981	/* send SMC Proposal CLC message */
982	memset(&msg, 0, sizeof(msg));
983	i = 0;
984	vec[i].iov_base = pclc_base;
985	vec[i++].iov_len = sizeof(*pclc_base);
986	vec[i].iov_base = pclc_smcd;
987	vec[i++].iov_len = sizeof(*pclc_smcd);
988	if (ini->smc_type_v1 != SMC_TYPE_N) {
989		vec[i].iov_base = pclc_prfx;
990		vec[i++].iov_len = sizeof(*pclc_prfx);
991		if (pclc_prfx->ipv6_prefixes_cnt > 0) {
992			vec[i].iov_base = ipv6_prfx;
993			vec[i++].iov_len = pclc_prfx->ipv6_prefixes_cnt *
994					   sizeof(ipv6_prfx[0]);
995		}
996	}
997	if (ini->smc_type_v2 != SMC_TYPE_N) {
998		vec[i].iov_base = v2_ext;
999		vec[i++].iov_len = sizeof(*v2_ext) +
1000				   (v2_ext->hdr.eid_cnt * SMC_MAX_EID_LEN);
1001		if (smcd_indicated(ini->smc_type_v2)) {
1002			vec[i].iov_base = smcd_v2_ext;
1003			vec[i++].iov_len = sizeof(*smcd_v2_ext);
1004			if (ini->ism_offered_cnt) {
1005				vec[i].iov_base = gidchids;
1006				vec[i++].iov_len = v2_ext->hdr.ism_gid_cnt *
1007					sizeof(struct smc_clc_smcd_gid_chid);
1008			}
1009		}
1010	}
1011	vec[i].iov_base = trl;
1012	vec[i++].iov_len = sizeof(*trl);
1013	/* due to the few bytes needed for clc-handshake this cannot block */
1014	len = kernel_sendmsg(smc->clcsock, &msg, vec, i, plen);
1015	if (len < 0) {
1016		smc->sk.sk_err = smc->clcsock->sk->sk_err;
1017		reason_code = -smc->sk.sk_err;
1018	} else if (len < ntohs(pclc_base->hdr.length)) {
1019		reason_code = -ENETUNREACH;
1020		smc->sk.sk_err = -reason_code;
1021	}
1022
1023	kfree(pclc);
1024	return reason_code;
1025}
1026
1027static void
1028smcd_clc_prep_confirm_accept(struct smc_connection *conn,
1029			     struct smc_clc_msg_accept_confirm *clc,
1030			     int first_contact, u8 version,
1031			     u8 *eid, struct smc_init_info *ini,
1032			     int *fce_len,
1033			     struct smc_clc_first_contact_ext_v2x *fce_v2x,
1034			     struct smc_clc_msg_trail *trl)
1035{
1036	struct smcd_dev *smcd = conn->lgr->smcd;
1037	struct smcd_gid smcd_gid;
1038	u16 chid;
1039	int len;
1040
1041	/* SMC-D specific settings */
1042	memcpy(clc->hdr.eyecatcher, SMCD_EYECATCHER,
1043	       sizeof(SMCD_EYECATCHER));
1044	smcd->ops->get_local_gid(smcd, &smcd_gid);
1045	clc->hdr.typev1 = SMC_TYPE_D;
1046	clc->d0.gid = htonll(smcd_gid.gid);
1047	clc->d0.token = htonll(conn->rmb_desc->token);
1048	clc->d0.dmbe_size = conn->rmbe_size_comp;
1049	clc->d0.dmbe_idx = 0;
1050	memcpy(&clc->d0.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
1051	if (version == SMC_V1) {
1052		clc->hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
1053	} else {
1054		chid = smc_ism_get_chid(smcd);
1055		clc->d1.chid = htons(chid);
1056		if (eid && eid[0])
1057			memcpy(clc->d1.eid, eid, SMC_MAX_EID_LEN);
1058		if (__smc_ism_is_emulated(chid))
1059			clc->d1.gid_ext = htonll(smcd_gid.gid_ext);
1060		len = SMCD_CLC_ACCEPT_CONFIRM_LEN_V2;
1061		if (first_contact) {
1062			*fce_len = smc_clc_fill_fce_v2x(fce_v2x, ini);
1063			len += *fce_len;
1064		}
1065		clc->hdr.length = htons(len);
1066	}
1067	memcpy(trl->eyecatcher, SMCD_EYECATCHER,
1068	       sizeof(SMCD_EYECATCHER));
1069}
1070
1071static void
1072smcr_clc_prep_confirm_accept(struct smc_connection *conn,
1073			     struct smc_clc_msg_accept_confirm *clc,
1074			     int first_contact, u8 version,
1075			     u8 *eid, struct smc_init_info *ini,
1076			     int *fce_len,
1077			     struct smc_clc_first_contact_ext_v2x *fce_v2x,
1078			     struct smc_clc_fce_gid_ext *gle,
1079			     struct smc_clc_msg_trail *trl)
1080{
1081	struct smc_link *link = conn->lnk;
1082	int len;
1083
1084	/* SMC-R specific settings */
1085	memcpy(clc->hdr.eyecatcher, SMC_EYECATCHER,
1086	       sizeof(SMC_EYECATCHER));
1087	clc->hdr.typev1 = SMC_TYPE_R;
1088	memcpy(clc->r0.lcl.id_for_peer, local_systemid,
1089	       sizeof(local_systemid));
1090	memcpy(&clc->r0.lcl.gid, link->gid, SMC_GID_SIZE);
1091	memcpy(&clc->r0.lcl.mac, &link->smcibdev->mac[link->ibport - 1],
1092	       ETH_ALEN);
1093	hton24(clc->r0.qpn, link->roce_qp->qp_num);
1094	clc->r0.rmb_rkey =
1095		htonl(conn->rmb_desc->mr[link->link_idx]->rkey);
1096	clc->r0.rmbe_idx = 1; /* for now: 1 RMB = 1 RMBE */
1097	clc->r0.rmbe_alert_token = htonl(conn->alert_token_local);
1098	switch (clc->hdr.type) {
1099	case SMC_CLC_ACCEPT:
1100		clc->r0.qp_mtu = link->path_mtu;
1101		break;
1102	case SMC_CLC_CONFIRM:
1103		clc->r0.qp_mtu = min(link->path_mtu, link->peer_mtu);
1104		break;
1105	}
1106	clc->r0.rmbe_size = conn->rmbe_size_comp;
1107	clc->r0.rmb_dma_addr = conn->rmb_desc->is_vm ?
1108		cpu_to_be64((uintptr_t)conn->rmb_desc->cpu_addr) :
1109		cpu_to_be64((u64)sg_dma_address
1110			    (conn->rmb_desc->sgt[link->link_idx].sgl));
1111	hton24(clc->r0.psn, link->psn_initial);
1112	if (version == SMC_V1) {
1113		clc->hdr.length = htons(SMCR_CLC_ACCEPT_CONFIRM_LEN);
1114	} else {
1115		if (eid && eid[0])
1116			memcpy(clc->r1.eid, eid, SMC_MAX_EID_LEN);
1117		len = SMCR_CLC_ACCEPT_CONFIRM_LEN_V2;
1118		if (first_contact) {
1119			*fce_len = smc_clc_fill_fce_v2x(fce_v2x, ini);
1120			len += *fce_len;
1121			fce_v2x->fce_v2_base.v2_direct =
1122				!link->lgr->uses_gateway;
1123			if (clc->hdr.type == SMC_CLC_CONFIRM) {
1124				memset(gle, 0, sizeof(*gle));
1125				gle->gid_cnt = ini->smcrv2.gidlist.len;
1126				len += sizeof(*gle);
1127				len += gle->gid_cnt * sizeof(gle->gid[0]);
1128			}
1129		}
1130		clc->hdr.length = htons(len);
1131	}
1132	memcpy(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
1133}
1134
1135/* build and send CLC CONFIRM / ACCEPT message */
1136static int smc_clc_send_confirm_accept(struct smc_sock *smc,
1137				       struct smc_clc_msg_accept_confirm *clc,
1138				       int first_contact, u8 version,
1139				       u8 *eid, struct smc_init_info *ini)
1140{
1141	struct smc_clc_first_contact_ext_v2x fce_v2x;
1142	struct smc_connection *conn = &smc->conn;
1143	struct smc_clc_fce_gid_ext gle;
1144	struct smc_clc_msg_trail trl;
1145	int i, fce_len;
1146	struct kvec vec[5];
1147	struct msghdr msg;
1148
1149	/* send SMC Confirm CLC msg */
1150	clc->hdr.version = version;	/* SMC version */
1151	if (first_contact)
1152		clc->hdr.typev2 |= SMC_FIRST_CONTACT_MASK;
1153	if (conn->lgr->is_smcd)
1154		smcd_clc_prep_confirm_accept(conn, clc, first_contact,
1155					     version, eid, ini, &fce_len,
1156					     &fce_v2x, &trl);
1157	else
1158		smcr_clc_prep_confirm_accept(conn, clc, first_contact,
1159					     version, eid, ini, &fce_len,
1160					     &fce_v2x, &gle, &trl);
1161	memset(&msg, 0, sizeof(msg));
1162	i = 0;
1163	vec[i].iov_base = clc;
1164	if (version > SMC_V1)
1165		vec[i++].iov_len = (clc->hdr.typev1 == SMC_TYPE_D ?
1166					SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 :
1167					SMCR_CLC_ACCEPT_CONFIRM_LEN_V2) -
1168				   sizeof(trl);
1169	else
1170		vec[i++].iov_len = (clc->hdr.typev1 == SMC_TYPE_D ?
1171						SMCD_CLC_ACCEPT_CONFIRM_LEN :
1172						SMCR_CLC_ACCEPT_CONFIRM_LEN) -
1173				   sizeof(trl);
1174	if (version > SMC_V1 && first_contact) {
1175		vec[i].iov_base = &fce_v2x;
1176		vec[i++].iov_len = fce_len;
1177		if (!conn->lgr->is_smcd) {
1178			if (clc->hdr.type == SMC_CLC_CONFIRM) {
1179				vec[i].iov_base = &gle;
1180				vec[i++].iov_len = sizeof(gle);
1181				vec[i].iov_base = &ini->smcrv2.gidlist.list;
1182				vec[i++].iov_len = gle.gid_cnt *
1183						   sizeof(gle.gid[0]);
1184			}
1185		}
1186	}
1187	vec[i].iov_base = &trl;
1188	vec[i++].iov_len = sizeof(trl);
1189	return kernel_sendmsg(smc->clcsock, &msg, vec, 1,
1190			      ntohs(clc->hdr.length));
1191}
1192
1193/* send CLC CONFIRM message across internal TCP socket */
1194int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact,
1195			 u8 version, u8 *eid, struct smc_init_info *ini)
1196{
1197	struct smc_clc_msg_accept_confirm cclc;
1198	int reason_code = 0;
1199	int len;
1200
1201	/* send SMC Confirm CLC msg */
1202	memset(&cclc, 0, sizeof(cclc));
1203	cclc.hdr.type = SMC_CLC_CONFIRM;
1204	len = smc_clc_send_confirm_accept(smc, &cclc, clnt_first_contact,
1205					  version, eid, ini);
1206	if (len < ntohs(cclc.hdr.length)) {
1207		if (len >= 0) {
1208			reason_code = -ENETUNREACH;
1209			smc->sk.sk_err = -reason_code;
1210		} else {
1211			smc->sk.sk_err = smc->clcsock->sk->sk_err;
1212			reason_code = -smc->sk.sk_err;
1213		}
1214	}
1215	return reason_code;
1216}
1217
1218/* send CLC ACCEPT message across internal TCP socket */
1219int smc_clc_send_accept(struct smc_sock *new_smc, bool srv_first_contact,
1220			u8 version, u8 *negotiated_eid, struct smc_init_info *ini)
1221{
1222	struct smc_clc_msg_accept_confirm aclc;
1223	int len;
1224
1225	memset(&aclc, 0, sizeof(aclc));
1226	aclc.hdr.type = SMC_CLC_ACCEPT;
1227	len = smc_clc_send_confirm_accept(new_smc, &aclc, srv_first_contact,
1228					  version, negotiated_eid, ini);
1229	if (len < ntohs(aclc.hdr.length))
1230		len = len >= 0 ? -EPROTO : -new_smc->clcsock->sk->sk_err;
1231
1232	return len > 0 ? 0 : len;
1233}
1234
1235int smc_clc_srv_v2x_features_validate(struct smc_sock *smc,
1236				      struct smc_clc_msg_proposal *pclc,
1237				      struct smc_init_info *ini)
1238{
1239	struct smc_clc_v2_extension *pclc_v2_ext;
1240	struct net *net = sock_net(&smc->sk);
1241
1242	ini->max_conns = SMC_CONN_PER_LGR_MAX;
1243	ini->max_links = SMC_LINKS_ADD_LNK_MAX;
1244	ini->feature_mask = SMC_FEATURE_MASK;
1245
1246	if ((!(ini->smcd_version & SMC_V2) && !(ini->smcr_version & SMC_V2)) ||
1247	    ini->release_nr < SMC_RELEASE_1)
1248		return 0;
1249
1250	pclc_v2_ext = smc_get_clc_v2_ext(pclc);
1251	if (!pclc_v2_ext)
1252		return SMC_CLC_DECL_NOV2EXT;
1253
1254	if (ini->smcr_version & SMC_V2) {
1255		ini->max_conns = min_t(u8, pclc_v2_ext->max_conns,
1256				       net->smc.sysctl_max_conns_per_lgr);
1257		if (ini->max_conns < SMC_CONN_PER_LGR_MIN)
1258			return SMC_CLC_DECL_MAXCONNERR;
1259
1260		ini->max_links = min_t(u8, pclc_v2_ext->max_links,
1261				       net->smc.sysctl_max_links_per_lgr);
1262		if (ini->max_links < SMC_LINKS_ADD_LNK_MIN)
1263			return SMC_CLC_DECL_MAXLINKERR;
1264	}
1265
1266	return 0;
1267}
1268
1269int smc_clc_clnt_v2x_features_validate(struct smc_clc_first_contact_ext *fce,
1270				       struct smc_init_info *ini)
1271{
1272	struct smc_clc_first_contact_ext_v2x *fce_v2x =
1273		(struct smc_clc_first_contact_ext_v2x *)fce;
1274
1275	if (ini->release_nr < SMC_RELEASE_1)
1276		return 0;
1277
1278	if (!ini->is_smcd) {
1279		if (fce_v2x->max_conns < SMC_CONN_PER_LGR_MIN)
1280			return SMC_CLC_DECL_MAXCONNERR;
1281		ini->max_conns = fce_v2x->max_conns;
1282
1283		if (fce_v2x->max_links > SMC_LINKS_ADD_LNK_MAX ||
1284		    fce_v2x->max_links < SMC_LINKS_ADD_LNK_MIN)
1285			return SMC_CLC_DECL_MAXLINKERR;
1286		ini->max_links = fce_v2x->max_links;
1287	}
1288	/* common supplemental features of server and client */
1289	ini->feature_mask = ntohs(fce_v2x->feature_mask) & SMC_FEATURE_MASK;
1290
1291	return 0;
1292}
1293
1294int smc_clc_v2x_features_confirm_check(struct smc_clc_msg_accept_confirm *cclc,
1295				       struct smc_init_info *ini)
1296{
1297	struct smc_clc_first_contact_ext *fce =
1298		smc_get_clc_first_contact_ext(cclc, ini->is_smcd);
1299	struct smc_clc_first_contact_ext_v2x *fce_v2x =
1300		(struct smc_clc_first_contact_ext_v2x *)fce;
1301
1302	if (cclc->hdr.version == SMC_V1 ||
1303	    !(cclc->hdr.typev2 & SMC_FIRST_CONTACT_MASK))
1304		return 0;
1305
1306	if (ini->release_nr != fce->release)
1307		return SMC_CLC_DECL_RELEASEERR;
1308
1309	if (fce->release < SMC_RELEASE_1)
1310		return 0;
1311
1312	if (!ini->is_smcd) {
1313		if (fce_v2x->max_conns != ini->max_conns)
1314			return SMC_CLC_DECL_MAXCONNERR;
1315		if (fce_v2x->max_links != ini->max_links)
1316			return SMC_CLC_DECL_MAXLINKERR;
1317	}
1318	/* common supplemental features returned by client */
1319	ini->feature_mask = ntohs(fce_v2x->feature_mask);
1320
1321	return 0;
1322}
1323
1324void smc_clc_get_hostname(u8 **host)
1325{
1326	*host = &smc_hostname[0];
1327}
1328
1329void __init smc_clc_init(void)
1330{
1331	struct new_utsname *u;
1332
1333	memset(smc_hostname, _S, sizeof(smc_hostname)); /* ASCII blanks */
1334	u = utsname();
1335	memcpy(smc_hostname, u->nodename,
1336	       min_t(size_t, strlen(u->nodename), sizeof(smc_hostname)));
1337
1338	INIT_LIST_HEAD(&smc_clc_eid_table.list);
1339	rwlock_init(&smc_clc_eid_table.lock);
1340	smc_clc_eid_table.ueid_cnt = 0;
1341#if IS_ENABLED(CONFIG_S390)
1342	smc_clc_eid_table.seid_enabled = 1;
1343#else
1344	smc_clc_eid_table.seid_enabled = 0;
1345#endif
1346}
1347
1348void smc_clc_exit(void)
1349{
1350	smc_clc_ueid_remove(NULL);
1351}
1352