clnt.h 9.4 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11
/*
 *  linux/include/linux/sunrpc/clnt.h
 *
 *  Declarations for the high-level RPC client interface
 *
 *  Copyright (C) 1995, 1996, Olaf Kirch <okir@monad.swb.de>
 */

#ifndef _LINUX_SUNRPC_CLNT_H
#define _LINUX_SUNRPC_CLNT_H

T
Trond Myklebust 已提交
12
#include <linux/types.h>
13 14 15 16
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/in6.h>

L
Linus Torvalds 已提交
17 18 19 20 21 22 23 24
#include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/sched.h>
#include <linux/sunrpc/xprt.h>
#include <linux/sunrpc/auth.h>
#include <linux/sunrpc/stats.h>
#include <linux/sunrpc/xdr.h>
#include <linux/sunrpc/timer.h>
#include <asm/signal.h>
25
#include <linux/path.h>
26
#include <net/ipv6.h>
L
Linus Torvalds 已提交
27 28 29 30 31 32 33

struct rpc_inode;

/*
 * The high-level client handle
 */
struct rpc_clnt {
34
	atomic_t		cl_count;	/* Number of references */
35 36
	struct list_head	cl_clients;	/* Global list of clients */
	struct list_head	cl_tasks;	/* List of tasks */
37
	spinlock_t		cl_lock;	/* spinlock */
L
Linus Torvalds 已提交
38 39
	struct rpc_xprt *	cl_xprt;	/* transport */
	struct rpc_procinfo *	cl_procinfo;	/* procedure info */
40 41 42
	u32			cl_prog,	/* RPC program number */
				cl_vers,	/* RPC version number */
				cl_maxproc;	/* max procedure number */
L
Linus Torvalds 已提交
43 44 45 46

	char *			cl_server;	/* server machine name */
	char *			cl_protname;	/* protocol name */
	struct rpc_auth *	cl_auth;	/* authenticator */
47 48
	struct rpc_stat *	cl_stats;	/* per-program statistics */
	struct rpc_iostats *	cl_metrics;	/* per-client statistics */
L
Linus Torvalds 已提交
49 50

	unsigned int		cl_softrtry : 1,/* soft timeouts */
51
				cl_discrtry : 1,/* disconnect before retry */
O
Olga Kornievskaia 已提交
52 53
				cl_autobind : 1,/* use getport() */
				cl_chatty   : 1;/* be verbose */
L
Linus Torvalds 已提交
54 55

	struct rpc_rtt *	cl_rtt;		/* RTO estimator data */
56
	const struct rpc_timeout *cl_timeout;	/* Timeout strategy */
L
Linus Torvalds 已提交
57 58 59

	int			cl_nodelen;	/* nodename length */
	char 			cl_nodename[UNX_MAXNODENAME];
60
	struct dentry *		cl_dentry;
L
Linus Torvalds 已提交
61 62
	struct rpc_clnt *	cl_parent;	/* Points to parent of clones */
	struct rpc_rtt		cl_rtt_default;
63
	struct rpc_timeout	cl_timeout_default;
64
	struct rpc_program *	cl_program;
L
Linus Torvalds 已提交
65
	char			cl_inline_name[32];
66
	char			*cl_principal;	/* target to authenticate to */
L
Linus Torvalds 已提交
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
};

/*
 * General RPC program info
 */
#define RPC_MAXVERSION		4
struct rpc_program {
	char *			name;		/* protocol name */
	u32			number;		/* program number */
	unsigned int		nrvers;		/* number of versions */
	struct rpc_version **	version;	/* version array */
	struct rpc_stat *	stats;		/* statistics */
	char *			pipe_dir_name;	/* path to rpc_pipefs dir */
};

struct rpc_version {
	u32			number;		/* version number */
	unsigned int		nrprocs;	/* number of procs */
	struct rpc_procinfo *	procs;		/* procedure array */
};

/*
 * Procedure information
 */
struct rpc_procinfo {
	u32			p_proc;		/* RPC procedure number */
93
	kxdreproc_t		p_encode;	/* XDR encode function */
94
	kxdrdproc_t		p_decode;	/* XDR decode function */
95 96
	unsigned int		p_arglen;	/* argument hdr length (u32) */
	unsigned int		p_replen;	/* reply hdr length (u32) */
L
Linus Torvalds 已提交
97 98
	unsigned int		p_count;	/* call count */
	unsigned int		p_timer;	/* Which RTT timer to use */
99 100
	u32			p_statidx;	/* Which procedure to account */
	char *			p_name;		/* name of procedure */
L
Linus Torvalds 已提交
101 102 103 104
};

#ifdef __KERNEL__

