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