Branch data Line data Source code
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 : : 13 : : struct module; 14 : : 15 : : struct 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 : : 33 : : struct 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 : : */ 47 : : struct svc_xpt_user { 48 : : struct list_head list; 49 : : void (*callback)(struct svc_xpt_user *); 50 : : }; 51 : : 52 : : struct 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 : : 96 : : static 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 : : 103 : : static 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 : : 120 : : int svc_reg_xprt_class(struct svc_xprt_class *); 121 : : void svc_unreg_xprt_class(struct svc_xprt_class *); 122 : : void svc_xprt_init(struct net *, struct svc_xprt_class *, struct svc_xprt *, 123 : : struct svc_serv *); 124 : : int svc_create_xprt(struct svc_serv *, const char *, struct net *, 125 : : const int, const unsigned short, int, 126 : : const struct cred *); 127 : : void svc_xprt_do_enqueue(struct svc_xprt *xprt); 128 : : void svc_xprt_enqueue(struct svc_xprt *xprt); 129 : : void svc_xprt_put(struct svc_xprt *xprt); 130 : : void svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt); 131 : : void svc_close_xprt(struct svc_xprt *xprt); 132 : : int svc_port_is_privileged(struct sockaddr *sin); 133 : : int svc_print_xprts(char *buf, int maxlen); 134 : : struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name, 135 : : struct net *net, const sa_family_t af, 136 : : const unsigned short port); 137 : : int svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen); 138 : : void svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *xprt); 139 : : void svc_age_temp_xprts_now(struct svc_serv *, struct sockaddr *); 140 : : 141 : : static inline void svc_xprt_get(struct svc_xprt *xprt) 142 : : { 143 : : kref_get(&xprt->xpt_ref); 144 : : } 145 : : static inline void svc_xprt_set_local(struct svc_xprt *xprt, 146 : : const struct sockaddr *sa, 147 : : const size_t salen) 148 : : { 149 : 0 : memcpy(&xprt->xpt_local, sa, salen); 150 : 0 : xprt->xpt_locallen = salen; 151 : : } 152 : 0 : static inline void svc_xprt_set_remote(struct svc_xprt *xprt, 153 : : const struct sockaddr *sa, 154 : : const size_t salen) 155 : : { 156 : 0 : memcpy(&xprt->xpt_remote, sa, salen); 157 : 0 : xprt->xpt_remotelen = salen; 158 : 0 : snprintf(xprt->xpt_remotebuf, sizeof(xprt->xpt_remotebuf) - 1, 159 : : "%pISpc", sa); 160 : 0 : } 161 : : 162 : : static inline unsigned short svc_addr_port(const struct sockaddr *sa) 163 : : { 164 : : const struct sockaddr_in *sin = (const struct sockaddr_in *)sa; 165 : : const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa; 166 : : 167 : 0 : switch (sa->sa_family) { 168 : : case AF_INET: 169 : 0 : return ntohs(sin->sin_port); 170 : : case AF_INET6: 171 : 0 : return ntohs(sin6->sin6_port); 172 : : } 173 : : 174 : : return 0; 175 : : } 176 : : 177 : 0 : static inline size_t svc_addr_len(const struct sockaddr *sa) 178 : : { 179 : 0 : switch (sa->sa_family) { 180 : : case AF_INET: 181 : : return sizeof(struct sockaddr_in); 182 : : case AF_INET6: 183 : 0 : return sizeof(struct sockaddr_in6); 184 : : } 185 : 0 : BUG(); 186 : : } 187 : : 188 : : static inline unsigned short svc_xprt_local_port(const struct svc_xprt *xprt) 189 : : { 190 : : return svc_addr_port((const struct sockaddr *)&xprt->xpt_local); 191 : : } 192 : : 193 : : static inline unsigned short svc_xprt_remote_port(const struct svc_xprt *xprt) 194 : : { 195 : : return svc_addr_port((const struct sockaddr *)&xprt->xpt_remote); 196 : : } 197 : : 198 : 0 : static inline char *__svc_print_addr(const struct sockaddr *addr, 199 : : char *buf, const size_t len) 200 : : { 201 : : const struct sockaddr_in *sin = (const struct sockaddr_in *)addr; 202 : : const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)addr; 203 : : 204 : 0 : switch (addr->sa_family) { 205 : : case AF_INET: 206 : 0 : snprintf(buf, len, "%pI4, port=%u", &sin->sin_addr, 207 : 0 : ntohs(sin->sin_port)); 208 : 0 : break; 209 : : 210 : : case AF_INET6: 211 : 0 : snprintf(buf, len, "%pI6, port=%u", 212 : : &sin6->sin6_addr, 213 : 0 : ntohs(sin6->sin6_port)); 214 : 0 : break; 215 : : 216 : : default: 217 : 0 : snprintf(buf, len, "unknown address type: %d", addr->sa_family); 218 : 0 : break; 219 : : } 220 : : 221 : 0 : return buf; 222 : : } 223 : : #endif /* SUNRPC_SVC_XPRT_H */