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