Merge tag '9p-for-5.11-rc1' of git://github.com/martinetd/linux
[linux-2.6-microblaze.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
30 #define SMCR_CLC_ACCEPT_CONFIRM_LEN 68
31 #define SMCD_CLC_ACCEPT_CONFIRM_LEN 48
32 #define SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 78
33 #define SMC_CLC_RECV_BUF_LEN    100
34
35 /* eye catcher "SMCR" EBCDIC for CLC messages */
36 static const char SMC_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xd9'};
37 /* eye catcher "SMCD" EBCDIC for CLC messages */
38 static const char SMCD_EYECATCHER[4] = {'\xe2', '\xd4', '\xc3', '\xc4'};
39
40 static u8 smc_hostname[SMC_MAX_HOSTNAME_LEN];
41
42 /* check arriving CLC proposal */
43 static bool smc_clc_msg_prop_valid(struct smc_clc_msg_proposal *pclc)
44 {
45         struct smc_clc_msg_proposal_prefix *pclc_prfx;
46         struct smc_clc_smcd_v2_extension *smcd_v2_ext;
47         struct smc_clc_msg_hdr *hdr = &pclc->hdr;
48         struct smc_clc_v2_extension *v2_ext;
49
50         v2_ext = smc_get_clc_v2_ext(pclc);
51         pclc_prfx = smc_clc_proposal_get_prefix(pclc);
52         if (hdr->version == SMC_V1) {
53                 if (hdr->typev1 == SMC_TYPE_N)
54                         return false;
55                 if (ntohs(hdr->length) !=
56                         sizeof(*pclc) + ntohs(pclc->iparea_offset) +
57                         sizeof(*pclc_prfx) +
58                         pclc_prfx->ipv6_prefixes_cnt *
59                                 sizeof(struct smc_clc_ipv6_prefix) +
60                         sizeof(struct smc_clc_msg_trail))
61                         return false;
62         } else {
63                 if (ntohs(hdr->length) !=
64                         sizeof(*pclc) +
65                         sizeof(struct smc_clc_msg_smcd) +
66                         (hdr->typev1 != SMC_TYPE_N ?
67                                 sizeof(*pclc_prfx) +
68                                 pclc_prfx->ipv6_prefixes_cnt *
69                                 sizeof(struct smc_clc_ipv6_prefix) : 0) +
70                         (hdr->typev2 != SMC_TYPE_N ?
71                                 sizeof(*v2_ext) +
72                                 v2_ext->hdr.eid_cnt * SMC_MAX_EID_LEN : 0) +
73                         (smcd_indicated(hdr->typev2) ?
74                                 sizeof(*smcd_v2_ext) + v2_ext->hdr.ism_gid_cnt *
75                                         sizeof(struct smc_clc_smcd_gid_chid) :
76                                 0) +
77                         sizeof(struct smc_clc_msg_trail))
78                         return false;
79         }
80         return true;
81 }
82
83 /* check arriving CLC accept or confirm */
84 static bool
85 smc_clc_msg_acc_conf_valid(struct smc_clc_msg_accept_confirm_v2 *clc_v2)
86 {
87         struct smc_clc_msg_hdr *hdr = &clc_v2->hdr;
88
89         if (hdr->typev1 != SMC_TYPE_R && hdr->typev1 != SMC_TYPE_D)
90                 return false;
91         if (hdr->version == SMC_V1) {
92                 if ((hdr->typev1 == SMC_TYPE_R &&
93                      ntohs(hdr->length) != SMCR_CLC_ACCEPT_CONFIRM_LEN) ||
94                     (hdr->typev1 == SMC_TYPE_D &&
95                      ntohs(hdr->length) != SMCD_CLC_ACCEPT_CONFIRM_LEN))
96                         return false;
97         } else {
98                 if (hdr->typev1 == SMC_TYPE_D &&
99                     ntohs(hdr->length) != SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 &&
100                     (ntohs(hdr->length) != SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 +
101                                 sizeof(struct smc_clc_first_contact_ext)))
102                         return false;
103         }
104         return true;
105 }
106
107 static void smc_clc_fill_fce(struct smc_clc_first_contact_ext *fce, int *len)
108 {
109         memset(fce, 0, sizeof(*fce));
110         fce->os_type = SMC_CLC_OS_LINUX;
111         fce->release = SMC_RELEASE;
112         memcpy(fce->hostname, smc_hostname, sizeof(smc_hostname));
113         (*len) += sizeof(*fce);
114 }
115
116 /* check if received message has a correct header length and contains valid
117  * heading and trailing eyecatchers
118  */
119 static bool smc_clc_msg_hdr_valid(struct smc_clc_msg_hdr *clcm, bool check_trl)
120 {
121         struct smc_clc_msg_accept_confirm_v2 *clc_v2;
122         struct smc_clc_msg_proposal *pclc;
123         struct smc_clc_msg_decline *dclc;
124         struct smc_clc_msg_trail *trl;
125
126         if (memcmp(clcm->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&
127             memcmp(clcm->eyecatcher, SMCD_EYECATCHER, sizeof(SMCD_EYECATCHER)))
128                 return false;
129         switch (clcm->type) {
130         case SMC_CLC_PROPOSAL:
131                 pclc = (struct smc_clc_msg_proposal *)clcm;
132                 if (!smc_clc_msg_prop_valid(pclc))
133                         return false;
134                 trl = (struct smc_clc_msg_trail *)
135                         ((u8 *)pclc + ntohs(pclc->hdr.length) - sizeof(*trl));
136                 break;
137         case SMC_CLC_ACCEPT:
138         case SMC_CLC_CONFIRM:
139                 clc_v2 = (struct smc_clc_msg_accept_confirm_v2 *)clcm;
140                 if (!smc_clc_msg_acc_conf_valid(clc_v2))
141                         return false;
142                 trl = (struct smc_clc_msg_trail *)
143                         ((u8 *)clc_v2 + ntohs(clc_v2->hdr.length) -
144                                                         sizeof(*trl));
145                 break;
146         case SMC_CLC_DECLINE:
147                 dclc = (struct smc_clc_msg_decline *)clcm;
148                 if (ntohs(dclc->hdr.length) != sizeof(*dclc))
149                         return false;
150                 trl = &dclc->trl;
151                 break;
152         default:
153                 return false;
154         }
155         if (check_trl &&
156             memcmp(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER)) &&
157             memcmp(trl->eyecatcher, SMCD_EYECATCHER, sizeof(SMCD_EYECATCHER)))
158                 return false;
159         return true;
160 }
161
162 /* find ipv4 addr on device and get the prefix len, fill CLC proposal msg */
163 static int smc_clc_prfx_set4_rcu(struct dst_entry *dst, __be32 ipv4,
164                                  struct smc_clc_msg_proposal_prefix *prop)
165 {
166         struct in_device *in_dev = __in_dev_get_rcu(dst->dev);
167         const struct in_ifaddr *ifa;
168
169         if (!in_dev)
170                 return -ENODEV;
171
172         in_dev_for_each_ifa_rcu(ifa, in_dev) {
173                 if (!inet_ifa_match(ipv4, ifa))
174                         continue;
175                 prop->prefix_len = inet_mask_len(ifa->ifa_mask);
176                 prop->outgoing_subnet = ifa->ifa_address & ifa->ifa_mask;
177                 /* prop->ipv6_prefixes_cnt = 0; already done by memset before */
178                 return 0;
179         }
180         return -ENOENT;
181 }
182
183 /* fill CLC proposal msg with ipv6 prefixes from device */
184 static int smc_clc_prfx_set6_rcu(struct dst_entry *dst,
185                                  struct smc_clc_msg_proposal_prefix *prop,
186                                  struct smc_clc_ipv6_prefix *ipv6_prfx)
187 {
188 #if IS_ENABLED(CONFIG_IPV6)
189         struct inet6_dev *in6_dev = __in6_dev_get(dst->dev);
190         struct inet6_ifaddr *ifa;
191         int cnt = 0;
192
193         if (!in6_dev)
194                 return -ENODEV;
195         /* use a maximum of 8 IPv6 prefixes from device */
196         list_for_each_entry(ifa, &in6_dev->addr_list, if_list) {
197                 if (ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)
198                         continue;
199                 ipv6_addr_prefix(&ipv6_prfx[cnt].prefix,
200                                  &ifa->addr, ifa->prefix_len);
201                 ipv6_prfx[cnt].prefix_len = ifa->prefix_len;
202                 cnt++;
203                 if (cnt == SMC_CLC_MAX_V6_PREFIX)
204                         break;
205         }
206         prop->ipv6_prefixes_cnt = cnt;
207         if (cnt)
208                 return 0;
209 #endif
210         return -ENOENT;
211 }
212
213 /* retrieve and set prefixes in CLC proposal msg */
214 static int smc_clc_prfx_set(struct socket *clcsock,
215                             struct smc_clc_msg_proposal_prefix *prop,
216                             struct smc_clc_ipv6_prefix *ipv6_prfx)
217 {
218         struct dst_entry *dst = sk_dst_get(clcsock->sk);
219         struct sockaddr_storage addrs;
220         struct sockaddr_in6 *addr6;
221         struct sockaddr_in *addr;
222         int rc = -ENOENT;
223
224         if (!dst) {
225                 rc = -ENOTCONN;
226                 goto out;
227         }
228         if (!dst->dev) {
229                 rc = -ENODEV;
230                 goto out_rel;
231         }
232         /* get address to which the internal TCP socket is bound */
233         kernel_getsockname(clcsock, (struct sockaddr *)&addrs);
234         /* analyze IP specific data of net_device belonging to TCP socket */
235         addr6 = (struct sockaddr_in6 *)&addrs;
236         rcu_read_lock();
237         if (addrs.ss_family == PF_INET) {
238                 /* IPv4 */
239                 addr = (struct sockaddr_in *)&addrs;
240                 rc = smc_clc_prfx_set4_rcu(dst, addr->sin_addr.s_addr, prop);
241         } else if (ipv6_addr_v4mapped(&addr6->sin6_addr)) {
242                 /* mapped IPv4 address - peer is IPv4 only */
243                 rc = smc_clc_prfx_set4_rcu(dst, addr6->sin6_addr.s6_addr32[3],
244                                            prop);
245         } else {
246                 /* IPv6 */
247                 rc = smc_clc_prfx_set6_rcu(dst, prop, ipv6_prfx);
248         }
249         rcu_read_unlock();
250 out_rel:
251         dst_release(dst);
252 out:
253         return rc;
254 }
255
256 /* match ipv4 addrs of dev against addr in CLC proposal */
257 static int smc_clc_prfx_match4_rcu(struct net_device *dev,
258                                    struct smc_clc_msg_proposal_prefix *prop)
259 {
260         struct in_device *in_dev = __in_dev_get_rcu(dev);
261         const struct in_ifaddr *ifa;
262
263         if (!in_dev)
264                 return -ENODEV;
265         in_dev_for_each_ifa_rcu(ifa, in_dev) {
266                 if (prop->prefix_len == inet_mask_len(ifa->ifa_mask) &&
267                     inet_ifa_match(prop->outgoing_subnet, ifa))
268                         return 0;
269         }
270
271         return -ENOENT;
272 }
273
274 /* match ipv6 addrs of dev against addrs in CLC proposal */
275 static int smc_clc_prfx_match6_rcu(struct net_device *dev,
276                                    struct smc_clc_msg_proposal_prefix *prop)
277 {
278 #if IS_ENABLED(CONFIG_IPV6)
279         struct inet6_dev *in6_dev = __in6_dev_get(dev);
280         struct smc_clc_ipv6_prefix *ipv6_prfx;
281         struct inet6_ifaddr *ifa;
282         int i, max;
283
284         if (!in6_dev)
285                 return -ENODEV;
286         /* ipv6 prefix list starts behind smc_clc_msg_proposal_prefix */
287         ipv6_prfx = (struct smc_clc_ipv6_prefix *)((u8 *)prop + sizeof(*prop));
288         max = min_t(u8, prop->ipv6_prefixes_cnt, SMC_CLC_MAX_V6_PREFIX);
289         list_for_each_entry(ifa, &in6_dev->addr_list, if_list) {
290                 if (ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)
291                         continue;
292                 for (i = 0; i < max; i++) {
293                         if (ifa->prefix_len == ipv6_prfx[i].prefix_len &&
294                             ipv6_prefix_equal(&ifa->addr, &ipv6_prfx[i].prefix,
295                                               ifa->prefix_len))
296                                 return 0;
297                 }
298         }
299 #endif
300         return -ENOENT;
301 }
302
303 /* check if proposed prefixes match one of our device prefixes */
304 int smc_clc_prfx_match(struct socket *clcsock,
305                        struct smc_clc_msg_proposal_prefix *prop)
306 {
307         struct dst_entry *dst = sk_dst_get(clcsock->sk);
308         int rc;
309
310         if (!dst) {
311                 rc = -ENOTCONN;
312                 goto out;
313         }
314         if (!dst->dev) {
315                 rc = -ENODEV;
316                 goto out_rel;
317         }
318         rcu_read_lock();
319         if (!prop->ipv6_prefixes_cnt)
320                 rc = smc_clc_prfx_match4_rcu(dst->dev, prop);
321         else
322                 rc = smc_clc_prfx_match6_rcu(dst->dev, prop);
323         rcu_read_unlock();
324 out_rel:
325         dst_release(dst);
326 out:
327         return rc;
328 }
329
330 /* Wait for data on the tcp-socket, analyze received data
331  * Returns:
332  * 0 if success and it was not a decline that we received.
333  * SMC_CLC_DECL_REPLY if decline received for fallback w/o another decl send.
334  * clcsock error, -EINTR, -ECONNRESET, -EPROTO otherwise.
335  */
336 int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
337                      u8 expected_type, unsigned long timeout)
338 {
339         long rcvtimeo = smc->clcsock->sk->sk_rcvtimeo;
340         struct sock *clc_sk = smc->clcsock->sk;
341         struct smc_clc_msg_hdr *clcm = buf;
342         struct msghdr msg = {NULL, 0};
343         int reason_code = 0;
344         struct kvec vec = {buf, buflen};
345         int len, datlen, recvlen;
346         bool check_trl = true;
347         int krflags;
348
349         /* peek the first few bytes to determine length of data to receive
350          * so we don't consume any subsequent CLC message or payload data
351          * in the TCP byte stream
352          */
353         /*
354          * Caller must make sure that buflen is no less than
355          * sizeof(struct smc_clc_msg_hdr)
356          */
357         krflags = MSG_PEEK | MSG_WAITALL;
358         clc_sk->sk_rcvtimeo = timeout;
359         iov_iter_kvec(&msg.msg_iter, READ, &vec, 1,
360                         sizeof(struct smc_clc_msg_hdr));
361         len = sock_recvmsg(smc->clcsock, &msg, krflags);
362         if (signal_pending(current)) {
363                 reason_code = -EINTR;
364                 clc_sk->sk_err = EINTR;
365                 smc->sk.sk_err = EINTR;
366                 goto out;
367         }
368         if (clc_sk->sk_err) {
369                 reason_code = -clc_sk->sk_err;
370                 if (clc_sk->sk_err == EAGAIN &&
371                     expected_type == SMC_CLC_DECLINE)
372                         clc_sk->sk_err = 0; /* reset for fallback usage */
373                 else
374                         smc->sk.sk_err = clc_sk->sk_err;
375                 goto out;
376         }
377         if (!len) { /* peer has performed orderly shutdown */
378                 smc->sk.sk_err = ECONNRESET;
379                 reason_code = -ECONNRESET;
380                 goto out;
381         }
382         if (len < 0) {
383                 if (len != -EAGAIN || expected_type != SMC_CLC_DECLINE)
384                         smc->sk.sk_err = -len;
385                 reason_code = len;
386                 goto out;
387         }
388         datlen = ntohs(clcm->length);
389         if ((len < sizeof(struct smc_clc_msg_hdr)) ||
390             (clcm->version < SMC_V1) ||
391             ((clcm->type != SMC_CLC_DECLINE) &&
392              (clcm->type != expected_type))) {
393                 smc->sk.sk_err = EPROTO;
394                 reason_code = -EPROTO;
395                 goto out;
396         }
397
398         /* receive the complete CLC message */
399         memset(&msg, 0, sizeof(struct msghdr));
400         if (datlen > buflen) {
401                 check_trl = false;
402                 recvlen = buflen;
403         } else {
404                 recvlen = datlen;
405         }
406         iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, recvlen);
407         krflags = MSG_WAITALL;
408         len = sock_recvmsg(smc->clcsock, &msg, krflags);
409         if (len < recvlen || !smc_clc_msg_hdr_valid(clcm, check_trl)) {
410                 smc->sk.sk_err = EPROTO;
411                 reason_code = -EPROTO;
412                 goto out;
413         }
414         datlen -= len;
415         while (datlen) {
416                 u8 tmp[SMC_CLC_RECV_BUF_LEN];
417
418                 vec.iov_base = &tmp;
419                 vec.iov_len = SMC_CLC_RECV_BUF_LEN;
420                 /* receive remaining proposal message */
421                 recvlen = datlen > SMC_CLC_RECV_BUF_LEN ?
422                                                 SMC_CLC_RECV_BUF_LEN : datlen;
423                 iov_iter_kvec(&msg.msg_iter, READ, &vec, 1, recvlen);
424                 len = sock_recvmsg(smc->clcsock, &msg, krflags);
425                 datlen -= len;
426         }
427         if (clcm->type == SMC_CLC_DECLINE) {
428                 struct smc_clc_msg_decline *dclc;
429
430                 dclc = (struct smc_clc_msg_decline *)clcm;
431                 reason_code = SMC_CLC_DECL_PEERDECL;
432                 smc->peer_diagnosis = ntohl(dclc->peer_diagnosis);
433                 if (((struct smc_clc_msg_decline *)buf)->hdr.typev2 &
434                                                 SMC_FIRST_CONTACT_MASK) {
435                         smc->conn.lgr->sync_err = 1;
436                         smc_lgr_terminate_sched(smc->conn.lgr);
437                 }
438         }
439
440 out:
441         clc_sk->sk_rcvtimeo = rcvtimeo;
442         return reason_code;
443 }
444
445 /* send CLC DECLINE message across internal TCP socket */
446 int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, u8 version)
447 {
448         struct smc_clc_msg_decline dclc;
449         struct msghdr msg;
450         struct kvec vec;
451         int len;
452
453         memset(&dclc, 0, sizeof(dclc));
454         memcpy(dclc.hdr.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
455         dclc.hdr.type = SMC_CLC_DECLINE;
456         dclc.hdr.length = htons(sizeof(struct smc_clc_msg_decline));
457         dclc.hdr.version = version;
458         dclc.os_type = version == SMC_V1 ? 0 : SMC_CLC_OS_LINUX;
459         dclc.hdr.typev2 = (peer_diag_info == SMC_CLC_DECL_SYNCERR) ?
460                                                 SMC_FIRST_CONTACT_MASK : 0;
461         if ((!smc->conn.lgr || !smc->conn.lgr->is_smcd) &&
462             smc_ib_is_valid_local_systemid())
463                 memcpy(dclc.id_for_peer, local_systemid,
464                        sizeof(local_systemid));
465         dclc.peer_diagnosis = htonl(peer_diag_info);
466         memcpy(dclc.trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
467
468         memset(&msg, 0, sizeof(msg));
469         vec.iov_base = &dclc;
470         vec.iov_len = sizeof(struct smc_clc_msg_decline);
471         len = kernel_sendmsg(smc->clcsock, &msg, &vec, 1,
472                              sizeof(struct smc_clc_msg_decline));
473         if (len < 0 || len < sizeof(struct smc_clc_msg_decline))
474                 len = -EPROTO;
475         return len > 0 ? 0 : len;
476 }
477
478 /* send CLC PROPOSAL message across internal TCP socket */
479 int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini)
480 {
481         struct smc_clc_smcd_v2_extension *smcd_v2_ext;
482         struct smc_clc_msg_proposal_prefix *pclc_prfx;
483         struct smc_clc_msg_proposal *pclc_base;
484         struct smc_clc_smcd_gid_chid *gidchids;
485         struct smc_clc_msg_proposal_area *pclc;
486         struct smc_clc_ipv6_prefix *ipv6_prfx;
487         struct smc_clc_v2_extension *v2_ext;
488         struct smc_clc_msg_smcd *pclc_smcd;
489         struct smc_clc_msg_trail *trl;
490         int len, i, plen, rc;
491         int reason_code = 0;
492         struct kvec vec[8];
493         struct msghdr msg;
494
495         pclc = kzalloc(sizeof(*pclc), GFP_KERNEL);
496         if (!pclc)
497                 return -ENOMEM;
498
499         pclc_base = &pclc->pclc_base;
500         pclc_smcd = &pclc->pclc_smcd;
501         pclc_prfx = &pclc->pclc_prfx;
502         ipv6_prfx = pclc->pclc_prfx_ipv6;
503         v2_ext = &pclc->pclc_v2_ext;
504         smcd_v2_ext = &pclc->pclc_smcd_v2_ext;
505         gidchids = pclc->pclc_gidchids;
506         trl = &pclc->pclc_trl;
507
508         pclc_base->hdr.version = SMC_V2;
509         pclc_base->hdr.typev1 = ini->smc_type_v1;
510         pclc_base->hdr.typev2 = ini->smc_type_v2;
511         plen = sizeof(*pclc_base) + sizeof(*pclc_smcd) + sizeof(*trl);
512
513         /* retrieve ip prefixes for CLC proposal msg */
514         if (ini->smc_type_v1 != SMC_TYPE_N) {
515                 rc = smc_clc_prfx_set(smc->clcsock, pclc_prfx, ipv6_prfx);
516                 if (rc) {
517                         if (ini->smc_type_v2 == SMC_TYPE_N) {
518                                 kfree(pclc);
519                                 return SMC_CLC_DECL_CNFERR;
520                         }
521                         pclc_base->hdr.typev1 = SMC_TYPE_N;
522                 } else {
523                         pclc_base->iparea_offset = htons(sizeof(*pclc_smcd));
524                         plen += sizeof(*pclc_prfx) +
525                                         pclc_prfx->ipv6_prefixes_cnt *
526                                         sizeof(ipv6_prfx[0]);
527                 }
528         }
529
530         /* build SMC Proposal CLC message */
531         memcpy(pclc_base->hdr.eyecatcher, SMC_EYECATCHER,
532                sizeof(SMC_EYECATCHER));
533         pclc_base->hdr.type = SMC_CLC_PROPOSAL;
534         if (smcr_indicated(ini->smc_type_v1)) {
535                 /* add SMC-R specifics */
536                 memcpy(pclc_base->lcl.id_for_peer, local_systemid,
537                        sizeof(local_systemid));
538                 memcpy(pclc_base->lcl.gid, ini->ib_gid, SMC_GID_SIZE);
539                 memcpy(pclc_base->lcl.mac, &ini->ib_dev->mac[ini->ib_port - 1],
540                        ETH_ALEN);
541         }
542         if (smcd_indicated(ini->smc_type_v1)) {
543                 /* add SMC-D specifics */
544                 if (ini->ism_dev[0]) {
545                         pclc_smcd->ism.gid = htonll(ini->ism_dev[0]->local_gid);
546                         pclc_smcd->ism.chid =
547                                 htons(smc_ism_get_chid(ini->ism_dev[0]));
548                 }
549         }
550         if (ini->smc_type_v2 == SMC_TYPE_N) {
551                 pclc_smcd->v2_ext_offset = 0;
552         } else {
553                 u16 v2_ext_offset;
554                 u8 *eid = NULL;
555
556                 v2_ext_offset = sizeof(*pclc_smcd) -
557                         offsetofend(struct smc_clc_msg_smcd, v2_ext_offset);
558                 if (ini->smc_type_v1 != SMC_TYPE_N)
559                         v2_ext_offset += sizeof(*pclc_prfx) +
560                                                 pclc_prfx->ipv6_prefixes_cnt *
561                                                 sizeof(ipv6_prfx[0]);
562                 pclc_smcd->v2_ext_offset = htons(v2_ext_offset);
563                 v2_ext->hdr.eid_cnt = 0;
564                 v2_ext->hdr.ism_gid_cnt = ini->ism_offered_cnt;
565                 v2_ext->hdr.flag.release = SMC_RELEASE;
566                 v2_ext->hdr.flag.seid = 1;
567                 v2_ext->hdr.smcd_v2_ext_offset = htons(sizeof(*v2_ext) -
568                                 offsetofend(struct smc_clnt_opts_area_hdr,
569                                             smcd_v2_ext_offset) +
570                                 v2_ext->hdr.eid_cnt * SMC_MAX_EID_LEN);
571                 if (ini->ism_dev[0])
572                         smc_ism_get_system_eid(ini->ism_dev[0], &eid);
573                 else
574                         smc_ism_get_system_eid(ini->ism_dev[1], &eid);
575                 if (eid)
576                         memcpy(smcd_v2_ext->system_eid, eid, SMC_MAX_EID_LEN);
577                 plen += sizeof(*v2_ext) + sizeof(*smcd_v2_ext);
578                 if (ini->ism_offered_cnt) {
579                         for (i = 1; i <= ini->ism_offered_cnt; i++) {
580                                 gidchids[i - 1].gid =
581                                         htonll(ini->ism_dev[i]->local_gid);
582                                 gidchids[i - 1].chid =
583                                         htons(smc_ism_get_chid(ini->ism_dev[i]));
584                         }
585                         plen += ini->ism_offered_cnt *
586                                 sizeof(struct smc_clc_smcd_gid_chid);
587                 }
588         }
589         pclc_base->hdr.length = htons(plen);
590         memcpy(trl->eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
591
592         /* send SMC Proposal CLC message */
593         memset(&msg, 0, sizeof(msg));
594         i = 0;
595         vec[i].iov_base = pclc_base;
596         vec[i++].iov_len = sizeof(*pclc_base);
597         vec[i].iov_base = pclc_smcd;
598         vec[i++].iov_len = sizeof(*pclc_smcd);
599         if (ini->smc_type_v1 != SMC_TYPE_N) {
600                 vec[i].iov_base = pclc_prfx;
601                 vec[i++].iov_len = sizeof(*pclc_prfx);
602                 if (pclc_prfx->ipv6_prefixes_cnt > 0) {
603                         vec[i].iov_base = ipv6_prfx;
604                         vec[i++].iov_len = pclc_prfx->ipv6_prefixes_cnt *
605                                            sizeof(ipv6_prfx[0]);
606                 }
607         }
608         if (ini->smc_type_v2 != SMC_TYPE_N) {
609                 vec[i].iov_base = v2_ext;
610                 vec[i++].iov_len = sizeof(*v2_ext);
611                 vec[i].iov_base = smcd_v2_ext;
612                 vec[i++].iov_len = sizeof(*smcd_v2_ext);
613                 if (ini->ism_offered_cnt) {
614                         vec[i].iov_base = gidchids;
615                         vec[i++].iov_len = ini->ism_offered_cnt *
616                                         sizeof(struct smc_clc_smcd_gid_chid);
617                 }
618         }
619         vec[i].iov_base = trl;
620         vec[i++].iov_len = sizeof(*trl);
621         /* due to the few bytes needed for clc-handshake this cannot block */
622         len = kernel_sendmsg(smc->clcsock, &msg, vec, i, plen);
623         if (len < 0) {
624                 smc->sk.sk_err = smc->clcsock->sk->sk_err;
625                 reason_code = -smc->sk.sk_err;
626         } else if (len < ntohs(pclc_base->hdr.length)) {
627                 reason_code = -ENETUNREACH;
628                 smc->sk.sk_err = -reason_code;
629         }
630
631         kfree(pclc);
632         return reason_code;
633 }
634
635 /* build and send CLC CONFIRM / ACCEPT message */
636 static int smc_clc_send_confirm_accept(struct smc_sock *smc,
637                                        struct smc_clc_msg_accept_confirm_v2 *clc_v2,
638                                        int first_contact, u8 version)
639 {
640         struct smc_connection *conn = &smc->conn;
641         struct smc_clc_msg_accept_confirm *clc;
642         struct smc_clc_first_contact_ext fce;
643         struct smc_clc_msg_trail trl;
644         struct kvec vec[3];
645         struct msghdr msg;
646         int i, len;
647
648         /* send SMC Confirm CLC msg */
649         clc = (struct smc_clc_msg_accept_confirm *)clc_v2;
650         clc->hdr.version = version;     /* SMC version */
651         if (first_contact)
652                 clc->hdr.typev2 |= SMC_FIRST_CONTACT_MASK;
653         if (conn->lgr->is_smcd) {
654                 /* SMC-D specific settings */
655                 memcpy(clc->hdr.eyecatcher, SMCD_EYECATCHER,
656                        sizeof(SMCD_EYECATCHER));
657                 clc->hdr.typev1 = SMC_TYPE_D;
658                 clc->d0.gid = conn->lgr->smcd->local_gid;
659                 clc->d0.token = conn->rmb_desc->token;
660                 clc->d0.dmbe_size = conn->rmbe_size_short;
661                 clc->d0.dmbe_idx = 0;
662                 memcpy(&clc->d0.linkid, conn->lgr->id, SMC_LGR_ID_SIZE);
663                 if (version == SMC_V1) {
664                         clc->hdr.length = htons(SMCD_CLC_ACCEPT_CONFIRM_LEN);
665                 } else {
666                         u8 *eid = NULL;
667
668                         clc_v2->chid = htons(smc_ism_get_chid(conn->lgr->smcd));
669                         smc_ism_get_system_eid(conn->lgr->smcd, &eid);
670                         if (eid)
671                                 memcpy(clc_v2->eid, eid, SMC_MAX_EID_LEN);
672                         len = SMCD_CLC_ACCEPT_CONFIRM_LEN_V2;
673                         if (first_contact)
674                                 smc_clc_fill_fce(&fce, &len);
675                         clc_v2->hdr.length = htons(len);
676                 }
677                 memcpy(trl.eyecatcher, SMCD_EYECATCHER,
678                        sizeof(SMCD_EYECATCHER));
679         } else {
680                 struct smc_link *link = conn->lnk;
681
682                 /* SMC-R specific settings */
683                 link = conn->lnk;
684                 memcpy(clc->hdr.eyecatcher, SMC_EYECATCHER,
685                        sizeof(SMC_EYECATCHER));
686                 clc->hdr.typev1 = SMC_TYPE_R;
687                 clc->hdr.length = htons(SMCR_CLC_ACCEPT_CONFIRM_LEN);
688                 memcpy(clc->r0.lcl.id_for_peer, local_systemid,
689                        sizeof(local_systemid));
690                 memcpy(&clc->r0.lcl.gid, link->gid, SMC_GID_SIZE);
691                 memcpy(&clc->r0.lcl.mac, &link->smcibdev->mac[link->ibport - 1],
692                        ETH_ALEN);
693                 hton24(clc->r0.qpn, link->roce_qp->qp_num);
694                 clc->r0.rmb_rkey =
695                         htonl(conn->rmb_desc->mr_rx[link->link_idx]->rkey);
696                 clc->r0.rmbe_idx = 1; /* for now: 1 RMB = 1 RMBE */
697                 clc->r0.rmbe_alert_token = htonl(conn->alert_token_local);
698                 switch (clc->hdr.type) {
699                 case SMC_CLC_ACCEPT:
700                         clc->r0.qp_mtu = link->path_mtu;
701                         break;
702                 case SMC_CLC_CONFIRM:
703                         clc->r0.qp_mtu = min(link->path_mtu, link->peer_mtu);
704                         break;
705                 }
706                 clc->r0.rmbe_size = conn->rmbe_size_short;
707                 clc->r0.rmb_dma_addr = cpu_to_be64((u64)sg_dma_address
708                                 (conn->rmb_desc->sgt[link->link_idx].sgl));
709                 hton24(clc->r0.psn, link->psn_initial);
710                 memcpy(trl.eyecatcher, SMC_EYECATCHER, sizeof(SMC_EYECATCHER));
711         }
712
713         memset(&msg, 0, sizeof(msg));
714         i = 0;
715         vec[i].iov_base = clc_v2;
716         if (version > SMC_V1)
717                 vec[i++].iov_len = SMCD_CLC_ACCEPT_CONFIRM_LEN_V2 - sizeof(trl);
718         else
719                 vec[i++].iov_len = (clc->hdr.typev1 == SMC_TYPE_D ?
720                                                 SMCD_CLC_ACCEPT_CONFIRM_LEN :
721                                                 SMCR_CLC_ACCEPT_CONFIRM_LEN) -
722                                    sizeof(trl);
723         if (version > SMC_V1 && first_contact) {
724                 vec[i].iov_base = &fce;
725                 vec[i++].iov_len = sizeof(fce);
726         }
727         vec[i].iov_base = &trl;
728         vec[i++].iov_len = sizeof(trl);
729         return kernel_sendmsg(smc->clcsock, &msg, vec, 1,
730                               ntohs(clc->hdr.length));
731 }
732
733 /* send CLC CONFIRM message across internal TCP socket */
734 int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact,
735                          u8 version)
736 {
737         struct smc_clc_msg_accept_confirm_v2 cclc_v2;
738         int reason_code = 0;
739         int len;
740
741         /* send SMC Confirm CLC msg */
742         memset(&cclc_v2, 0, sizeof(cclc_v2));
743         cclc_v2.hdr.type = SMC_CLC_CONFIRM;
744         len = smc_clc_send_confirm_accept(smc, &cclc_v2, clnt_first_contact,
745                                           version);
746         if (len < ntohs(cclc_v2.hdr.length)) {
747                 if (len >= 0) {
748                         reason_code = -ENETUNREACH;
749                         smc->sk.sk_err = -reason_code;
750                 } else {
751                         smc->sk.sk_err = smc->clcsock->sk->sk_err;
752                         reason_code = -smc->sk.sk_err;
753                 }
754         }
755         return reason_code;
756 }
757
758 /* send CLC ACCEPT message across internal TCP socket */
759 int smc_clc_send_accept(struct smc_sock *new_smc, bool srv_first_contact,
760                         u8 version)
761 {
762         struct smc_clc_msg_accept_confirm_v2 aclc_v2;
763         int len;
764
765         memset(&aclc_v2, 0, sizeof(aclc_v2));
766         aclc_v2.hdr.type = SMC_CLC_ACCEPT;
767         len = smc_clc_send_confirm_accept(new_smc, &aclc_v2, srv_first_contact,
768                                           version);
769         if (len < ntohs(aclc_v2.hdr.length))
770                 len = len >= 0 ? -EPROTO : -new_smc->clcsock->sk->sk_err;
771
772         return len > 0 ? 0 : len;
773 }
774
775 void smc_clc_get_hostname(u8 **host)
776 {
777         *host = &smc_hostname[0];
778 }
779
780 void __init smc_clc_init(void)
781 {
782         struct new_utsname *u;
783
784         memset(smc_hostname, _S, sizeof(smc_hostname)); /* ASCII blanks */
785         u = utsname();
786         memcpy(smc_hostname, u->nodename,
787                min_t(size_t, strlen(u->nodename), sizeof(smc_hostname)));
788 }