105
struct rpc_create_args {
106
	struct net		*net;
107 108 109
	int			protocol;
	struct sockaddr		*address;
	size_t			addrsize;
110
	struct sockaddr		*saddress;
111
	const struct rpc_timeout *timeout;
112 113
	char			*servername;
	struct rpc_program	*program;
114
	u32			prognumber;	/* overrides program->number */
115 116 117
	u32			version;
	rpc_authflavor_t	authflavor;
	unsigned long		flags;
118
	char			*client_name;
119
	struct svc_xprt		*bc_xprt;	/* NFSv4.1 backchannel */
120 121 122 123 124
};

/* Values for "flags" field */
#define RPC_CLNT_CREATE_HARDRTRY	(1UL << 0)
#define RPC_CLNT_CREATE_AUTOBIND	(1UL << 2)
125 126 127
#define RPC_CLNT_CREATE_NONPRIVPORT	(1UL << 3)
#define RPC_CLNT_CREATE_NOPING		(1UL << 4)
#define RPC_CLNT_CREATE_DISCRTRY	(1UL << 5)
O
Olga Kornievskaia 已提交
128
#define RPC_CLNT_CREATE_QUIET		(1UL << 6)
129 130

struct rpc_clnt *rpc_create(struct rpc_create_args *args);
131
struct rpc_clnt	*rpc_bind_new_program(struct rpc_clnt *,
132
				struct rpc_program *, u32);
133
void rpc_task_reset_client(struct rpc_task *task, struct rpc_clnt *clnt);
L
Linus Torvalds 已提交
134
struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
135
void		rpc_shutdown_client(struct rpc_clnt *);
L
Linus Torvalds 已提交
136
void		rpc_release_client(struct rpc_clnt *);
137
void		rpc_task_release_client(struct rpc_task *);
138

139 140
int		rpcb_create_local(struct net *);
void		rpcb_put_local(struct net *);
141 142 143
int		rpcb_register(struct net *, u32, u32, int, unsigned short);
int		rpcb_v4_register(struct net *net, const u32 program,
				 const u32 version,
144
				 const struct sockaddr *address,
145
				 const char *netid);
146
void		rpcb_getport_async(struct rpc_task *);
L
Linus Torvalds 已提交
147

148
void		rpc_call_start(struct rpc_task *);
149 150 151
int		rpc_call_async(struct rpc_clnt *clnt,
			       const struct rpc_message *msg, int flags,
			       const struct rpc_call_ops *tk_ops,
152
			       void *calldata);
153 154
int		rpc_call_sync(struct rpc_clnt *clnt,
			      const struct rpc_message *msg, int flags);
155 156
struct rpc_task *rpc_call_null(struct rpc_clnt *clnt, struct rpc_cred *cred,
			       int flags);
157 158
int		rpc_restart_call_prepare(struct rpc_task *);
int		rpc_restart_call(struct rpc_task *);
L
Linus Torvalds 已提交
159 160
void		rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
size_t		rpc_max_payload(struct rpc_clnt *);
161
void		rpc_force_rebind(struct rpc_clnt *);
162
size_t		rpc_peeraddr(struct rpc_clnt *, struct sockaddr *, size_t);
163
const char	*rpc_peeraddr2str(struct rpc_clnt *, enum rpc_display_format_t);
L
Linus Torvalds 已提交
164

165 166 167
size_t		rpc_ntop(const struct sockaddr *, char *, const size_t);
size_t		rpc_pton(const char *, const size_t,
			 struct sockaddr *, const size_t);
T
Trond Myklebust 已提交
168
char *		rpc_sockaddr2uaddr(const struct sockaddr *, gfp_t);
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
size_t		rpc_uaddr2sockaddr(const char *, const size_t,
				   struct sockaddr *, const size_t);

static inline unsigned short rpc_get_port(const struct sockaddr *sap)
{
	switch (sap->sa_family) {
	case AF_INET:
		return ntohs(((struct sockaddr_in *)sap)->sin_port);
	case AF_INET6:
		return ntohs(((struct sockaddr_in6 *)sap)->sin6_port);
	}
	return 0;
}

static inline void rpc_set_port(struct sockaddr *sap,
				const unsigned short port)
{
	switch (sap->sa_family) {
	case AF_INET:
		((struct sockaddr_in *)sap)->sin_port = htons(port);
		break;
	case AF_INET6:
		((struct sockaddr_in6 *)sap)->sin6_port = htons(port);
		break;
	}
}

#define IPV6_SCOPE_DELIMITER		'%'
#define IPV6_SCOPE_ID_LEN		sizeof("%nnnnnnnnnn")

