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