xref: /linux/fs/smb/server/connection.h (revision a08de24c2b8568a26b560cda411284295decb3ba)
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/inet.h>
11 #include <linux/ip.h>
12 #include <net/sock.h>
13 #include <net/tcp.h>
14 #include <net/inet_connection_sock.h>
15 #include <net/request_sock.h>
16 #include <linux/kthread.h>
17 #include <linux/nls.h>
18 #include <linux/unicode.h>
19 #include <linux/workqueue.h>
20 
21 #include "smb_common.h"
22 #include "ksmbd_work.h"
23 
24 struct smbdirect_buffer_descriptor_v1;
25 
26 #define KSMBD_SOCKET_BACKLOG		16
27 
28 enum {
29 	KSMBD_SESS_NEW = 0,
30 	KSMBD_SESS_GOOD,
31 	KSMBD_SESS_EXITING,
32 	KSMBD_SESS_NEED_RECONNECT,
33 	KSMBD_SESS_NEED_NEGOTIATE,
34 	KSMBD_SESS_NEED_SETUP,
35 	KSMBD_SESS_RELEASING
36 };
37 
38 struct ksmbd_conn_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 	bool				stop_called;
54 	union {
55 		__be32			inet_addr;
56 #if IS_ENABLED(CONFIG_IPV6)
57 		u8			inet6_addr[16];
58 #endif
59 	};
60 	unsigned int			inet_hash;
61 	char				*request_buf;
62 	struct ksmbd_transport		*transport;
63 	struct nls_table		*local_nls;
64 	struct unicode_map		*um;
65 	struct hlist_node		hlist;
66 	struct rw_semaphore		session_lock;
67 	/* smb session 1 per user */
68 	struct xarray			sessions;
69 	unsigned long			last_active;
70 	/* How many request are running currently */
71 	atomic_t			req_running;
72 	/* References which are made for this Server object*/
73 	atomic_t			r_count;
74 	unsigned int			total_credits;
75 	unsigned int			outstanding_credits;
76 	spinlock_t			credits_lock;
77 	wait_queue_head_t		req_running_q;
78 	wait_queue_head_t		r_count_q;
79 	/* Lock to protect requests list*/
80 	spinlock_t			request_lock;
81 	struct list_head		requests;
82 	struct list_head		async_requests;
83 	int				connection_type;
84 	struct ksmbd_conn_stats		stats;
85 	char				ClientGUID[SMB2_CLIENT_GUID_SIZE];
86 	struct ntlmssp_auth		ntlmssp;
87 
88 	spinlock_t			llist_lock;
89 	struct list_head		lock_list;
90 
91 	struct preauth_integrity_info	*preauth_info;
92 
93 	bool				need_neg;
94 	unsigned int			auth_mechs;
95 	unsigned int			preferred_auth_mech;
96 	bool				sign;
97 	bool				use_spnego:1;
98 	__u16				cli_sec_mode;
99 	__u16				srv_sec_mode;
100 	/* dialect index that server chose */
101 	__u16				dialect;
102 
103 	char				*mechToken;
104 	unsigned int			mechTokenLen;
105 
106 	struct ksmbd_conn_ops	*conn_ops;
107 
108 	/* Preauth Session Table */
109 	struct list_head		preauth_sess_table;
110 
111 	struct sockaddr_storage		peer_addr;
112 
113 	/* Identifier for async message */
114 	struct ida			async_ida;
115 
116 	__le16				cipher_type;
117 	__le16				compress_algorithm;
118 	/* Negotiated SMB 3.1.1 compression capabilities. */
119 	bool				compress_chained;
120 	bool				compress_pattern;
121 	bool				posix_ext_supported;
122 	bool				signing_negotiated;
123 	__le16				signing_algorithm;
124 	bool				binding;
125 	atomic_t			refcnt;
126 	bool				is_aapl;
127 	struct work_struct		release_work;
128 };
129 
130 struct ksmbd_conn_ops {
131 	int	(*process_fn)(struct ksmbd_conn *conn);
132 	int	(*terminate_fn)(struct ksmbd_conn *conn);
133 };
134 
135 struct ksmbd_transport_ops {
136 	void (*disconnect)(struct ksmbd_transport *t);
137 	void (*shutdown)(struct ksmbd_transport *t);
138 	int (*read)(struct ksmbd_transport *t, char *buf,
139 		    unsigned int size, int max_retries);
140 	int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
141 		      int size, bool need_invalidate_rkey,
142 		      unsigned int remote_key);
143 	int (*rdma_read)(struct ksmbd_transport *t,
144 			 void *buf, unsigned int len,
145 			 struct smbdirect_buffer_descriptor_v1 *desc,
146 			 unsigned int desc_len);
147 	int (*rdma_write)(struct ksmbd_transport *t,
148 			  void *buf, unsigned int len,
149 			  struct smbdirect_buffer_descriptor_v1 *desc,
150 			  unsigned int desc_len);
151 	void (*free_transport)(struct ksmbd_transport *kt);
152 };
153 
154 struct ksmbd_transport {
155 	struct ksmbd_conn			*conn;
156 	const struct ksmbd_transport_ops	*ops;
157 };
158 
159 #define KSMBD_TCP_RECV_TIMEOUT	(7 * HZ)
160 #define KSMBD_TCP_SEND_TIMEOUT	(5 * HZ)
161 #define KSMBD_TCP_PEER_SOCKADDR(c)	((struct sockaddr *)&((c)->peer_addr))
162 
163 #define CONN_HASH_BITS	12
164 extern DECLARE_HASHTABLE(conn_list, CONN_HASH_BITS);
165 extern struct rw_semaphore conn_list_lock;
166 
167 bool ksmbd_conn_alive(struct ksmbd_conn *conn);
168 void ksmbd_conn_wait_idle(struct ksmbd_conn *conn);
169 int ksmbd_conn_wait_idle_sess_id(struct ksmbd_conn *curr_conn, u64 sess_id);
170 struct ksmbd_conn *ksmbd_conn_alloc(void);
171 void ksmbd_conn_free(struct ksmbd_conn *conn);
172 struct ksmbd_conn *ksmbd_conn_get(struct ksmbd_conn *conn);
173 void ksmbd_conn_put(struct ksmbd_conn *conn);
174 int ksmbd_conn_wq_init(void);
175 void ksmbd_conn_wq_destroy(void);
176 bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c);
177 int ksmbd_conn_write(struct ksmbd_work *work);
178 int ksmbd_conn_rdma_read(struct ksmbd_conn *conn,
179 			 void *buf, unsigned int buflen,
180 			 struct smbdirect_buffer_descriptor_v1 *desc,
181 			 unsigned int desc_len);
182 int ksmbd_conn_rdma_write(struct ksmbd_conn *conn,
183 			  void *buf, unsigned int buflen,
184 			  struct smbdirect_buffer_descriptor_v1 *desc,
185 			  unsigned int desc_len);
186 void ksmbd_conn_enqueue_request(struct ksmbd_work *work);
187 void ksmbd_conn_try_dequeue_request(struct ksmbd_work *work);
188 void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops);
189 int ksmbd_conn_handler_loop(void *p);
190 int ksmbd_conn_transport_init(void);
191 void ksmbd_conn_transport_destroy(void);
192 void ksmbd_conn_lock(struct ksmbd_conn *conn);
193 void ksmbd_conn_unlock(struct ksmbd_conn *conn);
194 void ksmbd_conn_r_count_inc(struct ksmbd_conn *conn);
195 void ksmbd_conn_r_count_dec(struct ksmbd_conn *conn);
196 
197 /*
198  * WARNING
199  *
200  * This is a hack. We will move status to a proper place once we land
201  * a multi-sessions support.
202  */
203 static inline bool ksmbd_conn_good(struct ksmbd_conn *conn)
204 {
205 	return READ_ONCE(conn->status) == KSMBD_SESS_GOOD;
206 }
207 
208 static inline bool ksmbd_conn_need_negotiate(struct ksmbd_conn *conn)
209 {
210 	return READ_ONCE(conn->status) == KSMBD_SESS_NEED_NEGOTIATE;
211 }
212 
213 static inline bool ksmbd_conn_need_setup(struct ksmbd_conn *conn)
214 {
215 	return READ_ONCE(conn->status) == KSMBD_SESS_NEED_SETUP;
216 }
217 
218 static inline bool ksmbd_conn_need_reconnect(struct ksmbd_conn *conn)
219 {
220 	return READ_ONCE(conn->status) == KSMBD_SESS_NEED_RECONNECT;
221 }
222 
223 static inline bool ksmbd_conn_exiting(struct ksmbd_conn *conn)
224 {
225 	return READ_ONCE(conn->status) == KSMBD_SESS_EXITING;
226 }
227 
228 static inline bool ksmbd_conn_releasing(struct ksmbd_conn *conn)
229 {
230 	return READ_ONCE(conn->status) == KSMBD_SESS_RELEASING;
231 }
232 
233 static inline void ksmbd_conn_set_new(struct ksmbd_conn *conn)
234 {
235 	WRITE_ONCE(conn->status, KSMBD_SESS_NEW);
236 }
237 
238 static inline void ksmbd_conn_set_good(struct ksmbd_conn *conn)
239 {
240 	WRITE_ONCE(conn->status, KSMBD_SESS_GOOD);
241 }
242 
243 static inline void ksmbd_conn_set_need_negotiate(struct ksmbd_conn *conn)
244 {
245 	WRITE_ONCE(conn->status, KSMBD_SESS_NEED_NEGOTIATE);
246 }
247 
248 static inline void ksmbd_conn_set_need_setup(struct ksmbd_conn *conn)
249 {
250 	WRITE_ONCE(conn->status, KSMBD_SESS_NEED_SETUP);
251 }
252 
253 static inline void ksmbd_conn_set_need_reconnect(struct ksmbd_conn *conn)
254 {
255 	WRITE_ONCE(conn->status, KSMBD_SESS_NEED_RECONNECT);
256 }
257 
258 static inline void ksmbd_conn_set_exiting(struct ksmbd_conn *conn)
259 {
260 	WRITE_ONCE(conn->status, KSMBD_SESS_EXITING);
261 }
262 
263 static inline void ksmbd_conn_set_releasing(struct ksmbd_conn *conn)
264 {
265 	WRITE_ONCE(conn->status, KSMBD_SESS_RELEASING);
266 }
267 
268 void ksmbd_all_conn_set_status(u64 sess_id, u32 status);
269 #endif /* __CONNECTION_H__ */
270