PageRenderTime 26ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/net/smc/smc_clc.h

https://gitlab.com/deepcypher/linux
C Header | 401 lines | 338 code | 44 blank | 19 comment | 16 complexity | f965961b7b0fe5790f115626c76a6208 MD5 | raw file
  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
  9. *
  10. * Author(s): Ursula Braun <ubraun@linux.vnet.ibm.com>
  11. */
  12. #ifndef _SMC_CLC_H
  13. #define _SMC_CLC_H
  14. #include <rdma/ib_verbs.h>
  15. #include <linux/smc.h>
  16. #include "smc.h"
  17. #include "smc_netlink.h"
  18. #define SMC_CLC_PROPOSAL 0x01
  19. #define SMC_CLC_ACCEPT 0x02
  20. #define SMC_CLC_CONFIRM 0x03
  21. #define SMC_CLC_DECLINE 0x04
  22. #define SMC_TYPE_R 0 /* SMC-R only */
  23. #define SMC_TYPE_D 1 /* SMC-D only */
  24. #define SMC_TYPE_N 2 /* neither SMC-R nor SMC-D */
  25. #define SMC_TYPE_B 3 /* SMC-R and SMC-D */
  26. #define CLC_WAIT_TIME (6 * HZ) /* max. wait time on clcsock */
  27. #define CLC_WAIT_TIME_SHORT HZ /* short wait time on clcsock */
  28. #define SMC_CLC_DECL_MEM 0x01010000 /* insufficient memory resources */
  29. #define SMC_CLC_DECL_TIMEOUT_CL 0x02010000 /* timeout w4 QP confirm link */
  30. #define SMC_CLC_DECL_TIMEOUT_AL 0x02020000 /* timeout w4 QP add link */
  31. #define SMC_CLC_DECL_CNFERR 0x03000000 /* configuration error */
  32. #define SMC_CLC_DECL_PEERNOSMC 0x03010000 /* peer did not indicate SMC */
  33. #define SMC_CLC_DECL_IPSEC 0x03020000 /* IPsec usage */
  34. #define SMC_CLC_DECL_NOSMCDEV 0x03030000 /* no SMC device found (R or D) */
  35. #define SMC_CLC_DECL_NOSMCDDEV 0x03030001 /* no SMC-D device found */
  36. #define SMC_CLC_DECL_NOSMCRDEV 0x03030002 /* no SMC-R device found */
  37. #define SMC_CLC_DECL_NOISM2SUPP 0x03030003 /* hardware has no ISMv2 support */
  38. #define SMC_CLC_DECL_NOV2EXT 0x03030004 /* peer sent no clc v2 extension */
  39. #define SMC_CLC_DECL_NOV2DEXT 0x03030005 /* peer sent no clc SMC-Dv2 ext. */
  40. #define SMC_CLC_DECL_NOSEID 0x03030006 /* peer sent no SEID */
  41. #define SMC_CLC_DECL_NOSMCD2DEV 0x03030007 /* no SMC-Dv2 device found */
  42. #define SMC_CLC_DECL_NOUEID 0x03030008 /* peer sent no UEID */
  43. #define SMC_CLC_DECL_MODEUNSUPP 0x03040000 /* smc modes do not match (R or D)*/
  44. #define SMC_CLC_DECL_RMBE_EC 0x03050000 /* peer has eyecatcher in RMBE */
  45. #define SMC_CLC_DECL_OPTUNSUPP 0x03060000 /* fastopen sockopt not supported */
  46. #define SMC_CLC_DECL_DIFFPREFIX 0x03070000 /* IP prefix / subnet mismatch */
  47. #define SMC_CLC_DECL_GETVLANERR 0x03080000 /* err to get vlan id of ip device*/
  48. #define SMC_CLC_DECL_ISMVLANERR 0x03090000 /* err to reg vlan id on ism dev */
  49. #define SMC_CLC_DECL_NOACTLINK 0x030a0000 /* no active smc-r link in lgr */
  50. #define SMC_CLC_DECL_NOSRVLINK 0x030b0000 /* SMC-R link from srv not found */
  51. #define SMC_CLC_DECL_VERSMISMAT 0x030c0000 /* SMC version mismatch */
  52. #define SMC_CLC_DECL_MAX_DMB 0x030d0000 /* SMC-D DMB limit exceeded */
  53. #define SMC_CLC_DECL_NOROUTE 0x030e0000 /* SMC-Rv2 conn. no route to peer */
  54. #define SMC_CLC_DECL_NOINDIRECT 0x030f0000 /* SMC-Rv2 conn. indirect mismatch*/
  55. #define SMC_CLC_DECL_SYNCERR 0x04000000 /* synchronization error */
  56. #define SMC_CLC_DECL_PEERDECL 0x05000000 /* peer declined during handshake */
  57. #define SMC_CLC_DECL_INTERR 0x09990000 /* internal error */
  58. #define SMC_CLC_DECL_ERR_RTOK 0x09990001 /* rtoken handling failed */
  59. #define SMC_CLC_DECL_ERR_RDYLNK 0x09990002 /* ib ready link failed */
  60. #define SMC_CLC_DECL_ERR_REGRMB 0x09990003 /* reg rmb failed */
  61. #define SMC_FIRST_CONTACT_MASK 0b10 /* first contact bit within typev2 */
  62. struct smc_clc_msg_hdr { /* header1 of clc messages */
  63. u8 eyecatcher[4]; /* eye catcher */
  64. u8 type; /* proposal / accept / confirm / decline */
  65. __be16 length;
  66. #if defined(__BIG_ENDIAN_BITFIELD)
  67. u8 version : 4,
  68. typev2 : 2,
  69. typev1 : 2;
  70. #elif defined(__LITTLE_ENDIAN_BITFIELD)
  71. u8 typev1 : 2,
  72. typev2 : 2,
  73. version : 4;
  74. #endif
  75. } __packed; /* format defined in RFC7609 */
  76. struct smc_clc_msg_trail { /* trailer of clc messages */
  77. u8 eyecatcher[4];
  78. };
  79. struct smc_clc_msg_local { /* header2 of clc messages */
  80. u8 id_for_peer[SMC_SYSTEMID_LEN]; /* unique system id */
  81. u8 gid[16]; /* gid of ib_device port */
  82. u8 mac[6]; /* mac of ib_device port */
  83. };
  84. /* Struct would be 4 byte aligned, but it is used in an array that is sent
  85. * to peers and must conform to RFC7609, hence we need to use packed here.
  86. */
  87. struct smc_clc_ipv6_prefix {
  88. struct in6_addr prefix;
  89. u8 prefix_len;
  90. } __packed; /* format defined in RFC7609 */
  91. #if defined(__BIG_ENDIAN_BITFIELD)
  92. struct smc_clc_v2_flag {
  93. u8 release : 4,
  94. rsvd : 3,
  95. seid : 1;
  96. };
  97. #elif defined(__LITTLE_ENDIAN_BITFIELD)
  98. struct smc_clc_v2_flag {
  99. u8 seid : 1,
  100. rsvd : 3,
  101. release : 4;
  102. };
  103. #endif
  104. struct smc_clnt_opts_area_hdr {
  105. u8 eid_cnt; /* number of user defined EIDs */
  106. u8 ism_gid_cnt; /* number of ISMv2 GIDs */
  107. u8 reserved1;
  108. struct smc_clc_v2_flag flag;
  109. u8 reserved2[2];
  110. __be16 smcd_v2_ext_offset; /* SMC-Dv2 Extension Offset */
  111. };
  112. struct smc_clc_smcd_gid_chid {
  113. __be64 gid; /* ISM GID */
  114. __be16 chid; /* ISMv2 CHID */
  115. } __packed; /* format defined in
  116. * IBM Shared Memory Communications Version 2
  117. * (https://www.ibm.com/support/pages/node/6326337)
  118. */
  119. struct smc_clc_v2_extension {
  120. struct smc_clnt_opts_area_hdr hdr;
  121. u8 roce[16]; /* RoCEv2 GID */
  122. u8 reserved[16];
  123. u8 user_eids[][SMC_MAX_EID_LEN];
  124. };
  125. struct smc_clc_msg_proposal_prefix { /* prefix part of clc proposal message*/
  126. __be32 outgoing_subnet; /* subnet mask */
  127. u8 prefix_len; /* number of significant bits in mask */
  128. u8 reserved[2];
  129. u8 ipv6_prefixes_cnt; /* number of IPv6 prefixes in prefix array */
  130. } __aligned(4);
  131. struct smc_clc_msg_smcd { /* SMC-D GID information */
  132. struct smc_clc_smcd_gid_chid ism; /* ISM native GID+CHID of requestor */
  133. __be16 v2_ext_offset; /* SMC Version 2 Extension Offset */
  134. u8 reserved[28];
  135. };
  136. struct smc_clc_smcd_v2_extension {
  137. u8 system_eid[SMC_MAX_EID_LEN];
  138. u8 reserved[16];
  139. struct smc_clc_smcd_gid_chid gidchid[];
  140. };
  141. struct smc_clc_msg_proposal { /* clc proposal message sent by Linux */
  142. struct smc_clc_msg_hdr hdr;
  143. struct smc_clc_msg_local lcl;
  144. __be16 iparea_offset; /* offset to IP address information area */
  145. } __aligned(4);
  146. #define SMC_CLC_MAX_V6_PREFIX 8
  147. #define SMC_CLC_MAX_UEID 8
  148. struct smc_clc_msg_proposal_area {
  149. struct smc_clc_msg_proposal pclc_base;
  150. struct smc_clc_msg_smcd pclc_smcd;
  151. struct smc_clc_msg_proposal_prefix pclc_prfx;
  152. struct smc_clc_ipv6_prefix pclc_prfx_ipv6[SMC_CLC_MAX_V6_PREFIX];
  153. struct smc_clc_v2_extension pclc_v2_ext;
  154. u8 user_eids[SMC_CLC_MAX_UEID][SMC_MAX_EID_LEN];
  155. struct smc_clc_smcd_v2_extension pclc_smcd_v2_ext;
  156. struct smc_clc_smcd_gid_chid pclc_gidchids[SMC_MAX_ISM_DEVS];
  157. struct smc_clc_msg_trail pclc_trl;
  158. };
  159. struct smcr_clc_msg_accept_confirm { /* SMCR accept/confirm */
  160. struct smc_clc_msg_local lcl;
  161. u8 qpn[3]; /* QP number */
  162. __be32 rmb_rkey; /* RMB rkey */
  163. u8 rmbe_idx; /* Index of RMBE in RMB */
  164. __be32 rmbe_alert_token; /* unique connection id */
  165. #if defined(__BIG_ENDIAN_BITFIELD)
  166. u8 rmbe_size : 4, /* buf size (compressed) */
  167. qp_mtu : 4; /* QP mtu */
  168. #elif defined(__LITTLE_ENDIAN_BITFIELD)
  169. u8 qp_mtu : 4,
  170. rmbe_size : 4;
  171. #endif
  172. u8 reserved;
  173. __be64 rmb_dma_addr; /* RMB virtual address */
  174. u8 reserved2;
  175. u8 psn[3]; /* packet sequence number */
  176. } __packed;
  177. struct smcd_clc_msg_accept_confirm_common { /* SMCD accept/confirm */
  178. u64 gid; /* Sender GID */
  179. u64 token; /* DMB token */
  180. u8 dmbe_idx; /* DMBE index */
  181. #if defined(__BIG_ENDIAN_BITFIELD)
  182. u8 dmbe_size : 4, /* buf size (compressed) */
  183. reserved3 : 4;
  184. #elif defined(__LITTLE_ENDIAN_BITFIELD)
  185. u8 reserved3 : 4,
  186. dmbe_size : 4;
  187. #endif
  188. u16 reserved4;
  189. __be32 linkid; /* Link identifier */
  190. } __packed;
  191. #define SMC_CLC_OS_ZOS 1
  192. #define SMC_CLC_OS_LINUX 2
  193. #define SMC_CLC_OS_AIX 3
  194. struct smc_clc_first_contact_ext {
  195. #if defined(__BIG_ENDIAN_BITFIELD)
  196. u8 v2_direct : 1,
  197. reserved : 7;
  198. u8 os_type : 4,
  199. release : 4;
  200. #elif defined(__LITTLE_ENDIAN_BITFIELD)
  201. u8 reserved : 7,
  202. v2_direct : 1;
  203. u8 release : 4,
  204. os_type : 4;
  205. #endif
  206. u8 reserved2[2];
  207. u8 hostname[SMC_MAX_HOSTNAME_LEN];
  208. };
  209. struct smc_clc_fce_gid_ext {
  210. u8 reserved[16];
  211. u8 gid_cnt;
  212. u8 reserved2[3];
  213. u8 gid[][SMC_GID_SIZE];
  214. };
  215. struct smc_clc_msg_accept_confirm { /* clc accept / confirm message */
  216. struct smc_clc_msg_hdr hdr;
  217. union {
  218. struct smcr_clc_msg_accept_confirm r0; /* SMC-R */
  219. struct { /* SMC-D */
  220. struct smcd_clc_msg_accept_confirm_common d0;
  221. u32 reserved5[3];
  222. };
  223. };
  224. } __packed; /* format defined in RFC7609 */
  225. struct smc_clc_msg_accept_confirm_v2 { /* clc accept / confirm message */
  226. struct smc_clc_msg_hdr hdr;
  227. union {
  228. struct { /* SMC-R */
  229. struct smcr_clc_msg_accept_confirm r0;
  230. u8 eid[SMC_MAX_EID_LEN];
  231. u8 reserved6[8];
  232. } r1;
  233. struct { /* SMC-D */
  234. struct smcd_clc_msg_accept_confirm_common d0;
  235. __be16 chid;
  236. u8 eid[SMC_MAX_EID_LEN];
  237. u8 reserved5[8];
  238. } d1;
  239. };
  240. };
  241. struct smc_clc_msg_decline { /* clc decline message */
  242. struct smc_clc_msg_hdr hdr;
  243. u8 id_for_peer[SMC_SYSTEMID_LEN]; /* sender peer_id */
  244. __be32 peer_diagnosis; /* diagnosis information */
  245. #if defined(__BIG_ENDIAN_BITFIELD)
  246. u8 os_type : 4,
  247. reserved : 4;
  248. #elif defined(__LITTLE_ENDIAN_BITFIELD)
  249. u8 reserved : 4,
  250. os_type : 4;
  251. #endif
  252. u8 reserved2[3];
  253. struct smc_clc_msg_trail trl; /* eye catcher "SMCD" or "SMCR" EBCDIC */
  254. } __aligned(4);
  255. #define SMC_DECL_DIAG_COUNT_V2 4 /* no. of additional peer diagnosis codes */
  256. struct smc_clc_msg_decline_v2 { /* clc decline message */
  257. struct smc_clc_msg_hdr hdr;
  258. u8 id_for_peer[SMC_SYSTEMID_LEN]; /* sender peer_id */
  259. __be32 peer_diagnosis; /* diagnosis information */
  260. #if defined(__BIG_ENDIAN_BITFIELD)
  261. u8 os_type : 4,
  262. reserved : 4;
  263. #elif defined(__LITTLE_ENDIAN_BITFIELD)
  264. u8 reserved : 4,
  265. os_type : 4;
  266. #endif
  267. u8 reserved2[3];
  268. __be32 peer_diagnosis_v2[SMC_DECL_DIAG_COUNT_V2];
  269. struct smc_clc_msg_trail trl; /* eye catcher "SMCD" or "SMCR" EBCDIC */
  270. } __aligned(4);
  271. /* determine start of the prefix area within the proposal message */
  272. static inline struct smc_clc_msg_proposal_prefix *
  273. smc_clc_proposal_get_prefix(struct smc_clc_msg_proposal *pclc)
  274. {
  275. return (struct smc_clc_msg_proposal_prefix *)
  276. ((u8 *)pclc + sizeof(*pclc) + ntohs(pclc->iparea_offset));
  277. }
  278. static inline bool smcr_indicated(int smc_type)
  279. {
  280. return smc_type == SMC_TYPE_R || smc_type == SMC_TYPE_B;
  281. }
  282. static inline bool smcd_indicated(int smc_type)
  283. {
  284. return smc_type == SMC_TYPE_D || smc_type == SMC_TYPE_B;
  285. }
  286. static inline u8 smc_indicated_type(int is_smcd, int is_smcr)
  287. {
  288. if (is_smcd && is_smcr)
  289. return SMC_TYPE_B;
  290. if (is_smcd)
  291. return SMC_TYPE_D;
  292. if (is_smcr)
  293. return SMC_TYPE_R;
  294. return SMC_TYPE_N;
  295. }
  296. /* get SMC-D info from proposal message */
  297. static inline struct smc_clc_msg_smcd *
  298. smc_get_clc_msg_smcd(struct smc_clc_msg_proposal *prop)
  299. {
  300. if (smcd_indicated(prop->hdr.typev1) &&
  301. ntohs(prop->iparea_offset) != sizeof(struct smc_clc_msg_smcd))
  302. return NULL;
  303. return (struct smc_clc_msg_smcd *)(prop + 1);
  304. }
  305. static inline struct smc_clc_v2_extension *
  306. smc_get_clc_v2_ext(struct smc_clc_msg_proposal *prop)
  307. {
  308. struct smc_clc_msg_smcd *prop_smcd = smc_get_clc_msg_smcd(prop);
  309. if (!prop_smcd || !ntohs(prop_smcd->v2_ext_offset))
  310. return NULL;
  311. return (struct smc_clc_v2_extension *)
  312. ((u8 *)prop_smcd +
  313. offsetof(struct smc_clc_msg_smcd, v2_ext_offset) +
  314. sizeof(prop_smcd->v2_ext_offset) +
  315. ntohs(prop_smcd->v2_ext_offset));
  316. }
  317. static inline struct smc_clc_smcd_v2_extension *
  318. smc_get_clc_smcd_v2_ext(struct smc_clc_v2_extension *prop_v2ext)
  319. {
  320. if (!prop_v2ext)
  321. return NULL;
  322. if (!ntohs(prop_v2ext->hdr.smcd_v2_ext_offset))
  323. return NULL;
  324. return (struct smc_clc_smcd_v2_extension *)
  325. ((u8 *)prop_v2ext +
  326. offsetof(struct smc_clc_v2_extension, hdr) +
  327. offsetof(struct smc_clnt_opts_area_hdr, smcd_v2_ext_offset) +
  328. sizeof(prop_v2ext->hdr.smcd_v2_ext_offset) +
  329. ntohs(prop_v2ext->hdr.smcd_v2_ext_offset));
  330. }
  331. struct smcd_dev;
  332. struct smc_init_info;
  333. int smc_clc_prfx_match(struct socket *clcsock,
  334. struct smc_clc_msg_proposal_prefix *prop);
  335. int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
  336. u8 expected_type, unsigned long timeout);
  337. int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, u8 version);
  338. int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini);
  339. int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact,
  340. u8 version, u8 *eid, struct smc_init_info *ini);
  341. int smc_clc_send_accept(struct smc_sock *smc, bool srv_first_contact,
  342. u8 version, u8 *negotiated_eid);
  343. void smc_clc_init(void) __init;
  344. void smc_clc_exit(void);
  345. void smc_clc_get_hostname(u8 **host);
  346. bool smc_clc_match_eid(u8 *negotiated_eid,
  347. struct smc_clc_v2_extension *smc_v2_ext,
  348. u8 *peer_eid, u8 *local_eid);
  349. int smc_clc_ueid_count(void);
  350. int smc_nl_dump_ueid(struct sk_buff *skb, struct netlink_callback *cb);
  351. int smc_nl_add_ueid(struct sk_buff *skb, struct genl_info *info);
  352. int smc_nl_remove_ueid(struct sk_buff *skb, struct genl_info *info);
  353. int smc_nl_flush_ueid(struct sk_buff *skb, struct genl_info *info);
  354. int smc_nl_dump_seid(struct sk_buff *skb, struct netlink_callback *cb);
  355. int smc_nl_enable_seid(struct sk_buff *skb, struct genl_info *info);
  356. int smc_nl_disable_seid(struct sk_buff *skb, struct genl_info *info);
  357. #endif