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