xref: /openbmc/linux/fs/smb/server/connection.h (revision 24290ba9)
138c8a9a5SSteve French /* SPDX-License-Identifier: GPL-2.0-or-later */
238c8a9a5SSteve French /*
338c8a9a5SSteve French  *   Copyright (C) 2018 Samsung Electronics Co., Ltd.
438c8a9a5SSteve French  */
538c8a9a5SSteve French 
638c8a9a5SSteve French #ifndef __KSMBD_CONNECTION_H__
738c8a9a5SSteve French #define __KSMBD_CONNECTION_H__
838c8a9a5SSteve French 
938c8a9a5SSteve French #include <linux/list.h>
1038c8a9a5SSteve French #include <linux/ip.h>
1138c8a9a5SSteve French #include <net/sock.h>
1238c8a9a5SSteve French #include <net/tcp.h>
1338c8a9a5SSteve French #include <net/inet_connection_sock.h>
1438c8a9a5SSteve French #include <net/request_sock.h>
1538c8a9a5SSteve French #include <linux/kthread.h>
1638c8a9a5SSteve French #include <linux/nls.h>
1738c8a9a5SSteve French #include <linux/unicode.h>
1838c8a9a5SSteve French 
1938c8a9a5SSteve French #include "smb_common.h"
2038c8a9a5SSteve French #include "ksmbd_work.h"
2138c8a9a5SSteve French 
2238c8a9a5SSteve French #define KSMBD_SOCKET_BACKLOG		16
2338c8a9a5SSteve French 
2438c8a9a5SSteve French enum {
2538c8a9a5SSteve French 	KSMBD_SESS_NEW = 0,
2638c8a9a5SSteve French 	KSMBD_SESS_GOOD,
2738c8a9a5SSteve French 	KSMBD_SESS_EXITING,
2838c8a9a5SSteve French 	KSMBD_SESS_NEED_RECONNECT,
2938c8a9a5SSteve French 	KSMBD_SESS_NEED_NEGOTIATE,
3038c8a9a5SSteve French 	KSMBD_SESS_RELEASING
3138c8a9a5SSteve French };
3238c8a9a5SSteve French 
3338c8a9a5SSteve French struct ksmbd_stats {
3438c8a9a5SSteve French 	atomic_t			open_files_count;
3538c8a9a5SSteve French 	atomic64_t			request_served;
3638c8a9a5SSteve French };
3738c8a9a5SSteve French 
3838c8a9a5SSteve French struct ksmbd_transport;
3938c8a9a5SSteve French 
4038c8a9a5SSteve French struct ksmbd_conn {
4138c8a9a5SSteve French 	struct smb_version_values	*vals;
4238c8a9a5SSteve French 	struct smb_version_ops		*ops;
4338c8a9a5SSteve French 	struct smb_version_cmds		*cmds;
4438c8a9a5SSteve French 	unsigned int			max_cmds;
4538c8a9a5SSteve French 	struct mutex			srv_mutex;
4638c8a9a5SSteve French 	int				status;
4738c8a9a5SSteve French 	unsigned int			cli_cap;
4838c8a9a5SSteve French 	char				*request_buf;
4938c8a9a5SSteve French 	struct ksmbd_transport		*transport;
5038c8a9a5SSteve French 	struct nls_table		*local_nls;
5138c8a9a5SSteve French 	struct unicode_map		*um;
5238c8a9a5SSteve French 	struct list_head		conns_list;
5353ff5cf8SNamjae Jeon 	struct rw_semaphore		session_lock;
5438c8a9a5SSteve French 	/* smb session 1 per user */
5538c8a9a5SSteve French 	struct xarray			sessions;
5638c8a9a5SSteve French 	unsigned long			last_active;
5738c8a9a5SSteve French 	/* How many request are running currently */
5838c8a9a5SSteve French 	atomic_t			req_running;
5938c8a9a5SSteve French 	/* References which are made for this Server object*/
6038c8a9a5SSteve French 	atomic_t			r_count;
6138c8a9a5SSteve French 	unsigned int			total_credits;
6238c8a9a5SSteve French 	unsigned int			outstanding_credits;
6338c8a9a5SSteve French 	spinlock_t			credits_lock;
6438c8a9a5SSteve French 	wait_queue_head_t		req_running_q;
6538c8a9a5SSteve French 	wait_queue_head_t		r_count_q;
6638c8a9a5SSteve French 	/* Lock to protect requests list*/
6738c8a9a5SSteve French 	spinlock_t			request_lock;
6838c8a9a5SSteve French 	struct list_head		requests;
6938c8a9a5SSteve French 	struct list_head		async_requests;
7038c8a9a5SSteve French 	int				connection_type;
7138c8a9a5SSteve French 	struct ksmbd_stats		stats;
7238c8a9a5SSteve French 	char				ClientGUID[SMB2_CLIENT_GUID_SIZE];
7338c8a9a5SSteve French 	struct ntlmssp_auth		ntlmssp;
7438c8a9a5SSteve French 
7538c8a9a5SSteve French 	spinlock_t			llist_lock;
7638c8a9a5SSteve French 	struct list_head		lock_list;
7738c8a9a5SSteve French 
7838c8a9a5SSteve French 	struct preauth_integrity_info	*preauth_info;
7938c8a9a5SSteve French 
8038c8a9a5SSteve French 	bool				need_neg;
8138c8a9a5SSteve French 	unsigned int			auth_mechs;
8238c8a9a5SSteve French 	unsigned int			preferred_auth_mech;
8338c8a9a5SSteve French 	bool				sign;
8438c8a9a5SSteve French 	bool				use_spnego:1;
8538c8a9a5SSteve French 	__u16				cli_sec_mode;
8638c8a9a5SSteve French 	__u16				srv_sec_mode;
8738c8a9a5SSteve French 	/* dialect index that server chose */
8838c8a9a5SSteve French 	__u16				dialect;
8938c8a9a5SSteve French 
9038c8a9a5SSteve French 	char				*mechToken;
91*a2b21ef1SNamjae Jeon 	unsigned int			mechTokenLen;
9238c8a9a5SSteve French 
9338c8a9a5SSteve French 	struct ksmbd_conn_ops	*conn_ops;
9438c8a9a5SSteve French 
9538c8a9a5SSteve French 	/* Preauth Session Table */
9638c8a9a5SSteve French 	struct list_head		preauth_sess_table;
9738c8a9a5SSteve French 
9838c8a9a5SSteve French 	struct sockaddr_storage		peer_addr;
9938c8a9a5SSteve French 
10038c8a9a5SSteve French 	/* Identifier for async message */
10138c8a9a5SSteve French 	struct ida			async_ida;
10238c8a9a5SSteve French 
10338c8a9a5SSteve French 	__le16				cipher_type;
10438c8a9a5SSteve French 	__le16				compress_algorithm;
10538c8a9a5SSteve French 	bool				posix_ext_supported;
10638c8a9a5SSteve French 	bool				signing_negotiated;
10738c8a9a5SSteve French 	__le16				signing_algorithm;
10838c8a9a5SSteve French 	bool				binding;
10938c8a9a5SSteve French };
11038c8a9a5SSteve French 
11138c8a9a5SSteve French struct ksmbd_conn_ops {
11238c8a9a5SSteve French 	int	(*process_fn)(struct ksmbd_conn *conn);
11338c8a9a5SSteve French 	int	(*terminate_fn)(struct ksmbd_conn *conn);
11438c8a9a5SSteve French };
11538c8a9a5SSteve French 
11638c8a9a5SSteve French struct ksmbd_transport_ops {
11738c8a9a5SSteve French 	int (*prepare)(struct ksmbd_transport *t);
11838c8a9a5SSteve French 	void (*disconnect)(struct ksmbd_transport *t);
11938c8a9a5SSteve French 	void (*shutdown)(struct ksmbd_transport *t);
12038c8a9a5SSteve French 	int (*read)(struct ksmbd_transport *t, char *buf,
12138c8a9a5SSteve French 		    unsigned int size, int max_retries);
12238c8a9a5SSteve French 	int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
12338c8a9a5SSteve French 		      int size, bool need_invalidate_rkey,
12438c8a9a5SSteve French 		      unsigned int remote_key);
12538c8a9a5SSteve French 	int (*rdma_read)(struct ksmbd_transport *t,
12638c8a9a5SSteve French 			 void *buf, unsigned int len,
12738c8a9a5SSteve French 			 struct smb2_buffer_desc_v1 *desc,
12838c8a9a5SSteve French 			 unsigned int desc_len);
12938c8a9a5SSteve French 	int (*rdma_write)(struct ksmbd_transport *t,
13038c8a9a5SSteve French 			  void *buf, unsigned int len,
13138c8a9a5SSteve French 			  struct smb2_buffer_desc_v1 *desc,
13238c8a9a5SSteve French 			  unsigned int desc_len);
13338c8a9a5SSteve French };
13438c8a9a5SSteve French 
13538c8a9a5SSteve French struct ksmbd_transport {
13638c8a9a5SSteve French 	struct ksmbd_conn		*conn;
13738c8a9a5SSteve French 	struct ksmbd_transport_ops	*ops;
13838c8a9a5SSteve French };
13938c8a9a5SSteve French 
14038c8a9a5SSteve French #define KSMBD_TCP_RECV_TIMEOUT	(7 * HZ)
14138c8a9a5SSteve French #define KSMBD_TCP_SEND_TIMEOUT	(5 * HZ)
14238c8a9a5SSteve French #define KSMBD_TCP_PEER_SOCKADDR(c)	((struct sockaddr *)&((c)->peer_addr))
14338c8a9a5SSteve French 
14438c8a9a5SSteve French extern struct list_head conn_list;
14538c8a9a5SSteve French extern struct rw_semaphore conn_list_lock;
14638c8a9a5SSteve French 
14738c8a9a5SSteve French bool ksmbd_conn_alive(struct ksmbd_conn *conn);
14838c8a9a5SSteve French void ksmbd_conn_wait_idle(struct ksmbd_conn *conn, u64 sess_id);
14938c8a9a5SSteve French struct ksmbd_conn *ksmbd_conn_alloc(void);
15038c8a9a5SSteve French void ksmbd_conn_free(struct ksmbd_conn *conn);
15138c8a9a5SSteve French bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c);
15238c8a9a5SSteve French int ksmbd_conn_write(struct ksmbd_work *work);
15338c8a9a5SSteve French int ksmbd_conn_rdma_read(struct ksmbd_conn *conn,
15438c8a9a5SSteve French 			 void *buf, unsigned int buflen,
15538c8a9a5SSteve French 			 struct smb2_buffer_desc_v1 *desc,
15638c8a9a5SSteve French 			 unsigned int desc_len);
15738c8a9a5SSteve French int ksmbd_conn_rdma_write(struct ksmbd_conn *conn,
15838c8a9a5SSteve French 			  void *buf, unsigned int buflen,
15938c8a9a5SSteve French 			  struct smb2_buffer_desc_v1 *desc,
16038c8a9a5SSteve French 			  unsigned int desc_len);
16138c8a9a5SSteve French void ksmbd_conn_enqueue_request(struct ksmbd_work *work);
162e2b76ab8SNamjae Jeon void ksmbd_conn_try_dequeue_request(struct ksmbd_work *work);
16338c8a9a5SSteve French void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops);
16438c8a9a5SSteve French int ksmbd_conn_handler_loop(void *p);
16538c8a9a5SSteve French int ksmbd_conn_transport_init(void);
16638c8a9a5SSteve French void ksmbd_conn_transport_destroy(void);
16738c8a9a5SSteve French void ksmbd_conn_lock(struct ksmbd_conn *conn);
16838c8a9a5SSteve French void ksmbd_conn_unlock(struct ksmbd_conn *conn);
16938c8a9a5SSteve French 
17038c8a9a5SSteve French /*
17138c8a9a5SSteve French  * WARNING
17238c8a9a5SSteve French  *
17338c8a9a5SSteve French  * This is a hack. We will move status to a proper place once we land
17438c8a9a5SSteve French  * a multi-sessions support.
17538c8a9a5SSteve French  */
ksmbd_conn_good(struct ksmbd_conn * conn)17638c8a9a5SSteve French static inline bool ksmbd_conn_good(struct ksmbd_conn *conn)
17738c8a9a5SSteve French {
17838c8a9a5SSteve French 	return READ_ONCE(conn->status) == KSMBD_SESS_GOOD;
17938c8a9a5SSteve French }
18038c8a9a5SSteve French 
ksmbd_conn_need_negotiate(struct ksmbd_conn * conn)18138c8a9a5SSteve French static inline bool ksmbd_conn_need_negotiate(struct ksmbd_conn *conn)
18238c8a9a5SSteve French {
18338c8a9a5SSteve French 	return READ_ONCE(conn->status) == KSMBD_SESS_NEED_NEGOTIATE;
18438c8a9a5SSteve French }
18538c8a9a5SSteve French 
ksmbd_conn_need_reconnect(struct ksmbd_conn * conn)18638c8a9a5SSteve French static inline bool ksmbd_conn_need_reconnect(struct ksmbd_conn *conn)
18738c8a9a5SSteve French {
18838c8a9a5SSteve French 	return READ_ONCE(conn->status) == KSMBD_SESS_NEED_RECONNECT;
18938c8a9a5SSteve French }
19038c8a9a5SSteve French 
ksmbd_conn_exiting(struct ksmbd_conn * conn)19138c8a9a5SSteve French static inline bool ksmbd_conn_exiting(struct ksmbd_conn *conn)
19238c8a9a5SSteve French {
19338c8a9a5SSteve French 	return READ_ONCE(conn->status) == KSMBD_SESS_EXITING;
19438c8a9a5SSteve French }
19538c8a9a5SSteve French 
ksmbd_conn_releasing(struct ksmbd_conn * conn)19638c8a9a5SSteve French static inline bool ksmbd_conn_releasing(struct ksmbd_conn *conn)
19738c8a9a5SSteve French {
19838c8a9a5SSteve French 	return READ_ONCE(conn->status) == KSMBD_SESS_RELEASING;
19938c8a9a5SSteve French }
20038c8a9a5SSteve French 
ksmbd_conn_set_new(struct ksmbd_conn * conn)20138c8a9a5SSteve French static inline void ksmbd_conn_set_new(struct ksmbd_conn *conn)
20238c8a9a5SSteve French {
20338c8a9a5SSteve French 	WRITE_ONCE(conn->status, KSMBD_SESS_NEW);
20438c8a9a5SSteve French }
20538c8a9a5SSteve French 
ksmbd_conn_set_good(struct ksmbd_conn * conn)20638c8a9a5SSteve French static inline void ksmbd_conn_set_good(struct ksmbd_conn *conn)
20738c8a9a5SSteve French {
20838c8a9a5SSteve French 	WRITE_ONCE(conn->status, KSMBD_SESS_GOOD);
20938c8a9a5SSteve French }
21038c8a9a5SSteve French 
ksmbd_conn_set_need_negotiate(struct ksmbd_conn * conn)21138c8a9a5SSteve French static inline void ksmbd_conn_set_need_negotiate(struct ksmbd_conn *conn)
21238c8a9a5SSteve French {
21338c8a9a5SSteve French 	WRITE_ONCE(conn->status, KSMBD_SESS_NEED_NEGOTIATE);
21438c8a9a5SSteve French }
21538c8a9a5SSteve French 
ksmbd_conn_set_need_reconnect(struct ksmbd_conn * conn)21638c8a9a5SSteve French static inline void ksmbd_conn_set_need_reconnect(struct ksmbd_conn *conn)
21738c8a9a5SSteve French {
21838c8a9a5SSteve French 	WRITE_ONCE(conn->status, KSMBD_SESS_NEED_RECONNECT);
21938c8a9a5SSteve French }
22038c8a9a5SSteve French 
ksmbd_conn_set_exiting(struct ksmbd_conn * conn)22138c8a9a5SSteve French static inline void ksmbd_conn_set_exiting(struct ksmbd_conn *conn)
22238c8a9a5SSteve French {
22338c8a9a5SSteve French 	WRITE_ONCE(conn->status, KSMBD_SESS_EXITING);
22438c8a9a5SSteve French }
22538c8a9a5SSteve French 
ksmbd_conn_set_releasing(struct ksmbd_conn * conn)22638c8a9a5SSteve French static inline void ksmbd_conn_set_releasing(struct ksmbd_conn *conn)
22738c8a9a5SSteve French {
22838c8a9a5SSteve French 	WRITE_ONCE(conn->status, KSMBD_SESS_RELEASING);
22938c8a9a5SSteve French }
23038c8a9a5SSteve French 
23138c8a9a5SSteve French void ksmbd_all_conn_set_status(u64 sess_id, u32 status);
23238c8a9a5SSteve French #endif /* __CONNECTION_H__ */
233