smc_clc.c 32 KB

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