GNU Linux-libre 6.0.2-gnu
[releases.git] / fs / ksmbd / connection.h
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
4  */
5
6 #ifndef __KSMBD_CONNECTION_H__
7 #define __KSMBD_CONNECTION_H__
8
9 #include <linux/list.h>
10 #include <linux/ip.h>
11 #include <net/sock.h>
12 #include <net/tcp.h>
13 #include <net/inet_connection_sock.h>
14 #include <net/request_sock.h>
15 #include <linux/kthread.h>
16 #include <linux/nls.h>
17
18 #include "smb_common.h"
19 #include "ksmbd_work.h"
20
21 #define KSMBD_SOCKET_BACKLOG            16
22
23 enum {
24         KSMBD_SESS_NEW = 0,
25         KSMBD_SESS_GOOD,
26         KSMBD_SESS_EXITING,
27         KSMBD_SESS_NEED_RECONNECT,
28         KSMBD_SESS_NEED_NEGOTIATE
29 };
30
31 struct ksmbd_stats {
32         atomic_t                        open_files_count;
33         atomic64_t                      request_served;
34 };
35
36 struct ksmbd_transport;
37
38 struct ksmbd_conn {
39         struct smb_version_values       *vals;
40         struct smb_version_ops          *ops;
41         struct smb_version_cmds         *cmds;
42         unsigned int                    max_cmds;
43         struct mutex                    srv_mutex;
44         int                             status;
45         unsigned int                    cli_cap;
46         char                            *request_buf;
47         struct ksmbd_transport          *transport;
48         struct nls_table                *local_nls;
49         struct list_head                conns_list;
50         /* smb session 1 per user */
51         struct xarray                   sessions;
52         unsigned long                   last_active;
53         /* How many request are running currently */
54         atomic_t                        req_running;
55         /* References which are made for this Server object*/
56         atomic_t                        r_count;
57         unsigned int                    total_credits;
58         unsigned int                    outstanding_credits;
59         spinlock_t                      credits_lock;
60         wait_queue_head_t               req_running_q;
61         wait_queue_head_t               r_count_q;
62         /* Lock to protect requests list*/
63         spinlock_t                      request_lock;
64         struct list_head                requests;
65         struct list_head                async_requests;
66         int                             connection_type;
67         struct ksmbd_stats              stats;
68         char                            ClientGUID[SMB2_CLIENT_GUID_SIZE];
69         struct ntlmssp_auth             ntlmssp;
70
71         spinlock_t                      llist_lock;
72         struct list_head                lock_list;
73
74         struct preauth_integrity_info   *preauth_info;
75
76         bool                            need_neg;
77         unsigned int                    auth_mechs;
78         unsigned int                    preferred_auth_mech;
79         bool                            sign;
80         bool                            use_spnego:1;
81         __u16                           cli_sec_mode;
82         __u16                           srv_sec_mode;
83         /* dialect index that server chose */
84         __u16                           dialect;
85
86         char                            *mechToken;
87
88         struct ksmbd_conn_ops   *conn_ops;
89
90         /* Preauth Session Table */
91         struct list_head                preauth_sess_table;
92
93         struct sockaddr_storage         peer_addr;
94
95         /* Identifier for async message */
96         struct ida                      async_ida;
97
98         __le16                          cipher_type;
99         __le16                          compress_algorithm;
100         bool                            posix_ext_supported;
101         bool                            signing_negotiated;
102         __le16                          signing_algorithm;
103         bool                            binding;
104 };
105
106 struct ksmbd_conn_ops {
107         int     (*process_fn)(struct ksmbd_conn *conn);
108         int     (*terminate_fn)(struct ksmbd_conn *conn);
109 };
110
111 struct ksmbd_transport_ops {
112         int (*prepare)(struct ksmbd_transport *t);
113         void (*disconnect)(struct ksmbd_transport *t);
114         void (*shutdown)(struct ksmbd_transport *t);
115         int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size);
116         int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
117                       int size, bool need_invalidate_rkey,
118                       unsigned int remote_key);
119         int (*rdma_read)(struct ksmbd_transport *t,
120                          void *buf, unsigned int len,
121                          struct smb2_buffer_desc_v1 *desc,
122                          unsigned int desc_len);
123         int (*rdma_write)(struct ksmbd_transport *t,
124                           void *buf, unsigned int len,
125                           struct smb2_buffer_desc_v1 *desc,
126                           unsigned int desc_len);
127 };
128
129 struct ksmbd_transport {
130         struct ksmbd_conn               *conn;
131         struct ksmbd_transport_ops      *ops;
132         struct task_struct              *handler;
133 };
134
135 #define KSMBD_TCP_RECV_TIMEOUT  (7 * HZ)
136 #define KSMBD_TCP_SEND_TIMEOUT  (5 * HZ)
137 #define KSMBD_TCP_PEER_SOCKADDR(c)      ((struct sockaddr *)&((c)->peer_addr))
138
139 extern struct list_head conn_list;
140 extern rwlock_t conn_list_lock;
141
142 bool ksmbd_conn_alive(struct ksmbd_conn *conn);
143 void ksmbd_conn_wait_idle(struct ksmbd_conn *conn);
144 struct ksmbd_conn *ksmbd_conn_alloc(void);
145 void ksmbd_conn_free(struct ksmbd_conn *conn);
146 bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c);
147 int ksmbd_conn_write(struct ksmbd_work *work);
148 int ksmbd_conn_rdma_read(struct ksmbd_conn *conn,
149                          void *buf, unsigned int buflen,
150                          struct smb2_buffer_desc_v1 *desc,
151                          unsigned int desc_len);
152 int ksmbd_conn_rdma_write(struct ksmbd_conn *conn,
153                           void *buf, unsigned int buflen,
154                           struct smb2_buffer_desc_v1 *desc,
155                           unsigned int desc_len);
156 void ksmbd_conn_enqueue_request(struct ksmbd_work *work);
157 int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work);
158 void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops);
159 int ksmbd_conn_handler_loop(void *p);
160 int ksmbd_conn_transport_init(void);
161 void ksmbd_conn_transport_destroy(void);
162
163 /*
164  * WARNING
165  *
166  * This is a hack. We will move status to a proper place once we land
167  * a multi-sessions support.
168  */
169 static inline bool ksmbd_conn_good(struct ksmbd_work *work)
170 {
171         return work->conn->status == KSMBD_SESS_GOOD;
172 }
173
174 static inline bool ksmbd_conn_need_negotiate(struct ksmbd_work *work)
175 {
176         return work->conn->status == KSMBD_SESS_NEED_NEGOTIATE;
177 }
178
179 static inline bool ksmbd_conn_need_reconnect(struct ksmbd_work *work)
180 {
181         return work->conn->status == KSMBD_SESS_NEED_RECONNECT;
182 }
183
184 static inline bool ksmbd_conn_exiting(struct ksmbd_work *work)
185 {
186         return work->conn->status == KSMBD_SESS_EXITING;
187 }
188
189 static inline void ksmbd_conn_set_good(struct ksmbd_work *work)
190 {
191         work->conn->status = KSMBD_SESS_GOOD;
192 }
193
194 static inline void ksmbd_conn_set_need_negotiate(struct ksmbd_work *work)
195 {
196         work->conn->status = KSMBD_SESS_NEED_NEGOTIATE;
197 }
198
199 static inline void ksmbd_conn_set_need_reconnect(struct ksmbd_work *work)
200 {
201         work->conn->status = KSMBD_SESS_NEED_RECONNECT;
202 }
203
204 static inline void ksmbd_conn_set_exiting(struct ksmbd_work *work)
205 {
206         work->conn->status = KSMBD_SESS_EXITING;
207 }
208 #endif /* __CONNECTION_H__ */