blob: 7a59aacb5daa5879608dd55955877cf85043ee47 [file] [log] [blame]
Namjae Jeon0626e662021-03-16 13:07:11 +09001/* 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
18#include "smb_common.h"
19#include "ksmbd_work.h"
20
21#define KSMBD_SOCKET_BACKLOG 16
22
23/*
24 * WARNING
25 *
26 * This is nothing but a HACK. Session status should move to channel
27 * or to session. As of now we have 1 tcp_conn : 1 ksmbd_session, but
28 * we need to change it to 1 tcp_conn : N ksmbd_sessions.
29 */
30enum {
31 KSMBD_SESS_NEW = 0,
32 KSMBD_SESS_GOOD,
33 KSMBD_SESS_EXITING,
34 KSMBD_SESS_NEED_RECONNECT,
35 KSMBD_SESS_NEED_NEGOTIATE
36};
37
38struct ksmbd_stats {
39 atomic_t open_files_count;
40 atomic64_t request_served;
41};
42
43struct ksmbd_transport;
44
45struct 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 char *request_buf;
54 struct ksmbd_transport *transport;
55 struct nls_table *local_nls;
56 struct list_head conns_list;
57 /* smb session 1 per user */
58 struct list_head sessions;
59 unsigned long last_active;
60 /* How many request are running currently */
61 atomic_t req_running;
62 /* References which are made for this Server object*/
63 atomic_t r_count;
Namjae Jeonb589f5d2021-12-31 09:26:25 +090064 unsigned int total_credits;
65 unsigned int outstanding_credits;
Namjae Jeon0626e662021-03-16 13:07:11 +090066 spinlock_t credits_lock;
67 wait_queue_head_t req_running_q;
68 /* Lock to protect requests list*/
69 spinlock_t request_lock;
70 struct list_head requests;
71 struct list_head async_requests;
72 int connection_type;
73 struct ksmbd_stats stats;
74 char ClientGUID[SMB2_CLIENT_GUID_SIZE];
Namjae Jeonce53d362021-12-15 14:57:27 +090075 struct ntlmssp_auth ntlmssp;
Namjae Jeon0626e662021-03-16 13:07:11 +090076
Hyunchul Leed63528e2021-07-10 16:22:41 +090077 spinlock_t llist_lock;
78 struct list_head lock_list;
79
Namjae Jeon0626e662021-03-16 13:07:11 +090080 struct preauth_integrity_info *preauth_info;
81
82 bool need_neg;
83 unsigned int auth_mechs;
84 unsigned int preferred_auth_mech;
85 bool sign;
86 bool use_spnego:1;
87 __u16 cli_sec_mode;
88 __u16 srv_sec_mode;
89 /* dialect index that server chose */
90 __u16 dialect;
91
92 char *mechToken;
93
94 struct ksmbd_conn_ops *conn_ops;
95
96 /* Preauth Session Table */
97 struct list_head preauth_sess_table;
98
99 struct sockaddr_storage peer_addr;
100
101 /* Identifier for async message */
Namjae Jeond40012a2021-04-13 13:06:30 +0900102 struct ida async_ida;
Namjae Jeon0626e662021-03-16 13:07:11 +0900103
104 __le16 cipher_type;
105 __le16 compress_algorithm;
106 bool posix_ext_supported;
Namjae Jeon378087c2021-07-21 10:05:53 +0900107 bool signing_negotiated;
108 __le16 signing_algorithm;
Namjae Jeonf5a544e2021-06-18 10:04:19 +0900109 bool binding;
Namjae Jeon0626e662021-03-16 13:07:11 +0900110};
111
112struct ksmbd_conn_ops {
113 int (*process_fn)(struct ksmbd_conn *conn);
114 int (*terminate_fn)(struct ksmbd_conn *conn);
115};
116
117struct ksmbd_transport_ops {
118 int (*prepare)(struct ksmbd_transport *t);
119 void (*disconnect)(struct ksmbd_transport *t);
Yufan Chen136dff32022-01-09 11:34:16 +0900120 void (*shutdown)(struct ksmbd_transport *t);
Namjae Jeon64b39f42021-03-30 14:25:35 +0900121 int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size);
122 int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
Namjae Jeon070fb212021-05-26 17:57:12 +0900123 int size, bool need_invalidate_rkey,
124 unsigned int remote_key);
Namjae Jeon64b39f42021-03-30 14:25:35 +0900125 int (*rdma_read)(struct ksmbd_transport *t, void *buf, unsigned int len,
Namjae Jeon070fb212021-05-26 17:57:12 +0900126 u32 remote_key, u64 remote_offset, u32 remote_len);
Namjae Jeon64b39f42021-03-30 14:25:35 +0900127 int (*rdma_write)(struct ksmbd_transport *t, void *buf,
Namjae Jeon070fb212021-05-26 17:57:12 +0900128 unsigned int len, u32 remote_key, u64 remote_offset,
129 u32 remote_len);
Namjae Jeon0626e662021-03-16 13:07:11 +0900130};
131
132struct ksmbd_transport {
133 struct ksmbd_conn *conn;
134 struct ksmbd_transport_ops *ops;
135 struct task_struct *handler;
136};
137
138#define KSMBD_TCP_RECV_TIMEOUT (7 * HZ)
139#define KSMBD_TCP_SEND_TIMEOUT (5 * HZ)
140#define KSMBD_TCP_PEER_SOCKADDR(c) ((struct sockaddr *)&((c)->peer_addr))
141
Hyunchul Leed63528e2021-07-10 16:22:41 +0900142extern struct list_head conn_list;
143extern rwlock_t conn_list_lock;
144
Namjae Jeon0626e662021-03-16 13:07:11 +0900145bool ksmbd_conn_alive(struct ksmbd_conn *conn);
146void ksmbd_conn_wait_idle(struct ksmbd_conn *conn);
Namjae Jeon0626e662021-03-16 13:07:11 +0900147struct ksmbd_conn *ksmbd_conn_alloc(void);
148void ksmbd_conn_free(struct ksmbd_conn *conn);
149bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c);
150int ksmbd_conn_write(struct ksmbd_work *work);
Namjae Jeon64b39f42021-03-30 14:25:35 +0900151int ksmbd_conn_rdma_read(struct ksmbd_conn *conn, void *buf,
Namjae Jeon070fb212021-05-26 17:57:12 +0900152 unsigned int buflen, u32 remote_key, u64 remote_offset,
153 u32 remote_len);
Namjae Jeon64b39f42021-03-30 14:25:35 +0900154int ksmbd_conn_rdma_write(struct ksmbd_conn *conn, void *buf,
Namjae Jeon070fb212021-05-26 17:57:12 +0900155 unsigned int buflen, u32 remote_key, u64 remote_offset,
156 u32 remote_len);
Namjae Jeon0626e662021-03-16 13:07:11 +0900157void ksmbd_conn_enqueue_request(struct ksmbd_work *work);
158int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work);
159void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops);
Namjae Jeon0626e662021-03-16 13:07:11 +0900160int ksmbd_conn_handler_loop(void *p);
Namjae Jeon0626e662021-03-16 13:07:11 +0900161int ksmbd_conn_transport_init(void);
162void ksmbd_conn_transport_destroy(void);
163
164/*
165 * WARNING
166 *
167 * This is a hack. We will move status to a proper place once we land
168 * a multi-sessions support.
169 */
170static inline bool ksmbd_conn_good(struct ksmbd_work *work)
171{
172 return work->conn->status == KSMBD_SESS_GOOD;
173}
174
175static inline bool ksmbd_conn_need_negotiate(struct ksmbd_work *work)
176{
177 return work->conn->status == KSMBD_SESS_NEED_NEGOTIATE;
178}
179
180static inline bool ksmbd_conn_need_reconnect(struct ksmbd_work *work)
181{
182 return work->conn->status == KSMBD_SESS_NEED_RECONNECT;
183}
184
185static inline bool ksmbd_conn_exiting(struct ksmbd_work *work)
186{
187 return work->conn->status == KSMBD_SESS_EXITING;
188}
189
190static inline void ksmbd_conn_set_good(struct ksmbd_work *work)
191{
192 work->conn->status = KSMBD_SESS_GOOD;
193}
194
195static inline void ksmbd_conn_set_need_negotiate(struct ksmbd_work *work)
196{
197 work->conn->status = KSMBD_SESS_NEED_NEGOTIATE;
198}
199
200static inline void ksmbd_conn_set_need_reconnect(struct ksmbd_work *work)
201{
202 work->conn->status = KSMBD_SESS_NEED_RECONNECT;
203}
204
205static inline void ksmbd_conn_set_exiting(struct ksmbd_work *work)
206{
207 work->conn->status = KSMBD_SESS_EXITING;
208}
209#endif /* __CONNECTION_H__ */