linux/fs/ksmbd/connection.h
<<
>>
Prefs
   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 short                  total_credits;
  65        unsigned short                  max_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        union {
  76                /* pending trans request table */
  77                struct trans_state      *recent_trans;
  78                /* Used by ntlmssp */
  79                char                    *ntlmssp_cryptkey;
  80        };
  81
  82        spinlock_t                      llist_lock;
  83        struct list_head                lock_list;
  84
  85        struct preauth_integrity_info   *preauth_info;
  86
  87        bool                            need_neg;
  88        unsigned int                    auth_mechs;
  89        unsigned int                    preferred_auth_mech;
  90        bool                            sign;
  91        bool                            use_spnego:1;
  92        __u16                           cli_sec_mode;
  93        __u16                           srv_sec_mode;
  94        /* dialect index that server chose */
  95        __u16                           dialect;
  96
  97        char                            *mechToken;
  98
  99        struct ksmbd_conn_ops   *conn_ops;
 100
 101        /* Preauth Session Table */
 102        struct list_head                preauth_sess_table;
 103
 104        struct sockaddr_storage         peer_addr;
 105
 106        /* Identifier for async message */
 107        struct ida                      async_ida;
 108
 109        __le16                          cipher_type;
 110        __le16                          compress_algorithm;
 111        bool                            posix_ext_supported;
 112        bool                            signing_negotiated;
 113        __le16                          signing_algorithm;
 114        bool                            binding;
 115};
 116
 117struct ksmbd_conn_ops {
 118        int     (*process_fn)(struct ksmbd_conn *conn);
 119        int     (*terminate_fn)(struct ksmbd_conn *conn);
 120};
 121
 122struct ksmbd_transport_ops {
 123        int (*prepare)(struct ksmbd_transport *t);
 124        void (*disconnect)(struct ksmbd_transport *t);
 125        int (*read)(struct ksmbd_transport *t, char *buf, unsigned int size);
 126        int (*writev)(struct ksmbd_transport *t, struct kvec *iovs, int niov,
 127                      int size, bool need_invalidate_rkey,
 128                      unsigned int remote_key);
 129        int (*rdma_read)(struct ksmbd_transport *t, void *buf, unsigned int len,
 130                         u32 remote_key, u64 remote_offset, u32 remote_len);
 131        int (*rdma_write)(struct ksmbd_transport *t, void *buf,
 132                          unsigned int len, u32 remote_key, u64 remote_offset,
 133                          u32 remote_len);
 134};
 135
 136struct ksmbd_transport {
 137        struct ksmbd_conn               *conn;
 138        struct ksmbd_transport_ops      *ops;
 139        struct task_struct              *handler;
 140};
 141
 142#define KSMBD_TCP_RECV_TIMEOUT  (7 * HZ)
 143#define KSMBD_TCP_SEND_TIMEOUT  (5 * HZ)
 144#define KSMBD_TCP_PEER_SOCKADDR(c)      ((struct sockaddr *)&((c)->peer_addr))
 145
 146extern struct list_head conn_list;
 147extern rwlock_t conn_list_lock;
 148
 149bool ksmbd_conn_alive(struct ksmbd_conn *conn);
 150void ksmbd_conn_wait_idle(struct ksmbd_conn *conn);
 151struct ksmbd_conn *ksmbd_conn_alloc(void);
 152void ksmbd_conn_free(struct ksmbd_conn *conn);
 153bool ksmbd_conn_lookup_dialect(struct ksmbd_conn *c);
 154int ksmbd_conn_write(struct ksmbd_work *work);
 155int ksmbd_conn_rdma_read(struct ksmbd_conn *conn, void *buf,
 156                         unsigned int buflen, u32 remote_key, u64 remote_offset,
 157                         u32 remote_len);
 158int ksmbd_conn_rdma_write(struct ksmbd_conn *conn, void *buf,
 159                          unsigned int buflen, u32 remote_key, u64 remote_offset,
 160                          u32 remote_len);
 161void ksmbd_conn_enqueue_request(struct ksmbd_work *work);
 162int 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);
 167
 168/*
 169 * WARNING
 170 *
 171 * This is a hack. We will move status to a proper place once we land
 172 * a multi-sessions support.
 173 */
 174static inline bool ksmbd_conn_good(struct ksmbd_work *work)
 175{
 176        return work->conn->status == KSMBD_SESS_GOOD;
 177}
 178
 179static inline bool ksmbd_conn_need_negotiate(struct ksmbd_work *work)
 180{
 181        return work->conn->status == KSMBD_SESS_NEED_NEGOTIATE;
 182}
 183
 184static inline bool ksmbd_conn_need_reconnect(struct ksmbd_work *work)
 185{
 186        return work->conn->status == KSMBD_SESS_NEED_RECONNECT;
 187}
 188
 189static inline bool ksmbd_conn_exiting(struct ksmbd_work *work)
 190{
 191        return work->conn->status == KSMBD_SESS_EXITING;
 192}
 193
 194static inline void ksmbd_conn_set_good(struct ksmbd_work *work)
 195{
 196        work->conn->status = KSMBD_SESS_GOOD;
 197}
 198
 199static inline void ksmbd_conn_set_need_negotiate(struct ksmbd_work *work)
 200{
 201        work->conn->status = KSMBD_SESS_NEED_NEGOTIATE;
 202}
 203
 204static inline void ksmbd_conn_set_need_reconnect(struct ksmbd_work *work)
 205{
 206        work->conn->status = KSMBD_SESS_NEED_RECONNECT;
 207}
 208
 209static inline void ksmbd_conn_set_exiting(struct ksmbd_work *work)
 210{
 211        work->conn->status = KSMBD_SESS_EXITING;
 212}
 213#endif /* __CONNECTION_H__ */
 214