ksmbd: add support for SMB3 multichannel
[linux-block.git] / fs / cifsd / 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 /*
24  * WARNING
25  *
26  * This is nothing but a HACK. Session status should move to channel
27  * or to session. As of now we have 1 tcp_conn : 1 ksmbd_session, but
28  * we need to change it to 1 tcp_conn : N ksmbd_sessions.
29  */
30 enum {
31         KSMBD_SESS_NEW = 0,
32         KSMBD_SESS_GOOD,
33         KSMBD_SESS_EXITING,
34         KSMBD_SESS_NEED_RECONNECT,
35         KSMBD_SESS_NEED_NEGOTIATE
36 };
37
38 struct ksmbd_stats {
39         atomic_t                        open_files_count;
40         atomic64_t                      request_served;
41 };
42
43 struct ksmbd_transport;
44
45 struct ksmbd_conn {
46         struct smb_version_values       *vals;
47         struct smb_version_ops          *ops;
48         struct smb_version_cmds         *cmds;
49         unsigned int                    max_cmds;
50         struct mutex                    srv_mutex;
51         int                             status;
52         unsigned int                    cli_cap;
53         char                            *request_buf;
54         struct ksmbd_transport          *transport;
55         struct nls_table                *local_nls;
56         struct list_head                conns_list;
57         /* smb session 1 per user */
58         struct list_head                sessions;
59         unsigned long                   last_active;
60         /* How many request are running currently */
61         atomic_t                        req_running;
62         /* References which are made for this Server object*/
63         atomic_t                        r_count;
64         unsigned short                  total_credits;
65         unsigned short                  max_credits;
66         spinlock_t                      credits_lock;
67         wait_queue_head_t               req_running_q;
68         /* Lock to protect requests list*/
69         spinlock_t                      request_lock;
70         struct list_head                requests;
71         struct list_head                async_requests;
72         int                             connection_type;
73         struct ksmbd_stats              stats;
74         char                            ClientGUID[SMB2_CLIENT_GUID_SIZE];
75         union {
76                 /* pending trans request table */
77                 struct trans_state      *recent_trans;
78                 /* Used by ntlmssp */
79                 char                    *ntlmssp_cryptkey;
80         };
81
82         struct preauth_integrity_info   *preauth_info;
83
84         bool                            need_neg;
85         unsigned int                    auth_mechs;
86         unsigned int                    preferred_auth_mech;
87         bool                            sign;
88         bool                            use_spnego:1;
89         __u16                           cli_sec_mode;
90         __u16                           srv_sec_mode;
91         /* dialect index that server chose */
92         __u16                           dialect;
93
94         char                            *mechToken;
95
96         struct ksmbd_conn_ops   *conn_ops;
97
98         /* Preauth Session Table */
99         struct list_head                preauth_sess_table;
100
101         struct sockaddr_storage         peer_addr;
102
103         /* Identifier for async message */
104         struct ida                      async_ida;
105
106         __le16                          cipher_type;
107         __le16                          compress_algorithm;
108         bool                            posix_ext_supported;
109         bool                            binding;
110 };
111
112 struct ksmbd_conn_ops {
113         int     (*process_fn)(struct ksmbd_conn *conn);
114         int     (*terminate_fn)(struct ksmbd_conn *conn);
115 };
116
117 struct ksmbd_transport_ops {
118         int (*prepare)(struct ksmbd_transport *t);
119         void (*disconnect)(struct ksmbd_transport *t);
120         int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size);
121         int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
122                       int size, bool need_invalidate_rkey,
123                       unsigned int remote_key);
124         int (*rdma_read)(struct ksmbd_transport *t, void *buf, unsigned int len,
125                          u32 remote_key, u64 remote_offset, u32 remote_len);
126         int (*rdma_write)(struct ksmbd_transport *t, void *buf,
127                           unsigned int len, u32 remote_key, u64 remote_offset,
128                           u32 remote_len);
129 };
130
131 struct ksmbd_transport {
132         struct ksmbd_conn               *conn;
133         struct ksmbd_transport_ops      *ops;
134         struct task_struct              *handler;
135 };
136
137 #define KSMBD_TCP_RECV_TIMEOUT  (7 * HZ)
138 #define KSMBD_TCP_SEND_TIMEOUT  (5 * HZ)
139 #define KSMBD_TCP_PEER_SOCKADDR(c)      ((struct sockaddr *)&((c)->peer_addr))
140
141 bool ksmbd_conn_alive(struct ksmbd_conn *conn);
142 void ksmbd_conn_wait_idle(struct ksmbd_conn *conn);
143 struct ksmbd_conn *ksmbd_conn_alloc(void);
144 void ksmbd_conn_free(struct ksmbd_conn *conn);
145 bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c);
146 int ksmbd_conn_write(struct ksmbd_work *work);
147 int ksmbd_conn_rdma_read(struct ksmbd_conn *conn, void *buf,
148                          unsigned int buflen, u32 remote_key, u64 remote_offset,
149                          u32 remote_len);
150 int ksmbd_conn_rdma_write(struct ksmbd_conn *conn, void *buf,
151                           unsigned int buflen, u32 remote_key, u64 remote_offset,
152                           u32 remote_len);
153 void ksmbd_conn_enqueue_request(struct ksmbd_work *work);
154 int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work);
155 void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops);
156 int ksmbd_conn_handler_loop(void *p);
157 int ksmbd_conn_transport_init(void);
158 void ksmbd_conn_transport_destroy(void);
159
160 /*
161  * WARNING
162  *
163  * This is a hack. We will move status to a proper place once we land
164  * a multi-sessions support.
165  */
166 static inline bool ksmbd_conn_good(struct ksmbd_work *work)
167 {
168         return work->conn->status == KSMBD_SESS_GOOD;
169 }
170
171 static inline bool ksmbd_conn_need_negotiate(struct ksmbd_work *work)
172 {
173         return work->conn->status == KSMBD_SESS_NEED_NEGOTIATE;
174 }
175
176 static inline bool ksmbd_conn_need_reconnect(struct ksmbd_work *work)
177 {
178         return work->conn->status == KSMBD_SESS_NEED_RECONNECT;
179 }
180
181 static inline bool ksmbd_conn_exiting(struct ksmbd_work *work)
182 {
183         return work->conn->status == KSMBD_SESS_EXITING;
184 }
185
186 static inline void ksmbd_conn_set_good(struct ksmbd_work *work)
187 {
188         work->conn->status = KSMBD_SESS_GOOD;
189 }
190
191 static inline void ksmbd_conn_set_need_negotiate(struct ksmbd_work *work)
192 {
193         work->conn->status = KSMBD_SESS_NEED_NEGOTIATE;
194 }
195
196 static inline void ksmbd_conn_set_need_reconnect(struct ksmbd_work *work)
197 {
198         work->conn->status = KSMBD_SESS_NEED_RECONNECT;
199 }
200
201 static inline void ksmbd_conn_set_exiting(struct ksmbd_work *work)
202 {
203         work->conn->status = KSMBD_SESS_EXITING;
204 }
205 #endif /* __CONNECTION_H__ */