aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/sunrpc
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/sunrpc')
-rw-r--r--include/linux/sunrpc/auth.h149
-rw-r--r--include/linux/sunrpc/auth_gss.h97
-rw-r--r--include/linux/sunrpc/cache.h312
-rw-r--r--include/linux/sunrpc/clnt.h153
-rw-r--r--include/linux/sunrpc/debug.h99
-rw-r--r--include/linux/sunrpc/gss_api.h122
-rw-r--r--include/linux/sunrpc/gss_asn1.h81
-rw-r--r--include/linux/sunrpc/gss_err.h177
-rw-r--r--include/linux/sunrpc/gss_krb5.h148
-rw-r--r--include/linux/sunrpc/gss_spkm3.h61
-rw-r--r--include/linux/sunrpc/msg_prot.h80
-rw-r--r--include/linux/sunrpc/rpc_pipe_fs.h50
-rw-r--r--include/linux/sunrpc/sched.h273
-rw-r--r--include/linux/sunrpc/stats.h78
-rw-r--r--include/linux/sunrpc/svc.h306
-rw-r--r--include/linux/sunrpc/svcauth.h167
-rw-r--r--include/linux/sunrpc/svcauth_gss.h27
-rw-r--r--include/linux/sunrpc/svcsock.h65
-rw-r--r--include/linux/sunrpc/timer.h49
-rw-r--r--include/linux/sunrpc/types.h22
-rw-r--r--include/linux/sunrpc/xdr.h192
-rw-r--r--include/linux/sunrpc/xprt.h232
22 files changed, 2940 insertions, 0 deletions
diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h
new file mode 100644
index 000000000000..04ebc24db348
--- /dev/null
+++ b/include/linux/sunrpc/auth.h
@@ -0,0 +1,149 @@
1/*
2 * linux/include/linux/sunrpc/auth.h
3 *
4 * Declarations for the RPC client authentication machinery.
5 *
6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
7 */
8
9#ifndef _LINUX_SUNRPC_AUTH_H
10#define _LINUX_SUNRPC_AUTH_H
11
12#ifdef __KERNEL__
13
14#include <linux/config.h>
15#include <linux/sunrpc/sched.h>
16#include <linux/sunrpc/msg_prot.h>
17#include <linux/sunrpc/xdr.h>
18
19#include <asm/atomic.h>
20
21/* size of the nodename buffer */
22#define UNX_MAXNODENAME 32
23
24/* Maximum size (in bytes) of an rpc credential or verifier */
25#define RPC_MAX_AUTH_SIZE (400)
26
27/* Work around the lack of a VFS credential */
28struct auth_cred {
29 uid_t uid;
30 gid_t gid;
31 struct group_info *group_info;
32};
33
34/*
35 * Client user credentials
36 */
37struct rpc_cred {
38 struct hlist_node cr_hash; /* hash chain */
39 struct rpc_credops * cr_ops;
40 unsigned long cr_expire; /* when to gc */
41 atomic_t cr_count; /* ref count */
42 unsigned short cr_flags; /* various flags */
43#ifdef RPC_DEBUG
44 unsigned long cr_magic; /* 0x0f4aa4f0 */
45#endif
46
47 uid_t cr_uid;
48
49 /* per-flavor data */
50};
51#define RPCAUTH_CRED_LOCKED 0x0001
52#define RPCAUTH_CRED_UPTODATE 0x0002
53
54#define RPCAUTH_CRED_MAGIC 0x0f4aa4f0
55
56/*
57 * Client authentication handle
58 */
59#define RPC_CREDCACHE_NR 8
60#define RPC_CREDCACHE_MASK (RPC_CREDCACHE_NR - 1)
61struct rpc_cred_cache {
62 struct hlist_head hashtable[RPC_CREDCACHE_NR];
63 unsigned long nextgc; /* next garbage collection */
64 unsigned long expire; /* cache expiry interval */
65};
66
67struct rpc_auth {
68 unsigned int au_cslack; /* call cred size estimate */
69 unsigned int au_rslack; /* reply verf size guess */
70 unsigned int au_flags; /* various flags */
71 struct rpc_authops * au_ops; /* operations */
72 rpc_authflavor_t au_flavor; /* pseudoflavor (note may
73 * differ from the flavor in
74 * au_ops->au_flavor in gss
75 * case) */
76 atomic_t au_count; /* Reference counter */
77
78 struct rpc_cred_cache * au_credcache;
79 /* per-flavor data */
80};
81#define RPC_AUTH_PROC_CREDS 0x0010 /* process creds (including
82 * uid/gid, fs[ug]id, gids)
83 */
84
85/*
86 * Client authentication ops
87 */
88struct rpc_authops {
89 struct module *owner;
90 rpc_authflavor_t au_flavor; /* flavor (RPC_AUTH_*) */
91#ifdef RPC_DEBUG
92 char * au_name;
93#endif
94 struct rpc_auth * (*create)(struct rpc_clnt *, rpc_authflavor_t);
95 void (*destroy)(struct rpc_auth *);
96
97 struct rpc_cred * (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int);
98 struct rpc_cred * (*crcreate)(struct rpc_auth*, struct auth_cred *, int);
99};
100
101struct rpc_credops {
102 const char * cr_name; /* Name of the auth flavour */
103 void (*crdestroy)(struct rpc_cred *);
104
105 int (*crmatch)(struct auth_cred *, struct rpc_cred *, int);
106 u32 * (*crmarshal)(struct rpc_task *, u32 *);
107 int (*crrefresh)(struct rpc_task *);
108 u32 * (*crvalidate)(struct rpc_task *, u32 *);
109 int (*crwrap_req)(struct rpc_task *, kxdrproc_t,
110 void *, u32 *, void *);
111 int (*crunwrap_resp)(struct rpc_task *, kxdrproc_t,
112 void *, u32 *, void *);
113};
114
115extern struct rpc_authops authunix_ops;
116extern struct rpc_authops authnull_ops;
117#ifdef CONFIG_SUNRPC_SECURE
118extern struct rpc_authops authdes_ops;
119#endif
120
121int rpcauth_register(struct rpc_authops *);
122int rpcauth_unregister(struct rpc_authops *);
123struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *);
124void rpcauth_destroy(struct rpc_auth *);
125struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int);
126struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int);
127struct rpc_cred * rpcauth_bindcred(struct rpc_task *);
128void rpcauth_holdcred(struct rpc_task *);
129void put_rpccred(struct rpc_cred *);
130void rpcauth_unbindcred(struct rpc_task *);
131u32 * rpcauth_marshcred(struct rpc_task *, u32 *);
132u32 * rpcauth_checkverf(struct rpc_task *, u32 *);
133int rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, u32 *data, void *obj);
134int rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, u32 *data, void *obj);
135int rpcauth_refreshcred(struct rpc_task *);
136void rpcauth_invalcred(struct rpc_task *);
137int rpcauth_uptodatecred(struct rpc_task *);
138int rpcauth_init_credcache(struct rpc_auth *, unsigned long);
139void rpcauth_free_credcache(struct rpc_auth *);
140
141static inline
142struct rpc_cred * get_rpccred(struct rpc_cred *cred)
143{
144 atomic_inc(&cred->cr_count);
145 return cred;
146}
147
148#endif /* __KERNEL__ */
149#endif /* _LINUX_SUNRPC_AUTH_H */
diff --git a/include/linux/sunrpc/auth_gss.h b/include/linux/sunrpc/auth_gss.h
new file mode 100644
index 000000000000..03084dc4bb6a
--- /dev/null
+++ b/include/linux/sunrpc/auth_gss.h
@@ -0,0 +1,97 @@
1/*
2 * linux/include/linux/auth_gss.h
3 *
4 * Declarations for RPCSEC_GSS
5 *
6 * Dug Song <dugsong@monkey.org>
7 * Andy Adamson <andros@umich.edu>
8 * Bruce Fields <bfields@umich.edu>
9 * Copyright (c) 2000 The Regents of the University of Michigan
10 *
11 * $Id$
12 */
13
14#ifndef _LINUX_SUNRPC_AUTH_GSS_H
15#define _LINUX_SUNRPC_AUTH_GSS_H
16
17#ifdef __KERNEL__
18#include <linux/sunrpc/auth.h>
19#include <linux/sunrpc/svc.h>
20#include <linux/sunrpc/gss_api.h>
21
22#define RPC_GSS_VERSION 1
23
24#define MAXSEQ 0x80000000 /* maximum legal sequence number, from rfc 2203 */
25
26enum rpc_gss_proc {
27 RPC_GSS_PROC_DATA = 0,
28 RPC_GSS_PROC_INIT = 1,
29 RPC_GSS_PROC_CONTINUE_INIT = 2,
30 RPC_GSS_PROC_DESTROY = 3
31};
32
33enum rpc_gss_svc {
34 RPC_GSS_SVC_NONE = 1,
35 RPC_GSS_SVC_INTEGRITY = 2,
36 RPC_GSS_SVC_PRIVACY = 3
37};
38
39/* on-the-wire gss cred: */
40struct rpc_gss_wire_cred {
41 u32 gc_v; /* version */
42 u32 gc_proc; /* control procedure */
43 u32 gc_seq; /* sequence number */
44 u32 gc_svc; /* service */
45 struct xdr_netobj gc_ctx; /* context handle */
46};
47
48/* on-the-wire gss verifier: */
49struct rpc_gss_wire_verf {
50 u32 gv_flavor;
51 struct xdr_netobj gv_verf;
52};
53
54/* return from gss NULL PROC init sec context */
55struct rpc_gss_init_res {
56 struct xdr_netobj gr_ctx; /* context handle */
57 u32 gr_major; /* major status */
58 u32 gr_minor; /* minor status */
59 u32 gr_win; /* sequence window */
60 struct xdr_netobj gr_token; /* token */
61};
62
63/* The gss_cl_ctx struct holds all the information the rpcsec_gss client
64 * code needs to know about a single security context. In particular,
65 * gc_gss_ctx is the context handle that is used to do gss-api calls, while
66 * gc_wire_ctx is the context handle that is used to identify the context on
67 * the wire when communicating with a server. */
68
69struct gss_cl_ctx {
70 atomic_t count;
71 enum rpc_gss_proc gc_proc;
72 u32 gc_seq;
73 spinlock_t gc_seq_lock;
74 struct gss_ctx *gc_gss_ctx;
75 struct xdr_netobj gc_wire_ctx;
76 u32 gc_win;
77 unsigned long gc_expiry;
78};
79
80struct gss_upcall_msg;
81struct gss_cred {
82 struct rpc_cred gc_base;
83 enum rpc_gss_svc gc_service;
84 struct gss_cl_ctx *gc_ctx;
85 struct gss_upcall_msg *gc_upcall;
86};
87
88#define gc_uid gc_base.cr_uid
89#define gc_count gc_base.cr_count
90#define gc_flags gc_base.cr_flags
91#define gc_expire gc_base.cr_expire
92
93void print_hexl(u32 *p, u_int length, u_int offset);
94
95#endif /* __KERNEL__ */
96#endif /* _LINUX_SUNRPC_AUTH_GSS_H */
97
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
new file mode 100644
index 000000000000..6864063d1b9f
--- /dev/null
+++ b/include/linux/sunrpc/cache.h
@@ -0,0 +1,312 @@
1/*
2 * include/linux/sunrpc/cache.h
3 *
4 * Generic code for various authentication-related caches
5 * used by sunrpc clients and servers.
6 *
7 * Copyright (C) 2002 Neil Brown <neilb@cse.unsw.edu.au>
8 *
9 * Released under terms in GPL version 2. See COPYING.
10 *
11 */
12
13#ifndef _LINUX_SUNRPC_CACHE_H_
14#define _LINUX_SUNRPC_CACHE_H_
15
16#include <linux/slab.h>
17#include <asm/atomic.h>
18#include <linux/proc_fs.h>
19
20/*
21 * Each cache requires:
22 * - A 'struct cache_detail' which contains information specific to the cache
23 * for common code to use.
24 * - An item structure that must contain a "struct cache_head"
25 * - A lookup function defined using DefineCacheLookup
26 * - A 'put' function that can release a cache item. It will only
27 * be called after cache_put has succeed, so there are guarantee
28 * to be no references.
29 * - A function to calculate a hash of an item's key.
30 *
31 * as well as assorted code fragments (e.g. compare keys) and numbers
32 * (e.g. hash size, goal_age, etc).
33 *
34 * Each cache must be registered so that it can be cleaned regularly.
35 * When the cache is unregistered, it is flushed completely.
36 *
37 * Entries have a ref count and a 'hashed' flag which counts the existance
38 * in the hash table.
39 * We only expire entries when refcount is zero.
40 * Existance in the cache is counted the refcount.
41 */
42
43/* Every cache item has a common header that is used
44 * for expiring and refreshing entries.
45 *
46 */
47struct cache_head {
48 struct cache_head * next;
49 time_t expiry_time; /* After time time, don't use the data */
50 time_t last_refresh; /* If CACHE_PENDING, this is when upcall
51 * was sent, else this is when update was received
52 */
53 atomic_t refcnt;
54 unsigned long flags;
55};
56#define CACHE_VALID 0 /* Entry contains valid data */
57#define CACHE_NEGATIVE 1 /* Negative entry - there is no match for the key */
58#define CACHE_PENDING 2 /* An upcall has been sent but no reply received yet*/
59
60#define CACHE_NEW_EXPIRY 120 /* keep new things pending confirmation for 120 seconds */
61
62struct cache_detail {
63 int hash_size;
64 struct cache_head ** hash_table;
65 rwlock_t hash_lock;
66
67 atomic_t inuse; /* active user-space update or lookup */
68
69 char *name;
70 void (*cache_put)(struct cache_head *,
71 struct cache_detail*);
72
73 void (*cache_request)(struct cache_detail *cd,
74 struct cache_head *h,
75 char **bpp, int *blen);
76 int (*cache_parse)(struct cache_detail *,
77 char *buf, int len);
78
79 int (*cache_show)(struct seq_file *m,
80 struct cache_detail *cd,
81 struct cache_head *h);
82
83 /* fields below this comment are for internal use
84 * and should not be touched by cache owners
85 */
86 time_t flush_time; /* flush all cache items with last_refresh
87 * earlier than this */
88 struct list_head others;
89 time_t nextcheck;
90 int entries;
91
92 /* fields for communication over channel */
93 struct list_head queue;
94 struct proc_dir_entry *proc_ent;
95 struct proc_dir_entry *flush_ent, *channel_ent, *content_ent;
96
97 atomic_t readers; /* how many time is /chennel open */
98 time_t last_close; /* if no readers, when did last close */
99 time_t last_warn; /* when we last warned about no readers */
100 void (*warn_no_listener)(struct cache_detail *cd);
101};
102
103
104/* this must be embedded in any request structure that
105 * identifies an object that will want a callback on
106 * a cache fill
107 */
108struct cache_req {
109 struct cache_deferred_req *(*defer)(struct cache_req *req);
110};
111/* this must be embedded in a deferred_request that is being
112 * delayed awaiting cache-fill
113 */
114struct cache_deferred_req {
115 struct list_head hash; /* on hash chain */
116 struct list_head recent; /* on fifo */
117 struct cache_head *item; /* cache item we wait on */
118 time_t recv_time;
119 void *owner; /* we might need to discard all defered requests
120 * owned by someone */
121 void (*revisit)(struct cache_deferred_req *req,
122 int too_many);
123};
124
125/*
126 * just like a template in C++, this macro does cache lookup
127 * for us.
128 * The function is passed some sort of HANDLE from which a cache_detail
129 * structure can be determined (via SETUP, DETAIL), a template
130 * cache entry (type RTN*), and a "set" flag. Using the HASHFN and the
131 * TEST, the function will try to find a matching cache entry in the cache.
132 * If "set" == 0 :
133 * If an entry is found, it is returned
134 * If no entry is found, a new non-VALID entry is created.
135 * If "set" == 1 and INPLACE == 0 :
136 * If no entry is found a new one is inserted with data from "template"
137 * If a non-CACHE_VALID entry is found, it is updated from template using UPDATE
138 * If a CACHE_VALID entry is found, a new entry is swapped in with data
139 * from "template"
140 * If set == 1, and INPLACE == 1 :
141 * As above, except that if a CACHE_VALID entry is found, we UPDATE in place
142 * instead of swapping in a new entry.
143 *
144 * If the passed handle has the CACHE_NEGATIVE flag set, then UPDATE is not
145 * run but insteead CACHE_NEGATIVE is set in any new item.
146
147 * In any case, the new entry is returned with a reference count.
148 *
149 *
150 * RTN is a struct type for a cache entry
151 * MEMBER is the member of the cache which is cache_head, which must be first
152 * FNAME is the name for the function
153 * ARGS are arguments to function and must contain RTN *item, int set. May
154 * also contain something to be usedby SETUP or DETAIL to find cache_detail.
155 * SETUP locates the cache detail and makes it available as...
156 * DETAIL identifies the cache detail, possibly set up by SETUP
157 * HASHFN returns a hash value of the cache entry "item"
158 * TEST tests if "tmp" matches "item"
159 * INIT copies key information from "item" to "new"
160 * UPDATE copies content information from "item" to "tmp"
161 * INPLACE is true if updates can happen inplace rather than allocating a new structure
162 *
163 * WARNING: any substantial changes to this must be reflected in
164 * net/sunrpc/svcauth.c(auth_domain_lookup)
165 * which is a similar routine that is open-coded.
166 */
167#define DefineCacheLookup(RTN,MEMBER,FNAME,ARGS,SETUP,DETAIL,HASHFN,TEST,INIT,UPDATE,INPLACE) \
168RTN *FNAME ARGS \
169{ \
170 RTN *tmp, *new=NULL; \
171 struct cache_head **hp, **head; \
172 SETUP; \
173 head = &(DETAIL)->hash_table[HASHFN]; \
174 retry: \
175 if (set||new) write_lock(&(DETAIL)->hash_lock); \
176 else read_lock(&(DETAIL)->hash_lock); \
177 for(hp=head; *hp != NULL; hp = &tmp->MEMBER.next) { \
178 tmp = container_of(*hp, RTN, MEMBER); \
179 if (TEST) { /* found a match */ \
180 \
181 if (set && !INPLACE && test_bit(CACHE_VALID, &tmp->MEMBER.flags) && !new) \
182 break; \
183 \
184 if (new) \
185 {INIT;} \
186 if (set) { \
187 if (!INPLACE && test_bit(CACHE_VALID, &tmp->MEMBER.flags))\
188 { /* need to swap in new */ \
189 RTN *t2; \
190 \
191 new->MEMBER.next = tmp->MEMBER.next; \
192 *hp = &new->MEMBER; \
193 tmp->MEMBER.next = NULL; \
194 t2 = tmp; tmp = new; new = t2; \
195 } \
196 if (test_bit(CACHE_NEGATIVE, &item->MEMBER.flags)) \
197 set_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags); \
198 else { \
199 UPDATE; \
200 clear_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags); \
201 } \
202 } \
203 cache_get(&tmp->MEMBER); \
204 if (set||new) write_unlock(&(DETAIL)->hash_lock); \
205 else read_unlock(&(DETAIL)->hash_lock); \
206 if (set) \
207 cache_fresh(DETAIL, &tmp->MEMBER, item->MEMBER.expiry_time); \
208 if (set && !INPLACE && new) cache_fresh(DETAIL, &new->MEMBER, 0); \
209 if (new) (DETAIL)->cache_put(&new->MEMBER, DETAIL); \
210 return tmp; \
211 } \
212 } \
213 /* Didn't find anything */ \
214 if (new) { \
215 INIT; \
216 new->MEMBER.next = *head; \
217 *head = &new->MEMBER; \
218 (DETAIL)->entries ++; \
219 cache_get(&new->MEMBER); \
220 if (set) { \
221 tmp = new; \
222 if (test_bit(CACHE_NEGATIVE, &item->MEMBER.flags)) \
223 set_bit(CACHE_NEGATIVE, &tmp->MEMBER.flags); \
224 else {UPDATE;} \
225 } \
226 } \
227 if (set||new) write_unlock(&(DETAIL)->hash_lock); \
228 else read_unlock(&(DETAIL)->hash_lock); \
229 if (new && set) \
230 cache_fresh(DETAIL, &new->MEMBER, item->MEMBER.expiry_time); \
231 if (new) \
232 return new; \
233 new = kmalloc(sizeof(*new), GFP_KERNEL); \
234 if (new) { \
235 cache_init(&new->MEMBER); \
236 goto retry; \
237 } \
238 return NULL; \
239}
240
241#define DefineSimpleCacheLookup(STRUCT,INPLACE) \
242 DefineCacheLookup(struct STRUCT, h, STRUCT##_lookup, (struct STRUCT *item, int set), /*no setup */, \
243 & STRUCT##_cache, STRUCT##_hash(item), STRUCT##_match(item, tmp),\
244 STRUCT##_init(new, item), STRUCT##_update(tmp, item),INPLACE)
245
246#define cache_for_each(pos, detail, index, member) \
247 for (({read_lock(&(detail)->hash_lock); index = (detail)->hash_size;}) ; \
248 ({if (index==0)read_unlock(&(detail)->hash_lock); index--;}); \
249 ) \
250 for (pos = container_of((detail)->hash_table[index], typeof(*pos), member); \
251 &pos->member; \
252 pos = container_of(pos->member.next, typeof(*pos), member))
253
254
255
256extern void cache_clean_deferred(void *owner);
257
258static inline struct cache_head *cache_get(struct cache_head *h)
259{
260 atomic_inc(&h->refcnt);
261 return h;
262}
263
264
265static inline int cache_put(struct cache_head *h, struct cache_detail *cd)
266{
267 if (atomic_read(&h->refcnt) <= 2 &&
268 h->expiry_time < cd->nextcheck)
269 cd->nextcheck = h->expiry_time;
270 return atomic_dec_and_test(&h->refcnt);
271}
272
273extern void cache_init(struct cache_head *h);
274extern void cache_fresh(struct cache_detail *detail,
275 struct cache_head *head, time_t expiry);
276extern int cache_check(struct cache_detail *detail,
277 struct cache_head *h, struct cache_req *rqstp);
278extern void cache_flush(void);
279extern void cache_purge(struct cache_detail *detail);
280#define NEVER (0x7FFFFFFF)
281extern void cache_register(struct cache_detail *cd);
282extern int cache_unregister(struct cache_detail *cd);
283
284extern void qword_add(char **bpp, int *lp, char *str);
285extern void qword_addhex(char **bpp, int *lp, char *buf, int blen);
286extern int qword_get(char **bpp, char *dest, int bufsize);
287
288static inline int get_int(char **bpp, int *anint)
289{
290 char buf[50];
291 char *ep;
292 int rv;
293 int len = qword_get(bpp, buf, 50);
294 if (len < 0) return -EINVAL;
295 if (len ==0) return -ENOENT;
296 rv = simple_strtol(buf, &ep, 0);
297 if (*ep) return -EINVAL;
298 *anint = rv;
299 return 0;
300}
301
302static inline time_t get_expiry(char **bpp)
303{
304 int rv;
305 if (get_int(bpp, &rv))
306 return 0;
307 if (rv < 0)
308 return 0;
309 return rv;
310}
311
312#endif /* _LINUX_SUNRPC_CACHE_H_ */
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
new file mode 100644
index 000000000000..2709caf4d128
--- /dev/null
+++ b/include/linux/sunrpc/clnt.h
@@ -0,0 +1,153 @@
1/*
2 * linux/include/linux/sunrpc/clnt.h
3 *
4 * Declarations for the high-level RPC client interface
5 *
6 * Copyright (C) 1995, 1996, Olaf Kirch <okir@monad.swb.de>
7 */
8
9#ifndef _LINUX_SUNRPC_CLNT_H
10#define _LINUX_SUNRPC_CLNT_H
11
12#include <linux/sunrpc/msg_prot.h>
13#include <linux/sunrpc/sched.h>
14#include <linux/sunrpc/xprt.h>
15#include <linux/sunrpc/auth.h>
16#include <linux/sunrpc/stats.h>
17#include <linux/sunrpc/xdr.h>
18#include <linux/sunrpc/timer.h>
19#include <asm/signal.h>
20
21/*
22 * This defines an RPC port mapping
23 */
24struct rpc_portmap {
25 __u32 pm_prog;
26 __u32 pm_vers;
27 __u32 pm_prot;
28 __u16 pm_port;
29 unsigned char pm_binding : 1; /* doing a getport() */
30 struct rpc_wait_queue pm_bindwait; /* waiting on getport() */
31};
32
33struct rpc_inode;
34
35/*
36 * The high-level client handle
37 */
38struct rpc_clnt {
39 atomic_t cl_count; /* Number of clones */
40 atomic_t cl_users; /* number of references */
41 struct rpc_xprt * cl_xprt; /* transport */
42 struct rpc_procinfo * cl_procinfo; /* procedure info */
43 u32 cl_maxproc; /* max procedure number */
44
45 char * cl_server; /* server machine name */
46 char * cl_protname; /* protocol name */
47 struct rpc_auth * cl_auth; /* authenticator */
48 struct rpc_stat * cl_stats; /* statistics */
49
50 unsigned int cl_softrtry : 1,/* soft timeouts */
51 cl_intr : 1,/* interruptible */
52 cl_chatty : 1,/* be verbose */
53 cl_autobind : 1,/* use getport() */
54 cl_oneshot : 1,/* dispose after use */
55 cl_dead : 1;/* abandoned */
56
57 struct rpc_rtt * cl_rtt; /* RTO estimator data */
58 struct rpc_portmap * cl_pmap; /* port mapping */
59
60 int cl_nodelen; /* nodename length */
61 char cl_nodename[UNX_MAXNODENAME];
62 char cl_pathname[30];/* Path in rpc_pipe_fs */
63 struct dentry * cl_dentry; /* inode */
64 struct rpc_clnt * cl_parent; /* Points to parent of clones */
65 struct rpc_rtt cl_rtt_default;
66 struct rpc_portmap cl_pmap_default;
67 char cl_inline_name[32];
68};
69#define cl_timeout cl_xprt->timeout
70#define cl_prog cl_pmap->pm_prog
71#define cl_vers cl_pmap->pm_vers
72#define cl_port cl_pmap->pm_port
73#define cl_prot cl_pmap->pm_prot
74
75/*
76 * General RPC program info
77 */
78#define RPC_MAXVERSION 4
79struct rpc_program {
80 char * name; /* protocol name */
81 u32 number; /* program number */
82 unsigned int nrvers; /* number of versions */
83 struct rpc_version ** version; /* version array */
84 struct rpc_stat * stats; /* statistics */
85 char * pipe_dir_name; /* path to rpc_pipefs dir */
86};
87
88struct rpc_version {
89 u32 number; /* version number */
90 unsigned int nrprocs; /* number of procs */
91 struct rpc_procinfo * procs; /* procedure array */
92};
93
94/*
95 * Procedure information
96 */
97struct rpc_procinfo {
98 u32 p_proc; /* RPC procedure number */
99 kxdrproc_t p_encode; /* XDR encode function */
100 kxdrproc_t p_decode; /* XDR decode function */
101 unsigned int p_bufsiz; /* req. buffer size */
102 unsigned int p_count; /* call count */
103 unsigned int p_timer; /* Which RTT timer to use */
104};
105
106#define RPC_CONGESTED(clnt) (RPCXPRT_CONGESTED((clnt)->cl_xprt))
107#define RPC_PEERADDR(clnt) (&(clnt)->cl_xprt->addr)
108
109#ifdef __KERNEL__
110
111struct rpc_clnt *rpc_create_client(struct rpc_xprt *xprt, char *servname,
112 struct rpc_program *info,
113 u32 version, rpc_authflavor_t authflavor);
114struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
115int rpc_shutdown_client(struct rpc_clnt *);
116int rpc_destroy_client(struct rpc_clnt *);
117void rpc_release_client(struct rpc_clnt *);
118void rpc_getport(struct rpc_task *, struct rpc_clnt *);
119int rpc_register(u32, u32, int, unsigned short, int *);
120
121void rpc_call_setup(struct rpc_task *, struct rpc_message *, int);
122
123int rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg,
124 int flags, rpc_action callback, void *clntdata);
125int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg,
126 int flags);
127void rpc_restart_call(struct rpc_task *);
128void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset);
129void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset);
130void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int);
131size_t rpc_max_payload(struct rpc_clnt *);
132
133static __inline__
134int rpc_call(struct rpc_clnt *clnt, u32 proc, void *argp, void *resp, int flags)
135{
136 struct rpc_message msg = {
137 .rpc_proc = &clnt->cl_procinfo[proc],
138 .rpc_argp = argp,
139 .rpc_resp = resp,
140 .rpc_cred = NULL
141 };
142 return rpc_call_sync(clnt, &msg, flags);
143}
144
145extern void rpciod_wake_up(void);
146
147/*
148 * Helper function for NFSroot support
149 */
150int rpc_getport_external(struct sockaddr_in *, __u32, __u32, int);
151
152#endif /* __KERNEL__ */
153#endif /* _LINUX_SUNRPC_CLNT_H */
diff --git a/include/linux/sunrpc/debug.h b/include/linux/sunrpc/debug.h
new file mode 100644
index 000000000000..eadb31e3c198
--- /dev/null
+++ b/include/linux/sunrpc/debug.h
@@ -0,0 +1,99 @@
1/*
2 * linux/include/linux/sunrpc/debug.h
3 *
4 * Debugging support for sunrpc module
5 *
6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
7 */
8
9#ifndef _LINUX_SUNRPC_DEBUG_H_
10#define _LINUX_SUNRPC_DEBUG_H_
11
12#include <linux/config.h>
13
14#include <linux/timer.h>
15#include <linux/workqueue.h>
16
17/*
18 * Enable RPC debugging/profiling.
19 */
20#ifdef CONFIG_SYSCTL
21#define RPC_DEBUG
22#endif
23/* #define RPC_PROFILE */
24
25/*
26 * RPC debug facilities
27 */
28#define RPCDBG_XPRT 0x0001
29#define RPCDBG_CALL 0x0002
30#define RPCDBG_DEBUG 0x0004
31#define RPCDBG_NFS 0x0008
32#define RPCDBG_AUTH 0x0010
33#define RPCDBG_PMAP 0x0020
34#define RPCDBG_SCHED 0x0040
35#define RPCDBG_SVCSOCK 0x0100
36#define RPCDBG_SVCDSP 0x0200
37#define RPCDBG_MISC 0x0400
38#define RPCDBG_CACHE 0x0800
39#define RPCDBG_ALL 0x7fff
40
41#ifdef __KERNEL__
42
43/*
44 * Debugging macros etc
45 */
46#ifdef RPC_DEBUG
47extern unsigned int rpc_debug;
48extern unsigned int nfs_debug;
49extern unsigned int nfsd_debug;
50extern unsigned int nlm_debug;
51#endif
52
53#define dprintk(args...) dfprintk(FACILITY, ## args)
54
55#undef ifdebug
56#ifdef RPC_DEBUG
57# define ifdebug(fac) if (unlikely(rpc_debug & RPCDBG_##fac))
58# define dfprintk(fac, args...) do { ifdebug(fac) printk(args); } while(0)
59# define RPC_IFDEBUG(x) x
60#else
61# define ifdebug(fac) if (0)
62# define dfprintk(fac, args...) do ; while (0)
63# define RPC_IFDEBUG(x)
64#endif
65
66#ifdef RPC_PROFILE
67# define pprintk(args...) printk(## args)
68#else
69# define pprintk(args...) do ; while (0)
70#endif
71
72/*
73 * Sysctl interface for RPC debugging
74 */
75#ifdef RPC_DEBUG
76void rpc_register_sysctl(void);
77void rpc_unregister_sysctl(void);
78#endif
79
80#endif /* __KERNEL__ */
81
82/*
83 * Declarations for the sysctl debug interface, which allows to read or
84 * change the debug flags for rpc, nfs, nfsd, and lockd. Since the sunrpc
85 * module currently registers its sysctl table dynamically, the sysctl path
86 * for module FOO is <CTL_SUNRPC, CTL_FOODEBUG>.
87 */
88#define CTL_SUNRPC 7249 /* arbitrary and hopefully unused */
89
90enum {
91 CTL_RPCDEBUG = 1,
92 CTL_NFSDEBUG,
93 CTL_NFSDDEBUG,
94 CTL_NLMDEBUG,
95 CTL_SLOTTABLE_UDP,
96 CTL_SLOTTABLE_TCP,
97};
98
99#endif /* _LINUX_SUNRPC_DEBUG_H_ */
diff --git a/include/linux/sunrpc/gss_api.h b/include/linux/sunrpc/gss_api.h
new file mode 100644
index 000000000000..689262f63059
--- /dev/null
+++ b/include/linux/sunrpc/gss_api.h
@@ -0,0 +1,122 @@
1/*
2 * linux/include/linux/gss_api.h
3 *
4 * Somewhat simplified version of the gss api.
5 *
6 * Dug Song <dugsong@monkey.org>
7 * Andy Adamson <andros@umich.edu>
8 * Bruce Fields <bfields@umich.edu>
9 * Copyright (c) 2000 The Regents of the University of Michigan
10 *
11 * $Id$
12 */
13
14#ifndef _LINUX_SUNRPC_GSS_API_H
15#define _LINUX_SUNRPC_GSS_API_H
16
17#ifdef __KERNEL__
18#include <linux/sunrpc/xdr.h>
19#include <linux/uio.h>
20
21/* The mechanism-independent gss-api context: */
22struct gss_ctx {
23 struct gss_api_mech *mech_type;
24 void *internal_ctx_id;
25};
26
27#define GSS_C_NO_BUFFER ((struct xdr_netobj) 0)
28#define GSS_C_NO_CONTEXT ((struct gss_ctx *) 0)
29#define GSS_C_NULL_OID ((struct xdr_netobj) 0)
30
31/*XXX arbitrary length - is this set somewhere? */
32#define GSS_OID_MAX_LEN 32
33
34/* gss-api prototypes; note that these are somewhat simplified versions of
35 * the prototypes specified in RFC 2744. */
36int gss_import_sec_context(
37 const void* input_token,
38 size_t bufsize,
39 struct gss_api_mech *mech,
40 struct gss_ctx **ctx_id);
41u32 gss_get_mic(
42 struct gss_ctx *ctx_id,
43 u32 qop,
44 struct xdr_buf *message,
45 struct xdr_netobj *mic_token);
46u32 gss_verify_mic(
47 struct gss_ctx *ctx_id,
48 struct xdr_buf *message,
49 struct xdr_netobj *mic_token,
50 u32 *qstate);
51u32 gss_delete_sec_context(
52 struct gss_ctx **ctx_id);
53
54u32 gss_pseudoflavor_to_service(struct gss_api_mech *, u32 pseudoflavor);
55char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service);
56
57struct pf_desc {
58 u32 pseudoflavor;
59 u32 qop;
60 u32 service;
61 char *name;
62 char *auth_domain_name;
63};
64
65/* Different mechanisms (e.g., krb5 or spkm3) may implement gss-api, and
66 * mechanisms may be dynamically registered or unregistered by modules. */
67
68/* Each mechanism is described by the following struct: */
69struct gss_api_mech {
70 struct list_head gm_list;
71 struct module *gm_owner;
72 struct xdr_netobj gm_oid;
73 char *gm_name;
74 struct gss_api_ops *gm_ops;
75 /* pseudoflavors supported by this mechanism: */
76 int gm_pf_num;
77 struct pf_desc * gm_pfs;
78};
79
80/* and must provide the following operations: */
81struct gss_api_ops {
82 int (*gss_import_sec_context)(
83 const void *input_token,
84 size_t bufsize,
85 struct gss_ctx *ctx_id);
86 u32 (*gss_get_mic)(
87 struct gss_ctx *ctx_id,
88 u32 qop,
89 struct xdr_buf *message,
90 struct xdr_netobj *mic_token);
91 u32 (*gss_verify_mic)(
92 struct gss_ctx *ctx_id,
93 struct xdr_buf *message,
94 struct xdr_netobj *mic_token,
95 u32 *qstate);
96 void (*gss_delete_sec_context)(
97 void *internal_ctx_id);
98};
99
100int gss_mech_register(struct gss_api_mech *);
101void gss_mech_unregister(struct gss_api_mech *);
102
103/* returns a mechanism descriptor given an OID, and increments the mechanism's
104 * reference count. */
105struct gss_api_mech * gss_mech_get_by_OID(struct xdr_netobj *);
106
107/* Returns a reference to a mechanism, given a name like "krb5" etc. */
108struct gss_api_mech *gss_mech_get_by_name(const char *);
109
110/* Similar, but get by pseudoflavor. */
111struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32);
112
113/* Just increments the mechanism's reference count and returns its input: */
114struct gss_api_mech * gss_mech_get(struct gss_api_mech *);
115
116/* For every succesful gss_mech_get or gss_mech_get_by_* call there must be a
117 * corresponding call to gss_mech_put. */
118void gss_mech_put(struct gss_api_mech *);
119
120#endif /* __KERNEL__ */
121#endif /* _LINUX_SUNRPC_GSS_API_H */
122
diff --git a/include/linux/sunrpc/gss_asn1.h b/include/linux/sunrpc/gss_asn1.h
new file mode 100644
index 000000000000..3ccecd0ad229
--- /dev/null
+++ b/include/linux/sunrpc/gss_asn1.h
@@ -0,0 +1,81 @@
1/*
2 * linux/include/linux/sunrpc/gss_asn1.h
3 *
4 * minimal asn1 for generic encoding/decoding of gss tokens
5 *
6 * Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
7 * lib/gssapi/krb5/gssapiP_krb5.h, and others
8 *
9 * Copyright (c) 2000 The Regents of the University of Michigan.
10 * All rights reserved.
11 *
12 * Andy Adamson <andros@umich.edu>
13 */
14
15/*
16 * Copyright 1995 by the Massachusetts Institute of Technology.
17 * All Rights Reserved.
18 *
19 * Export of this software from the United States of America may
20 * require a specific license from the United States Government.
21 * It is the responsibility of any person or organization contemplating
22 * export to obtain such a license before exporting.
23 *
24 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
25 * distribute this software and its documentation for any purpose and
26 * without fee is hereby granted, provided that the above copyright
27 * notice appear in all copies and that both that copyright notice and
28 * this permission notice appear in supporting documentation, and that
29 * the name of M.I.T. not be used in advertising or publicity pertaining
30 * to distribution of the software without specific, written prior
31 * permission. Furthermore if you modify this software you must label
32 * your software as modified software and not distribute it in such a
33 * fashion that it might be confused with the original M.I.T. software.
34 * M.I.T. makes no representations about the suitability of
35 * this software for any purpose. It is provided "as is" without express
36 * or implied warranty.
37 *
38 */
39
40
41#include <linux/sunrpc/gss_api.h>
42
43#define SIZEOF_INT 4
44
45/* from gssapi_err_generic.h */
46#define G_BAD_SERVICE_NAME (-2045022976L)
47#define G_BAD_STRING_UID (-2045022975L)
48#define G_NOUSER (-2045022974L)
49#define G_VALIDATE_FAILED (-2045022973L)
50#define G_BUFFER_ALLOC (-2045022972L)
51#define G_BAD_MSG_CTX (-2045022971L)
52#define G_WRONG_SIZE (-2045022970L)
53#define G_BAD_USAGE (-2045022969L)
54#define G_UNKNOWN_QOP (-2045022968L)
55#define G_NO_HOSTNAME (-2045022967L)
56#define G_BAD_HOSTNAME (-2045022966L)
57#define G_WRONG_MECH (-2045022965L)
58#define G_BAD_TOK_HEADER (-2045022964L)
59#define G_BAD_DIRECTION (-2045022963L)
60#define G_TOK_TRUNC (-2045022962L)
61#define G_REFLECT (-2045022961L)
62#define G_WRONG_TOKID (-2045022960L)
63
64#define g_OID_equal(o1,o2) \
65 (((o1)->len == (o2)->len) && \
66 (memcmp((o1)->data,(o2)->data,(int) (o1)->len) == 0))
67
68u32 g_verify_token_header(
69 struct xdr_netobj *mech,
70 int *body_size,
71 unsigned char **buf_in,
72 int toksize);
73
74int g_token_size(
75 struct xdr_netobj *mech,
76 unsigned int body_size);
77
78void g_make_token_header(
79 struct xdr_netobj *mech,
80 int body_size,
81 unsigned char **buf);
diff --git a/include/linux/sunrpc/gss_err.h b/include/linux/sunrpc/gss_err.h
new file mode 100644
index 000000000000..92608a2e574c
--- /dev/null
+++ b/include/linux/sunrpc/gss_err.h
@@ -0,0 +1,177 @@
1/*
2 * linux/include/sunrpc/gss_err.h
3 *
4 * Adapted from MIT Kerberos 5-1.2.1 include/gssapi/gssapi.h
5 *
6 * Copyright (c) 2002 The Regents of the University of Michigan.
7 * All rights reserved.
8 *
9 * Andy Adamson <andros@umich.edu>
10 */
11
12/*
13 * Copyright 1993 by OpenVision Technologies, Inc.
14 *
15 * Permission to use, copy, modify, distribute, and sell this software
16 * and its documentation for any purpose is hereby granted without fee,
17 * provided that the above copyright notice appears in all copies and
18 * that both that copyright notice and this permission notice appear in
19 * supporting documentation, and that the name of OpenVision not be used
20 * in advertising or publicity pertaining to distribution of the software
21 * without specific, written prior permission. OpenVision makes no
22 * representations about the suitability of this software for any
23 * purpose. It is provided "as is" without express or implied warranty.
24 *
25 * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
26 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
27 * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
28 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
29 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
30 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
31 * PERFORMANCE OF THIS SOFTWARE.
32 */
33
34#ifndef _LINUX_SUNRPC_GSS_ERR_H
35#define _LINUX_SUNRPC_GSS_ERR_H
36
37#ifdef __KERNEL__
38
39typedef unsigned int OM_uint32;
40
41/*
42 * Flag bits for context-level services.
43 */
44#define GSS_C_DELEG_FLAG 1
45#define GSS_C_MUTUAL_FLAG 2
46#define GSS_C_REPLAY_FLAG 4
47#define GSS_C_SEQUENCE_FLAG 8
48#define GSS_C_CONF_FLAG 16
49#define GSS_C_INTEG_FLAG 32
50#define GSS_C_ANON_FLAG 64
51#define GSS_C_PROT_READY_FLAG 128
52#define GSS_C_TRANS_FLAG 256
53
54/*
55 * Credential usage options
56 */
57#define GSS_C_BOTH 0
58#define GSS_C_INITIATE 1
59#define GSS_C_ACCEPT 2
60
61/*
62 * Status code types for gss_display_status
63 */
64#define GSS_C_GSS_CODE 1
65#define GSS_C_MECH_CODE 2
66
67
68/*
69 * Define the default Quality of Protection for per-message services. Note
70 * that an implementation that offers multiple levels of QOP may either reserve
71 * a value (for example zero, as assumed here) to mean "default protection", or
72 * alternatively may simply equate GSS_C_QOP_DEFAULT to a specific explicit
73 * QOP value. However a value of 0 should always be interpreted by a GSSAPI
74 * implementation as a request for the default protection level.
75 */
76#define GSS_C_QOP_DEFAULT 0
77
78/*
79 * Expiration time of 2^32-1 seconds means infinite lifetime for a
80 * credential or security context
81 */
82#define GSS_C_INDEFINITE ((OM_uint32) 0xfffffffful)
83
84
85/* Major status codes */
86
87#define GSS_S_COMPLETE 0
88
89/*
90 * Some "helper" definitions to make the status code macros obvious.
91 */
92#define GSS_C_CALLING_ERROR_OFFSET 24
93#define GSS_C_ROUTINE_ERROR_OFFSET 16
94#define GSS_C_SUPPLEMENTARY_OFFSET 0
95#define GSS_C_CALLING_ERROR_MASK ((OM_uint32) 0377ul)
96#define GSS_C_ROUTINE_ERROR_MASK ((OM_uint32) 0377ul)
97#define GSS_C_SUPPLEMENTARY_MASK ((OM_uint32) 0177777ul)
98
99/*
100 * The macros that test status codes for error conditions. Note that the
101 * GSS_ERROR() macro has changed slightly from the V1 GSSAPI so that it now
102 * evaluates its argument only once.
103 */
104#define GSS_CALLING_ERROR(x) \
105 ((x) & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
106#define GSS_ROUTINE_ERROR(x) \
107 ((x) & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
108#define GSS_SUPPLEMENTARY_INFO(x) \
109 ((x) & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
110#define GSS_ERROR(x) \
111 ((x) & ((GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET) | \
112 (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET)))
113
114/*
115 * Now the actual status code definitions
116 */
117
118/*
119 * Calling errors:
120 */
121#define GSS_S_CALL_INACCESSIBLE_READ \
122 (((OM_uint32) 1ul) << GSS_C_CALLING_ERROR_OFFSET)
123#define GSS_S_CALL_INACCESSIBLE_WRITE \
124 (((OM_uint32) 2ul) << GSS_C_CALLING_ERROR_OFFSET)
125#define GSS_S_CALL_BAD_STRUCTURE \
126 (((OM_uint32) 3ul) << GSS_C_CALLING_ERROR_OFFSET)
127
128/*
129 * Routine errors:
130 */
131#define GSS_S_BAD_MECH (((OM_uint32) 1ul) << GSS_C_ROUTINE_ERROR_OFFSET)
132#define GSS_S_BAD_NAME (((OM_uint32) 2ul) << GSS_C_ROUTINE_ERROR_OFFSET)
133#define GSS_S_BAD_NAMETYPE (((OM_uint32) 3ul) << GSS_C_ROUTINE_ERROR_OFFSET)
134#define GSS_S_BAD_BINDINGS (((OM_uint32) 4ul) << GSS_C_ROUTINE_ERROR_OFFSET)
135#define GSS_S_BAD_STATUS (((OM_uint32) 5ul) << GSS_C_ROUTINE_ERROR_OFFSET)
136#define GSS_S_BAD_SIG (((OM_uint32) 6ul) << GSS_C_ROUTINE_ERROR_OFFSET)
137#define GSS_S_NO_CRED (((OM_uint32) 7ul) << GSS_C_ROUTINE_ERROR_OFFSET)
138#define GSS_S_NO_CONTEXT (((OM_uint32) 8ul) << GSS_C_ROUTINE_ERROR_OFFSET)
139#define GSS_S_DEFECTIVE_TOKEN (((OM_uint32) 9ul) << GSS_C_ROUTINE_ERROR_OFFSET)
140#define GSS_S_DEFECTIVE_CREDENTIAL \
141 (((OM_uint32) 10ul) << GSS_C_ROUTINE_ERROR_OFFSET)
142#define GSS_S_CREDENTIALS_EXPIRED \
143 (((OM_uint32) 11ul) << GSS_C_ROUTINE_ERROR_OFFSET)
144#define GSS_S_CONTEXT_EXPIRED \
145 (((OM_uint32) 12ul) << GSS_C_ROUTINE_ERROR_OFFSET)
146#define GSS_S_FAILURE (((OM_uint32) 13ul) << GSS_C_ROUTINE_ERROR_OFFSET)
147#define GSS_S_BAD_QOP (((OM_uint32) 14ul) << GSS_C_ROUTINE_ERROR_OFFSET)
148#define GSS_S_UNAUTHORIZED (((OM_uint32) 15ul) << GSS_C_ROUTINE_ERROR_OFFSET)
149#define GSS_S_UNAVAILABLE (((OM_uint32) 16ul) << GSS_C_ROUTINE_ERROR_OFFSET)
150#define GSS_S_DUPLICATE_ELEMENT \
151 (((OM_uint32) 17ul) << GSS_C_ROUTINE_ERROR_OFFSET)
152#define GSS_S_NAME_NOT_MN \
153 (((OM_uint32) 18ul) << GSS_C_ROUTINE_ERROR_OFFSET)
154
155/*
156 * Supplementary info bits:
157 */
158#define GSS_S_CONTINUE_NEEDED (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
159#define GSS_S_DUPLICATE_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
160#define GSS_S_OLD_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
161#define GSS_S_UNSEQ_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
162#define GSS_S_GAP_TOKEN (1 << (GSS_C_SUPPLEMENTARY_OFFSET + 4))
163
164/* XXXX these are not part of the GSSAPI C bindings! (but should be) */
165
166#define GSS_CALLING_ERROR_FIELD(x) \
167 (((x) >> GSS_C_CALLING_ERROR_OFFSET) & GSS_C_CALLING_ERROR_MASK)
168#define GSS_ROUTINE_ERROR_FIELD(x) \
169 (((x) >> GSS_C_ROUTINE_ERROR_OFFSET) & GSS_C_ROUTINE_ERROR_MASK)
170#define GSS_SUPPLEMENTARY_INFO_FIELD(x) \
171 (((x) >> GSS_C_SUPPLEMENTARY_OFFSET) & GSS_C_SUPPLEMENTARY_MASK)
172
173/* XXXX This is a necessary evil until the spec is fixed */
174#define GSS_S_CRED_UNAVAIL GSS_S_FAILURE
175
176#endif /* __KERNEL__ */
177#endif /* __LINUX_SUNRPC_GSS_ERR_H */
diff --git a/include/linux/sunrpc/gss_krb5.h b/include/linux/sunrpc/gss_krb5.h
new file mode 100644
index 000000000000..ffe31d2eb9ec
--- /dev/null
+++ b/include/linux/sunrpc/gss_krb5.h
@@ -0,0 +1,148 @@
1/*
2 * linux/include/linux/sunrpc/gss_krb5_types.h
3 *
4 * Adapted from MIT Kerberos 5-1.2.1 lib/include/krb5.h,
5 * lib/gssapi/krb5/gssapiP_krb5.h, and others
6 *
7 * Copyright (c) 2000 The Regents of the University of Michigan.
8 * All rights reserved.
9 *
10 * Andy Adamson <andros@umich.edu>
11 * Bruce Fields <bfields@umich.edu>
12 */
13
14/*
15 * Copyright 1995 by the Massachusetts Institute of Technology.
16 * All Rights Reserved.
17 *
18 * Export of this software from the United States of America may
19 * require a specific license from the United States Government.
20 * It is the responsibility of any person or organization contemplating
21 * export to obtain such a license before exporting.
22 *
23 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
24 * distribute this software and its documentation for any purpose and
25 * without fee is hereby granted, provided that the above copyright
26 * notice appear in all copies and that both that copyright notice and
27 * this permission notice appear in supporting documentation, and that
28 * the name of M.I.T. not be used in advertising or publicity pertaining
29 * to distribution of the software without specific, written prior
30 * permission. Furthermore if you modify this software you must label
31 * your software as modified software and not distribute it in such a
32 * fashion that it might be confused with the original M.I.T. software.
33 * M.I.T. makes no representations about the suitability of
34 * this software for any purpose. It is provided "as is" without express
35 * or implied warranty.
36 *
37 */
38
39#include <linux/sunrpc/auth_gss.h>
40#include <linux/sunrpc/gss_err.h>
41#include <linux/sunrpc/gss_asn1.h>
42
43struct krb5_ctx {
44 int initiate; /* 1 = initiating, 0 = accepting */
45 int seed_init;
46 unsigned char seed[16];
47 int signalg;
48 int sealalg;
49 struct crypto_tfm *enc;
50 struct crypto_tfm *seq;
51 s32 endtime;
52 u32 seq_send;
53 struct xdr_netobj mech_used;
54};
55
56#define KG_TOK_MIC_MSG 0x0101
57#define KG_TOK_WRAP_MSG 0x0201
58
59enum sgn_alg {
60 SGN_ALG_DES_MAC_MD5 = 0x0000,
61 SGN_ALG_MD2_5 = 0x0001,
62 SGN_ALG_DES_MAC = 0x0002,
63 SGN_ALG_3 = 0x0003, /* not published */
64 SGN_ALG_HMAC_MD5 = 0x0011, /* microsoft w2k; no support */
65 SGN_ALG_HMAC_SHA1_DES3_KD = 0x0004
66};
67enum seal_alg {
68 SEAL_ALG_NONE = 0xffff,
69 SEAL_ALG_DES = 0x0000,
70 SEAL_ALG_1 = 0x0001, /* not published */
71 SEAL_ALG_MICROSOFT_RC4 = 0x0010,/* microsoft w2k; no support */
72 SEAL_ALG_DES3KD = 0x0002
73};
74
75#define KRB5_CKSUM_LENGTH 8
76
77#define CKSUMTYPE_CRC32 0x0001
78#define CKSUMTYPE_RSA_MD4 0x0002
79#define CKSUMTYPE_RSA_MD4_DES 0x0003
80#define CKSUMTYPE_DESCBC 0x0004
81#define CKSUMTYPE_RSA_MD5 0x0007
82#define CKSUMTYPE_RSA_MD5_DES 0x0008
83#define CKSUMTYPE_NIST_SHA 0x0009
84#define CKSUMTYPE_HMAC_SHA1_DES3 0x000c
85
86/* from gssapi_err_krb5.h */
87#define KG_CCACHE_NOMATCH (39756032L)
88#define KG_KEYTAB_NOMATCH (39756033L)
89#define KG_TGT_MISSING (39756034L)
90#define KG_NO_SUBKEY (39756035L)
91#define KG_CONTEXT_ESTABLISHED (39756036L)
92#define KG_BAD_SIGN_TYPE (39756037L)
93#define KG_BAD_LENGTH (39756038L)
94#define KG_CTX_INCOMPLETE (39756039L)
95#define KG_CONTEXT (39756040L)
96#define KG_CRED (39756041L)
97#define KG_ENC_DESC (39756042L)
98#define KG_BAD_SEQ (39756043L)
99#define KG_EMPTY_CCACHE (39756044L)
100#define KG_NO_CTYPES (39756045L)
101
102/* per Kerberos v5 protocol spec crypto types from the wire.
103 * these get mapped to linux kernel crypto routines.
104 */
105#define ENCTYPE_NULL 0x0000
106#define ENCTYPE_DES_CBC_CRC 0x0001 /* DES cbc mode with CRC-32 */
107#define ENCTYPE_DES_CBC_MD4 0x0002 /* DES cbc mode with RSA-MD4 */
108#define ENCTYPE_DES_CBC_MD5 0x0003 /* DES cbc mode with RSA-MD5 */
109#define ENCTYPE_DES_CBC_RAW 0x0004 /* DES cbc mode raw */
110/* XXX deprecated? */
111#define ENCTYPE_DES3_CBC_SHA 0x0005 /* DES-3 cbc mode with NIST-SHA */
112#define ENCTYPE_DES3_CBC_RAW 0x0006 /* DES-3 cbc mode raw */
113#define ENCTYPE_DES_HMAC_SHA1 0x0008
114#define ENCTYPE_DES3_CBC_SHA1 0x0010
115#define ENCTYPE_UNKNOWN 0x01ff
116
117s32
118make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
119 struct xdr_netobj *cksum);
120
121u32
122krb5_make_token(struct krb5_ctx *context_handle, int qop_req,
123 struct xdr_buf *input_message_buffer,
124 struct xdr_netobj *output_message_buffer, int toktype);
125
126u32
127krb5_read_token(struct krb5_ctx *context_handle,
128 struct xdr_netobj *input_token_buffer,
129 struct xdr_buf *message_buffer,
130 int *qop_state, int toktype);
131
132u32
133krb5_encrypt(struct crypto_tfm * key,
134 void *iv, void *in, void *out, int length);
135
136u32
137krb5_decrypt(struct crypto_tfm * key,
138 void *iv, void *in, void *out, int length);
139
140s32
141krb5_make_seq_num(struct crypto_tfm * key,
142 int direction,
143 s32 seqnum, unsigned char *cksum, unsigned char *buf);
144
145s32
146krb5_get_seq_num(struct crypto_tfm * key,
147 unsigned char *cksum,
148 unsigned char *buf, int *direction, s32 * seqnum);
diff --git a/include/linux/sunrpc/gss_spkm3.h b/include/linux/sunrpc/gss_spkm3.h
new file mode 100644
index 000000000000..b5c9968c3c17
--- /dev/null
+++ b/include/linux/sunrpc/gss_spkm3.h
@@ -0,0 +1,61 @@
1/*
2 * linux/include/linux/sunrpc/gss_spkm3.h
3 *
4 * Copyright (c) 2000 The Regents of the University of Michigan.
5 * All rights reserved.
6 *
7 * Andy Adamson <andros@umich.edu>
8 */
9
10#include <linux/sunrpc/auth_gss.h>
11#include <linux/sunrpc/gss_err.h>
12#include <linux/sunrpc/gss_asn1.h>
13
14struct spkm3_ctx {
15 struct xdr_netobj ctx_id; /* per message context id */
16 int qop; /* negotiated qop */
17 struct xdr_netobj mech_used;
18 unsigned int ret_flags ;
19 unsigned int req_flags ;
20 struct xdr_netobj share_key;
21 int conf_alg;
22 struct crypto_tfm* derived_conf_key;
23 int intg_alg;
24 struct crypto_tfm* derived_integ_key;
25 int keyestb_alg; /* alg used to get share_key */
26 int owf_alg; /* one way function */
27};
28
29/* from openssl/objects.h */
30/* XXX need SEAL_ALG_NONE */
31#define NID_md5 4
32#define NID_dhKeyAgreement 28
33#define NID_des_cbc 31
34#define NID_sha1 64
35#define NID_cast5_cbc 108
36
37/* SPKM InnerContext Token types */
38
39#define SPKM_ERROR_TOK 3
40#define SPKM_MIC_TOK 4
41#define SPKM_WRAP_TOK 5
42#define SPKM_DEL_TOK 6
43
44u32 spkm3_make_token(struct spkm3_ctx *ctx, int qop_req, struct xdr_buf * text, struct xdr_netobj * token, int toktype);
45
46u32 spkm3_read_token(struct spkm3_ctx *ctx, struct xdr_netobj *read_token, struct xdr_buf *message_buffer, int *qop_state, int toktype);
47
48#define CKSUMTYPE_RSA_MD5 0x0007
49
50s32 make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
51 struct xdr_netobj *cksum);
52void asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits);
53int decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen,
54 int explen);
55void spkm3_mic_header(unsigned char **hdrbuf, unsigned int *hdrlen,
56 unsigned char *ctxhdr, int elen, int zbit);
57void spkm3_make_mic_token(unsigned char **tokp, int toklen,
58 struct xdr_netobj *mic_hdr,
59 struct xdr_netobj *md5cksum, int md5elen, int md5zbit);
60u32 spkm3_verify_mic_token(unsigned char **tokp, int *mic_hdrlen,
61 unsigned char **cksum);
diff --git a/include/linux/sunrpc/msg_prot.h b/include/linux/sunrpc/msg_prot.h
new file mode 100644
index 000000000000..15f115332389
--- /dev/null
+++ b/include/linux/sunrpc/msg_prot.h
@@ -0,0 +1,80 @@
1/*
2 * linux/include/net/sunrpc/msg_prot.h
3 *
4 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
5 */
6
7#ifndef _LINUX_SUNRPC_MSGPROT_H_
8#define _LINUX_SUNRPC_MSGPROT_H_
9
10#ifdef __KERNEL__ /* user programs should get these from the rpc header files */
11
12#define RPC_VERSION 2
13
14/* spec defines authentication flavor as an unsigned 32 bit integer */
15typedef u32 rpc_authflavor_t;
16
17enum rpc_auth_flavors {
18 RPC_AUTH_NULL = 0,
19 RPC_AUTH_UNIX = 1,
20 RPC_AUTH_SHORT = 2,
21 RPC_AUTH_DES = 3,
22 RPC_AUTH_KRB = 4,
23 RPC_AUTH_GSS = 6,
24 RPC_AUTH_MAXFLAVOR = 8,
25 /* pseudoflavors: */
26 RPC_AUTH_GSS_KRB5 = 390003,
27 RPC_AUTH_GSS_KRB5I = 390004,
28 RPC_AUTH_GSS_KRB5P = 390005,
29 RPC_AUTH_GSS_LKEY = 390006,
30 RPC_AUTH_GSS_LKEYI = 390007,
31 RPC_AUTH_GSS_LKEYP = 390008,
32 RPC_AUTH_GSS_SPKM = 390009,
33 RPC_AUTH_GSS_SPKMI = 390010,
34 RPC_AUTH_GSS_SPKMP = 390011,
35};
36
37enum rpc_msg_type {
38 RPC_CALL = 0,
39 RPC_REPLY = 1
40};
41
42enum rpc_reply_stat {
43 RPC_MSG_ACCEPTED = 0,
44 RPC_MSG_DENIED = 1
45};
46
47enum rpc_accept_stat {
48 RPC_SUCCESS = 0,
49 RPC_PROG_UNAVAIL = 1,
50 RPC_PROG_MISMATCH = 2,
51 RPC_PROC_UNAVAIL = 3,
52 RPC_GARBAGE_ARGS = 4,
53 RPC_SYSTEM_ERR = 5
54};
55
56enum rpc_reject_stat {
57 RPC_MISMATCH = 0,
58 RPC_AUTH_ERROR = 1
59};
60
61enum rpc_auth_stat {
62 RPC_AUTH_OK = 0,
63 RPC_AUTH_BADCRED = 1,
64 RPC_AUTH_REJECTEDCRED = 2,
65 RPC_AUTH_BADVERF = 3,
66 RPC_AUTH_REJECTEDVERF = 4,
67 RPC_AUTH_TOOWEAK = 5,
68 /* RPCSEC_GSS errors */
69 RPCSEC_GSS_CREDPROBLEM = 13,
70 RPCSEC_GSS_CTXPROBLEM = 14
71};
72
73#define RPC_PMAP_PROGRAM 100000
74#define RPC_PMAP_VERSION 2
75#define RPC_PMAP_PORT 111
76
77#define RPC_MAXNETNAMELEN 256
78
79#endif /* __KERNEL__ */
80#endif /* _LINUX_SUNRPC_MSGPROT_H_ */
diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
new file mode 100644
index 000000000000..63929349571f
--- /dev/null
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -0,0 +1,50 @@
1#ifndef _LINUX_SUNRPC_RPC_PIPE_FS_H
2#define _LINUX_SUNRPC_RPC_PIPE_FS_H
3
4#ifdef __KERNEL__
5
6struct rpc_pipe_msg {
7 struct list_head list;
8 void *data;
9 size_t len;
10 size_t copied;
11 int errno;
12};
13
14struct rpc_pipe_ops {
15 ssize_t (*upcall)(struct file *, struct rpc_pipe_msg *, char __user *, size_t);
16 ssize_t (*downcall)(struct file *, const char __user *, size_t);
17 void (*release_pipe)(struct inode *);
18 void (*destroy_msg)(struct rpc_pipe_msg *);
19};
20
21struct rpc_inode {
22 struct inode vfs_inode;
23 void *private;
24 struct list_head pipe;
25 struct list_head in_upcall;
26 int pipelen;
27 int nreaders;
28 int nwriters;
29 wait_queue_head_t waitq;
30#define RPC_PIPE_WAIT_FOR_OPEN 1
31 int flags;
32 struct rpc_pipe_ops *ops;
33 struct work_struct queue_timeout;
34};
35
36static inline struct rpc_inode *
37RPC_I(struct inode *inode)
38{
39 return container_of(inode, struct rpc_inode, vfs_inode);
40}
41
42extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
43
44extern struct dentry *rpc_mkdir(char *, struct rpc_clnt *);
45extern int rpc_rmdir(char *);
46extern struct dentry *rpc_mkpipe(char *, void *, struct rpc_pipe_ops *, int flags);
47extern int rpc_unlink(char *);
48
49#endif
50#endif
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
new file mode 100644
index 000000000000..99d17ed7cebb
--- /dev/null
+++ b/include/linux/sunrpc/sched.h
@@ -0,0 +1,273 @@
1/*
2 * linux/include/linux/sunrpc/sched.h
3 *
4 * Scheduling primitives for kernel Sun RPC.
5 *
6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
7 */
8
9#ifndef _LINUX_SUNRPC_SCHED_H_
10#define _LINUX_SUNRPC_SCHED_H_
11
12#include <linux/timer.h>
13#include <linux/sunrpc/types.h>
14#include <linux/spinlock.h>
15#include <linux/wait.h>
16#include <linux/workqueue.h>
17#include <linux/sunrpc/xdr.h>
18
19/*
20 * This is the actual RPC procedure call info.
21 */
22struct rpc_procinfo;
23struct rpc_message {
24 struct rpc_procinfo * rpc_proc; /* Procedure information */
25 void * rpc_argp; /* Arguments */
26 void * rpc_resp; /* Result */
27 struct rpc_cred * rpc_cred; /* Credentials */
28};
29
30struct rpc_wait_queue;
31struct rpc_wait {
32 struct list_head list; /* wait queue links */
33 struct list_head links; /* Links to related tasks */
34 wait_queue_head_t waitq; /* sync: sleep on this q */
35 struct rpc_wait_queue * rpc_waitq; /* RPC wait queue we're on */
36};
37
38/*
39 * This is the RPC task struct
40 */
41struct rpc_task {
42#ifdef RPC_DEBUG
43 unsigned long tk_magic; /* 0xf00baa */
44#endif
45 struct list_head tk_task; /* global list of tasks */
46 struct rpc_clnt * tk_client; /* RPC client */
47 struct rpc_rqst * tk_rqstp; /* RPC request */
48 int tk_status; /* result of last operation */
49
50 /*
51 * RPC call state
52 */
53 struct rpc_message tk_msg; /* RPC call info */
54 __u32 * tk_buffer; /* XDR buffer */
55 size_t tk_bufsize;
56 __u8 tk_garb_retry;
57 __u8 tk_cred_retry;
58
59 unsigned long tk_cookie; /* Cookie for batching tasks */
60
61 /*
62 * timeout_fn to be executed by timer bottom half
63 * callback to be executed after waking up
64 * action next procedure for async tasks
65 * exit exit async task and report to caller
66 */
67 void (*tk_timeout_fn)(struct rpc_task *);
68 void (*tk_callback)(struct rpc_task *);
69 void (*tk_action)(struct rpc_task *);
70 void (*tk_exit)(struct rpc_task *);
71 void (*tk_release)(struct rpc_task *);
72 void * tk_calldata;
73
74 /*
75 * tk_timer is used for async processing by the RPC scheduling
76 * primitives. You should not access this directly unless
77 * you have a pathological interest in kernel oopses.
78 */
79 struct timer_list tk_timer; /* kernel timer */
80 unsigned long tk_timeout; /* timeout for rpc_sleep() */
81 unsigned short tk_flags; /* misc flags */
82 unsigned char tk_active : 1;/* Task has been activated */
83 unsigned char tk_priority : 2;/* Task priority */
84 unsigned long tk_runstate; /* Task run status */
85 struct workqueue_struct *tk_workqueue; /* Normally rpciod, but could
86 * be any workqueue
87 */
88 union {
89 struct work_struct tk_work; /* Async task work queue */
90 struct rpc_wait tk_wait; /* RPC wait */
91 } u;
92#ifdef RPC_DEBUG
93 unsigned short tk_pid; /* debugging aid */
94#endif
95};
96#define tk_auth tk_client->cl_auth
97#define tk_xprt tk_client->cl_xprt
98
99/* support walking a list of tasks on a wait queue */
100#define task_for_each(task, pos, head) \
101 list_for_each(pos, head) \
102 if ((task=list_entry(pos, struct rpc_task, u.tk_wait.list)),1)
103
104#define task_for_first(task, head) \
105 if (!list_empty(head) && \
106 ((task=list_entry((head)->next, struct rpc_task, u.tk_wait.list)),1))
107
108/* .. and walking list of all tasks */
109#define alltask_for_each(task, pos, head) \
110 list_for_each(pos, head) \
111 if ((task=list_entry(pos, struct rpc_task, tk_task)),1)
112
113typedef void (*rpc_action)(struct rpc_task *);
114
115/*
116 * RPC task flags
117 */
118#define RPC_TASK_ASYNC 0x0001 /* is an async task */
119#define RPC_TASK_SWAPPER 0x0002 /* is swapping in/out */
120#define RPC_TASK_CHILD 0x0008 /* is child of other task */
121#define RPC_CALL_MAJORSEEN 0x0020 /* major timeout seen */
122#define RPC_TASK_ROOTCREDS 0x0040 /* force root creds */
123#define RPC_TASK_DYNAMIC 0x0080 /* task was kmalloc'ed */
124#define RPC_TASK_KILLED 0x0100 /* task was killed */
125#define RPC_TASK_SOFT 0x0200 /* Use soft timeouts */
126#define RPC_TASK_NOINTR 0x0400 /* uninterruptible task */
127
128#define RPC_IS_ASYNC(t) ((t)->tk_flags & RPC_TASK_ASYNC)
129#define RPC_IS_CHILD(t) ((t)->tk_flags & RPC_TASK_CHILD)
130#define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER)
131#define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS)
132#define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED)
133#define RPC_IS_ACTIVATED(t) ((t)->tk_active)
134#define RPC_DO_CALLBACK(t) ((t)->tk_callback != NULL)
135#define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT)
136#define RPC_TASK_UNINTERRUPTIBLE(t) ((t)->tk_flags & RPC_TASK_NOINTR)
137
138#define RPC_TASK_RUNNING 0
139#define RPC_TASK_QUEUED 1
140#define RPC_TASK_WAKEUP 2
141#define RPC_TASK_HAS_TIMER 3
142
143#define RPC_IS_RUNNING(t) (test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
144#define rpc_set_running(t) (set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
145#define rpc_test_and_set_running(t) \
146 (test_and_set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
147#define rpc_clear_running(t) \
148 do { \
149 smp_mb__before_clear_bit(); \
150 clear_bit(RPC_TASK_RUNNING, &(t)->tk_runstate); \
151 smp_mb__after_clear_bit(); \
152 } while (0)
153
154#define RPC_IS_QUEUED(t) (test_bit(RPC_TASK_QUEUED, &(t)->tk_runstate))
155#define rpc_set_queued(t) (set_bit(RPC_TASK_QUEUED, &(t)->tk_runstate))
156#define rpc_clear_queued(t) \
157 do { \
158 smp_mb__before_clear_bit(); \
159 clear_bit(RPC_TASK_QUEUED, &(t)->tk_runstate); \
160 smp_mb__after_clear_bit(); \
161 } while (0)
162
163#define rpc_start_wakeup(t) \
164 (test_and_set_bit(RPC_TASK_WAKEUP, &(t)->tk_runstate) == 0)
165#define rpc_finish_wakeup(t) \
166 do { \
167 smp_mb__before_clear_bit(); \
168 clear_bit(RPC_TASK_WAKEUP, &(t)->tk_runstate); \
169 smp_mb__after_clear_bit(); \
170 } while (0)
171
172/*
173 * Task priorities.
174 * Note: if you change these, you must also change
175 * the task initialization definitions below.
176 */
177#define RPC_PRIORITY_LOW 0
178#define RPC_PRIORITY_NORMAL 1
179#define RPC_PRIORITY_HIGH 2
180#define RPC_NR_PRIORITY (RPC_PRIORITY_HIGH+1)
181
182/*
183 * RPC synchronization objects
184 */
185struct rpc_wait_queue {
186 spinlock_t lock;
187 struct list_head tasks[RPC_NR_PRIORITY]; /* task queue for each priority level */
188 unsigned long cookie; /* cookie of last task serviced */
189 unsigned char maxpriority; /* maximum priority (0 if queue is not a priority queue) */
190 unsigned char priority; /* current priority */
191 unsigned char count; /* # task groups remaining serviced so far */
192 unsigned char nr; /* # tasks remaining for cookie */
193#ifdef RPC_DEBUG
194 const char * name;
195#endif
196};
197
198/*
199 * This is the # requests to send consecutively
200 * from a single cookie. The aim is to improve
201 * performance of NFS operations such as read/write.
202 */
203#define RPC_BATCH_COUNT 16
204
205#ifndef RPC_DEBUG
206# define RPC_WAITQ_INIT(var,qname) { \
207 .lock = SPIN_LOCK_UNLOCKED, \
208 .tasks = { \
209 [0] = LIST_HEAD_INIT(var.tasks[0]), \
210 [1] = LIST_HEAD_INIT(var.tasks[1]), \
211 [2] = LIST_HEAD_INIT(var.tasks[2]), \
212 }, \
213 }
214#else
215# define RPC_WAITQ_INIT(var,qname) { \
216 .lock = SPIN_LOCK_UNLOCKED, \
217 .tasks = { \
218 [0] = LIST_HEAD_INIT(var.tasks[0]), \
219 [1] = LIST_HEAD_INIT(var.tasks[1]), \
220 [2] = LIST_HEAD_INIT(var.tasks[2]), \
221 }, \
222 .name = qname, \
223 }
224#endif
225# define RPC_WAITQ(var,qname) struct rpc_wait_queue var = RPC_WAITQ_INIT(var,qname)
226
227#define RPC_IS_PRIORITY(q) ((q)->maxpriority > 0)
228
229/*
230 * Function prototypes
231 */
232struct rpc_task *rpc_new_task(struct rpc_clnt *, rpc_action, int flags);
233struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent);
234void rpc_init_task(struct rpc_task *, struct rpc_clnt *,
235 rpc_action exitfunc, int flags);
236void rpc_release_task(struct rpc_task *);
237void rpc_killall_tasks(struct rpc_clnt *);
238int rpc_execute(struct rpc_task *);
239void rpc_run_child(struct rpc_task *parent, struct rpc_task *child,
240 rpc_action action);
241void rpc_init_priority_wait_queue(struct rpc_wait_queue *, const char *);
242void rpc_init_wait_queue(struct rpc_wait_queue *, const char *);
243void rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *,
244 rpc_action action, rpc_action timer);
245void rpc_wake_up_task(struct rpc_task *);
246void rpc_wake_up(struct rpc_wait_queue *);
247struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *);
248void rpc_wake_up_status(struct rpc_wait_queue *, int);
249void rpc_delay(struct rpc_task *, unsigned long);
250void * rpc_malloc(struct rpc_task *, size_t);
251int rpciod_up(void);
252void rpciod_down(void);
253void rpciod_wake_up(void);
254#ifdef RPC_DEBUG
255void rpc_show_tasks(void);
256#endif
257int rpc_init_mempool(void);
258void rpc_destroy_mempool(void);
259
260static inline void rpc_exit(struct rpc_task *task, int status)
261{
262 task->tk_status = status;
263 task->tk_action = NULL;
264}
265
266#ifdef RPC_DEBUG
267static inline const char * rpc_qname(struct rpc_wait_queue *q)
268{
269 return ((q && q->name) ? q->name : "unknown");
270}
271#endif
272
273#endif /* _LINUX_SUNRPC_SCHED_H_ */
diff --git a/include/linux/sunrpc/stats.h b/include/linux/sunrpc/stats.h
new file mode 100644
index 000000000000..0d6ed3c8bdc4
--- /dev/null
+++ b/include/linux/sunrpc/stats.h
@@ -0,0 +1,78 @@
1/*
2 * linux/include/linux/sunrpc/stats.h
3 *
4 * Client statistics collection for SUN RPC
5 *
6 * Copyright (C) 1996 Olaf Kirch <okir@monad.swb.de>
7 */
8
9#ifndef _LINUX_SUNRPC_STATS_H
10#define _LINUX_SUNRPC_STATS_H
11
12#include <linux/config.h>
13#include <linux/proc_fs.h>
14
15struct rpc_stat {
16 struct rpc_program * program;
17
18 unsigned int netcnt,
19 netudpcnt,
20 nettcpcnt,
21 nettcpconn,
22 netreconn;
23 unsigned int rpccnt,
24 rpcretrans,
25 rpcauthrefresh,
26 rpcgarbage;
27};
28
29struct svc_stat {
30 struct svc_program * program;
31
32 unsigned int netcnt,
33 netudpcnt,
34 nettcpcnt,
35 nettcpconn;
36 unsigned int rpccnt,
37 rpcbadfmt,
38 rpcbadauth,
39 rpcbadclnt;
40};
41
42void rpc_proc_init(void);
43void rpc_proc_exit(void);
44#ifdef MODULE
45void rpc_modcount(struct inode *, int);
46#endif
47
48#ifdef CONFIG_PROC_FS
49struct proc_dir_entry * rpc_proc_register(struct rpc_stat *);
50void rpc_proc_unregister(const char *);
51void rpc_proc_zero(struct rpc_program *);
52struct proc_dir_entry * svc_proc_register(struct svc_stat *,
53 struct file_operations *);
54void svc_proc_unregister(const char *);
55
56void svc_seq_show(struct seq_file *,
57 const struct svc_stat *);
58
59extern struct proc_dir_entry *proc_net_rpc;
60
61#else
62
63static inline struct proc_dir_entry *rpc_proc_register(struct rpc_stat *s) { return NULL; }
64static inline void rpc_proc_unregister(const char *p) {}
65static inline void rpc_proc_zero(struct rpc_program *p) {}
66
67static inline struct proc_dir_entry *svc_proc_register(struct svc_stat *s,
68 struct file_operations *f) { return NULL; }
69static inline void svc_proc_unregister(const char *p) {}
70
71static inline void svc_seq_show(struct seq_file *seq,
72 const struct svc_stat *st) {}
73
74#define proc_net_rpc NULL
75
76#endif
77
78#endif /* _LINUX_SUNRPC_STATS_H */
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
new file mode 100644
index 000000000000..37003970cf2e
--- /dev/null
+++ b/include/linux/sunrpc/svc.h
@@ -0,0 +1,306 @@
1/*
2 * linux/include/linux/sunrpc/svc.h
3 *
4 * RPC server declarations.
5 *
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7 */
8
9
10#ifndef SUNRPC_SVC_H
11#define SUNRPC_SVC_H
12
13#include <linux/in.h>
14#include <linux/sunrpc/types.h>
15#include <linux/sunrpc/xdr.h>
16#include <linux/sunrpc/svcauth.h>
17#include <linux/wait.h>
18#include <linux/mm.h>
19
20/*
21 * RPC service.
22 *
23 * An RPC service is a ``daemon,'' possibly multithreaded, which
24 * receives and processes incoming RPC messages.
25 * It has one or more transport sockets associated with it, and maintains
26 * a list of idle threads waiting for input.
27 *
28 * We currently do not support more than one RPC program per daemon.
29 */
30struct svc_serv {
31 struct list_head sv_threads; /* idle server threads */
32 struct list_head sv_sockets; /* pending sockets */
33 struct svc_program * sv_program; /* RPC program */
34 struct svc_stat * sv_stats; /* RPC statistics */
35 spinlock_t sv_lock;
36 unsigned int sv_nrthreads; /* # of server threads */
37 unsigned int sv_bufsz; /* datagram buffer size */
38 unsigned int sv_xdrsize; /* XDR buffer size */
39
40 struct list_head sv_permsocks; /* all permanent sockets */
41 struct list_head sv_tempsocks; /* all temporary sockets */
42 int sv_tmpcnt; /* count of temporary sockets */
43
44 char * sv_name; /* service name */
45};
46
47/*
48 * Maximum payload size supported by a kernel RPC server.
49 * This is use to determine the max number of pages nfsd is
50 * willing to return in a single READ operation.
51 */
52#define RPCSVC_MAXPAYLOAD (64*1024u)
53
54/*
55 * RPC Requsts and replies are stored in one or more pages.
56 * We maintain an array of pages for each server thread.
57 * Requests are copied into these pages as they arrive. Remaining
58 * pages are available to write the reply into.
59 *
60 * Pages are sent using ->sendpage so each server thread needs to
61 * allocate more to replace those used in sending. To help keep track
62 * of these pages we have a receive list where all pages initialy live,
63 * and a send list where pages are moved to when there are to be part
64 * of a reply.
65 *
66 * We use xdr_buf for holding responses as it fits well with NFS
67 * read responses (that have a header, and some data pages, and possibly
68 * a tail) and means we can share some client side routines.
69 *
70 * The xdr_buf.head kvec always points to the first page in the rq_*pages
71 * list. The xdr_buf.pages pointer points to the second page on that
72 * list. xdr_buf.tail points to the end of the first page.
73 * This assumes that the non-page part of an rpc reply will fit
74 * in a page - NFSd ensures this. lockd also has no trouble.
75 *
76 * Each request/reply pair can have at most one "payload", plus two pages,
77 * one for the request, and one for the reply.
78 */
79#define RPCSVC_MAXPAGES ((RPCSVC_MAXPAYLOAD+PAGE_SIZE-1)/PAGE_SIZE + 2)
80
81static inline u32 svc_getu32(struct kvec *iov)
82{
83 u32 val, *vp;
84 vp = iov->iov_base;
85 val = *vp++;
86 iov->iov_base = (void*)vp;
87 iov->iov_len -= sizeof(u32);
88 return val;
89}
90
91static inline void svc_ungetu32(struct kvec *iov)
92{
93 u32 *vp = (u32 *)iov->iov_base;
94 iov->iov_base = (void *)(vp - 1);
95 iov->iov_len += sizeof(*vp);
96}
97
98static inline void svc_putu32(struct kvec *iov, u32 val)
99{
100 u32 *vp = iov->iov_base + iov->iov_len;
101 *vp = val;
102 iov->iov_len += sizeof(u32);
103}
104
105
106/*
107 * The context of a single thread, including the request currently being
108 * processed.
109 * NOTE: First two items must be prev/next.
110 */
111struct svc_rqst {
112 struct list_head rq_list; /* idle list */
113 struct svc_sock * rq_sock; /* socket */
114 struct sockaddr_in rq_addr; /* peer address */
115 int rq_addrlen;
116
117 struct svc_serv * rq_server; /* RPC service definition */
118 struct svc_procedure * rq_procinfo; /* procedure info */
119 struct auth_ops * rq_authop; /* authentication flavour */
120 struct svc_cred rq_cred; /* auth info */
121 struct sk_buff * rq_skbuff; /* fast recv inet buffer */
122 struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */
123
124 struct xdr_buf rq_arg;
125 struct xdr_buf rq_res;
126 struct page * rq_argpages[RPCSVC_MAXPAGES];
127 struct page * rq_respages[RPCSVC_MAXPAGES];
128 int rq_restailpage;
129 short rq_argused; /* pages used for argument */
130 short rq_arghi; /* pages available in argument page list */
131 short rq_resused; /* pages used for result */
132
133 u32 rq_xid; /* transmission id */
134 u32 rq_prog; /* program number */
135 u32 rq_vers; /* program version */
136 u32 rq_proc; /* procedure number */
137 u32 rq_prot; /* IP protocol */
138 unsigned short
139 rq_secure : 1; /* secure port */
140
141
142 __u32 rq_daddr; /* dest addr of request - reply from here */
143
144 void * rq_argp; /* decoded arguments */
145 void * rq_resp; /* xdr'd results */
146 void * rq_auth_data; /* flavor-specific data */
147
148 int rq_reserved; /* space on socket outq
149 * reserved for this request
150 */
151
152 struct cache_req rq_chandle; /* handle passed to caches for
153 * request delaying
154 */
155 /* Catering to nfsd */
156 struct auth_domain * rq_client; /* RPC peer info */
157 struct svc_cacherep * rq_cacherep; /* cache info */
158 struct knfsd_fh * rq_reffh; /* Referrence filehandle, used to
159 * determine what device number
160 * to report (real or virtual)
161 */
162
163 wait_queue_head_t rq_wait; /* synchronization */
164};
165
166/*
167 * Check buffer bounds after decoding arguments
168 */
169static inline int
170xdr_argsize_check(struct svc_rqst *rqstp, u32 *p)
171{
172 char *cp = (char *)p;
173 struct kvec *vec = &rqstp->rq_arg.head[0];
174 return cp - (char*)vec->iov_base <= vec->iov_len;
175}
176
177static inline int
178xdr_ressize_check(struct svc_rqst *rqstp, u32 *p)
179{
180 struct kvec *vec = &rqstp->rq_res.head[0];
181 char *cp = (char*)p;
182
183 vec->iov_len = cp - (char*)vec->iov_base;
184
185 return vec->iov_len <= PAGE_SIZE;
186}
187
188static inline int svc_take_page(struct svc_rqst *rqstp)
189{
190 if (rqstp->rq_arghi <= rqstp->rq_argused)
191 return -ENOMEM;
192 rqstp->rq_arghi--;
193 rqstp->rq_respages[rqstp->rq_resused] =
194 rqstp->rq_argpages[rqstp->rq_arghi];
195 rqstp->rq_resused++;
196 return 0;
197}
198
199static inline void svc_pushback_allpages(struct svc_rqst *rqstp)
200{
201 while (rqstp->rq_resused) {
202 if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
203 continue;
204 rqstp->rq_argpages[rqstp->rq_arghi++] =
205 rqstp->rq_respages[rqstp->rq_resused];
206 rqstp->rq_respages[rqstp->rq_resused] = NULL;
207 }
208}
209
210static inline void svc_pushback_unused_pages(struct svc_rqst *rqstp)
211{
212 while (rqstp->rq_resused &&
213 rqstp->rq_res.pages != &rqstp->rq_respages[rqstp->rq_resused]) {
214
215 if (rqstp->rq_respages[--rqstp->rq_resused] != NULL) {
216 rqstp->rq_argpages[rqstp->rq_arghi++] =
217 rqstp->rq_respages[rqstp->rq_resused];
218 rqstp->rq_respages[rqstp->rq_resused] = NULL;
219 }
220 }
221}
222
223static inline void svc_free_allpages(struct svc_rqst *rqstp)
224{
225 while (rqstp->rq_resused) {
226 if (rqstp->rq_respages[--rqstp->rq_resused] == NULL)
227 continue;
228 put_page(rqstp->rq_respages[rqstp->rq_resused]);
229 rqstp->rq_respages[rqstp->rq_resused] = NULL;
230 }
231}
232
233struct svc_deferred_req {
234 u32 prot; /* protocol (UDP or TCP) */
235 struct sockaddr_in addr;
236 struct svc_sock *svsk; /* where reply must go */
237 struct cache_deferred_req handle;
238 int argslen;
239 u32 args[0];
240};
241
242/*
243 * RPC program
244 */
245struct svc_program {
246 u32 pg_prog; /* program number */
247 unsigned int pg_lovers; /* lowest version */
248 unsigned int pg_hivers; /* lowest version */
249 unsigned int pg_nvers; /* number of versions */
250 struct svc_version ** pg_vers; /* version array */
251 char * pg_name; /* service name */
252 char * pg_class; /* class name: services sharing authentication */
253 struct svc_stat * pg_stats; /* rpc statistics */
254 int (*pg_authenticate)(struct svc_rqst *);
255};
256
257/*
258 * RPC program version
259 */
260struct svc_version {
261 u32 vs_vers; /* version number */
262 u32 vs_nproc; /* number of procedures */
263 struct svc_procedure * vs_proc; /* per-procedure info */
264 u32 vs_xdrsize; /* xdrsize needed for this version */
265
266 /* Override dispatch function (e.g. when caching replies).
267 * A return value of 0 means drop the request.
268 * vs_dispatch == NULL means use default dispatcher.
269 */
270 int (*vs_dispatch)(struct svc_rqst *, u32 *);
271};
272
273/*
274 * RPC procedure info
275 */
276typedef int (*svc_procfunc)(struct svc_rqst *, void *argp, void *resp);
277struct svc_procedure {
278 svc_procfunc pc_func; /* process the request */
279 kxdrproc_t pc_decode; /* XDR decode args */
280 kxdrproc_t pc_encode; /* XDR encode result */
281 kxdrproc_t pc_release; /* XDR free result */
282 unsigned int pc_argsize; /* argument struct size */
283 unsigned int pc_ressize; /* result struct size */
284 unsigned int pc_count; /* call count */
285 unsigned int pc_cachetype; /* cache info (NFS) */
286 unsigned int pc_xdrressize; /* maximum size of XDR reply */
287};
288
289/*
290 * This is the RPC server thread function prototype
291 */
292typedef void (*svc_thread_fn)(struct svc_rqst *);
293
294/*
295 * Function prototypes.
296 */
297struct svc_serv * svc_create(struct svc_program *, unsigned int);
298int svc_create_thread(svc_thread_fn, struct svc_serv *);
299void svc_exit_thread(struct svc_rqst *);
300void svc_destroy(struct svc_serv *);
301int svc_process(struct svc_serv *, struct svc_rqst *);
302int svc_register(struct svc_serv *, int, unsigned short);
303void svc_wake_up(struct svc_serv *);
304void svc_reserve(struct svc_rqst *rqstp, int space);
305
306#endif /* SUNRPC_SVC_H */
diff --git a/include/linux/sunrpc/svcauth.h b/include/linux/sunrpc/svcauth.h
new file mode 100644
index 000000000000..c119ce7cbd22
--- /dev/null
+++ b/include/linux/sunrpc/svcauth.h
@@ -0,0 +1,167 @@
1/*
2 * linux/include/linux/sunrpc/svcauth.h
3 *
4 * RPC server-side authentication stuff.
5 *
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7 */
8
9#ifndef _LINUX_SUNRPC_SVCAUTH_H_
10#define _LINUX_SUNRPC_SVCAUTH_H_
11
12#ifdef __KERNEL__
13
14#include <linux/string.h>
15#include <linux/sunrpc/msg_prot.h>
16#include <linux/sunrpc/cache.h>
17#include <linux/hash.h>
18
19#define SVC_CRED_NGROUPS 32
20struct svc_cred {
21 uid_t cr_uid;
22 gid_t cr_gid;
23 struct group_info *cr_group_info;
24};
25
26struct svc_rqst; /* forward decl */
27
28/* Authentication is done in the context of a domain.
29 *
30 * Currently, the nfs server uses the auth_domain to stand
31 * for the "client" listed in /etc/exports.
32 *
33 * More generally, a domain might represent a group of clients using
34 * a common mechanism for authentication and having a common mapping
35 * between local identity (uid) and network identity. All clients
36 * in a domain have similar general access rights. Each domain can
37 * contain multiple principals which will have different specific right
38 * based on normal Discretionary Access Control.
39 *
40 * A domain is created by an authentication flavour module based on name
41 * only. Userspace then fills in detail on demand.
42 *
43 * In the case of auth_unix and auth_null, the auth_domain is also
44 * associated with entries in another cache representing the mapping
45 * of ip addresses to the given client.
46 */
47struct auth_domain {
48 struct cache_head h;
49 char *name;
50 int flavour;
51};
52
53/*
54 * Each authentication flavour registers an auth_ops
55 * structure.
56 * name is simply the name.
57 * flavour gives the auth flavour. It determines where the flavour is registered
58 * accept() is given a request and should verify it.
59 * It should inspect the authenticator and verifier, and possibly the data.
60 * If there is a problem with the authentication *authp should be set.
61 * The return value of accept() can indicate:
62 * OK - authorised. client and credential are set in rqstp.
63 * reqbuf points to arguments
64 * resbuf points to good place for results. verfier
65 * is (probably) already in place. Certainly space is
66 * reserved for it.
67 * DROP - simply drop the request. It may have been deferred
68 * GARBAGE - rpc garbage_args error
69 * SYSERR - rpc system_err error
70 * DENIED - authp holds reason for denial.
71 * COMPLETE - the reply is encoded already and ready to be sent; no
72 * further processing is necessary. (This is used for processing
73 * null procedure calls which are used to set up encryption
74 * contexts.)
75 *
76 * accept is passed the proc number so that it can accept NULL rpc requests
77 * even if it cannot authenticate the client (as is sometimes appropriate).
78 *
79 * release() is given a request after the procedure has been run.
80 * It should sign/encrypt the results if needed
81 * It should return:
82 * OK - the resbuf is ready to be sent
83 * DROP - the reply should be quitely dropped
84 * DENIED - authp holds a reason for MSG_DENIED
85 * SYSERR - rpc system_err
86 *
87 * domain_release()
88 * This call releases a domain.
89 */
90struct auth_ops {
91 char * name;
92 struct module *owner;
93 int flavour;
94 int (*accept)(struct svc_rqst *rq, u32 *authp);
95 int (*release)(struct svc_rqst *rq);
96 void (*domain_release)(struct auth_domain *);
97 int (*set_client)(struct svc_rqst *rq);
98};
99
100#define SVC_GARBAGE 1
101#define SVC_SYSERR 2
102#define SVC_VALID 3
103#define SVC_NEGATIVE 4
104#define SVC_OK 5
105#define SVC_DROP 6
106#define SVC_DENIED 7
107#define SVC_PENDING 8
108#define SVC_COMPLETE 9
109
110
111extern int svc_authenticate(struct svc_rqst *rqstp, u32 *authp);
112extern int svc_authorise(struct svc_rqst *rqstp);
113extern int svc_set_client(struct svc_rqst *rqstp);
114extern int svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops);
115extern void svc_auth_unregister(rpc_authflavor_t flavor);
116
117extern struct auth_domain *unix_domain_find(char *name);
118extern void auth_domain_put(struct auth_domain *item);
119extern int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom);
120extern struct auth_domain *auth_domain_lookup(struct auth_domain *item, int set);
121extern struct auth_domain *auth_domain_find(char *name);
122extern struct auth_domain *auth_unix_lookup(struct in_addr addr);
123extern int auth_unix_forget_old(struct auth_domain *dom);
124extern void svcauth_unix_purge(void);
125
126static inline unsigned long hash_str(char *name, int bits)
127{
128 unsigned long hash = 0;
129 unsigned long l = 0;
130 int len = 0;
131 unsigned char c;
132 do {
133 if (unlikely(!(c = *name++))) {
134 c = (char)len; len = -1;
135 }
136 l = (l << 8) | c;
137 len++;
138 if ((len & (BITS_PER_LONG/8-1))==0)
139 hash = hash_long(hash^l, BITS_PER_LONG);
140 } while (len);
141 return hash >> (BITS_PER_LONG - bits);
142}
143
144static inline unsigned long hash_mem(char *buf, int length, int bits)
145{
146 unsigned long hash = 0;
147 unsigned long l = 0;
148 int len = 0;
149 unsigned char c;
150 do {
151 if (len == length) {
152 c = (char)len; len = -1;
153 } else
154 c = *buf++;
155 l = (l << 8) | c;
156 len++;
157 if ((len & (BITS_PER_LONG/8-1))==0)
158 hash = hash_long(hash^l, BITS_PER_LONG);
159 } while (len);
160 return hash >> (BITS_PER_LONG - bits);
161}
162
163extern struct cache_detail auth_domain_cache, ip_map_cache;
164
165#endif /* __KERNEL__ */
166
167#endif /* _LINUX_SUNRPC_SVCAUTH_H_ */
diff --git a/include/linux/sunrpc/svcauth_gss.h b/include/linux/sunrpc/svcauth_gss.h
new file mode 100644
index 000000000000..3a2206f61de0
--- /dev/null
+++ b/include/linux/sunrpc/svcauth_gss.h
@@ -0,0 +1,27 @@
1/*
2 * linux/include/linux/svcauth_gss.h
3 *
4 * Bruce Fields <bfields@umich.edu>
5 * Copyright (c) 2002 The Regents of the Unviersity of Michigan
6 *
7 * $Id$
8 *
9 */
10
11#ifndef _LINUX_SUNRPC_SVCAUTH_GSS_H
12#define _LINUX_SUNRPC_SVCAUTH_GSS_H
13
14#ifdef __KERNEL__
15#include <linux/sched.h>
16#include <linux/sunrpc/types.h>
17#include <linux/sunrpc/xdr.h>
18#include <linux/sunrpc/svcauth.h>
19#include <linux/sunrpc/svcsock.h>
20#include <linux/sunrpc/auth_gss.h>
21
22int gss_svc_init(void);
23void gss_svc_shutdown(void);
24int svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name);
25
26#endif /* __KERNEL__ */
27#endif /* _LINUX_SUNRPC_SVCAUTH_GSS_H */
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
new file mode 100644
index 000000000000..d33c6face032
--- /dev/null
+++ b/include/linux/sunrpc/svcsock.h
@@ -0,0 +1,65 @@
1/*
2 * linux/include/linux/sunrpc/svcsock.h
3 *
4 * RPC server socket I/O.
5 *
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7 */
8
9#ifndef SUNRPC_SVCSOCK_H
10#define SUNRPC_SVCSOCK_H
11
12#include <linux/sunrpc/svc.h>
13
14/*
15 * RPC server socket.
16 */
17struct svc_sock {
18 struct list_head sk_ready; /* list of ready sockets */
19 struct list_head sk_list; /* list of all sockets */
20 struct socket * sk_sock; /* berkeley socket layer */
21 struct sock * sk_sk; /* INET layer */
22
23 struct svc_serv * sk_server; /* service for this socket */
24 unsigned int sk_inuse; /* use count */
25 unsigned long sk_flags;
26#define SK_BUSY 0 /* enqueued/receiving */
27#define SK_CONN 1 /* conn pending */
28#define SK_CLOSE 2 /* dead or dying */
29#define SK_DATA 3 /* data pending */
30#define SK_TEMP 4 /* temp (TCP) socket */
31#define SK_DEAD 6 /* socket closed */
32#define SK_CHNGBUF 7 /* need to change snd/rcv buffer sizes */
33#define SK_DEFERRED 8 /* request on sk_deferred */
34
35 int sk_reserved; /* space on outq that is reserved */
36
37 struct list_head sk_deferred; /* deferred requests that need to
38 * be revisted */
39 struct semaphore sk_sem; /* to serialize sending data */
40
41 int (*sk_recvfrom)(struct svc_rqst *rqstp);
42 int (*sk_sendto)(struct svc_rqst *rqstp);
43
44 /* We keep the old state_change and data_ready CB's here */
45 void (*sk_ostate)(struct sock *);
46 void (*sk_odata)(struct sock *, int bytes);
47 void (*sk_owspace)(struct sock *);
48
49 /* private TCP part */
50 int sk_reclen; /* length of record */
51 int sk_tcplen; /* current read length */
52 time_t sk_lastrecv; /* time of last received request */
53};
54
55/*
56 * Function prototypes.
57 */
58int svc_makesock(struct svc_serv *, int, unsigned short);
59void svc_delete_socket(struct svc_sock *);
60int svc_recv(struct svc_serv *, struct svc_rqst *, long);
61int svc_send(struct svc_rqst *);
62void svc_drop(struct svc_rqst *);
63void svc_sock_update_bufs(struct svc_serv *serv);
64
65#endif /* SUNRPC_SVCSOCK_H */
diff --git a/include/linux/sunrpc/timer.h b/include/linux/sunrpc/timer.h
new file mode 100644
index 000000000000..a67fd734c73b
--- /dev/null
+++ b/include/linux/sunrpc/timer.h
@@ -0,0 +1,49 @@
1/*
2 * linux/include/linux/sunrpc/timer.h
3 *
4 * Declarations for the RPC transport timer.
5 *
6 * Copyright (C) 2002 Trond Myklebust <trond.myklebust@fys.uio.no>
7 */
8
9#ifndef _LINUX_SUNRPC_TIMER_H
10#define _LINUX_SUNRPC_TIMER_H
11
12#include <asm/atomic.h>
13
14struct rpc_rtt {
15 unsigned long timeo; /* default timeout value */
16 unsigned long srtt[5]; /* smoothed round trip time << 3 */
17 unsigned long sdrtt[5]; /* smoothed medium deviation of RTT */
18 int ntimeouts[5]; /* Number of timeouts for the last request */
19};
20
21
22extern void rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo);
23extern void rpc_update_rtt(struct rpc_rtt *rt, unsigned timer, long m);
24extern unsigned long rpc_calc_rto(struct rpc_rtt *rt, unsigned timer);
25
26static inline void rpc_set_timeo(struct rpc_rtt *rt, int timer, int ntimeo)
27{
28 int *t;
29 if (!timer)
30 return;
31 t = &rt->ntimeouts[timer-1];
32 if (ntimeo < *t) {
33 if (*t > 0)
34 (*t)--;
35 } else {
36 if (ntimeo > 8)
37 ntimeo = 8;
38 *t = ntimeo;
39 }
40}
41
42static inline int rpc_ntimeo(struct rpc_rtt *rt, int timer)
43{
44 if (!timer)
45 return 0;
46 return rt->ntimeouts[timer-1];
47}
48
49#endif /* _LINUX_SUNRPC_TIMER_H */
diff --git a/include/linux/sunrpc/types.h b/include/linux/sunrpc/types.h
new file mode 100644
index 000000000000..d222f47550af
--- /dev/null
+++ b/include/linux/sunrpc/types.h
@@ -0,0 +1,22 @@
1/*
2 * linux/include/linux/sunrpc/types.h
3 *
4 * Generic types and misc stuff for RPC.
5 *
6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
7 */
8
9#ifndef _LINUX_SUNRPC_TYPES_H_
10#define _LINUX_SUNRPC_TYPES_H_
11
12#include <linux/timer.h>
13#include <linux/workqueue.h>
14#include <linux/sunrpc/debug.h>
15#include <linux/list.h>
16
17/*
18 * Shorthands
19 */
20#define signalled() (signal_pending(current))
21
22#endif /* _LINUX_SUNRPC_TYPES_H_ */
diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h
new file mode 100644
index 000000000000..541dcf838abf
--- /dev/null
+++ b/include/linux/sunrpc/xdr.h
@@ -0,0 +1,192 @@
1/*
2 * include/linux/sunrpc/xdr.h
3 *
4 * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de>
5 */
6
7#ifndef _SUNRPC_XDR_H_
8#define _SUNRPC_XDR_H_
9
10#ifdef __KERNEL__
11
12#include <linux/uio.h>
13#include <asm/byteorder.h>
14
15/*
16 * Buffer adjustment
17 */
18#define XDR_QUADLEN(l) (((l) + 3) >> 2)
19
20/*
21 * Generic opaque `network object.' At the kernel level, this type
22 * is used only by lockd.
23 */
24#define XDR_MAX_NETOBJ 1024
25struct xdr_netobj {
26 unsigned int len;
27 u8 * data;
28};
29
30/*
31 * This is the generic XDR function. rqstp is either a rpc_rqst (client
32 * side) or svc_rqst pointer (server side).
33 * Encode functions always assume there's enough room in the buffer.
34 */
35typedef int (*kxdrproc_t)(void *rqstp, u32 *data, void *obj);
36
37/*
38 * Basic structure for transmission/reception of a client XDR message.
39 * Features a header (for a linear buffer containing RPC headers
40 * and the data payload for short messages), and then an array of
41 * pages.
42 * The tail iovec allows you to append data after the page array. Its
43 * main interest is for appending padding to the pages in order to
44 * satisfy the int_32-alignment requirements in RFC1832.
45 *
46 * For the future, we might want to string several of these together
47 * in a list if anybody wants to make use of NFSv4 COMPOUND
48 * operations and/or has a need for scatter/gather involving pages.
49 */
50struct xdr_buf {
51 struct kvec head[1], /* RPC header + non-page data */
52 tail[1]; /* Appended after page data */
53
54 struct page ** pages; /* Array of contiguous pages */
55 unsigned int page_base, /* Start of page data */
56 page_len; /* Length of page data */
57
58 unsigned int buflen, /* Total length of storage buffer */
59 len; /* Length of XDR encoded message */
60
61};
62
63/*
64 * pre-xdr'ed macros.
65 */
66
67#define xdr_zero __constant_htonl(0)
68#define xdr_one __constant_htonl(1)
69#define xdr_two __constant_htonl(2)
70
71#define rpc_success __constant_htonl(RPC_SUCCESS)
72#define rpc_prog_unavail __constant_htonl(RPC_PROG_UNAVAIL)
73#define rpc_prog_mismatch __constant_htonl(RPC_PROG_MISMATCH)
74#define rpc_proc_unavail __constant_htonl(RPC_PROC_UNAVAIL)
75#define rpc_garbage_args __constant_htonl(RPC_GARBAGE_ARGS)
76#define rpc_system_err __constant_htonl(RPC_SYSTEM_ERR)
77
78#define rpc_auth_ok __constant_htonl(RPC_AUTH_OK)
79#define rpc_autherr_badcred __constant_htonl(RPC_AUTH_BADCRED)
80#define rpc_autherr_rejectedcred __constant_htonl(RPC_AUTH_REJECTEDCRED)
81#define rpc_autherr_badverf __constant_htonl(RPC_AUTH_BADVERF)
82#define rpc_autherr_rejectedverf __constant_htonl(RPC_AUTH_REJECTEDVERF)
83#define rpc_autherr_tooweak __constant_htonl(RPC_AUTH_TOOWEAK)
84#define rpcsec_gsserr_credproblem __constant_htonl(RPCSEC_GSS_CREDPROBLEM)
85#define rpcsec_gsserr_ctxproblem __constant_htonl(RPCSEC_GSS_CTXPROBLEM)
86#define rpc_autherr_oldseqnum __constant_htonl(101)
87
88/*
89 * Miscellaneous XDR helper functions
90 */
91u32 * xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int len);
92u32 * xdr_encode_opaque(u32 *p, const void *ptr, unsigned int len);
93u32 * xdr_encode_string(u32 *p, const char *s);
94u32 * xdr_decode_string(u32 *p, char **sp, int *lenp, int maxlen);
95u32 * xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen);
96u32 * xdr_encode_netobj(u32 *p, const struct xdr_netobj *);
97u32 * xdr_decode_netobj(u32 *p, struct xdr_netobj *);
98
99void xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int,
100 unsigned int);
101void xdr_inline_pages(struct xdr_buf *, unsigned int,
102 struct page **, unsigned int, unsigned int);
103
104static inline u32 *xdr_encode_array(u32 *p, const void *s, unsigned int len)
105{
106 return xdr_encode_opaque(p, s, len);
107}
108
109/*
110 * Decode 64bit quantities (NFSv3 support)
111 */
112static inline u32 *
113xdr_encode_hyper(u32 *p, __u64 val)
114{
115 *p++ = htonl(val >> 32);
116 *p++ = htonl(val & 0xFFFFFFFF);
117 return p;
118}
119
120static inline u32 *
121xdr_decode_hyper(u32 *p, __u64 *valp)
122{
123 *valp = ((__u64) ntohl(*p++)) << 32;
124 *valp |= ntohl(*p++);
125 return p;
126}
127
128/*
129 * Adjust kvec to reflect end of xdr'ed data (RPC client XDR)
130 */
131static inline int
132xdr_adjust_iovec(struct kvec *iov, u32 *p)
133{
134 return iov->iov_len = ((u8 *) p - (u8 *) iov->iov_base);
135}
136
137/*
138 * Maximum number of iov's we use.
139 */
140#define MAX_IOVEC (12)
141
142/*
143 * XDR buffer helper functions
144 */
145extern void xdr_shift_buf(struct xdr_buf *, size_t);
146extern void xdr_buf_from_iov(struct kvec *, struct xdr_buf *);
147extern int xdr_buf_subsegment(struct xdr_buf *, struct xdr_buf *, int, int);
148extern int xdr_buf_read_netobj(struct xdr_buf *, struct xdr_netobj *, int);
149extern int read_bytes_from_xdr_buf(struct xdr_buf *buf, int base, void *obj, int len);
150
151/*
152 * Helper structure for copying from an sk_buff.
153 */
154typedef struct {
155 struct sk_buff *skb;
156 unsigned int offset;
157 size_t count;
158 unsigned int csum;
159} skb_reader_t;
160
161typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len);
162
163extern void xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int,
164 skb_reader_t *, skb_read_actor_t);
165
166struct socket;
167struct sockaddr;
168extern int xdr_sendpages(struct socket *, struct sockaddr *, int,
169 struct xdr_buf *, unsigned int, int);
170
171/*
172 * Provide some simple tools for XDR buffer overflow-checking etc.
173 */
174struct xdr_stream {
175 uint32_t *p; /* start of available buffer */
176 struct xdr_buf *buf; /* XDR buffer to read/write */
177
178 uint32_t *end; /* end of available buffer space */
179 struct kvec *iov; /* pointer to the current kvec */
180};
181
182extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
183extern uint32_t *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes);
184extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages,
185 unsigned int base, unsigned int len);
186extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p);
187extern uint32_t *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes);
188extern void xdr_read_pages(struct xdr_stream *xdr, unsigned int len);
189
190#endif /* __KERNEL__ */
191
192#endif /* _SUNRPC_XDR_H_ */
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
new file mode 100644
index 000000000000..e618c1649814
--- /dev/null
+++ b/include/linux/sunrpc/xprt.h
@@ -0,0 +1,232 @@
1/*
2 * linux/include/linux/sunrpc/clnt_xprt.h
3 *
4 * Declarations for the RPC transport interface.
5 *
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7 */
8
9#ifndef _LINUX_SUNRPC_XPRT_H
10#define _LINUX_SUNRPC_XPRT_H
11
12#include <linux/uio.h>
13#include <linux/socket.h>
14#include <linux/in.h>
15#include <linux/sunrpc/sched.h>
16#include <linux/sunrpc/xdr.h>
17
18/*
19 * The transport code maintains an estimate on the maximum number of out-
20 * standing RPC requests, using a smoothed version of the congestion
21 * avoidance implemented in 44BSD. This is basically the Van Jacobson
22 * congestion algorithm: If a retransmit occurs, the congestion window is
23 * halved; otherwise, it is incremented by 1/cwnd when
24 *
25 * - a reply is received and
26 * - a full number of requests are outstanding and
27 * - the congestion window hasn't been updated recently.
28 *
29 * Upper procedures may check whether a request would block waiting for
30 * a free RPC slot by using the RPC_CONGESTED() macro.
31 */
32extern unsigned int xprt_udp_slot_table_entries;
33extern unsigned int xprt_tcp_slot_table_entries;
34
35#define RPC_MIN_SLOT_TABLE (2U)
36#define RPC_DEF_SLOT_TABLE (16U)
37#define RPC_MAX_SLOT_TABLE (128U)
38
39#define RPC_CWNDSHIFT (8U)
40#define RPC_CWNDSCALE (1U << RPC_CWNDSHIFT)
41#define RPC_INITCWND RPC_CWNDSCALE
42#define RPC_MAXCWND(xprt) ((xprt)->max_reqs << RPC_CWNDSHIFT)
43#define RPCXPRT_CONGESTED(xprt) ((xprt)->cong >= (xprt)->cwnd)
44
45/* Default timeout values */
46#define RPC_MAX_UDP_TIMEOUT (60*HZ)
47#define RPC_MAX_TCP_TIMEOUT (600*HZ)
48
49/*
50 * Wait duration for an RPC TCP connection to be established. Solaris
51 * NFS over TCP uses 60 seconds, for example, which is in line with how
52 * long a server takes to reboot.
53 */
54#define RPC_CONNECT_TIMEOUT (60*HZ)
55
56/*
57 * Delay an arbitrary number of seconds before attempting to reconnect
58 * after an error.
59 */
60#define RPC_REESTABLISH_TIMEOUT (15*HZ)
61
62/* RPC call and reply header size as number of 32bit words (verifier
63 * size computed separately)
64 */
65#define RPC_CALLHDRSIZE 6
66#define RPC_REPHDRSIZE 4
67
68/*
69 * This describes a timeout strategy
70 */
71struct rpc_timeout {
72 unsigned long to_initval, /* initial timeout */
73 to_maxval, /* max timeout */
74 to_increment; /* if !exponential */
75 unsigned int to_retries; /* max # of retries */
76 unsigned char to_exponential;
77};
78
79/*
80 * This describes a complete RPC request
81 */
82struct rpc_rqst {
83 /*
84 * This is the user-visible part
85 */
86 struct rpc_xprt * rq_xprt; /* RPC client */
87 struct xdr_buf rq_snd_buf; /* send buffer */
88 struct xdr_buf rq_rcv_buf; /* recv buffer */
89
90 /*
91 * This is the private part
92 */
93 struct rpc_task * rq_task; /* RPC task data */
94 __u32 rq_xid; /* request XID */
95 int rq_cong; /* has incremented xprt->cong */
96 int rq_received; /* receive completed */
97 u32 rq_seqno; /* gss seq no. used on req. */
98
99 struct list_head rq_list;
100
101 struct xdr_buf rq_private_buf; /* The receive buffer
102 * used in the softirq.
103 */
104 unsigned long rq_majortimeo; /* major timeout alarm */
105 unsigned long rq_timeout; /* Current timeout value */
106 unsigned int rq_retries; /* # of retries */
107 /*
108 * For authentication (e.g. auth_des)
109 */
110 u32 rq_creddata[2];
111
112 /*
113 * Partial send handling
114 */
115
116 u32 rq_bytes_sent; /* Bytes we have sent */
117
118 unsigned long rq_xtime; /* when transmitted */
119 int rq_ntrans;
120};
121#define rq_svec rq_snd_buf.head
122#define rq_slen rq_snd_buf.len
123
124#define XPRT_LAST_FRAG (1 << 0)
125#define XPRT_COPY_RECM (1 << 1)
126#define XPRT_COPY_XID (1 << 2)
127#define XPRT_COPY_DATA (1 << 3)
128
129struct rpc_xprt {
130 struct socket * sock; /* BSD socket layer */
131 struct sock * inet; /* INET layer */
132
133 struct rpc_timeout timeout; /* timeout parms */
134 struct sockaddr_in addr; /* server address */
135 int prot; /* IP protocol */
136
137 unsigned long cong; /* current congestion */
138 unsigned long cwnd; /* congestion window */
139
140 unsigned int rcvsize, /* socket receive buffer size */
141 sndsize; /* socket send buffer size */
142
143 size_t max_payload; /* largest RPC payload size,
144 in bytes */
145
146 struct rpc_wait_queue sending; /* requests waiting to send */
147 struct rpc_wait_queue resend; /* requests waiting to resend */
148 struct rpc_wait_queue pending; /* requests in flight */
149 struct rpc_wait_queue backlog; /* waiting for slot */
150 struct list_head free; /* free slots */
151 struct rpc_rqst * slot; /* slot table storage */
152 unsigned int max_reqs; /* total slots */
153 unsigned long sockstate; /* Socket state */
154 unsigned char shutdown : 1, /* being shut down */
155 nocong : 1, /* no congestion control */
156 resvport : 1, /* use a reserved port */
157 stream : 1; /* TCP */
158
159 /*
160 * XID
161 */
162 __u32 xid; /* Next XID value to use */
163
164 /*
165 * State of TCP reply receive stuff
166 */
167 u32 tcp_recm, /* Fragment header */
168 tcp_xid, /* Current XID */
169 tcp_reclen, /* fragment length */
170 tcp_offset; /* fragment offset */
171 unsigned long tcp_copied, /* copied to request */
172 tcp_flags;
173 /*
174 * Connection of sockets
175 */
176 struct work_struct sock_connect;
177 unsigned short port;
178 /*
179 * Disconnection of idle sockets
180 */
181 struct work_struct task_cleanup;
182 struct timer_list timer;
183 unsigned long last_used;
184
185 /*
186 * Send stuff
187 */
188 spinlock_t sock_lock; /* lock socket info */
189 spinlock_t xprt_lock; /* lock xprt info */
190 struct rpc_task * snd_task; /* Task blocked in send */
191
192 struct list_head recv;
193
194
195 void (*old_data_ready)(struct sock *, int);
196 void (*old_state_change)(struct sock *);
197 void (*old_write_space)(struct sock *);
198
199 wait_queue_head_t cong_wait;
200};
201
202#ifdef __KERNEL__
203
204struct rpc_xprt * xprt_create_proto(int proto, struct sockaddr_in *addr,
205 struct rpc_timeout *toparms);
206int xprt_destroy(struct rpc_xprt *);
207void xprt_set_timeout(struct rpc_timeout *, unsigned int,
208 unsigned long);
209
210void xprt_reserve(struct rpc_task *);
211int xprt_prepare_transmit(struct rpc_task *);
212void xprt_transmit(struct rpc_task *);
213void xprt_receive(struct rpc_task *);
214int xprt_adjust_timeout(struct rpc_rqst *req);
215void xprt_release(struct rpc_task *);
216void xprt_connect(struct rpc_task *);
217void xprt_sock_setbufsize(struct rpc_xprt *);
218
219#define XPRT_LOCKED 0
220#define XPRT_CONNECT 1
221#define XPRT_CONNECTING 2
222
223#define xprt_connected(xp) (test_bit(XPRT_CONNECT, &(xp)->sockstate))
224#define xprt_set_connected(xp) (set_bit(XPRT_CONNECT, &(xp)->sockstate))
225#define xprt_test_and_set_connected(xp) (test_and_set_bit(XPRT_CONNECT, &(xp)->sockstate))
226#define xprt_test_and_clear_connected(xp) \
227 (test_and_clear_bit(XPRT_CONNECT, &(xp)->sockstate))
228#define xprt_clear_connected(xp) (clear_bit(XPRT_CONNECT, &(xp)->sockstate))
229
230#endif /* __KERNEL__*/
231
232#endif /* _LINUX_SUNRPC_XPRT_H */