1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2017, Microsoft Corporation.
4 * Copyright (C) 2018, LG Electronics.
5 *
6 * Author(s): Long Li <longli@microsoft.com>,
7 * Hyunchul Lee <hyc.lee@gmail.com>
8 */
9
10 #define SUBMOD_NAME "smb_direct"
11
12 #include <linux/kthread.h>
13 #include <linux/list.h>
14 #include <linux/string_choices.h>
15
16 #include "glob.h"
17 #include "connection.h"
18 #include "smb_common.h"
19 #include "../common/smb2status.h"
20 #include "transport_rdma.h"
21 #include "../smbdirect/public.h"
22
23
24 #define SMB_DIRECT_PORT_IWARP 5445
25 #define SMB_DIRECT_PORT_INFINIBAND 445
26
27 /* SMB_DIRECT negotiation timeout (for the server) in seconds */
28 #define SMB_DIRECT_NEGOTIATE_TIMEOUT 5
29
30 /* The timeout to wait for a keepalive message from peer in seconds */
31 #define SMB_DIRECT_KEEPALIVE_SEND_INTERVAL 120
32
33 /* The timeout to wait for a keepalive message from peer in seconds */
34 #define SMB_DIRECT_KEEPALIVE_RECV_TIMEOUT 5
35
36 /*
37 * Default maximum number of RDMA read/write outstanding on this connection
38 * This value is possibly decreased during QP creation on hardware limit
39 */
40 #define SMB_DIRECT_CM_INITIATOR_DEPTH 8
41
42 /*
43 * User configurable initial values per SMB_DIRECT transport connection
44 * as defined in [MS-SMBD] 3.1.1.1
45 * Those may change after a SMB_DIRECT negotiation
46 */
47
48 /* The local peer's maximum number of credits to grant to the peer */
49 static int smb_direct_receive_credit_max = 255;
50
51 /* The remote peer's credit request of local peer */
52 static int smb_direct_send_credit_target = 255;
53
54 /* The maximum single message size can be sent to remote peer */
55 static int smb_direct_max_send_size = 1364;
56
57 /*
58 * The maximum fragmented upper-layer payload receive size supported
59 *
60 * Assume max_payload_per_credit is
61 * smb_direct_receive_credit_max - 24 = 1340
62 *
63 * The maximum number would be
64 * smb_direct_receive_credit_max * max_payload_per_credit
65 *
66 * 1340 * 255 = 341700 (0x536C4)
67 *
68 * The minimum value from the spec is 131072 (0x20000)
69 *
70 * For now we use the logic we used before:
71 * (1364 * 255) / 2 = 173910 (0x2A756)
72 */
73 static int smb_direct_max_fragmented_recv_size = (1364 * 255) / 2;
74
75 /* The maximum single-message size which can be received */
76 static int smb_direct_max_receive_size = 1364;
77
78 static int smb_direct_max_read_write_size = SMBD_DEFAULT_IOSIZE;
79
80 static struct smb_direct_listener {
81 int port;
82
83 struct task_struct *thread;
84
85 struct smbdirect_socket *socket;
86 } smb_direct_ib_listener, smb_direct_iw_listener;
87
88 struct smb_direct_transport {
89 struct ksmbd_transport transport;
90
91 struct smbdirect_socket *socket;
92 };
93
smb_direct_logging_needed(struct smbdirect_socket * sc,void * private_ptr,unsigned int lvl,unsigned int cls)94 static bool smb_direct_logging_needed(struct smbdirect_socket *sc,
95 void *private_ptr,
96 unsigned int lvl,
97 unsigned int cls)
98 {
99 if (lvl <= SMBDIRECT_LOG_ERR)
100 return true;
101
102 if (lvl > SMBDIRECT_LOG_INFO)
103 return false;
104
105 switch (cls) {
106 /*
107 * These were more or less also logged before
108 * the move to common code.
109 *
110 * SMBDIRECT_LOG_RDMA_MR was not used, but
111 * that's client only code and we should
112 * notice if it's used on the server...
113 */
114 case SMBDIRECT_LOG_RDMA_EVENT:
115 case SMBDIRECT_LOG_RDMA_SEND:
116 case SMBDIRECT_LOG_RDMA_RECV:
117 case SMBDIRECT_LOG_WRITE:
118 case SMBDIRECT_LOG_READ:
119 case SMBDIRECT_LOG_NEGOTIATE:
120 case SMBDIRECT_LOG_OUTGOING:
121 case SMBDIRECT_LOG_RDMA_RW:
122 case SMBDIRECT_LOG_RDMA_MR:
123 return true;
124 /*
125 * These were not logged before the move
126 * to common code.
127 */
128 case SMBDIRECT_LOG_KEEP_ALIVE:
129 case SMBDIRECT_LOG_INCOMING:
130 return false;
131 }
132
133 /*
134 * Log all unknown messages
135 */
136 return true;
137 }
138
smb_direct_logging_vaprintf(struct smbdirect_socket * sc,const char * func,unsigned int line,void * private_ptr,unsigned int lvl,unsigned int cls,struct va_format * vaf)139 static void smb_direct_logging_vaprintf(struct smbdirect_socket *sc,
140 const char *func,
141 unsigned int line,
142 void *private_ptr,
143 unsigned int lvl,
144 unsigned int cls,
145 struct va_format *vaf)
146 {
147 if (lvl <= SMBDIRECT_LOG_ERR)
148 pr_err("%pV", vaf);
149 else
150 ksmbd_debug(RDMA, "%pV", vaf);
151 }
152
153 #define KSMBD_TRANS(t) (&(t)->transport)
154 #define SMBD_TRANS(t) (container_of(t, \
155 struct smb_direct_transport, transport))
156
157 static const struct ksmbd_transport_ops ksmbd_smb_direct_transport_ops;
158
init_smbd_max_io_size(unsigned int sz)159 void init_smbd_max_io_size(unsigned int sz)
160 {
161 sz = clamp_val(sz, SMBD_MIN_IOSIZE, SMBD_MAX_IOSIZE);
162 smb_direct_max_read_write_size = sz;
163 }
164
get_smbd_max_read_write_size(struct ksmbd_transport * kt)165 unsigned int get_smbd_max_read_write_size(struct ksmbd_transport *kt)
166 {
167 struct smb_direct_transport *t;
168 const struct smbdirect_socket_parameters *sp;
169
170 if (kt->ops != &ksmbd_smb_direct_transport_ops)
171 return 0;
172
173 t = SMBD_TRANS(kt);
174 sp = smbdirect_socket_get_current_parameters(t->socket);
175
176 return sp->max_read_write_size;
177 }
178
alloc_transport(struct smbdirect_socket * sc)179 static struct smb_direct_transport *alloc_transport(struct smbdirect_socket *sc)
180 {
181 struct smb_direct_transport *t;
182 struct ksmbd_conn *conn;
183
184 t = kzalloc_obj(*t, KSMBD_DEFAULT_GFP);
185 if (!t)
186 return NULL;
187 t->socket = sc;
188
189 conn = ksmbd_conn_alloc();
190 if (!conn)
191 goto conn_alloc_failed;
192
193 down_write(&conn_list_lock);
194 hash_add(conn_list, &conn->hlist, 0);
195 up_write(&conn_list_lock);
196
197 conn->transport = KSMBD_TRANS(t);
198 KSMBD_TRANS(t)->conn = conn;
199 KSMBD_TRANS(t)->ops = &ksmbd_smb_direct_transport_ops;
200
201 return t;
202
203 conn_alloc_failed:
204 kfree(t);
205 return NULL;
206 }
207
smb_direct_free_transport(struct ksmbd_transport * kt)208 static void smb_direct_free_transport(struct ksmbd_transport *kt)
209 {
210 struct smb_direct_transport *t = SMBD_TRANS(kt);
211
212 smbdirect_socket_release(t->socket);
213 kfree(t);
214 }
215
free_transport(struct smb_direct_transport * t)216 static void free_transport(struct smb_direct_transport *t)
217 {
218 smbdirect_socket_shutdown(t->socket);
219 ksmbd_conn_free(KSMBD_TRANS(t)->conn);
220 }
221
smb_direct_read(struct ksmbd_transport * t,char * buf,unsigned int size,int unused)222 static int smb_direct_read(struct ksmbd_transport *t, char *buf,
223 unsigned int size, int unused)
224 {
225 struct smb_direct_transport *st = SMBD_TRANS(t);
226 struct smbdirect_socket *sc = st->socket;
227 struct msghdr msg = { .msg_flags = 0, };
228 struct kvec iov = {
229 .iov_base = buf,
230 .iov_len = size,
231 };
232 int ret;
233
234 iov_iter_kvec(&msg.msg_iter, ITER_DEST, &iov, 1, size);
235
236 ret = smbdirect_connection_recvmsg(sc, &msg, 0);
237 if (ret == -ERESTARTSYS)
238 ret = -EINTR;
239 return ret;
240 }
241
smb_direct_writev(struct ksmbd_transport * t,struct kvec * iov,int niovs,int buflen,bool need_invalidate,unsigned int remote_key)242 static int smb_direct_writev(struct ksmbd_transport *t,
243 struct kvec *iov, int niovs, int buflen,
244 bool need_invalidate, unsigned int remote_key)
245 {
246 struct smb_direct_transport *st = SMBD_TRANS(t);
247 struct smbdirect_socket *sc = st->socket;
248 struct iov_iter iter;
249
250 iov_iter_kvec(&iter, ITER_SOURCE, iov, niovs, buflen);
251
252 return smbdirect_connection_send_iter(sc, &iter, 0,
253 need_invalidate, remote_key);
254 }
255
smb_direct_rdma_write(struct ksmbd_transport * t,void * buf,unsigned int buflen,struct smbdirect_buffer_descriptor_v1 * desc,unsigned int desc_len)256 static int smb_direct_rdma_write(struct ksmbd_transport *t,
257 void *buf, unsigned int buflen,
258 struct smbdirect_buffer_descriptor_v1 *desc,
259 unsigned int desc_len)
260 {
261 struct smb_direct_transport *st = SMBD_TRANS(t);
262 struct smbdirect_socket *sc = st->socket;
263
264 return smbdirect_connection_rdma_xmit(sc, buf, buflen,
265 desc, desc_len, false);
266 }
267
smb_direct_rdma_read(struct ksmbd_transport * t,void * buf,unsigned int buflen,struct smbdirect_buffer_descriptor_v1 * desc,unsigned int desc_len)268 static int smb_direct_rdma_read(struct ksmbd_transport *t,
269 void *buf, unsigned int buflen,
270 struct smbdirect_buffer_descriptor_v1 *desc,
271 unsigned int desc_len)
272 {
273 struct smb_direct_transport *st = SMBD_TRANS(t);
274 struct smbdirect_socket *sc = st->socket;
275
276 return smbdirect_connection_rdma_xmit(sc, buf, buflen,
277 desc, desc_len, true);
278 }
279
smb_direct_disconnect(struct ksmbd_transport * t)280 static void smb_direct_disconnect(struct ksmbd_transport *t)
281 {
282 struct smb_direct_transport *st = SMBD_TRANS(t);
283 struct smbdirect_socket *sc = st->socket;
284
285 ksmbd_debug(RDMA, "Disconnecting sc=%p\n", sc);
286
287 free_transport(st);
288 }
289
smb_direct_shutdown(struct ksmbd_transport * t)290 static void smb_direct_shutdown(struct ksmbd_transport *t)
291 {
292 struct smb_direct_transport *st = SMBD_TRANS(t);
293 struct smbdirect_socket *sc = st->socket;
294
295 ksmbd_debug(RDMA, "smb-direct shutdown sc=%p\n", sc);
296
297 smbdirect_socket_shutdown(sc);
298 }
299
smb_direct_new_connection(struct smb_direct_listener * listener,struct smbdirect_socket * client_sc)300 static int smb_direct_new_connection(struct smb_direct_listener *listener,
301 struct smbdirect_socket *client_sc)
302 {
303 struct smb_direct_transport *t;
304 struct task_struct *handler;
305 int ret;
306
307 t = alloc_transport(client_sc);
308 if (!t) {
309 smbdirect_socket_release(client_sc);
310 return -ENOMEM;
311 }
312
313 handler = kthread_run(ksmbd_conn_handler_loop,
314 KSMBD_TRANS(t)->conn, "ksmbd:r%u",
315 listener->port);
316 if (IS_ERR(handler)) {
317 ret = PTR_ERR(handler);
318 pr_err("Can't start thread\n");
319 goto out_err;
320 }
321
322 return 0;
323 out_err:
324 free_transport(t);
325 return ret;
326 }
327
smb_direct_listener_kthread_fn(void * p)328 static int smb_direct_listener_kthread_fn(void *p)
329 {
330 struct smb_direct_listener *listener = (struct smb_direct_listener *)p;
331 struct smbdirect_socket *client_sc = NULL;
332
333 while (!kthread_should_stop()) {
334 struct proto_accept_arg arg = { .err = -EINVAL, };
335 long timeo = MAX_SCHEDULE_TIMEOUT;
336
337 if (!listener->socket)
338 break;
339 client_sc = smbdirect_socket_accept(listener->socket, timeo, &arg);
340 if (!client_sc && arg.err == -EINVAL)
341 break;
342 if (!client_sc)
343 continue;
344
345 ksmbd_debug(CONN, "connect success: accepted new connection\n");
346 smb_direct_new_connection(listener, client_sc);
347 }
348
349 ksmbd_debug(CONN, "releasing socket\n");
350 return 0;
351 }
352
smb_direct_listener_destroy(struct smb_direct_listener * listener)353 static void smb_direct_listener_destroy(struct smb_direct_listener *listener)
354 {
355 int ret;
356
357 if (listener->socket)
358 smbdirect_socket_shutdown(listener->socket);
359
360 if (listener->thread) {
361 ret = kthread_stop(listener->thread);
362 if (ret)
363 pr_err("failed to stop forker thread\n");
364 listener->thread = NULL;
365 }
366
367 if (listener->socket) {
368 smbdirect_socket_release(listener->socket);
369 listener->socket = NULL;
370 }
371
372 listener->port = 0;
373 }
374
smb_direct_listen(struct smb_direct_listener * listener,int port)375 static int smb_direct_listen(struct smb_direct_listener *listener,
376 int port)
377 {
378 struct net *net = current->nsproxy->net_ns;
379 struct task_struct *kthread;
380 struct sockaddr_in sin = {
381 .sin_family = AF_INET,
382 .sin_addr.s_addr = htonl(INADDR_ANY),
383 .sin_port = htons(port),
384 };
385 struct smbdirect_socket_parameters init_params = {};
386 struct smbdirect_socket_parameters *sp;
387 struct smbdirect_socket *sc;
388 u64 port_flags = 0;
389 int ret;
390
391 switch (port) {
392 case SMB_DIRECT_PORT_IWARP:
393 /*
394 * only allow iWarp devices
395 * for port 5445.
396 */
397 port_flags |= SMBDIRECT_FLAG_PORT_RANGE_ONLY_IW;
398 break;
399 case SMB_DIRECT_PORT_INFINIBAND:
400 /*
401 * only allow InfiniBand, RoCEv1 or RoCEv2
402 * devices for port 445.
403 *
404 * (Basically don't allow iWarp devices)
405 */
406 port_flags |= SMBDIRECT_FLAG_PORT_RANGE_ONLY_IB;
407 break;
408 default:
409 pr_err("unsupported smbdirect port=%d!\n", port);
410 return -ENODEV;
411 }
412
413 ret = smbdirect_socket_create_kern(net, &sc);
414 if (ret) {
415 pr_err("smbdirect_socket_create_kern() failed: %d %1pe\n",
416 ret, ERR_PTR(ret));
417 return ret;
418 }
419
420 /*
421 * Create the initial parameters
422 */
423 sp = &init_params;
424 sp->flags |= port_flags;
425 sp->negotiate_timeout_msec = SMB_DIRECT_NEGOTIATE_TIMEOUT * 1000;
426 sp->initiator_depth = SMB_DIRECT_CM_INITIATOR_DEPTH;
427 sp->responder_resources = 1;
428 sp->recv_credit_max = smb_direct_receive_credit_max;
429 sp->send_credit_target = smb_direct_send_credit_target;
430 sp->max_send_size = smb_direct_max_send_size;
431 sp->max_fragmented_recv_size = smb_direct_max_fragmented_recv_size;
432 sp->max_recv_size = smb_direct_max_receive_size;
433 sp->max_read_write_size = smb_direct_max_read_write_size;
434 sp->keepalive_interval_msec = SMB_DIRECT_KEEPALIVE_SEND_INTERVAL * 1000;
435 sp->keepalive_timeout_msec = SMB_DIRECT_KEEPALIVE_RECV_TIMEOUT * 1000;
436
437 smbdirect_socket_set_logging(sc, NULL,
438 smb_direct_logging_needed,
439 smb_direct_logging_vaprintf);
440 ret = smbdirect_socket_set_initial_parameters(sc, sp);
441 if (ret) {
442 pr_err("Failed smbdirect_socket_set_initial_parameters(): %d %1pe\n",
443 ret, ERR_PTR(ret));
444 goto err;
445 }
446 ret = smbdirect_socket_set_kernel_settings(sc, IB_POLL_WORKQUEUE, KSMBD_DEFAULT_GFP);
447 if (ret) {
448 pr_err("Failed smbdirect_socket_set_kernel_settings(): %d %1pe\n",
449 ret, ERR_PTR(ret));
450 goto err;
451 }
452
453 ret = smbdirect_socket_bind(sc, (struct sockaddr *)&sin);
454 if (ret) {
455 pr_err("smbdirect_socket_bind() failed: %d %1pe\n",
456 ret, ERR_PTR(ret));
457 goto err;
458 }
459
460 ret = smbdirect_socket_listen(sc, 10);
461 if (ret) {
462 pr_err("Port[%d] smbdirect_socket_listen() failed: %d %1pe\n",
463 port, ret, ERR_PTR(ret));
464 goto err;
465 }
466
467 listener->port = port;
468 listener->socket = sc;
469
470 kthread = kthread_run(smb_direct_listener_kthread_fn,
471 listener,
472 "ksmbd-smbdirect-listener-%u", port);
473 if (IS_ERR(kthread)) {
474 ret = PTR_ERR(kthread);
475 pr_err("Can't start ksmbd listen kthread: %d %1pe\n",
476 ret, ERR_PTR(ret));
477 goto err;
478 }
479
480 listener->thread = kthread;
481 return 0;
482 err:
483 smb_direct_listener_destroy(listener);
484 return ret;
485 }
486
ksmbd_rdma_init(void)487 int ksmbd_rdma_init(void)
488 {
489 int ret;
490
491 smb_direct_ib_listener = smb_direct_iw_listener = (struct smb_direct_listener) {
492 .socket = NULL,
493 };
494
495 ret = smb_direct_listen(&smb_direct_ib_listener,
496 SMB_DIRECT_PORT_INFINIBAND);
497 if (ret) {
498 pr_err("Can't listen on InfiniBand/RoCEv1/RoCEv2: %d\n", ret);
499 goto err;
500 }
501
502 ksmbd_debug(RDMA, "InfiniBand/RoCEv1/RoCEv2 RDMA listener. socket=%p\n",
503 smb_direct_ib_listener.socket);
504
505 ret = smb_direct_listen(&smb_direct_iw_listener,
506 SMB_DIRECT_PORT_IWARP);
507 if (ret) {
508 pr_err("Can't listen on iWarp: %d\n", ret);
509 goto err;
510 }
511
512 ksmbd_debug(RDMA, "iWarp RDMA listener. socket=%p\n",
513 smb_direct_iw_listener.socket);
514
515 return 0;
516 err:
517 ksmbd_rdma_stop_listening();
518 return ret;
519 }
520
ksmbd_rdma_stop_listening(void)521 void ksmbd_rdma_stop_listening(void)
522 {
523 smb_direct_listener_destroy(&smb_direct_ib_listener);
524 smb_direct_listener_destroy(&smb_direct_iw_listener);
525 }
526
ksmbd_rdma_capable_netdev(struct net_device * netdev)527 bool ksmbd_rdma_capable_netdev(struct net_device *netdev)
528 {
529 u8 node_type = smbdirect_netdev_rdma_capable_node_type(netdev);
530
531 return node_type != RDMA_NODE_UNSPECIFIED;
532 }
533
534 static const struct ksmbd_transport_ops ksmbd_smb_direct_transport_ops = {
535 .disconnect = smb_direct_disconnect,
536 .shutdown = smb_direct_shutdown,
537 .writev = smb_direct_writev,
538 .read = smb_direct_read,
539 .rdma_read = smb_direct_rdma_read,
540 .rdma_write = smb_direct_rdma_write,
541 .free_transport = smb_direct_free_transport,
542 };
543