File Index
Files and directories
Sign in
FILE

svc_xprt.h

File preview with syntax highlighting.

linux-6.19.14/include/linux/sunrpc/svc_xprt.h C
  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_result_payload)(struct svc_rqst *, unsigned int,
 25					      unsigned int);
 26	void		(*xpo_release_ctxt)(struct svc_xprt *xprt, void *ctxt);
 27	void		(*xpo_detach)(struct svc_xprt *);
 28	void		(*xpo_free)(struct svc_xprt *);
 29	void		(*xpo_kill_temp_xprt)(struct svc_xprt *);
 30	void		(*xpo_handshake)(struct svc_xprt *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	ktime_t			xpt_qtime;
 57	struct list_head	xpt_list;
 58	struct lwq_node		xpt_ready;
 59	unsigned long		xpt_flags;
 60
 61	struct svc_serv		*xpt_server;	/* service for transport */
 62	atomic_t    	    	xpt_reserved;	/* space on outq that is rsvd */
 63	atomic_t		xpt_nr_rqsts;	/* Number of requests */
 64	struct mutex		xpt_mutex;	/* to serialize sending data */
 65	spinlock_t		xpt_lock;	/* protects sk_deferred
 66						 * and xpt_auth_cache */
 67	void			*xpt_auth_cache;/* auth cache */
 68	struct list_head	xpt_deferred;	/* deferred requests that need
 69						 * to be revisted */
 70	struct sockaddr_storage	xpt_local;	/* local address */
 71	size_t			xpt_locallen;	/* length of address */
 72	struct sockaddr_storage	xpt_remote;	/* remote peer's address */
 73	size_t			xpt_remotelen;	/* length of address */
 74	char			xpt_remotebuf[INET6_ADDRSTRLEN + 10];
 75	struct list_head	xpt_users;	/* callbacks on free */
 76
 77	struct net		*xpt_net;
 78	netns_tracker		ns_tracker;
 79	const struct cred	*xpt_cred;
 80	struct rpc_xprt		*xpt_bc_xprt;	/* NFSv4.1 backchannel */
 81	struct rpc_xprt_switch	*xpt_bc_xps;	/* NFSv4.1 backchannel */
 82};
 83
 84/* flag bits for xpt_flags */
 85enum {
 86	XPT_BUSY,		/* enqueued/receiving */
 87	XPT_CONN,		/* conn pending */
 88	XPT_CLOSE,		/* dead or dying */
 89	XPT_DATA,		/* data pending */
 90	XPT_TEMP,		/* connected transport */
 91	XPT_DEAD,		/* transport closed */
 92	XPT_CHNGBUF,		/* need to change snd/rcv buf sizes */
 93	XPT_DEFERRED,		/* deferred request pending */
 94	XPT_OLD,		/* used for xprt aging mark+sweep */
 95	XPT_LISTENER,		/* listening endpoint */
 96	XPT_CACHE_AUTH,		/* cache auth info */
 97	XPT_LOCAL,		/* connection from loopback interface */
 98	XPT_KILL_TEMP,		/* call xpo_kill_temp_xprt before closing */
 99	XPT_CONG_CTRL,		/* has congestion control */
100	XPT_HANDSHAKE,		/* xprt requests a handshake */
101	XPT_TLS_SESSION,	/* transport-layer security established */
102	XPT_PEER_AUTH,		/* peer has been authenticated */
103	XPT_PEER_VALID,		/* peer has presented a filehandle that
104				 * it has access to.  It is NOT counted
105				 * in ->sv_tmpcnt.
106				 */
107	XPT_RPCB_UNREG,		/* transport that needs unregistering
108				 * with rpcbind (TCP, UDP) on destroy
109				 */
110};
111
112/*
113 * Maximum number of "tmp" connections - those without XPT_PEER_VALID -
114 * permitted on any service.
115 */
116#define XPT_MAX_TMP_CONN	64
117
118static inline void svc_xprt_set_valid(struct svc_xprt *xpt)
119{
120	if (test_bit(XPT_TEMP, &xpt->xpt_flags) &&
121	    !test_and_set_bit(XPT_PEER_VALID, &xpt->xpt_flags)) {
122		struct svc_serv *serv = xpt->xpt_server;
123
124		spin_lock(&serv->sv_lock);
125		serv->sv_tmpcnt -= 1;
126		spin_unlock(&serv->sv_lock);
127	}
128}
129
130static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
131{
132	spin_lock(&xpt->xpt_lock);
133	list_del_init(&u->list);
134	spin_unlock(&xpt->xpt_lock);
135}
136
137static inline int register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
138{
139	spin_lock(&xpt->xpt_lock);
140	if (test_bit(XPT_CLOSE, &xpt->xpt_flags)) {
141		/*
142		 * The connection is about to be deleted soon (or,
143		 * worse, may already be deleted--in which case we've
144		 * already notified the xpt_users).
145		 */
146		spin_unlock(&xpt->xpt_lock);
147		return -ENOTCONN;
148	}
149	list_add(&u->list, &xpt->xpt_users);
150	spin_unlock(&xpt->xpt_lock);
151	return 0;
152}
153
154static inline bool svc_xprt_is_dead(const struct svc_xprt *xprt)
155{
156	return (test_bit(XPT_DEAD, &xprt->xpt_flags) != 0) ||
157		(test_bit(XPT_CLOSE, &xprt->xpt_flags) != 0);
158}
159
160int	svc_reg_xprt_class(struct svc_xprt_class *);
161void	svc_unreg_xprt_class(struct svc_xprt_class *);
162void	svc_xprt_init(struct net *, struct svc_xprt_class *, struct svc_xprt *,
163		      struct svc_serv *);
164int	svc_xprt_create_from_sa(struct svc_serv *serv, const char *xprt_name,
165				struct net *net, struct sockaddr *sap,
166				int flags, const struct cred *cred);
167int	svc_xprt_create(struct svc_serv *serv, const char *xprt_name,
168			struct net *net, const int family,
169			const unsigned short port, int flags,
170			const struct cred *cred);
171void	svc_xprt_destroy_all(struct svc_serv *serv, struct net *net,
172			     bool unregister);
173void	svc_xprt_received(struct svc_xprt *xprt);
174void	svc_xprt_enqueue(struct svc_xprt *xprt);
175void	svc_xprt_put(struct svc_xprt *xprt);
176void	svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt);
177void	svc_xprt_close(struct svc_xprt *xprt);
178int	svc_port_is_privileged(struct sockaddr *sin);
179int	svc_print_xprts(char *buf, int maxlen);
180struct svc_xprt *svc_find_listener(struct svc_serv *serv, const char *xcl_name,
181				   struct net *net, const struct sockaddr *sa);
182struct	svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
183			struct net *net, const sa_family_t af,
184			const unsigned short port);
185int	svc_xprt_names(struct svc_serv *serv, char *buf, const int buflen);
186void	svc_add_new_perm_xprt(struct svc_serv *serv, struct svc_xprt *xprt);
187void	svc_age_temp_xprts_now(struct svc_serv *, struct sockaddr *);
188void	svc_xprt_deferred_close(struct svc_xprt *xprt);
189
190static inline void svc_xprt_get(struct svc_xprt *xprt)
191{
192	kref_get(&xprt->xpt_ref);
193}
194static inline void svc_xprt_set_local(struct svc_xprt *xprt,
195				      const struct sockaddr *sa,
196				      const size_t salen)
197{
198	memcpy(&xprt->xpt_local, sa, salen);
199	xprt->xpt_locallen = salen;
200}
201static inline void svc_xprt_set_remote(struct svc_xprt *xprt,
202				       const struct sockaddr *sa,
203				       const size_t salen)
204{
205	memcpy(&xprt->xpt_remote, sa, salen);
206	xprt->xpt_remotelen = salen;
207	snprintf(xprt->xpt_remotebuf, sizeof(xprt->xpt_remotebuf) - 1,
208		 "%pISpc", sa);
209}
210
211static inline unsigned short svc_addr_port(const struct sockaddr *sa)
212{
213	const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
214	const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sa;
215
216	switch (sa->sa_family) {
217	case AF_INET:
218		return ntohs(sin->sin_port);
219	case AF_INET6:
220		return ntohs(sin6->sin6_port);
221	}
222
223	return 0;
224}
225
226static inline size_t svc_addr_len(const struct sockaddr *sa)
227{
228	switch (sa->sa_family) {
229	case AF_INET:
230		return sizeof(struct sockaddr_in);
231	case AF_INET6:
232		return sizeof(struct sockaddr_in6);
233	}
234	BUG();
235}
236
237static inline unsigned short svc_xprt_local_port(const struct svc_xprt *xprt)
238{
239	return svc_addr_port((const struct sockaddr *)&xprt->xpt_local);
240}
241
242static inline unsigned short svc_xprt_remote_port(const struct svc_xprt *xprt)
243{
244	return svc_addr_port((const struct sockaddr *)&xprt->xpt_remote);
245}
246
247static inline char *__svc_print_addr(const struct sockaddr *addr,
248				     char *buf, const size_t len)
249{
250	const struct sockaddr_in *sin = (const struct sockaddr_in *)addr;
251	const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)addr;
252
253	switch (addr->sa_family) {
254	case AF_INET:
255		snprintf(buf, len, "%pI4, port=%u", &sin->sin_addr,
256			ntohs(sin->sin_port));
257		break;
258
259	case AF_INET6:
260		snprintf(buf, len, "%pI6, port=%u",
261			 &sin6->sin6_addr,
262			ntohs(sin6->sin6_port));
263		break;
264
265	default:
266		snprintf(buf, len, "unknown address type: %d", addr->sa_family);
267		break;
268	}
269
270	return buf;
271}
272#endif /* SUNRPC_SVC_XPRT_H */
~/ Read-only file preview.