linux/include/linux/sunrpc/svc_xprt.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2/*
   3 * linux/include/linux/sunrpc/svc_xprt.h
   4 *
   5 * RPC server transport I/O
   6 */
   7
   8#ifndef SUNRPC_SVC_XPRT_H
   9#define SUNRPC_SVC_XPRT_H
  10
  11#include <linux/sunrpc/svc.h>
  12
  13struct module;
  14
  15struct svc_xprt_ops {
  16        struct svc_xprt *(*xpo_create)(struct svc_serv *,
  17                                       struct net *net,
  18                                       struct sockaddr *, int,
  19                                       int);
  20        struct svc_xprt *(*xpo_accept)(struct svc_xprt *);
  21        int             (*xpo_has_wspace)(struct svc_xprt *);
  22        int             (*xpo_recvfrom)(struct svc_rqst *);
  23        int             (*xpo_sendto)(struct svc_rqst *);
  24        int             (*xpo_read_payload)(struct svc_rqst *, unsigned int,
  25                                            unsigned int);
  26        void            (*xpo_release_rqst)(struct svc_rqst *);
  27        void            (*xpo_detach)(struct svc_xprt *);
  28        void            (*xpo_free)(struct svc_xprt *);
  29        void            (*xpo_secure_port)(struct svc_rqst *rqstp);
  30        void            (*xpo_kill_temp_xprt)(struct svc_xprt *);
  31};
  32
  33struct svc_xprt_class {
  34        const char              *xcl_name;
  35        struct module           *xcl_owner;
  36        const struct svc_xprt_ops *xcl_ops;
  37        struct list_head        xcl_list;
  38        u32                     xcl_max_payload;
  39        int                     xcl_ident;
  40};
  41
  42/*
  43 * This is embedded in an object that wants a callback before deleting
  44 * an xprt; intended for use by NFSv4.1, which needs to know when a
  45 * client's tcp connection (and hence possibly a backchannel) goes away.
  46 */
  47struct svc_xpt_user {
  48        struct list_head list;
  49        void (*callback)(struct svc_xpt_user *);
  50};
  51
  52struct svc_xprt {
  53        struct svc_xprt_class   *xpt_class;
  54        const struct svc_xprt_ops *xpt_ops;
  55        struct kref             xpt_ref;
  56        struct list_head        xpt_list;
  57        struct list_head        xpt_ready;
  58        unsigned long           xpt_flags;
  59#define XPT_BUSY        0               /* enqueued/receiving */
  60#define XPT_CONN        1               /* conn pending */
  61#define XPT_CLOSE       2               /* dead or dying */
  62#define XPT_DATA        3               /* data pending */
  63#define XPT_TEMP        4               /* connected transport */
  64#define XPT_DEAD        6               /* transport closed */
  65#define XPT_CHNGBUF     7               /* need to change snd/rcv buf sizes */
  66#define XPT_DEFERRED    8               /* deferred request pending */
  67#define XPT_OLD         9               /* used for xprt aging mark+sweep */
  68#define XPT_LISTENER    10              /* listening endpoint */
  69#define XPT_CACHE_AUTH  11              /* cache auth info */
  70#define XPT_LOCAL       12              /* connection from loopback interface */
  71#define XPT_KILL_TEMP   13              /* call xpo_kill_temp_xprt before closing */
  72#define XPT_CONG_CTRL   14              /* has congestion control */
  73
  74        struct svc_serv         *xpt_server;    /* service for transport */
  75        atomic_t                xpt_reserved;   /* space on outq that is rsvd */
  76        atomic_t                xpt_nr_rqsts;   /* Number of requests */
  77        struct mutex            xpt_mutex;      /* to serialize sending data */
  78        spinlock_t              xpt_lock;       /* protects sk_deferred
  79                                                 * and xpt_auth_cache */
  80        void                    *xpt_auth_cache;/* auth cache */
  81        struct list_head        xpt_deferred;   /* deferred requests that need
  82                                                 * to be revisted */
  83        struct sockaddr_storage xpt_local;      /* local address */
  84        size_t                  xpt_locallen;   /* length of address */
  85        struct sockaddr_storage xpt_remote;     /* remote peer's address */
  86        size_t                  xpt_remotelen;  /* length of address */
  87        char                    xpt_remotebuf[INET6_ADDRSTRLEN + 10];
  88        struct list_head        xpt_users;      /* callbacks on free */
  89
  90        struct net              *xpt_net;
  91        const struct cred       *xpt_cred;
  92        struct rpc_xprt         *xpt_bc_xprt;   /* NFSv4.1 backchannel */
  93        struct rpc_xprt_switch  *xpt_bc_xps;    /* NFSv4.1 backchannel */
  94};
  95
  96static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
  97{
  98        spin_lock(&xpt->xpt_lock);
  99        list_del_init(&u->list);
 100        spin_unlock(&xpt->xpt_lock);
 101}
 102
 103static inline int register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
 104{
 105        spin_lock(&xpt->xpt_lock);
 106        if (test_bit(XPT_CLOSE, &xpt->xpt_flags)) {
 107                /*
 108                 * The connection is about to be deleted soon (or,
 109                 * worse, may already be deleted--in which case we've
 110                 * already notified the xpt_users).
 111                 */
 112                spin_unlock(&xpt->xpt_lock);
 113                return -ENOTCONN;
 114        }
 115        list_add(&u->list, &xpt->xpt_users);
 116        spin_unlock(&xpt->xpt_lock);
 117        return 0;
 118}
 119
 120static inline bool svc_xprt_is_dead(const struct svc_xprt *xprt)
 121{
 122        return (test_bit(XPT_DEAD, &xprt->xpt_flags) != 0) ||
 123                (test_bit(XPT_CLOSE, &xprt->xpt_flags) != 0);
 124}
 125
 126int     svc_reg_xprt_class(struct svc_xprt_class *);
 127void    svc_unreg_xprt_class(struct svc_xprt_class *);
 128void    svc_xprt_init(struct net *, struct svc_xprt_class *, struct svc_xprt *,
 129                      struct svc_serv *);
 130int     svc_create_xprt(struct svc_serv *, const char *, struct net *,
 131                        const int, const unsigned short, int,
 132                        const struct cred *);
 133void    svc_xprt_do_enqueue(struct svc_xprt *xprt);
 134void    svc_xprt_enqueue(struct svc_xprt *xprt);
 135void    svc_xprt_put(struct svc_xprt *xprt);
 136void    svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt);
 137void    svc_close_xprt(struct svc_xprt *xprt);
 138int     svc_port_is_privileged(struct sockaddr *sin);
 139int     svc_print_xprts(char *buf, int maxlen);
 140struct  svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
 141                        struct net *net, const sa_family_t af,
 142                        const unsigned short port);
 143int     svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen);
 144void    svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *xprt);
 145void    svc_age_temp_xprts_now(struct svc_serv *, struct sockaddr *);
 146
 147static inline void svc_xprt_get(struct svc_xprt *xprt)
 148{
 149        kref_get(&xprt->xpt_ref);
 150}
 151static inline void svc_xprt_set_local(struct svc_xprt *xprt,
 152                                      const struct sockaddr *sa,
 153                                      const size_t salen)
 154{
 155        memcpy(&xprt->xpt_local, sa, salen);
 156        xprt->xpt_locallen = salen;
 157}
 158static inline void svc_xprt_set_remote(struct svc_xprt *xprt,
 159                                       const struct sockaddr *sa,
 160                                       const size_t salen)
 161{
 162        memcpy(&xprt->xpt_remote, sa, salen);
 163        xprt->xpt_remotelen = salen;
 164        snprintf(xprt->xpt_remotebuf, sizeof(xprt->xpt_remotebuf) - 1,
 165                 "%pISpc", sa);
 166}
 167
 168static inline unsigned short svc_addr_port(const struct sockaddr *sa)
 169{
 170        const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
 171        const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
 172
 173        switch (sa->sa_family) {
 174        case AF_INET:
 175                return ntohs(sin->sin_port);
 176        case AF_INET6:
 177                return ntohs(sin6->sin6_port);
 178        }
 179
 180        return 0;
 181}
 182
 183static inline size_t svc_addr_len(const struct sockaddr *sa)
 184{
 185        switch (sa->sa_family) {
 186        case AF_INET:
 187                return sizeof(struct sockaddr_in);
 188        case AF_INET6:
 189                return sizeof(struct sockaddr_in6);
 190        }
 191        BUG();
 192}
 193
 194static inline unsigned short svc_xprt_local_port(const struct svc_xprt *xprt)
 195{
 196        return svc_addr_port((const struct sockaddr *)&xprt->xpt_local);
 197}
 198
 199static inline unsigned short svc_xprt_remote_port(const struct svc_xprt *xprt)
 200{
 201        return svc_addr_port((const struct sockaddr *)&xprt->xpt_remote);
 202}
 203
 204static inline char *__svc_print_addr(const struct sockaddr *addr,
 205                                     char *buf, const size_t len)
 206{
 207        const struct sockaddr_in *sin = (const struct sockaddr_in *)addr;
 208        const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)addr;
 209
 210        switch (addr->sa_family) {
 211        case AF_INET:
 212                snprintf(buf, len, "%pI4, port=%u", &sin->sin_addr,
 213                        ntohs(sin->sin_port));
 214                break;
 215
 216        case AF_INET6:
 217                snprintf(buf, len, "%pI6, port=%u",
 218                         &sin6->sin6_addr,
 219                        ntohs(sin6->sin6_port));
 220                break;
 221
 222        default:
 223                snprintf(buf, len, "unknown address type: %d", addr->sa_family);
 224                break;
 225        }
 226
 227        return buf;
 228}
 229#endif /* SUNRPC_SVC_XPRT_H */
 230