199 200 201 202 203 204 205 206 207
static inline bool __rpc_cmp_addr4(const struct sockaddr *sap1,
				   const struct sockaddr *sap2)
{
	const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sap1;
	const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sap2;

	return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
}

208 209 210 211 212 213 214 215 216 217 218
static inline bool __rpc_copy_addr4(struct sockaddr *dst,
				    const struct sockaddr *src)
{
	const struct sockaddr_in *ssin = (struct sockaddr_in *) src;
	struct sockaddr_in *dsin = (struct sockaddr_in *) dst;

	dsin->sin_family = ssin->sin_family;
	dsin->sin_addr.s_addr = ssin->sin_addr.s_addr;
	return true;
}

E
Eric Dumazet 已提交
219
#if IS_ENABLED(CONFIG_IPV6)
220 221 222 223 224
static inline bool __rpc_cmp_addr6(const struct sockaddr *sap1,
				   const struct sockaddr *sap2)
{
	const struct sockaddr_in6 *sin1 = (const struct sockaddr_in6 *)sap1;
	const struct sockaddr_in6 *sin2 = (const struct sockaddr_in6 *)sap2;
225 226 227 228 229 230 231

	if (!ipv6_addr_equal(&sin1->sin6_addr, &sin2->sin6_addr))
		return false;
	else if (ipv6_addr_type(&sin1->sin6_addr) & IPV6_ADDR_LINKLOCAL)
		return sin1->sin6_scope_id == sin2->sin6_scope_id;

	return true;
232
}
233 234 235 236 237 238 239 240

static inline bool __rpc_copy_addr6(struct sockaddr *dst,
				    const struct sockaddr *src)
{
	const struct sockaddr_in6 *ssin6 = (const struct sockaddr_in6 *) src;
	struct sockaddr_in6 *dsin6 = (struct sockaddr_in6 *) dst;

	dsin6->sin6_family = ssin6->sin6_family;
A
Alexey Dobriyan 已提交
241
	dsin6->sin6_addr = ssin6->sin6_addr;
242 243
	return true;
}
E
Eric Dumazet 已提交
244
#else	/* !(IS_ENABLED(CONFIG_IPV6) */
245 246 247 248 249
static inline bool __rpc_cmp_addr6(const struct sockaddr *sap1,
				   const struct sockaddr *sap2)
{
	return false;
}
250 251 252 253 254 255

static inline bool __rpc_copy_addr6(struct sockaddr *dst,
				    const struct sockaddr *src)
{
	return false;
}
E
Eric Dumazet 已提交
256
#endif	/* !(IS_ENABLED(CONFIG_IPV6) */
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279

/**
 * rpc_cmp_addr - compare the address portion of two sockaddrs.
 * @sap1: first sockaddr
 * @sap2: second sockaddr
 *
 * Just compares the family and address portion. Ignores port, scope, etc.
 * Returns true if the addrs are equal, false if they aren't.
 */
static inline bool rpc_cmp_addr(const struct sockaddr *sap1,
				const struct sockaddr *sap2)
{
	if (sap1->sa_family == sap2->sa_family) {
		switch (sap1->sa_family) {
		case AF_INET:
			return __rpc_cmp_addr4(sap1, sap2);
		case AF_INET6:
			return __rpc_cmp_addr6(sap1, sap2);
		}
	}
	return false;
}

280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
/**
 * rpc_copy_addr - copy the address portion of one sockaddr to another
 * @dst: destination sockaddr
 * @src: source sockaddr
 *
 * Just copies the address portion and family. Ignores port, scope, etc.
 * Caller is responsible for making certain that dst is large enough to hold
 * the address in src. Returns true if address family is supported. Returns
 * false otherwise.
 */
static inline bool rpc_copy_addr(struct sockaddr *dst,
				 const struct sockaddr *src)
{
	switch (src->sa_family) {
	case AF_INET:
		return __rpc_copy_addr4(dst, src);
	case AF_INET6:
		return __rpc_copy_addr6(dst, src);
	}
	return false;
}

302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
/**
 * rpc_get_scope_id - return scopeid for a given sockaddr
 * @sa: sockaddr to get scopeid from
 *
 * Returns the value of the sin6_scope_id for AF_INET6 addrs, or 0 if
 * not an AF_INET6 address.
 */
static inline u32 rpc_get_scope_id(const struct sockaddr *sa)
{
	if (sa->sa_family != AF_INET6)
		return 0;

	return ((struct sockaddr_in6 *) sa)->sin6_scope_id;
}

L
Linus Torvalds 已提交
317 318
#endif /* __KERNEL__ */
#endif /* _LINUX_SUNRPC_CLNT_H */