cifsd: clean-up codes using chechpatch.pl --strict
[linux-block.git] / fs / cifsd / transport_ipc.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
4  */
5
6 #include <linux/jhash.h>
7 #include <linux/slab.h>
8 #include <linux/rwsem.h>
9 #include <linux/mutex.h>
10 #include <linux/wait.h>
11 #include <linux/hashtable.h>
12 #include <net/net_namespace.h>
13 #include <net/genetlink.h>
14 #include <linux/socket.h>
15 #include <linux/workqueue.h>
16
17 #include "vfs_cache.h"
18 #include "transport_ipc.h"
19 #include "buffer_pool.h"
20 #include "server.h"
21 #include "smb_common.h"
22
23 #include "mgmt/user_config.h"
24 #include "mgmt/share_config.h"
25 #include "mgmt/user_session.h"
26 #include "mgmt/tree_connect.h"
27 #include "mgmt/ksmbd_ida.h"
28 #include "connection.h"
29 #include "transport_tcp.h"
30
31 #define IPC_WAIT_TIMEOUT        (2 * HZ)
32
33 #define IPC_MSG_HASH_BITS       3
34 static DEFINE_HASHTABLE(ipc_msg_table, IPC_MSG_HASH_BITS);
35 static DECLARE_RWSEM(ipc_msg_table_lock);
36 static DEFINE_MUTEX(startup_lock);
37
38 static struct ksmbd_ida *ida;
39
40 static unsigned int ksmbd_tools_pid;
41
42 #define KSMBD_IPC_MSG_HANDLE(m) (*(unsigned int *)m)
43
44 static bool ksmbd_ipc_validate_version(struct genl_info *m)
45 {
46         if (m->genlhdr->version != KSMBD_GENL_VERSION) {
47                 ksmbd_err("%s. ksmbd: %d, kernel module: %d. %s.\n",
48                           "Daemon and kernel module version mismatch",
49                           m->genlhdr->version,
50                           KSMBD_GENL_VERSION,
51                           "User-space ksmbd should terminate");
52                 return false;
53         }
54         return true;
55 }
56
57 struct ksmbd_ipc_msg {
58         unsigned int            type;
59         unsigned int            sz;
60         unsigned char           ____payload[0];
61 };
62
63 #define KSMBD_IPC_MSG_PAYLOAD(m)                                        \
64         ((void *)(((struct ksmbd_ipc_msg *)(m))->____payload))
65
66 struct ipc_msg_table_entry {
67         unsigned int            handle;
68         unsigned int            type;
69         wait_queue_head_t       wait;
70         struct hlist_node       ipc_table_hlist;
71
72         void                    *response;
73 };
74
75 static struct delayed_work ipc_timer_work;
76
77 static int handle_startup_event(struct sk_buff *skb, struct genl_info *info);
78 static int handle_unsupported_event(struct sk_buff *skb, struct genl_info *info);
79 static int handle_generic_event(struct sk_buff *skb, struct genl_info *info);
80 static int ksmbd_ipc_heartbeat_request(void);
81
82 static const struct nla_policy ksmbd_nl_policy[KSMBD_EVENT_MAX] = {
83         [KSMBD_EVENT_UNSPEC] = {
84                 .len = 0,
85         },
86         [KSMBD_EVENT_HEARTBEAT_REQUEST] = {
87                 .len = sizeof(struct ksmbd_heartbeat),
88         },
89         [KSMBD_EVENT_STARTING_UP] = {
90                 .len = sizeof(struct ksmbd_startup_request),
91         },
92         [KSMBD_EVENT_SHUTTING_DOWN] = {
93                 .len = sizeof(struct ksmbd_shutdown_request),
94         },
95         [KSMBD_EVENT_LOGIN_REQUEST] = {
96                 .len = sizeof(struct ksmbd_login_request),
97         },
98         [KSMBD_EVENT_LOGIN_RESPONSE] = {
99                 .len = sizeof(struct ksmbd_login_response),
100         },
101         [KSMBD_EVENT_SHARE_CONFIG_REQUEST] = {
102                 .len = sizeof(struct ksmbd_share_config_request),
103         },
104         [KSMBD_EVENT_SHARE_CONFIG_RESPONSE] = {
105                 .len = sizeof(struct ksmbd_share_config_response),
106         },
107         [KSMBD_EVENT_TREE_CONNECT_REQUEST] = {
108                 .len = sizeof(struct ksmbd_tree_connect_request),
109         },
110         [KSMBD_EVENT_TREE_CONNECT_RESPONSE] = {
111                 .len = sizeof(struct ksmbd_tree_connect_response),
112         },
113         [KSMBD_EVENT_TREE_DISCONNECT_REQUEST] = {
114                 .len = sizeof(struct ksmbd_tree_disconnect_request),
115         },
116         [KSMBD_EVENT_LOGOUT_REQUEST] = {
117                 .len = sizeof(struct ksmbd_logout_request),
118         },
119         [KSMBD_EVENT_RPC_REQUEST] = {
120         },
121         [KSMBD_EVENT_RPC_RESPONSE] = {
122         },
123         [KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST] = {
124         },
125         [KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE] = {
126         },
127 };
128
129 static struct genl_ops ksmbd_genl_ops[] = {
130         {
131                 .cmd    = KSMBD_EVENT_UNSPEC,
132                 .doit   = handle_unsupported_event,
133         },
134         {
135                 .cmd    = KSMBD_EVENT_HEARTBEAT_REQUEST,
136                 .doit   = handle_unsupported_event,
137         },
138         {
139                 .cmd    = KSMBD_EVENT_STARTING_UP,
140                 .doit   = handle_startup_event,
141         },
142         {
143                 .cmd    = KSMBD_EVENT_SHUTTING_DOWN,
144                 .doit   = handle_unsupported_event,
145         },
146         {
147                 .cmd    = KSMBD_EVENT_LOGIN_REQUEST,
148                 .doit   = handle_unsupported_event,
149         },
150         {
151                 .cmd    = KSMBD_EVENT_LOGIN_RESPONSE,
152                 .doit   = handle_generic_event,
153         },
154         {
155                 .cmd    = KSMBD_EVENT_SHARE_CONFIG_REQUEST,
156                 .doit   = handle_unsupported_event,
157         },
158         {
159                 .cmd    = KSMBD_EVENT_SHARE_CONFIG_RESPONSE,
160                 .doit   = handle_generic_event,
161         },
162         {
163                 .cmd    = KSMBD_EVENT_TREE_CONNECT_REQUEST,
164                 .doit   = handle_unsupported_event,
165         },
166         {
167                 .cmd    = KSMBD_EVENT_TREE_CONNECT_RESPONSE,
168                 .doit   = handle_generic_event,
169         },
170         {
171                 .cmd    = KSMBD_EVENT_TREE_DISCONNECT_REQUEST,
172                 .doit   = handle_unsupported_event,
173         },
174         {
175                 .cmd    = KSMBD_EVENT_LOGOUT_REQUEST,
176                 .doit   = handle_unsupported_event,
177         },
178         {
179                 .cmd    = KSMBD_EVENT_RPC_REQUEST,
180                 .doit   = handle_unsupported_event,
181         },
182         {
183                 .cmd    = KSMBD_EVENT_RPC_RESPONSE,
184                 .doit   = handle_generic_event,
185         },
186         {
187                 .cmd    = KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST,
188                 .doit   = handle_unsupported_event,
189         },
190         {
191                 .cmd    = KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE,
192                 .doit   = handle_generic_event,
193         },
194 };
195
196 static struct genl_family ksmbd_genl_family = {
197         .name           = KSMBD_GENL_NAME,
198         .version        = KSMBD_GENL_VERSION,
199         .hdrsize        = 0,
200         .maxattr        = KSMBD_EVENT_MAX,
201         .netnsok        = true,
202         .module         = THIS_MODULE,
203         .ops            = ksmbd_genl_ops,
204         .n_ops          = ARRAY_SIZE(ksmbd_genl_ops),
205 };
206
207 static void ksmbd_nl_init_fixup(void)
208 {
209         int i;
210
211         for (i = 0; i < ARRAY_SIZE(ksmbd_genl_ops); i++)
212                 ksmbd_genl_ops[i].validate = GENL_DONT_VALIDATE_STRICT |
213                                                 GENL_DONT_VALIDATE_DUMP;
214
215         ksmbd_genl_family.policy = ksmbd_nl_policy;
216 }
217
218 static int rpc_context_flags(struct ksmbd_session *sess)
219 {
220         if (user_guest(sess->user))
221                 return KSMBD_RPC_RESTRICTED_CONTEXT;
222         return 0;
223 }
224
225 static void ipc_update_last_active(void)
226 {
227         if (server_conf.ipc_timeout)
228                 server_conf.ipc_last_active = jiffies;
229 }
230
231 static struct ksmbd_ipc_msg *ipc_msg_alloc(size_t sz)
232 {
233         struct ksmbd_ipc_msg *msg;
234         size_t msg_sz = sz + sizeof(struct ksmbd_ipc_msg);
235
236         msg = ksmbd_alloc(msg_sz);
237         if (msg)
238                 msg->sz = sz;
239         return msg;
240 }
241
242 static void ipc_msg_free(struct ksmbd_ipc_msg *msg)
243 {
244         ksmbd_free(msg);
245 }
246
247 static void ipc_msg_handle_free(int handle)
248 {
249         if (handle >= 0)
250                 ksmbd_release_id(ida, handle);
251 }
252
253 static int handle_response(int type, void *payload, size_t sz)
254 {
255         int handle = KSMBD_IPC_MSG_HANDLE(payload);
256         struct ipc_msg_table_entry *entry;
257         int ret = 0;
258
259         ipc_update_last_active();
260         down_read(&ipc_msg_table_lock);
261         hash_for_each_possible(ipc_msg_table, entry, ipc_table_hlist, handle) {
262                 if (handle != entry->handle)
263                         continue;
264
265                 entry->response = NULL;
266                 /*
267                  * Response message type value should be equal to
268                  * request message type + 1.
269                  */
270                 if (entry->type + 1 != type) {
271                         ksmbd_err("Waiting for IPC type %d, got %d. Ignore.\n",
272                                 entry->type + 1, type);
273                 }
274
275                 entry->response = ksmbd_alloc(sz);
276                 if (!entry->response) {
277                         ret = -ENOMEM;
278                         break;
279                 }
280
281                 memcpy(entry->response, payload, sz);
282                 wake_up_interruptible(&entry->wait);
283                 ret = 0;
284                 break;
285         }
286         up_read(&ipc_msg_table_lock);
287
288         return ret;
289 }
290
291 static int ipc_server_config_on_startup(struct ksmbd_startup_request *req)
292 {
293         int ret;
294
295         ksmbd_set_fd_limit(req->file_max);
296         server_conf.flags = req->flags;
297         server_conf.signing = req->signing;
298         server_conf.tcp_port = req->tcp_port;
299         server_conf.ipc_timeout = req->ipc_timeout * HZ;
300         server_conf.deadtime = req->deadtime * SMB_ECHO_INTERVAL;
301         server_conf.share_fake_fscaps = req->share_fake_fscaps;
302         ksmbd_init_domain(req->sub_auth);
303
304         if (req->smb2_max_read)
305                 init_smb2_max_read_size(req->smb2_max_read);
306         if (req->smb2_max_write)
307                 init_smb2_max_write_size(req->smb2_max_write);
308         if (req->smb2_max_trans)
309                 init_smb2_max_trans_size(req->smb2_max_trans);
310
311         ret = ksmbd_set_netbios_name(req->netbios_name);
312         ret |= ksmbd_set_server_string(req->server_string);
313         ret |= ksmbd_set_work_group(req->work_group);
314         ret |= ksmbd_tcp_set_interfaces(KSMBD_STARTUP_CONFIG_INTERFACES(req),
315                                         req->ifc_list_sz);
316         if (ret) {
317                 ksmbd_err("Server configuration error: %s %s %s\n",
318                                 req->netbios_name,
319                                 req->server_string,
320                                 req->work_group);
321                 return ret;
322         }
323
324         if (req->min_prot[0]) {
325                 ret = ksmbd_lookup_protocol_idx(req->min_prot);
326                 if (ret >= 0)
327                         server_conf.min_protocol = ret;
328         }
329         if (req->max_prot[0]) {
330                 ret = ksmbd_lookup_protocol_idx(req->max_prot);
331                 if (ret >= 0)
332                         server_conf.max_protocol = ret;
333         }
334
335         if (server_conf.ipc_timeout)
336                 schedule_delayed_work(&ipc_timer_work, server_conf.ipc_timeout);
337         return 0;
338 }
339
340 static int handle_startup_event(struct sk_buff *skb, struct genl_info *info)
341 {
342         int ret = 0;
343
344 #ifdef CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN
345         if (!netlink_capable(skb, CAP_NET_ADMIN))
346                 return -EPERM;
347 #endif
348
349         if (!ksmbd_ipc_validate_version(info))
350                 return -EINVAL;
351
352         if (!info->attrs[KSMBD_EVENT_STARTING_UP])
353                 return -EINVAL;
354
355         mutex_lock(&startup_lock);
356         if (!ksmbd_server_configurable()) {
357                 mutex_unlock(&startup_lock);
358                 ksmbd_err("Server reset is in progress, can't start daemon\n");
359                 return -EINVAL;
360         }
361
362         if (ksmbd_tools_pid) {
363                 if (ksmbd_ipc_heartbeat_request() == 0) {
364                         ret = -EINVAL;
365                         goto out;
366                 }
367
368                 ksmbd_err("Reconnect to a new user space daemon\n");
369         } else {
370                 struct ksmbd_startup_request *req;
371
372                 req = nla_data(info->attrs[info->genlhdr->cmd]);
373                 ret = ipc_server_config_on_startup(req);
374                 if (ret)
375                         goto out;
376                 server_queue_ctrl_init_work();
377         }
378
379         ksmbd_tools_pid = info->snd_portid;
380         ipc_update_last_active();
381
382 out:
383         mutex_unlock(&startup_lock);
384         return ret;
385 }
386
387 static int handle_unsupported_event(struct sk_buff *skb, struct genl_info *info)
388 {
389         ksmbd_err("Unknown IPC event: %d, ignore.\n", info->genlhdr->cmd);
390         return -EINVAL;
391 }
392
393 static int handle_generic_event(struct sk_buff *skb, struct genl_info *info)
394 {
395         void *payload;
396         int sz;
397         int type = info->genlhdr->cmd;
398
399 #ifdef CONFIG_SMB_SERVER_CHECK_CAP_NET_ADMIN
400         if (!netlink_capable(skb, CAP_NET_ADMIN))
401                 return -EPERM;
402 #endif
403
404         if (type >= KSMBD_EVENT_MAX) {
405                 WARN_ON(1);
406                 return -EINVAL;
407         }
408
409         if (!ksmbd_ipc_validate_version(info))
410                 return -EINVAL;
411
412         if (!info->attrs[type])
413                 return -EINVAL;
414
415         payload = nla_data(info->attrs[info->genlhdr->cmd]);
416         sz = nla_len(info->attrs[info->genlhdr->cmd]);
417         return handle_response(type, payload, sz);
418 }
419
420 static int ipc_msg_send(struct ksmbd_ipc_msg *msg)
421 {
422         struct genlmsghdr *nlh;
423         struct sk_buff *skb;
424         int ret = -EINVAL;
425
426         if (!ksmbd_tools_pid)
427                 return ret;
428
429         skb = genlmsg_new(msg->sz, GFP_KERNEL);
430         if (!skb)
431                 return -ENOMEM;
432
433         nlh = genlmsg_put(skb, 0, 0, &ksmbd_genl_family, 0, msg->type);
434         if (!nlh)
435                 goto out;
436
437         ret = nla_put(skb, msg->type, msg->sz, KSMBD_IPC_MSG_PAYLOAD(msg));
438         if (ret) {
439                 genlmsg_cancel(skb, nlh);
440                 goto out;
441         }
442
443         genlmsg_end(skb, nlh);
444         ret = genlmsg_unicast(&init_net, skb, ksmbd_tools_pid);
445         if (!ret)
446                 ipc_update_last_active();
447         return ret;
448
449 out:
450         nlmsg_free(skb);
451         return ret;
452 }
453
454 static void *ipc_msg_send_request(struct ksmbd_ipc_msg *msg, unsigned int handle)
455 {
456         struct ipc_msg_table_entry entry;
457         int ret;
458
459         if ((int)handle < 0)
460                 return NULL;
461
462         entry.type = msg->type;
463         entry.response = NULL;
464         init_waitqueue_head(&entry.wait);
465
466         down_write(&ipc_msg_table_lock);
467         entry.handle = handle;
468         hash_add(ipc_msg_table, &entry.ipc_table_hlist, entry.handle);
469         up_write(&ipc_msg_table_lock);
470
471         ret = ipc_msg_send(msg);
472         if (ret)
473                 goto out;
474
475         ret = wait_event_interruptible_timeout(entry.wait,
476                                                entry.response != NULL,
477                                                IPC_WAIT_TIMEOUT);
478 out:
479         down_write(&ipc_msg_table_lock);
480         hash_del(&entry.ipc_table_hlist);
481         up_write(&ipc_msg_table_lock);
482         return entry.response;
483 }
484
485 static int ksmbd_ipc_heartbeat_request(void)
486 {
487         struct ksmbd_ipc_msg *msg;
488         int ret;
489
490         msg = ipc_msg_alloc(sizeof(struct ksmbd_heartbeat));
491         if (!msg)
492                 return -EINVAL;
493
494         msg->type = KSMBD_EVENT_HEARTBEAT_REQUEST;
495         ret = ipc_msg_send(msg);
496         ipc_msg_free(msg);
497         return ret;
498 }
499
500 struct ksmbd_login_response *ksmbd_ipc_login_request(const char *account)
501 {
502         struct ksmbd_ipc_msg *msg;
503         struct ksmbd_login_request *req;
504         struct ksmbd_login_response *resp;
505
506         if (strlen(account) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ)
507                 return NULL;
508
509         msg = ipc_msg_alloc(sizeof(struct ksmbd_login_request));
510         if (!msg)
511                 return NULL;
512
513         msg->type = KSMBD_EVENT_LOGIN_REQUEST;
514         req = KSMBD_IPC_MSG_PAYLOAD(msg);
515         req->handle = ksmbd_acquire_id(ida);
516         strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ);
517
518         resp = ipc_msg_send_request(msg, req->handle);
519         ipc_msg_handle_free(req->handle);
520         ipc_msg_free(msg);
521         return resp;
522 }
523
524 struct ksmbd_spnego_authen_response *
525 ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len)
526 {
527         struct ksmbd_ipc_msg *msg;
528         struct ksmbd_spnego_authen_request *req;
529         struct ksmbd_spnego_authen_response *resp;
530
531         msg = ipc_msg_alloc(sizeof(struct ksmbd_spnego_authen_request) +
532                         blob_len + 1);
533         if (!msg)
534                 return NULL;
535
536         msg->type = KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST;
537         req = KSMBD_IPC_MSG_PAYLOAD(msg);
538         req->handle = ksmbd_acquire_id(ida);
539         req->spnego_blob_len = blob_len;
540         memcpy(req->spnego_blob, spnego_blob, blob_len);
541
542         resp = ipc_msg_send_request(msg, req->handle);
543         ipc_msg_handle_free(req->handle);
544         ipc_msg_free(msg);
545         return resp;
546 }
547
548 struct ksmbd_tree_connect_response *
549 ksmbd_ipc_tree_connect_request(struct ksmbd_session *sess,
550                 struct ksmbd_share_config *share,
551                 struct ksmbd_tree_connect *tree_conn,
552                 struct sockaddr *peer_addr)
553 {
554         struct ksmbd_ipc_msg *msg;
555         struct ksmbd_tree_connect_request *req;
556         struct ksmbd_tree_connect_response *resp;
557
558         if (strlen(user_name(sess->user)) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ)
559                 return NULL;
560
561         if (strlen(share->name) >= KSMBD_REQ_MAX_SHARE_NAME)
562                 return NULL;
563
564         msg = ipc_msg_alloc(sizeof(struct ksmbd_tree_connect_request));
565         if (!msg)
566                 return NULL;
567
568         msg->type = KSMBD_EVENT_TREE_CONNECT_REQUEST;
569         req = KSMBD_IPC_MSG_PAYLOAD(msg);
570
571         req->handle = ksmbd_acquire_id(ida);
572         req->account_flags = sess->user->flags;
573         req->session_id = sess->id;
574         req->connect_id = tree_conn->id;
575         strscpy(req->account, user_name(sess->user), KSMBD_REQ_MAX_ACCOUNT_NAME_SZ);
576         strscpy(req->share, share->name, KSMBD_REQ_MAX_SHARE_NAME);
577         snprintf(req->peer_addr, sizeof(req->peer_addr), "%pIS", peer_addr);
578
579         if (peer_addr->sa_family == AF_INET6)
580                 req->flags |= KSMBD_TREE_CONN_FLAG_REQUEST_IPV6;
581         if (test_session_flag(sess, CIFDS_SESSION_FLAG_SMB2))
582                 req->flags |= KSMBD_TREE_CONN_FLAG_REQUEST_SMB2;
583
584         resp = ipc_msg_send_request(msg, req->handle);
585         ipc_msg_handle_free(req->handle);
586         ipc_msg_free(msg);
587         return resp;
588 }
589
590 int ksmbd_ipc_tree_disconnect_request(unsigned long long session_id,
591                 unsigned long long connect_id)
592 {
593         struct ksmbd_ipc_msg *msg;
594         struct ksmbd_tree_disconnect_request *req;
595         int ret;
596
597         msg = ipc_msg_alloc(sizeof(struct ksmbd_tree_disconnect_request));
598         if (!msg)
599                 return -ENOMEM;
600
601         msg->type = KSMBD_EVENT_TREE_DISCONNECT_REQUEST;
602         req = KSMBD_IPC_MSG_PAYLOAD(msg);
603         req->session_id = session_id;
604         req->connect_id = connect_id;
605
606         ret = ipc_msg_send(msg);
607         ipc_msg_free(msg);
608         return ret;
609 }
610
611 int ksmbd_ipc_logout_request(const char *account)
612 {
613         struct ksmbd_ipc_msg *msg;
614         struct ksmbd_logout_request *req;
615         int ret;
616
617         if (strlen(account) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ)
618                 return -EINVAL;
619
620         msg = ipc_msg_alloc(sizeof(struct ksmbd_logout_request));
621         if (!msg)
622                 return -ENOMEM;
623
624         msg->type = KSMBD_EVENT_LOGOUT_REQUEST;
625         req = KSMBD_IPC_MSG_PAYLOAD(msg);
626         strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ);
627
628         ret = ipc_msg_send(msg);
629         ipc_msg_free(msg);
630         return ret;
631 }
632
633 struct ksmbd_share_config_response *
634 ksmbd_ipc_share_config_request(const char *name)
635 {
636         struct ksmbd_ipc_msg *msg;
637         struct ksmbd_share_config_request *req;
638         struct ksmbd_share_config_response *resp;
639
640         if (strlen(name) >= KSMBD_REQ_MAX_SHARE_NAME)
641                 return NULL;
642
643         msg = ipc_msg_alloc(sizeof(struct ksmbd_share_config_request));
644         if (!msg)
645                 return NULL;
646
647         msg->type = KSMBD_EVENT_SHARE_CONFIG_REQUEST;
648         req = KSMBD_IPC_MSG_PAYLOAD(msg);
649         req->handle = ksmbd_acquire_id(ida);
650         strscpy(req->share_name, name, KSMBD_REQ_MAX_SHARE_NAME);
651
652         resp = ipc_msg_send_request(msg, req->handle);
653         ipc_msg_handle_free(req->handle);
654         ipc_msg_free(msg);
655         return resp;
656 }
657
658 struct ksmbd_rpc_command *ksmbd_rpc_open(struct ksmbd_session *sess, int handle)
659 {
660         struct ksmbd_ipc_msg *msg;
661         struct ksmbd_rpc_command *req;
662         struct ksmbd_rpc_command *resp;
663
664         msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command));
665         if (!msg)
666                 return NULL;
667
668         msg->type = KSMBD_EVENT_RPC_REQUEST;
669         req = KSMBD_IPC_MSG_PAYLOAD(msg);
670         req->handle = handle;
671         req->flags = ksmbd_session_rpc_method(sess, handle);
672         req->flags |= KSMBD_RPC_OPEN_METHOD;
673         req->payload_sz = 0;
674
675         resp = ipc_msg_send_request(msg, req->handle);
676         ipc_msg_free(msg);
677         return resp;
678 }
679
680 struct ksmbd_rpc_command *ksmbd_rpc_close(struct ksmbd_session *sess, int handle)
681 {
682         struct ksmbd_ipc_msg *msg;
683         struct ksmbd_rpc_command *req;
684         struct ksmbd_rpc_command *resp;
685
686         msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command));
687         if (!msg)
688                 return NULL;
689
690         msg->type = KSMBD_EVENT_RPC_REQUEST;
691         req = KSMBD_IPC_MSG_PAYLOAD(msg);
692         req->handle = handle;
693         req->flags = ksmbd_session_rpc_method(sess, handle);
694         req->flags |= KSMBD_RPC_CLOSE_METHOD;
695         req->payload_sz = 0;
696
697         resp = ipc_msg_send_request(msg, req->handle);
698         ipc_msg_free(msg);
699         return resp;
700 }
701
702 struct ksmbd_rpc_command *ksmbd_rpc_write(struct ksmbd_session *sess, int handle,
703                 void *payload, size_t payload_sz)
704 {
705         struct ksmbd_ipc_msg *msg;
706         struct ksmbd_rpc_command *req;
707         struct ksmbd_rpc_command *resp;
708
709         msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1);
710         if (!msg)
711                 return NULL;
712
713         msg->type = KSMBD_EVENT_RPC_REQUEST;
714         req = KSMBD_IPC_MSG_PAYLOAD(msg);
715         req->handle = handle;
716         req->flags = ksmbd_session_rpc_method(sess, handle);
717         req->flags |= rpc_context_flags(sess);
718         req->flags |= KSMBD_RPC_WRITE_METHOD;
719         req->payload_sz = payload_sz;
720         memcpy(req->payload, payload, payload_sz);
721
722         resp = ipc_msg_send_request(msg, req->handle);
723         ipc_msg_free(msg);
724         return resp;
725 }
726
727 struct ksmbd_rpc_command *ksmbd_rpc_read(struct ksmbd_session *sess, int handle)
728 {
729         struct ksmbd_ipc_msg *msg;
730         struct ksmbd_rpc_command *req;
731         struct ksmbd_rpc_command *resp;
732
733         msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command));
734         if (!msg)
735                 return NULL;
736
737         msg->type = KSMBD_EVENT_RPC_REQUEST;
738         req = KSMBD_IPC_MSG_PAYLOAD(msg);
739         req->handle = handle;
740         req->flags = ksmbd_session_rpc_method(sess, handle);
741         req->flags |= rpc_context_flags(sess);
742         req->flags |= KSMBD_RPC_READ_METHOD;
743         req->payload_sz = 0;
744
745         resp = ipc_msg_send_request(msg, req->handle);
746         ipc_msg_free(msg);
747         return resp;
748 }
749
750 struct ksmbd_rpc_command *ksmbd_rpc_ioctl(struct ksmbd_session *sess, int handle,
751                 void *payload, size_t payload_sz)
752 {
753         struct ksmbd_ipc_msg *msg;
754         struct ksmbd_rpc_command *req;
755         struct ksmbd_rpc_command *resp;
756
757         msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1);
758         if (!msg)
759                 return NULL;
760
761         msg->type = KSMBD_EVENT_RPC_REQUEST;
762         req = KSMBD_IPC_MSG_PAYLOAD(msg);
763         req->handle = handle;
764         req->flags = ksmbd_session_rpc_method(sess, handle);
765         req->flags |= rpc_context_flags(sess);
766         req->flags |= KSMBD_RPC_IOCTL_METHOD;
767         req->payload_sz = payload_sz;
768         memcpy(req->payload, payload, payload_sz);
769
770         resp = ipc_msg_send_request(msg, req->handle);
771         ipc_msg_free(msg);
772         return resp;
773 }
774
775 struct ksmbd_rpc_command *ksmbd_rpc_rap(struct ksmbd_session *sess, void *payload,
776                 size_t payload_sz)
777 {
778         struct ksmbd_ipc_msg *msg;
779         struct ksmbd_rpc_command *req;
780         struct ksmbd_rpc_command *resp;
781
782         msg = ipc_msg_alloc(sizeof(struct ksmbd_rpc_command) + payload_sz + 1);
783         if (!msg)
784                 return NULL;
785
786         msg->type = KSMBD_EVENT_RPC_REQUEST;
787         req = KSMBD_IPC_MSG_PAYLOAD(msg);
788         req->handle = ksmbd_acquire_id(ida);
789         req->flags = rpc_context_flags(sess);
790         req->flags |= KSMBD_RPC_RAP_METHOD;
791         req->payload_sz = payload_sz;
792         memcpy(req->payload, payload, payload_sz);
793
794         resp = ipc_msg_send_request(msg, req->handle);
795         ipc_msg_handle_free(req->handle);
796         ipc_msg_free(msg);
797         return resp;
798 }
799
800 static int __ipc_heartbeat(void)
801 {
802         unsigned long delta;
803
804         if (!ksmbd_server_running())
805                 return 0;
806
807         if (time_after(jiffies, server_conf.ipc_last_active)) {
808                 delta = (jiffies - server_conf.ipc_last_active);
809         } else {
810                 ipc_update_last_active();
811                 schedule_delayed_work(&ipc_timer_work,
812                                       server_conf.ipc_timeout);
813                 return 0;
814         }
815
816         if (delta < server_conf.ipc_timeout) {
817                 schedule_delayed_work(&ipc_timer_work,
818                                       server_conf.ipc_timeout - delta);
819                 return 0;
820         }
821
822         if (ksmbd_ipc_heartbeat_request() == 0) {
823                 schedule_delayed_work(&ipc_timer_work,
824                                       server_conf.ipc_timeout);
825                 return 0;
826         }
827
828         mutex_lock(&startup_lock);
829         WRITE_ONCE(server_conf.state, SERVER_STATE_RESETTING);
830         server_conf.ipc_last_active = 0;
831         ksmbd_tools_pid = 0;
832         ksmbd_err("No IPC daemon response for %lus\n", delta / HZ);
833         mutex_unlock(&startup_lock);
834         return -EINVAL;
835 }
836
837 static void ipc_timer_heartbeat(struct work_struct *w)
838 {
839         if (__ipc_heartbeat())
840                 server_queue_ctrl_reset_work();
841 }
842
843 int ksmbd_ipc_id_alloc(void)
844 {
845         return ksmbd_acquire_id(ida);
846 }
847
848 void ksmbd_rpc_id_free(int handle)
849 {
850         ksmbd_release_id(ida, handle);
851 }
852
853 void ksmbd_ipc_release(void)
854 {
855         cancel_delayed_work_sync(&ipc_timer_work);
856         ksmbd_ida_free(ida);
857         genl_unregister_family(&ksmbd_genl_family);
858 }
859
860 void ksmbd_ipc_soft_reset(void)
861 {
862         mutex_lock(&startup_lock);
863         ksmbd_tools_pid = 0;
864         cancel_delayed_work_sync(&ipc_timer_work);
865         mutex_unlock(&startup_lock);
866 }
867
868 int ksmbd_ipc_init(void)
869 {
870         int ret;
871
872         ksmbd_nl_init_fixup();
873         INIT_DELAYED_WORK(&ipc_timer_work, ipc_timer_heartbeat);
874
875         ret = genl_register_family(&ksmbd_genl_family);
876         if (ret) {
877                 ksmbd_err("Failed to register KSMBD netlink interface %d\n", ret);
878                 goto cancel_work;
879         }
880
881         ida = ksmbd_ida_alloc();
882         if (!ida) {
883                 ret = -ENOMEM;
884                 goto unregister;
885         }
886         return 0;
887
888 unregister:
889         genl_unregister_family(&ksmbd_genl_family);
890 cancel_work:
891         cancel_delayed_work_sync(&ipc_timer_work);
892         return ret;
893 }