GNU Linux-libre 6.1.90-gnu
[releases.git] / net / smc / smc_clc.c
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 */
38 static const char SMC_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xd9'};
39 /* eye catcher "SMCD" EBCDIC for CLC messages */
40 static const char SMCD_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xc4'};
41
42 static u8 smc_hostname[SMC_MAX_HOSTNAME_LEN];
43
44 struct smc_clc_eid_table {
45         rwlock_t lock;
46         struct list_head list;
47         u8 ueid_cnt;
48         u8 seid_enabled;
49 };
50
51 static struct smc_clc_eid_table smc_clc_eid_table;
52
53 struct 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  */
63 static 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
82 static 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
112 err_out:
113         write_unlock(&smc_clc_eid_table.lock);
114         kfree(new_ueid);
115         return rc;
116 }
117
118 int 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
129 int 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 */
142 static 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
168 int 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
180 int smc_nl_flush_ueid(struct sk_buff *skb, struct genl_info *info)
181 {
182         smc_clc_ueid_remove(NULL);
183         return 0;
184 }
185
186 static 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
206 static 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
226 int 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
238 int 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;
267 end:
268         genlmsg_end(skb, hdr);
269         cb_ctx->pos[0]++;
270         return skb->len;
271 err:
272         genlmsg_cancel(skb, hdr);
273         return -EMSGSIZE;
274 }
275
276 int 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
288 int 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
305 static 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
316 bool 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         }
342 out:
343         read_unlock(&smc_clc_eid_table.lock);
344         return match;
345 }
346
347 /* check arriving CLC proposal */
348 static 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 */
389 static bool
390 smc_clc_msg_acc_conf_valid(struct smc_clc_msg_accept_confirm_v2 *clc_v2)
391 {
392         struct smc_clc_msg_hdr *hdr = &clc_v2->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                     (ntohs(hdr->length) != SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 +
406                                 sizeof(struct smc_clc_first_contact_ext)))
407                         return false;
408                 if (hdr->typev1 == SMC_TYPE_R &&
409                     ntohs(hdr->length) < SMCR_CLC_ACCEPT_CONFIRM_LEN_V2)
410                         return false;
411         }
412         return true;
413 }
414
415 /* check arriving CLC decline */
416 static bool
417 smc_clc_msg_decl_valid(struct smc_clc_msg_decline *dclc)
418 {
419         struct smc_clc_msg_hdr *hdr = &dclc->hdr;
420
421         if (hdr->typev1 != SMC_TYPE_R && hdr->typev1 != SMC_TYPE_D)
422                 return false;
423         if (hdr->version == SMC_V1) {
424                 if (ntohs(hdr->length) != sizeof(struct smc_clc_msg_decline))
425                         return false;
426         } else {
427                 if (ntohs(hdr->length) != sizeof(struct smc_clc_msg_decline_v2))
428                         return false;
429         }
430         return true;
431 }
432
433 static void smc_clc_fill_fce(struct smc_clc_first_contact_ext *fce, int *len)
434 {
435         memset(fce, 0, sizeof(*fce));
436         fce->os_type = SMC_CLC_OS_LINUX;
437         fce->release = SMC_RELEASE;
438         memcpy(fce->hostname, smc_hostname, sizeof(smc_hostname));
439         (*len) += sizeof(*fce);
440 }
441
442 /* check if received message has a correct header length and contains valid
443  * heading and trailing eyecatchers
444  */
445 static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm, bool check_trl)
446 {
447         struct smc_clc_msg_accept_confirm_v2 *clc_v2;
448         struct smc_clc_msg_proposal *pclc;
449         struct smc_clc_msg_decline *dclc;
450         struct smc_clc_msg_trail *trl;
451
452         if (memcmp(clcm->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&
453             memcmp(clcm->eyecatcher, SMCD_EYECATCHER, sizeof(SMCD_EYECATCHER)))
454                 return false;
455         switch (clcm->type) {
456         case SMC_CLC_PROPOSAL:
457                 pclc = (struct smc_clc_msg_proposal *)clcm;
458                 if (!smc_clc_msg_prop_valid(pclc))
459                         return false;
460                 trl = (struct smc_clc_msg_trail *)
461                         ((u8 *)pclc + ntohs(pclc->hdr.length) - sizeof(*trl));
462                 break;
463         case SMC_CLC_ACCEPT:
464         case SMC_CLC_CONFIRM:
465                 clc_v2 = (struct smc_clc_msg_accept_confirm_v2 *)clcm;
466                 if (!smc_clc_msg_acc_conf_valid(clc_v2))
467                         return false;
468                 trl = (struct smc_clc_msg_trail *)
469                         ((u8 *)clc_v2 + ntohs(clc_v2->hdr.length) -
470                                                         sizeof(*trl));
471                 break;
472         case SMC_CLC_DECLINE:
473                 dclc = (struct smc_clc_msg_decline *)clcm;
474                 if (!smc_clc_msg_decl_valid(dclc))
475                         return false;
476                 check_trl = false;
477                 break;
478         default:
479                 return false;
480         }
481         if (check_trl &&
482             memcmp(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&
483             memcmp(trl->eyecatcher, SMCD_EYECATCHER, sizeof(SMCD_EYECATCHER)))
484                 return false;
485         return true;
486 }
487
488 /* find ipv4 addr on device and get the prefix len, fill CLC proposal msg */
489 static int smc_clc_prfx_set4_rcu(struct dst_entry *dst, __be32 ipv4,
490                                  struct smc_clc_msg_proposal_prefix *prop)
491 {
492         struct in_device *in_dev = __in_dev_get_rcu(dst->dev);
493         const struct in_ifaddr *ifa;
494
495         if (!in_dev)
496                 return -ENODEV;
497
498         in_dev_for_each_ifa_rcu(ifa, in_dev) {
499                 if (!inet_ifa_match(ipv4, ifa))
500                         continue;
501                 prop->prefix_len = inet_mask_len(ifa->ifa_mask);
502                 prop->outgoing_subnet = ifa->ifa_address & ifa->ifa_mask;
503                 /* prop->ipv6_prefixes_cnt = 0; already done by memset before */
504                 return 0;
505         }
506         return -ENOENT;
507 }
508
509 /* fill CLC proposal msg with ipv6 prefixes from device */
510 static int smc_clc_prfx_set6_rcu(struct dst_entry *dst,
511                                  struct smc_clc_msg_proposal_prefix *prop,
512                                  struct smc_clc_ipv6_prefix *ipv6_prfx)
513 {
514 #if IS_ENABLED(CONFIG_IPV6)
515         struct inet6_dev *in6_dev = __in6_dev_get(dst->dev);
516         struct inet6_ifaddr *ifa;
517         int cnt = 0;
518
519         if (!in6_dev)
520                 return -ENODEV;
521         /* use a maximum of 8 IPv6 prefixes from device */
522         list_for_each_entry(ifa, &in6_dev->addr_list, if_list) {
523                 if (ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)
524                         continue;
525                 ipv6_addr_prefix(&ipv6_prfx[cnt].prefix,
526                                  &ifa->addr, ifa->prefix_len);
527                 ipv6_prfx[cnt].prefix_len = ifa->prefix_len;
528                 cnt++;
529                 if (cnt == SMC_CLC_MAX_V6_PREFIX)
530                         break;
531         }
532         prop->ipv6_prefixes_cnt = cnt;
533         if (cnt)
534                 return 0;
535 #endif
536         return -ENOENT;
537 }
538
539 /* retrieve and set prefixes in CLC proposal msg */
540 static int smc_clc_prfx_set(struct socket *clcsock,
541                             struct smc_clc_msg_proposal_prefix *prop,
542                             struct smc_clc_ipv6_prefix *ipv6_prfx)
543 {
544         struct dst_entry *dst = sk_dst_get(clcsock->sk);
545         struct sockaddr_storage addrs;
546         struct sockaddr_in6 *addr6;
547         struct sockaddr_in *addr;
548         int rc = -ENOENT;
549
550         if (!dst) {
551                 rc = -ENOTCONN;
552                 goto out;
553         }
554         if (!dst->dev) {
555                 rc = -ENODEV;
556                 goto out_rel;
557         }
558         /* get address to which the internal TCP socket is bound */
559         if (kernel_getsockname(clcsock, (struct sockaddr *)&addrs) < 0)
560                 goto out_rel;
561         /* analyze IP specific data of net_device belonging to TCP socket */
562         addr6 = (struct sockaddr_in6 *)&addrs;
563         rcu_read_lock();
564         if (addrs.ss_family == PF_INET) {
565                 /* IPv4 */
566                 addr = (struct sockaddr_in *)&addrs;
567                 rc = smc_clc_prfx_set4_rcu(dst, addr->sin_addr.s_addr, prop);
568         } else if (ipv6_addr_v4mapped(&addr6->sin6_addr)) {
569                 /* mapped IPv4 address - peer is IPv4 only */
570                 rc = smc_clc_prfx_set4_rcu(dst, addr6->sin6_addr.s6_addr32[3],
571                                            prop);
572         } else {
573                 /* IPv6 */
574                 rc = smc_clc_prfx_set6_rcu(dst, prop, ipv6_prfx);
575         }
576         rcu_read_unlock();
577 out_rel:
578         dst_release(dst);
579 out:
580         return rc;
581 }
582
583 /* match ipv4 addrs of dev against addr in CLC proposal */
584 static int smc_clc_prfx_match4_rcu(struct net_device *dev,
585                                    struct smc_clc_msg_proposal_prefix *prop)
586 {
587         struct in_device *in_dev = __in_dev_get_rcu(dev);
588         const struct in_ifaddr *ifa;
589
590         if (!in_dev)
591                 return -ENODEV;
592         in_dev_for_each_ifa_rcu(ifa, in_dev) {
593                 if (prop->prefix_len == inet_mask_len(ifa->ifa_mask) &&
594                     inet_ifa_match(prop->outgoing_subnet, ifa))
595                         return 0;
596         }
597
598         return -ENOENT;
599 }
600
601 /* match ipv6 addrs of dev against addrs in CLC proposal */
602 static int smc_clc_prfx_match6_rcu(struct net_device *dev,
603                                    struct smc_clc_msg_proposal_prefix *prop)
604 {
605 #if IS_ENABLED(CONFIG_IPV6)
606         struct inet6_dev *in6_dev = __in6_dev_get(dev);
607         struct smc_clc_ipv6_prefix *ipv6_prfx;
608         struct inet6_ifaddr *ifa;
609         int i, max;
610
611         if (!in6_dev)
612                 return -ENODEV;
613         /* ipv6 prefix list starts behind smc_clc_msg_proposal_prefix */
614         ipv6_prfx = (struct smc_clc_ipv6_prefix *)((u8 *)prop + sizeof(*prop));
615         max = min_t(u8, prop->ipv6_prefixes_cnt, SMC_CLC_MAX_V6_PREFIX);
616         list_for_each_entry(ifa, &in6_dev->addr_list, if_list) {
617                 if (ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)
618                         continue;
619                 for (i = 0; i < max; i++) {
620                         if (ifa->prefix_len == ipv6_prfx[i].prefix_len &&
621                             ipv6_prefix_equal(&ifa->addr, &ipv6_prfx[i].prefix,
622                                               ifa->prefix_len))
623                                 return 0;
624                 }
625         }
626 #endif
627         return -ENOENT;
628 }
629
630 /* check if proposed prefixes match one of our device prefixes */
631 int smc_clc_prfx_match(struct socket *clcsock,
632                        struct smc_clc_msg_proposal_prefix *prop)
633 {
634         struct dst_entry *dst = sk_dst_get(clcsock->sk);
635         int rc;
636
637         if (!dst) {
638                 rc = -ENOTCONN;
639                 goto out;
640         }
641         if (!dst->dev) {
642                 rc = -ENODEV;
643                 goto out_rel;
644         }
645         rcu_read_lock();
646         if (!prop->ipv6_prefixes_cnt)
647                 rc = smc_clc_prfx_match4_rcu(dst->dev, prop);
648         else
649                 rc = smc_clc_prfx_match6_rcu(dst->dev, prop);
650         rcu_read_unlock();
651 out_rel:
652         dst_release(dst);
653 out:
654         return rc;
655 }
656
657 /* Wait for data on the tcp-socket, analyze received data
658  * Returns:
659  * 0 if success and it was not a decline that we received.
660  * SMC_CLC_DECL_REPLY if decline received for fallback w/o another decl send.
661  * clcsock error, -EINTR, -ECONNRESET, -EPROTO otherwise.
662  */
663 int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
664                      u8 expected_type, unsigned long timeout)
665 {
666         long rcvtimeo = smc->clcsock->sk->sk_rcvtimeo;
667         struct sock *clc_sk = smc->clcsock->sk;
668         struct smc_clc_msg_hdr *clcm = buf;
669         struct msghdr msg = {NULL, 0};
670         int reason_code = 0;
671         struct kvec vec = {buf, buflen};
672         int len, datlen, recvlen;
673         bool check_trl = true;
674         int krflags;
675
676         /* peek the first few bytes to determine length of data to receive
677          * so we don't consume any subsequent CLC message or payload data
678          * in the TCP byte stream
679          */
680         /*
681          * Caller must make sure that buflen is no less than
682          * sizeof(struct smc_clc_msg_hdr)
683          */
684         krflags = MSG_PEEK | MSG_WAITALL;
685         clc_sk->sk_rcvtimeo = timeout;
686         iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1,
687                         sizeof(struct smc_clc_msg_hdr));
688         len = sock_recvmsg(smc->clcsock, &msg, krflags);
689         if (signal_pending(current)) {
690                 reason_code = -EINTR;
691                 clc_sk->sk_err = EINTR;
692                 smc->sk.sk_err = EINTR;
693                 goto out;
694         }
695         if (clc_sk->sk_err) {
696                 reason_code = -clc_sk->sk_err;
697                 if (clc_sk->sk_err == EAGAIN &&
698                     expected_type == SMC_CLC_DECLINE)
699                         clc_sk->sk_err = 0; /* reset for fallback usage */
700                 else
701                         smc->sk.sk_err = clc_sk->sk_err;
702                 goto out;
703         }
704         if (!len) { /* peer has performed orderly shutdown */
705                 smc->sk.sk_err = ECONNRESET;
706                 reason_code = -ECONNRESET;
707                 goto out;
708         }
709         if (len < 0) {
710                 if (len != -EAGAIN || expected_type != SMC_CLC_DECLINE)
711                         smc->sk.sk_err = -len;
712                 reason_code = len;
713                 goto out;
714         }
715         datlen = ntohs(clcm->length);
716         if ((len < sizeof(struct smc_clc_msg_hdr)) ||
717             (clcm->version < SMC_V1) ||
718             ((clcm->type != SMC_CLC_DECLINE) &&
719              (clcm->type != expected_type))) {
720                 smc->sk.sk_err = EPROTO;
721                 reason_code = -EPROTO;
722                 goto out;
723         }
724
725         /* receive the complete CLC message */
726         memset(&msg, 0, sizeof(struct msghdr));
727         if (datlen > buflen) {
728                 check_trl = false;
729                 recvlen = buflen;
730         } else {
731                 recvlen = datlen;
732         }
733         iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, recvlen);
734         krflags = MSG_WAITALL;
735         len = sock_recvmsg(smc->clcsock, &msg, krflags);
736         if (len < recvlen || !smc_clc_msg_hdr_valid(clcm, check_trl)) {
737                 smc->sk.sk_err = EPROTO;
738                 reason_code = -EPROTO;
739                 goto out;
740         }
741         datlen -= len;
742         while (datlen) {
743                 u8 tmp[SMC_CLC_RECV_BUF_LEN];
744
745                 vec.iov_base = &tmp;
746                 vec.iov_len = SMC_CLC_RECV_BUF_LEN;
747                 /* receive remaining proposal message */
748                 recvlen = datlen > SMC_CLC_RECV_BUF_LEN ?
749                                                 SMC_CLC_RECV_BUF_LEN : datlen;
750                 iov_iter_kvec(&msg.msg_iter, ITER_DEST, &vec, 1, recvlen);
751                 len = sock_recvmsg(smc->clcsock, &msg, krflags);
752                 datlen -= len;
753         }
754         if (clcm->type == SMC_CLC_DECLINE) {
755                 struct smc_clc_msg_decline *dclc;
756
757                 dclc = (struct smc_clc_msg_decline *)clcm;
758                 reason_code = SMC_CLC_DECL_PEERDECL;
759                 smc->peer_diagnosis = ntohl(dclc->peer_diagnosis);
760                 if (((struct smc_clc_msg_decline *)buf)->hdr.typev2 &
761                                                 SMC_FIRST_CONTACT_MASK) {
762                         smc->conn.lgr->sync_err = 1;
763                         smc_lgr_terminate_sched(smc->conn.lgr);
764                 }
765         }
766
767 out:
768         clc_sk->sk_rcvtimeo = rcvtimeo;
769         return reason_code;
770 }
771
772 /* send CLC DECLINE message across internal TCP socket */
773 int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, u8 version)
774 {
775         struct smc_clc_msg_decline *dclc_v1;
776         struct smc_clc_msg_decline_v2 dclc;
777         struct msghdr msg;
778         int len, send_len;
779         struct kvec vec;
780
781         dclc_v1 = (struct smc_clc_msg_decline *)&dclc;
782         memset(&dclc, 0, sizeof(dclc));
783         memcpy(dclc.hdr.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
784         dclc.hdr.type = SMC_CLC_DECLINE;
785         dclc.hdr.version = version;
786         dclc.os_type = version == SMC_V1 ? 0 : SMC_CLC_OS_LINUX;
787         dclc.hdr.typev2 = (peer_diag_info == SMC_CLC_DECL_SYNCERR) ?
788                                                 SMC_FIRST_CONTACT_MASK : 0;
789         if ((!smc_conn_lgr_valid(&smc->conn) || !smc->conn.lgr->is_smcd) &&
790             smc_ib_is_valid_local_systemid())
791                 memcpy(dclc.id_for_peer, local_systemid,
792                        sizeof(local_systemid));
793         dclc.peer_diagnosis = htonl(peer_diag_info);
794         if (version == SMC_V1) {
795                 memcpy(dclc_v1->trl.eyecatcher, SMC_EYECATCHER,
796                        sizeof(SMC_EYECATCHER));
797                 send_len = sizeof(*dclc_v1);
798         } else {
799                 memcpy(dclc.trl.eyecatcher, SMC_EYECATCHER,
800                        sizeof(SMC_EYECATCHER));
801                 send_len = sizeof(dclc);
802         }
803         dclc.hdr.length = htons(send_len);
804
805         memset(&msg, 0, sizeof(msg));
806         vec.iov_base = &dclc;
807         vec.iov_len = send_len;
808         len = kernel_sendmsg(smc->clcsock, &msg, &vec, 1, send_len);
809         if (len < 0 || len < send_len)
810                 len = -EPROTO;
811         return len > 0 ? 0 : len;
812 }
813
814 /* send CLC PROPOSAL message across internal TCP socket */
815 int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
816 {
817         struct smc_clc_smcd_v2_extension *smcd_v2_ext;
818         struct smc_clc_msg_proposal_prefix *pclc_prfx;
819         struct smc_clc_msg_proposal *pclc_base;
820         struct smc_clc_smcd_gid_chid *gidchids;
821         struct smc_clc_msg_proposal_area *pclc;
822         struct smc_clc_ipv6_prefix *ipv6_prfx;
823         struct smc_clc_v2_extension *v2_ext;
824         struct smc_clc_msg_smcd *pclc_smcd;
825         struct smc_clc_msg_trail *trl;
826         int len, i, plen, rc;
827         int reason_code = 0;
828         struct kvec vec[8];
829         struct msghdr msg;
830
831         pclc = kzalloc(sizeof(*pclc), GFP_KERNEL);
832         if (!pclc)
833                 return -ENOMEM;
834
835         pclc_base = &pclc->pclc_base;
836         pclc_smcd = &pclc->pclc_smcd;
837         pclc_prfx = &pclc->pclc_prfx;
838         ipv6_prfx = pclc->pclc_prfx_ipv6;
839         v2_ext = &pclc->pclc_v2_ext;
840         smcd_v2_ext = &pclc->pclc_smcd_v2_ext;
841         gidchids = pclc->pclc_gidchids;
842         trl = &pclc->pclc_trl;
843
844         pclc_base->hdr.version = SMC_V2;
845         pclc_base->hdr.typev1 = ini->smc_type_v1;
846         pclc_base->hdr.typev2 = ini->smc_type_v2;
847         plen = sizeof(*pclc_base) + sizeof(*pclc_smcd) + sizeof(*trl);
848
849         /* retrieve ip prefixes for CLC proposal msg */
850         if (ini->smc_type_v1 != SMC_TYPE_N) {
851                 rc = smc_clc_prfx_set(smc->clcsock, pclc_prfx, ipv6_prfx);
852                 if (rc) {
853                         if (ini->smc_type_v2 == SMC_TYPE_N) {
854                                 kfree(pclc);
855                                 return SMC_CLC_DECL_CNFERR;
856                         }
857                         pclc_base->hdr.typev1 = SMC_TYPE_N;
858                 } else {
859                         pclc_base->iparea_offset = htons(sizeof(*pclc_smcd));
860                         plen += sizeof(*pclc_prfx) +
861                                         pclc_prfx->ipv6_prefixes_cnt *
862                                         sizeof(ipv6_prfx[0]);
863                 }
864         }
865
866         /* build SMC Proposal CLC message */
867         memcpy(pclc_base->hdr.eyecatcher, SMC_EYECATCHER,
868                sizeof(SMC_EYECATCHER));
869         pclc_base->hdr.type = SMC_CLC_PROPOSAL;
870         if (smcr_indicated(ini->smc_type_v1)) {
871                 /* add SMC-R specifics */
872                 memcpy(pclc_base->lcl.id_for_peer, local_systemid,
873                        sizeof(local_systemid));
874                 memcpy(pclc_base->lcl.gid, ini->ib_gid, SMC_GID_SIZE);
875                 memcpy(pclc_base->lcl.mac, &ini->ib_dev->mac[ini->ib_port - 1],
876                        ETH_ALEN);
877         }
878         if (smcd_indicated(ini->smc_type_v1)) {
879                 /* add SMC-D specifics */
880                 if (ini->ism_dev[0]) {
881                         pclc_smcd->ism.gid = htonll(ini->ism_dev[0]->local_gid);
882                         pclc_smcd->ism.chid =
883                                 htons(smc_ism_get_chid(ini->ism_dev[0]));
884                 }
885         }
886         if (ini->smc_type_v2 == SMC_TYPE_N) {
887                 pclc_smcd->v2_ext_offset = 0;
888         } else {
889                 struct smc_clc_eid_entry *ueident;
890                 u16 v2_ext_offset;
891
892                 v2_ext->hdr.flag.release = SMC_RELEASE;
893                 v2_ext_offset = sizeof(*pclc_smcd) -
894                         offsetofend(struct smc_clc_msg_smcd, v2_ext_offset);
895                 if (ini->smc_type_v1 != SMC_TYPE_N)
896                         v2_ext_offset += sizeof(*pclc_prfx) +
897                                                 pclc_prfx->ipv6_prefixes_cnt *
898                                                 sizeof(ipv6_prfx[0]);
899                 pclc_smcd->v2_ext_offset = htons(v2_ext_offset);
900                 plen += sizeof(*v2_ext);
901
902                 read_lock(&smc_clc_eid_table.lock);
903                 v2_ext->hdr.eid_cnt = smc_clc_eid_table.ueid_cnt;
904                 plen += smc_clc_eid_table.ueid_cnt * SMC_MAX_EID_LEN;
905                 i = 0;
906                 list_for_each_entry(ueident, &smc_clc_eid_table.list, list) {
907                         memcpy(v2_ext->user_eids[i++], ueident->eid,
908                                sizeof(ueident->eid));
909                 }
910                 read_unlock(&smc_clc_eid_table.lock);
911         }
912         if (smcd_indicated(ini->smc_type_v2)) {
913                 u8 *eid = NULL;
914
915                 v2_ext->hdr.flag.seid = smc_clc_eid_table.seid_enabled;
916                 v2_ext->hdr.ism_gid_cnt = ini->ism_offered_cnt;
917                 v2_ext->hdr.smcd_v2_ext_offset = htons(sizeof(*v2_ext) -
918                                 offsetofend(struct smc_clnt_opts_area_hdr,
919                                             smcd_v2_ext_offset) +
920                                 v2_ext->hdr.eid_cnt * SMC_MAX_EID_LEN);
921                 smc_ism_get_system_eid(&eid);
922                 if (eid && v2_ext->hdr.flag.seid)
923                         memcpy(smcd_v2_ext->system_eid, eid, SMC_MAX_EID_LEN);
924                 plen += sizeof(*smcd_v2_ext);
925                 if (ini->ism_offered_cnt) {
926                         for (i = 1; i <= ini->ism_offered_cnt; i++) {
927                                 gidchids[i - 1].gid =
928                                         htonll(ini->ism_dev[i]->local_gid);
929                                 gidchids[i - 1].chid =
930                                         htons(smc_ism_get_chid(ini->ism_dev[i]));
931                         }
932                         plen += ini->ism_offered_cnt *
933                                 sizeof(struct smc_clc_smcd_gid_chid);
934                 }
935         }
936         if (smcr_indicated(ini->smc_type_v2))
937                 memcpy(v2_ext->roce, ini->smcrv2.ib_gid_v2, SMC_GID_SIZE);
938
939         pclc_base->hdr.length = htons(plen);
940         memcpy(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
941
942         /* send SMC Proposal CLC message */
943         memset(&msg, 0, sizeof(msg));
944         i = 0;
945         vec[i].iov_base = pclc_base;
946         vec[i++].iov_len = sizeof(*pclc_base);
947         vec[i].iov_base = pclc_smcd;
948         vec[i++].iov_len = sizeof(*pclc_smcd);
949         if (ini->smc_type_v1 != SMC_TYPE_N) {
950                 vec[i].iov_base = pclc_prfx;
951                 vec[i++].iov_len = sizeof(*pclc_prfx);
952                 if (pclc_prfx->ipv6_prefixes_cnt > 0) {
953                         vec[i].iov_base = ipv6_prfx;
954                         vec[i++].iov_len = pclc_prfx->ipv6_prefixes_cnt *
955                                            sizeof(ipv6_prfx[0]);
956                 }
957         }
958         if (ini->smc_type_v2 != SMC_TYPE_N) {
959                 vec[i].iov_base = v2_ext;
960                 vec[i++].iov_len = sizeof(*v2_ext) +
961                                    (v2_ext->hdr.eid_cnt * SMC_MAX_EID_LEN);
962                 if (smcd_indicated(ini->smc_type_v2)) {
963                         vec[i].iov_base = smcd_v2_ext;
964                         vec[i++].iov_len = sizeof(*smcd_v2_ext);
965                         if (ini->ism_offered_cnt) {
966                                 vec[i].iov_base = gidchids;
967                                 vec[i++].iov_len = ini->ism_offered_cnt *
968                                         sizeof(struct smc_clc_smcd_gid_chid);
969                         }
970                 }
971         }
972         vec[i].iov_base = trl;
973         vec[i++].iov_len = sizeof(*trl);
974         /* due to the few bytes needed for clc-handshake this cannot block */
975         len = kernel_sendmsg(smc->clcsock, &msg, vec, i, plen);
976         if (len < 0) {
977                 smc->sk.sk_err = smc->clcsock->sk->sk_err;
978                 reason_code = -smc->sk.sk_err;
979         } else if (len < ntohs(pclc_base->hdr.length)) {
980                 reason_code = -ENETUNREACH;
981                 smc->sk.sk_err = -reason_code;
982         }
983
984         kfree(pclc);
985         return reason_code;
986 }
987
988 /* build and send CLC CONFIRM / ACCEPT message */
989 static int smc_clc_send_confirm_accept(struct smc_sock *smc,
990                                        struct smc_clc_msg_accept_confirm_v2 *clc_v2,
991                                        int first_contact, u8 version,
992                                        u8 *eid, struct smc_init_info *ini)
993 {
994         struct smc_connection *conn = &smc->conn;
995         struct smc_clc_msg_accept_confirm *clc;
996         struct smc_clc_first_contact_ext fce;
997         struct smc_clc_fce_gid_ext gle;
998         struct smc_clc_msg_trail trl;
999         struct kvec vec[5];
1000         struct msghdr msg;
1001         int i, len;
1002
1003         /* send SMC Confirm CLC msg */
1004         clc = (struct smc_clc_msg_accept_confirm *)clc_v2;
1005         clc->hdr.version = version;     /* SMC version */
1006         if (first_contact)
1007                 clc->hdr.typev2 |= SMC_FIRST_CONTACT_MASK;
1008         if (conn->lgr->is_smcd) {
1009                 /* SMC-D specific settings */
1010                 memcpy(clc->hdr.eyecatcher, SMCD_EYECATCHER,
1011                        sizeof(SMCD_EYECATCHER));
1012                 clc->hdr.typev1 = SMC_TYPE_D;
1013                 clc->d0.gid = conn->lgr->smcd->local_gid;
1014                 clc->d0.token = conn->rmb_desc->token;
1015                 clc->d0.dmbe_size = conn->rmbe_size_comp;
1016                 clc->d0.dmbe_idx = 0;
1017                 memcpy(&clc->d0.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
1018                 if (version == SMC_V1) {
1019                         clc->hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
1020                 } else {
1021                         clc_v2->d1.chid =
1022                                 htons(smc_ism_get_chid(conn->lgr->smcd));
1023                         if (eid && eid[0])
1024                                 memcpy(clc_v2->d1.eid, eid, SMC_MAX_EID_LEN);
1025                         len = SMCD_CLC_ACCEPT_CONFIRM_LEN_V2;
1026                         if (first_contact)
1027                                 smc_clc_fill_fce(&fce, &len);
1028                         clc_v2->hdr.length = htons(len);
1029                 }
1030                 memcpy(trl.eyecatcher, SMCD_EYECATCHER,
1031                        sizeof(SMCD_EYECATCHER));
1032         } else {
1033                 struct smc_link *link = conn->lnk;
1034
1035                 /* SMC-R specific settings */
1036                 memcpy(clc->hdr.eyecatcher, SMC_EYECATCHER,
1037                        sizeof(SMC_EYECATCHER));
1038                 clc->hdr.typev1 = SMC_TYPE_R;
1039                 clc->hdr.length = htons(SMCR_CLC_ACCEPT_CONFIRM_LEN);
1040                 memcpy(clc->r0.lcl.id_for_peer, local_systemid,
1041                        sizeof(local_systemid));
1042                 memcpy(&clc->r0.lcl.gid, link->gid, SMC_GID_SIZE);
1043                 memcpy(&clc->r0.lcl.mac, &link->smcibdev->mac[link->ibport - 1],
1044                        ETH_ALEN);
1045                 hton24(clc->r0.qpn, link->roce_qp->qp_num);
1046                 clc->r0.rmb_rkey =
1047                         htonl(conn->rmb_desc->mr[link->link_idx]->rkey);
1048                 clc->r0.rmbe_idx = 1; /* for now: 1 RMB = 1 RMBE */
1049                 clc->r0.rmbe_alert_token = htonl(conn->alert_token_local);
1050                 switch (clc->hdr.type) {
1051                 case SMC_CLC_ACCEPT:
1052                         clc->r0.qp_mtu = link->path_mtu;
1053                         break;
1054                 case SMC_CLC_CONFIRM:
1055                         clc->r0.qp_mtu = min(link->path_mtu, link->peer_mtu);
1056                         break;
1057                 }
1058                 clc->r0.rmbe_size = conn->rmbe_size_comp;
1059                 clc->r0.rmb_dma_addr = conn->rmb_desc->is_vm ?
1060                         cpu_to_be64((uintptr_t)conn->rmb_desc->cpu_addr) :
1061                         cpu_to_be64((u64)sg_dma_address
1062                                     (conn->rmb_desc->sgt[link->link_idx].sgl));
1063                 hton24(clc->r0.psn, link->psn_initial);
1064                 if (version == SMC_V1) {
1065                         clc->hdr.length = htons(SMCR_CLC_ACCEPT_CONFIRM_LEN);
1066                 } else {
1067                         if (eid && eid[0])
1068                                 memcpy(clc_v2->r1.eid, eid, SMC_MAX_EID_LEN);
1069                         len = SMCR_CLC_ACCEPT_CONFIRM_LEN_V2;
1070                         if (first_contact) {
1071                                 smc_clc_fill_fce(&fce, &len);
1072                                 fce.v2_direct = !link->lgr->uses_gateway;
1073                                 memset(&gle, 0, sizeof(gle));
1074                                 if (ini && clc->hdr.type == SMC_CLC_CONFIRM) {
1075                                         gle.gid_cnt = ini->smcrv2.gidlist.len;
1076                                         len += sizeof(gle);
1077                                         len += gle.gid_cnt * sizeof(gle.gid[0]);
1078                                 } else {
1079                                         len += sizeof(gle.reserved);
1080                                 }
1081                         }
1082                         clc_v2->hdr.length = htons(len);
1083                 }
1084                 memcpy(trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
1085         }
1086
1087         memset(&msg, 0, sizeof(msg));
1088         i = 0;
1089         vec[i].iov_base = clc_v2;
1090         if (version > SMC_V1)
1091                 vec[i++].iov_len = (clc->hdr.typev1 == SMC_TYPE_D ?
1092                                         SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 :
1093                                         SMCR_CLC_ACCEPT_CONFIRM_LEN_V2) -
1094                                    sizeof(trl);
1095         else
1096                 vec[i++].iov_len = (clc->hdr.typev1 == SMC_TYPE_D ?
1097                                                 SMCD_CLC_ACCEPT_CONFIRM_LEN :
1098                                                 SMCR_CLC_ACCEPT_CONFIRM_LEN) -
1099                                    sizeof(trl);
1100         if (version > SMC_V1 && first_contact) {
1101                 vec[i].iov_base = &fce;
1102                 vec[i++].iov_len = sizeof(fce);
1103                 if (!conn->lgr->is_smcd) {
1104                         if (clc->hdr.type == SMC_CLC_CONFIRM) {
1105                                 vec[i].iov_base = &gle;
1106                                 vec[i++].iov_len = sizeof(gle);
1107                                 vec[i].iov_base = &ini->smcrv2.gidlist.list;
1108                                 vec[i++].iov_len = gle.gid_cnt *
1109                                                    sizeof(gle.gid[0]);
1110                         } else {
1111                                 vec[i].iov_base = &gle.reserved;
1112                                 vec[i++].iov_len = sizeof(gle.reserved);
1113                         }
1114                 }
1115         }
1116         vec[i].iov_base = &trl;
1117         vec[i++].iov_len = sizeof(trl);
1118         return kernel_sendmsg(smc->clcsock, &msg, vec, 1,
1119                               ntohs(clc->hdr.length));
1120 }
1121
1122 /* send CLC CONFIRM message across internal TCP socket */
1123 int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact,
1124                          u8 version, u8 *eid, struct smc_init_info *ini)
1125 {
1126         struct smc_clc_msg_accept_confirm_v2 cclc_v2;
1127         int reason_code = 0;
1128         int len;
1129
1130         /* send SMC Confirm CLC msg */
1131         memset(&cclc_v2, 0, sizeof(cclc_v2));
1132         cclc_v2.hdr.type = SMC_CLC_CONFIRM;
1133         len = smc_clc_send_confirm_accept(smc, &cclc_v2, clnt_first_contact,
1134                                           version, eid, ini);
1135         if (len < ntohs(cclc_v2.hdr.length)) {
1136                 if (len >= 0) {
1137                         reason_code = -ENETUNREACH;
1138                         smc->sk.sk_err = -reason_code;
1139                 } else {
1140                         smc->sk.sk_err = smc->clcsock->sk->sk_err;
1141                         reason_code = -smc->sk.sk_err;
1142                 }
1143         }
1144         return reason_code;
1145 }
1146
1147 /* send CLC ACCEPT message across internal TCP socket */
1148 int smc_clc_send_accept(struct smc_sock *new_smc, bool srv_first_contact,
1149                         u8 version, u8 *negotiated_eid)
1150 {
1151         struct smc_clc_msg_accept_confirm_v2 aclc_v2;
1152         int len;
1153
1154         memset(&aclc_v2, 0, sizeof(aclc_v2));
1155         aclc_v2.hdr.type = SMC_CLC_ACCEPT;
1156         len = smc_clc_send_confirm_accept(new_smc, &aclc_v2, srv_first_contact,
1157                                           version, negotiated_eid, NULL);
1158         if (len < ntohs(aclc_v2.hdr.length))
1159                 len = len >= 0 ? -EPROTO : -new_smc->clcsock->sk->sk_err;
1160
1161         return len > 0 ? 0 : len;
1162 }
1163
1164 void smc_clc_get_hostname(u8 **host)
1165 {
1166         *host = &smc_hostname[0];
1167 }
1168
1169 void __init smc_clc_init(void)
1170 {
1171         struct new_utsname *u;
1172
1173         memset(smc_hostname, _S, sizeof(smc_hostname)); /* ASCII blanks */
1174         u = utsname();
1175         memcpy(smc_hostname, u->nodename,
1176                min_t(size_t, strlen(u->nodename), sizeof(smc_hostname)));
1177
1178         INIT_LIST_HEAD(&smc_clc_eid_table.list);
1179         rwlock_init(&smc_clc_eid_table.lock);
1180         smc_clc_eid_table.ueid_cnt = 0;
1181 #if IS_ENABLED(CONFIG_S390)
1182         smc_clc_eid_table.seid_enabled = 1;
1183 #else
1184         smc_clc_eid_table.seid_enabled = 0;
1185 #endif
1186 }
1187
1188 void smc_clc_exit(void)
1189 {
1190         smc_clc_ueid_remove(NULL);
1191 }