connection.h (5772B)
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 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; 64 unsigned int total_credits; 65 unsigned int outstanding_credits; 66 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]; 75 struct ntlmssp_auth ntlmssp; 76 77 spinlock_t llist_lock; 78 struct list_head lock_list; 79 80 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 */ 102 struct ida async_ida; 103 104 __le16 cipher_type; 105 __le16 compress_algorithm; 106 bool posix_ext_supported; 107 bool signing_negotiated; 108 __le16 signing_algorithm; 109 bool binding; 110}; 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); 120 void (*shutdown)(struct ksmbd_transport *t); 121 int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size); 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 struct task_struct *handler; 139}; 140 141#define KSMBD_TCP_RECV_TIMEOUT (7 * HZ) 142#define KSMBD_TCP_SEND_TIMEOUT (5 * HZ) 143#define KSMBD_TCP_PEER_SOCKADDR(c) ((struct sockaddr *)&((c)->peer_addr)) 144 145extern struct list_head conn_list; 146extern rwlock_t conn_list_lock; 147 148bool ksmbd_conn_alive(struct ksmbd_conn *conn); 149void ksmbd_conn_wait_idle(struct ksmbd_conn *conn); 150struct ksmbd_conn *ksmbd_conn_alloc(void); 151void ksmbd_conn_free(struct ksmbd_conn *conn); 152bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c); 153int ksmbd_conn_write(struct ksmbd_work *work); 154int ksmbd_conn_rdma_read(struct ksmbd_conn *conn, 155 void *buf, unsigned int buflen, 156 struct smb2_buffer_desc_v1 *desc, 157 unsigned int desc_len); 158int ksmbd_conn_rdma_write(struct ksmbd_conn *conn, 159 void *buf, unsigned int buflen, 160 struct smb2_buffer_desc_v1 *desc, 161 unsigned int desc_len); 162void ksmbd_conn_enqueue_request(struct ksmbd_work *work); 163int ksmbd_conn_try_dequeue_request(struct ksmbd_work *work); 164void ksmbd_conn_init_server_callbacks(struct ksmbd_conn_ops *ops); 165int ksmbd_conn_handler_loop(void *p); 166int ksmbd_conn_transport_init(void); 167void ksmbd_conn_transport_destroy(void); 168 169/* 170 * WARNING 171 * 172 * This is a hack. We will move status to a proper place once we land 173 * a multi-sessions support. 174 */ 175static inline bool ksmbd_conn_good(struct ksmbd_work *work) 176{ 177 return work->conn->status == KSMBD_SESS_GOOD; 178} 179 180static inline bool ksmbd_conn_need_negotiate(struct ksmbd_work *work) 181{ 182 return work->conn->status == KSMBD_SESS_NEED_NEGOTIATE; 183} 184 185static inline bool ksmbd_conn_need_reconnect(struct ksmbd_work *work) 186{ 187 return work->conn->status == KSMBD_SESS_NEED_RECONNECT; 188} 189 190static inline bool ksmbd_conn_exiting(struct ksmbd_work *work) 191{ 192 return work->conn->status == KSMBD_SESS_EXITING; 193} 194 195static inline void ksmbd_conn_set_good(struct ksmbd_work *work) 196{ 197 work->conn->status = KSMBD_SESS_GOOD; 198} 199 200static inline void ksmbd_conn_set_need_negotiate(struct ksmbd_work *work) 201{ 202 work->conn->status = KSMBD_SESS_NEED_NEGOTIATE; 203} 204 205static inline void ksmbd_conn_set_need_reconnect(struct ksmbd_work *work) 206{ 207 work->conn->status = KSMBD_SESS_NEED_RECONNECT; 208} 209 210static inline void ksmbd_conn_set_exiting(struct ksmbd_work *work) 211{ 212 work->conn->status = KSMBD_SESS_EXITING; 213} 214#endif /* __CONNECTION_H__ */