hc
2024-05-10 10ebd8556b7990499c896a550e3d416b444211e6
kernel/net/smc/smc_clc.h
....@@ -22,27 +22,39 @@
2222 #define SMC_CLC_CONFIRM 0x03
2323 #define SMC_CLC_DECLINE 0x04
2424
25
-#define SMC_CLC_V1 0x1 /* SMC version */
2625 #define SMC_TYPE_R 0 /* SMC-R only */
2726 #define SMC_TYPE_D 1 /* SMC-D only */
27
+#define SMC_TYPE_N 2 /* neither SMC-R nor SMC-D */
2828 #define SMC_TYPE_B 3 /* SMC-R and SMC-D */
2929 #define CLC_WAIT_TIME (6 * HZ) /* max. wait time on clcsock */
30
+#define CLC_WAIT_TIME_SHORT HZ /* short wait time on clcsock */
3031 #define SMC_CLC_DECL_MEM 0x01010000 /* insufficient memory resources */
3132 #define SMC_CLC_DECL_TIMEOUT_CL 0x02010000 /* timeout w4 QP confirm link */
3233 #define SMC_CLC_DECL_TIMEOUT_AL 0x02020000 /* timeout w4 QP add link */
3334 #define SMC_CLC_DECL_CNFERR 0x03000000 /* configuration error */
3435 #define SMC_CLC_DECL_PEERNOSMC 0x03010000 /* peer did not indicate SMC */
3536 #define SMC_CLC_DECL_IPSEC 0x03020000 /* IPsec usage */
36
-#define SMC_CLC_DECL_NOSMCDEV 0x03030000 /* no SMC device found */
37
+#define SMC_CLC_DECL_NOSMCDEV 0x03030000 /* no SMC device found (R or D) */
38
+#define SMC_CLC_DECL_NOSMCDDEV 0x03030001 /* no SMC-D device found */
39
+#define SMC_CLC_DECL_NOSMCRDEV 0x03030002 /* no SMC-R device found */
3740 #define SMC_CLC_DECL_MODEUNSUPP 0x03040000 /* smc modes do not match (R or D)*/
3841 #define SMC_CLC_DECL_RMBE_EC 0x03050000 /* peer has eyecatcher in RMBE */
3942 #define SMC_CLC_DECL_OPTUNSUPP 0x03060000 /* fastopen sockopt not supported */
43
+#define SMC_CLC_DECL_DIFFPREFIX 0x03070000 /* IP prefix / subnet mismatch */
44
+#define SMC_CLC_DECL_GETVLANERR 0x03080000 /* err to get vlan id of ip device*/
45
+#define SMC_CLC_DECL_ISMVLANERR 0x03090000 /* err to reg vlan id on ism dev */
46
+#define SMC_CLC_DECL_NOACTLINK 0x030a0000 /* no active smc-r link in lgr */
47
+#define SMC_CLC_DECL_NOSRVLINK 0x030b0000 /* SMC-R link from srv not found */
48
+#define SMC_CLC_DECL_VERSMISMAT 0x030c0000 /* SMC version mismatch */
49
+#define SMC_CLC_DECL_MAX_DMB 0x030d0000 /* SMC-D DMB limit exceeded */
4050 #define SMC_CLC_DECL_SYNCERR 0x04000000 /* synchronization error */
4151 #define SMC_CLC_DECL_PEERDECL 0x05000000 /* peer declined during handshake */
42
-#define SMC_CLC_DECL_INTERR 0x99990000 /* internal error */
43
-#define SMC_CLC_DECL_ERR_RTOK 0x99990001 /* rtoken handling failed */
44
-#define SMC_CLC_DECL_ERR_RDYLNK 0x99990002 /* ib ready link failed */
45
-#define SMC_CLC_DECL_ERR_REGRMB 0x99990003 /* reg rmb failed */
52
+#define SMC_CLC_DECL_INTERR 0x09990000 /* internal error */
53
+#define SMC_CLC_DECL_ERR_RTOK 0x09990001 /* rtoken handling failed */
54
+#define SMC_CLC_DECL_ERR_RDYLNK 0x09990002 /* ib ready link failed */
55
+#define SMC_CLC_DECL_ERR_REGRMB 0x09990003 /* reg rmb failed */
56
+
57
+#define SMC_FIRST_CONTACT_MASK 0b10 /* first contact bit within typev2 */
4658
4759 struct smc_clc_msg_hdr { /* header1 of clc messages */
4860 u8 eyecatcher[4]; /* eye catcher */
....@@ -50,13 +62,11 @@
5062 __be16 length;
5163 #if defined(__BIG_ENDIAN_BITFIELD)
5264 u8 version : 4,
53
- flag : 1,
54
- rsvd : 1,
55
- path : 2;
65
+ typev2 : 2,
66
+ typev1 : 2;
5667 #elif defined(__LITTLE_ENDIAN_BITFIELD)
57
- u8 path : 2,
58
- rsvd : 1,
59
- flag : 1,
68
+ u8 typev1 : 2,
69
+ typev2 : 2,
6070 version : 4;
6171 #endif
6272 } __packed; /* format defined in RFC7609 */
....@@ -71,8 +81,6 @@
7181 u8 mac[6]; /* mac of ib_device port */
7282 };
7383
74
-#define SMC_CLC_MAX_V6_PREFIX 8
75
-
7684 /* Struct would be 4 byte aligned, but it is used in an array that is sent
7785 * to peers and must conform to RFC7609, hence we need to use packed here.
7886 */
....@@ -80,6 +88,44 @@
8088 struct in6_addr prefix;
8189 u8 prefix_len;
8290 } __packed; /* format defined in RFC7609 */
91
+
92
+#if defined(__BIG_ENDIAN_BITFIELD)
93
+struct smc_clc_v2_flag {
94
+ u8 release : 4,
95
+ rsvd : 3,
96
+ seid : 1;
97
+};
98
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
99
+struct smc_clc_v2_flag {
100
+ u8 seid : 1,
101
+ rsvd : 3,
102
+ release : 4;
103
+};
104
+#endif
105
+
106
+struct smc_clnt_opts_area_hdr {
107
+ u8 eid_cnt; /* number of user defined EIDs */
108
+ u8 ism_gid_cnt; /* number of ISMv2 GIDs */
109
+ u8 reserved1;
110
+ struct smc_clc_v2_flag flag;
111
+ u8 reserved2[2];
112
+ __be16 smcd_v2_ext_offset; /* SMC-Dv2 Extension Offset */
113
+};
114
+
115
+struct smc_clc_smcd_gid_chid {
116
+ __be64 gid; /* ISM GID */
117
+ __be16 chid; /* ISMv2 CHID */
118
+} __packed; /* format defined in
119
+ * IBM Shared Memory Communications Version 2
120
+ * (https://www.ibm.com/support/pages/node/6326337)
121
+ */
122
+
123
+struct smc_clc_v2_extension {
124
+ struct smc_clnt_opts_area_hdr hdr;
125
+ u8 roce[16]; /* RoCEv2 GID */
126
+ u8 reserved[16];
127
+ u8 user_eids[][SMC_MAX_EID_LEN];
128
+};
83129
84130 struct smc_clc_msg_proposal_prefix { /* prefix part of clc proposal message*/
85131 __be32 outgoing_subnet; /* subnet mask */
....@@ -89,8 +135,15 @@
89135 } __aligned(4);
90136
91137 struct smc_clc_msg_smcd { /* SMC-D GID information */
92
- u64 gid; /* ISM GID of requestor */
93
- u8 res[32];
138
+ struct smc_clc_smcd_gid_chid ism; /* ISM native GID+CHID of requestor */
139
+ __be16 v2_ext_offset; /* SMC Version 2 Extension Offset */
140
+ u8 reserved[28];
141
+};
142
+
143
+struct smc_clc_smcd_v2_extension {
144
+ u8 system_eid[SMC_MAX_EID_LEN];
145
+ u8 reserved[16];
146
+ struct smc_clc_smcd_gid_chid gidchid[];
94147 };
95148
96149 struct smc_clc_msg_proposal { /* clc proposal message sent by Linux */
....@@ -99,64 +152,107 @@
99152 __be16 iparea_offset; /* offset to IP address information area */
100153 } __aligned(4);
101154
102
-#define SMC_CLC_PROPOSAL_MAX_OFFSET 0x28
103
-#define SMC_CLC_PROPOSAL_MAX_PREFIX (SMC_CLC_MAX_V6_PREFIX * \
104
- sizeof(struct smc_clc_ipv6_prefix))
105
-#define SMC_CLC_MAX_LEN (sizeof(struct smc_clc_msg_proposal) + \
106
- SMC_CLC_PROPOSAL_MAX_OFFSET + \
107
- sizeof(struct smc_clc_msg_proposal_prefix) + \
108
- SMC_CLC_PROPOSAL_MAX_PREFIX + \
109
- sizeof(struct smc_clc_msg_trail))
155
+#define SMC_CLC_MAX_V6_PREFIX 8
156
+
157
+struct smc_clc_msg_proposal_area {
158
+ struct smc_clc_msg_proposal pclc_base;
159
+ struct smc_clc_msg_smcd pclc_smcd;
160
+ struct smc_clc_msg_proposal_prefix pclc_prfx;
161
+ struct smc_clc_ipv6_prefix pclc_prfx_ipv6[SMC_CLC_MAX_V6_PREFIX];
162
+ struct smc_clc_v2_extension pclc_v2_ext;
163
+ struct smc_clc_smcd_v2_extension pclc_smcd_v2_ext;
164
+ struct smc_clc_smcd_gid_chid pclc_gidchids[SMC_MAX_ISM_DEVS];
165
+ struct smc_clc_msg_trail pclc_trl;
166
+};
167
+
168
+struct smcr_clc_msg_accept_confirm { /* SMCR accept/confirm */
169
+ struct smc_clc_msg_local lcl;
170
+ u8 qpn[3]; /* QP number */
171
+ __be32 rmb_rkey; /* RMB rkey */
172
+ u8 rmbe_idx; /* Index of RMBE in RMB */
173
+ __be32 rmbe_alert_token; /* unique connection id */
174
+ #if defined(__BIG_ENDIAN_BITFIELD)
175
+ u8 rmbe_size : 4, /* buf size (compressed) */
176
+ qp_mtu : 4; /* QP mtu */
177
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
178
+ u8 qp_mtu : 4,
179
+ rmbe_size : 4;
180
+#endif
181
+ u8 reserved;
182
+ __be64 rmb_dma_addr; /* RMB virtual address */
183
+ u8 reserved2;
184
+ u8 psn[3]; /* packet sequence number */
185
+} __packed;
186
+
187
+struct smcd_clc_msg_accept_confirm_common { /* SMCD accept/confirm */
188
+ u64 gid; /* Sender GID */
189
+ u64 token; /* DMB token */
190
+ u8 dmbe_idx; /* DMBE index */
191
+#if defined(__BIG_ENDIAN_BITFIELD)
192
+ u8 dmbe_size : 4, /* buf size (compressed) */
193
+ reserved3 : 4;
194
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
195
+ u8 reserved3 : 4,
196
+ dmbe_size : 4;
197
+#endif
198
+ u16 reserved4;
199
+ __be32 linkid; /* Link identifier */
200
+} __packed;
201
+
202
+#define SMC_CLC_OS_ZOS 1
203
+#define SMC_CLC_OS_LINUX 2
204
+#define SMC_CLC_OS_AIX 3
205
+
206
+struct smc_clc_first_contact_ext {
207
+ u8 reserved1;
208
+#if defined(__BIG_ENDIAN_BITFIELD)
209
+ u8 os_type : 4,
210
+ release : 4;
211
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
212
+ u8 release : 4,
213
+ os_type : 4;
214
+#endif
215
+ u8 reserved2[2];
216
+ u8 hostname[SMC_MAX_HOSTNAME_LEN];
217
+};
110218
111219 struct smc_clc_msg_accept_confirm { /* clc accept / confirm message */
112220 struct smc_clc_msg_hdr hdr;
113221 union {
114
- struct { /* SMC-R */
115
- struct smc_clc_msg_local lcl;
116
- u8 qpn[3]; /* QP number */
117
- __be32 rmb_rkey; /* RMB rkey */
118
- u8 rmbe_idx; /* Index of RMBE in RMB */
119
- __be32 rmbe_alert_token;/* unique connection id */
120
-#if defined(__BIG_ENDIAN_BITFIELD)
121
- u8 rmbe_size : 4, /* buf size (compressed) */
122
- qp_mtu : 4; /* QP mtu */
123
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
124
- u8 qp_mtu : 4,
125
- rmbe_size : 4;
126
-#endif
127
- u8 reserved;
128
- __be64 rmb_dma_addr; /* RMB virtual address */
129
- u8 reserved2;
130
- u8 psn[3]; /* packet sequence number */
131
- struct smc_clc_msg_trail smcr_trl;
132
- /* eye catcher "SMCR" EBCDIC */
133
- } __packed;
222
+ struct smcr_clc_msg_accept_confirm r0; /* SMC-R */
134223 struct { /* SMC-D */
135
- u64 gid; /* Sender GID */
136
- u64 token; /* DMB token */
137
- u8 dmbe_idx; /* DMBE index */
138
-#if defined(__BIG_ENDIAN_BITFIELD)
139
- u8 dmbe_size : 4, /* buf size (compressed) */
140
- reserved3 : 4;
141
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
142
- u8 reserved3 : 4,
143
- dmbe_size : 4;
144
-#endif
145
- u16 reserved4;
146
- u32 linkid; /* Link identifier */
224
+ struct smcd_clc_msg_accept_confirm_common d0;
147225 u32 reserved5[3];
148
- struct smc_clc_msg_trail smcd_trl;
149
- /* eye catcher "SMCD" EBCDIC */
150
- } __packed;
226
+ };
151227 };
152228 } __packed; /* format defined in RFC7609 */
229
+
230
+struct smc_clc_msg_accept_confirm_v2 { /* clc accept / confirm message */
231
+ struct smc_clc_msg_hdr hdr;
232
+ union {
233
+ struct smcr_clc_msg_accept_confirm r0; /* SMC-R */
234
+ struct { /* SMC-D */
235
+ struct smcd_clc_msg_accept_confirm_common d0;
236
+ __be16 chid;
237
+ u8 eid[SMC_MAX_EID_LEN];
238
+ u8 reserved5[8];
239
+ };
240
+ };
241
+};
153242
154243 struct smc_clc_msg_decline { /* clc decline message */
155244 struct smc_clc_msg_hdr hdr;
156245 u8 id_for_peer[SMC_SYSTEMID_LEN]; /* sender peer_id */
157246 __be32 peer_diagnosis; /* diagnosis information */
158
- u8 reserved2[4];
159
- struct smc_clc_msg_trail trl; /* eye catcher "SMCR" EBCDIC */
247
+#if defined(__BIG_ENDIAN_BITFIELD)
248
+ u8 os_type : 4,
249
+ reserved : 4;
250
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
251
+ u8 reserved : 4,
252
+ os_type : 4;
253
+#endif
254
+ u8 reserved2[3];
255
+ struct smc_clc_msg_trail trl; /* eye catcher "SMCD" or "SMCR" EBCDIC */
160256 } __aligned(4);
161257
162258 /* determine start of the prefix area within the proposal message */
....@@ -167,27 +263,71 @@
167263 ((u8 *)pclc + sizeof(*pclc) + ntohs(pclc->iparea_offset));
168264 }
169265
266
+static inline bool smcr_indicated(int smc_type)
267
+{
268
+ return smc_type == SMC_TYPE_R || smc_type == SMC_TYPE_B;
269
+}
270
+
271
+static inline bool smcd_indicated(int smc_type)
272
+{
273
+ return smc_type == SMC_TYPE_D || smc_type == SMC_TYPE_B;
274
+}
275
+
170276 /* get SMC-D info from proposal message */
171277 static inline struct smc_clc_msg_smcd *
172278 smc_get_clc_msg_smcd(struct smc_clc_msg_proposal *prop)
173279 {
174
- if (ntohs(prop->iparea_offset) != sizeof(struct smc_clc_msg_smcd))
280
+ if (smcd_indicated(prop->hdr.typev1) &&
281
+ ntohs(prop->iparea_offset) != sizeof(struct smc_clc_msg_smcd))
175282 return NULL;
176283
177284 return (struct smc_clc_msg_smcd *)(prop + 1);
178285 }
179286
287
+static inline struct smc_clc_v2_extension *
288
+smc_get_clc_v2_ext(struct smc_clc_msg_proposal *prop)
289
+{
290
+ struct smc_clc_msg_smcd *prop_smcd = smc_get_clc_msg_smcd(prop);
291
+
292
+ if (!prop_smcd || !ntohs(prop_smcd->v2_ext_offset))
293
+ return NULL;
294
+
295
+ return (struct smc_clc_v2_extension *)
296
+ ((u8 *)prop_smcd +
297
+ offsetof(struct smc_clc_msg_smcd, v2_ext_offset) +
298
+ sizeof(prop_smcd->v2_ext_offset) +
299
+ ntohs(prop_smcd->v2_ext_offset));
300
+}
301
+
302
+static inline struct smc_clc_smcd_v2_extension *
303
+smc_get_clc_smcd_v2_ext(struct smc_clc_v2_extension *prop_v2ext)
304
+{
305
+ if (!prop_v2ext)
306
+ return NULL;
307
+ if (!ntohs(prop_v2ext->hdr.smcd_v2_ext_offset))
308
+ return NULL;
309
+
310
+ return (struct smc_clc_smcd_v2_extension *)
311
+ ((u8 *)prop_v2ext +
312
+ offsetof(struct smc_clc_v2_extension, hdr) +
313
+ offsetof(struct smc_clnt_opts_area_hdr, smcd_v2_ext_offset) +
314
+ sizeof(prop_v2ext->hdr.smcd_v2_ext_offset) +
315
+ ntohs(prop_v2ext->hdr.smcd_v2_ext_offset));
316
+}
317
+
180318 struct smcd_dev;
319
+struct smc_init_info;
181320
182321 int smc_clc_prfx_match(struct socket *clcsock,
183322 struct smc_clc_msg_proposal_prefix *prop);
184323 int smc_clc_wait_msg(struct smc_sock *smc, void *buf, int buflen,
185
- u8 expected_type);
186
-int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info);
187
-int smc_clc_send_proposal(struct smc_sock *smc, int smc_type,
188
- struct smc_ib_device *smcibdev, u8 ibport, u8 gid[],
189
- struct smcd_dev *ismdev);
190
-int smc_clc_send_confirm(struct smc_sock *smc);
191
-int smc_clc_send_accept(struct smc_sock *smc, int srv_first_contact);
324
+ u8 expected_type, unsigned long timeout);
325
+int smc_clc_send_decline(struct smc_sock *smc, u32 peer_diag_info, u8 version);
326
+int smc_clc_send_proposal(struct smc_sock *smc, struct smc_init_info *ini);
327
+int smc_clc_send_confirm(struct smc_sock *smc, bool clnt_first_contact,
328
+ u8 version);
329
+int smc_clc_send_accept(struct smc_sock *smc, bool srv_first_contact,
330
+ u8 version);
331
+void smc_clc_init(void) __init;
192332
193333 #endif