diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /include/linux/sunrpc |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'include/linux/sunrpc')
-rw-r--r-- | include/linux/sunrpc/auth.h | 149 | ||||
-rw-r--r-- | include/linux/sunrpc/auth_gss.h | 97 | ||||
-rw-r--r-- | include/linux/sunrpc/cache.h | 312 | ||||
-rw-r--r-- | include/linux/sunrpc/clnt.h | 153 | ||||
-rw-r--r-- | include/linux/sunrpc/debug.h | 99 | ||||
-rw-r--r-- | include/linux/sunrpc/gss_api.h | 122 | ||||
-rw-r--r-- | include/linux/sunrpc/gss_asn1.h | 81 | ||||
-rw-r--r-- | include/linux/sunrpc/gss_err.h | 177 | ||||
-rw-r--r-- | include/linux/sunrpc/gss_krb5.h | 148 | ||||
-rw-r--r-- | include/linux/sunrpc/gss_spkm3.h | 61 | ||||
-rw-r--r-- | include/linux/sunrpc/msg_prot.h | 80 | ||||
-rw-r--r-- | include/linux/sunrpc/rpc_pipe_fs.h | 50 | ||||
-rw-r--r-- | include/linux/sunrpc/sched.h | 273 | ||||
-rw-r--r-- | include/linux/sunrpc/stats.h | 78 | ||||
-rw-r--r-- | include/linux/sunrpc/svc.h | 306 | ||||
-rw-r--r-- | include/linux/sunrpc/svcauth.h | 167 | ||||
-rw-r--r-- | include/linux/sunrpc/svcauth_gss.h | 27 | ||||
-rw-r--r-- | include/linux/sunrpc/svcsock.h | 65 | ||||
-rw-r--r-- | include/linux/sunrpc/timer.h | 49 | ||||
-rw-r--r-- | include/linux/sunrpc/types.h | 22 | ||||
-rw-r--r-- | include/linux/sunrpc/xdr.h | 192 | ||||
-rw-r--r-- | include/linux/sunrpc/xprt.h | 232 |
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 */ | ||
28 | struct auth_cred { | ||
29 | uid_t uid; | ||
30 | gid_t gid; | ||
31 | struct group_info *group_info; | ||
32 | }; | ||
33 | |||
34 | /* | ||
35 | * Client user credentials | ||
36 | */ | ||
37 | struct 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) | ||
61 | struct 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 | |||
67 | struct 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 | */ | ||
88 | struct 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 | |||
101 | struct 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 | |||
115 | extern struct rpc_authops authunix_ops; | ||
116 | extern struct rpc_authops authnull_ops; | ||
117 | #ifdef CONFIG_SUNRPC_SECURE | ||
118 | extern struct rpc_authops authdes_ops; | ||
119 | #endif | ||
120 | |||
121 | int rpcauth_register(struct rpc_authops *); | ||
122 | int rpcauth_unregister(struct rpc_authops *); | ||
123 | struct rpc_auth * rpcauth_create(rpc_authflavor_t, struct rpc_clnt *); | ||
124 | void rpcauth_destroy(struct rpc_auth *); | ||
125 | struct rpc_cred * rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int); | ||
126 | struct rpc_cred * rpcauth_lookupcred(struct rpc_auth *, int); | ||
127 | struct rpc_cred * rpcauth_bindcred(struct rpc_task *); | ||
128 | void rpcauth_holdcred(struct rpc_task *); | ||
129 | void put_rpccred(struct rpc_cred *); | ||
130 | void rpcauth_unbindcred(struct rpc_task *); | ||
131 | u32 * rpcauth_marshcred(struct rpc_task *, u32 *); | ||
132 | u32 * rpcauth_checkverf(struct rpc_task *, u32 *); | ||
133 | int rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, u32 *data, void *obj); | ||
134 | int rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, u32 *data, void *obj); | ||
135 | int rpcauth_refreshcred(struct rpc_task *); | ||
136 | void rpcauth_invalcred(struct rpc_task *); | ||
137 | int rpcauth_uptodatecred(struct rpc_task *); | ||
138 | int rpcauth_init_credcache(struct rpc_auth *, unsigned long); | ||
139 | void rpcauth_free_credcache(struct rpc_auth *); | ||
140 | |||
141 | static inline | ||
142 | struct 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 | |||
26 | enum 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 | |||
33 | enum 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: */ | ||
40 | struct 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: */ | ||
49 | struct 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 */ | ||
55 | struct 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 | |||
69 | struct 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 | |||
80 | struct gss_upcall_msg; | ||
81 | struct 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 | |||
93 | void 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 | */ | ||
47 | struct 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 | |||
62 | struct 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 | */ | ||
108 | struct 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 | */ | ||
114 | struct 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) \ | ||
168 | RTN *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 | |||
256 | extern void cache_clean_deferred(void *owner); | ||
257 | |||
258 | static inline struct cache_head *cache_get(struct cache_head *h) | ||
259 | { | ||
260 | atomic_inc(&h->refcnt); | ||
261 | return h; | ||
262 | } | ||
263 | |||
264 | |||
265 | static 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 | |||
273 | extern void cache_init(struct cache_head *h); | ||
274 | extern void cache_fresh(struct cache_detail *detail, | ||
275 | struct cache_head *head, time_t expiry); | ||
276 | extern int cache_check(struct cache_detail *detail, | ||
277 | struct cache_head *h, struct cache_req *rqstp); | ||
278 | extern void cache_flush(void); | ||
279 | extern void cache_purge(struct cache_detail *detail); | ||
280 | #define NEVER (0x7FFFFFFF) | ||
281 | extern void cache_register(struct cache_detail *cd); | ||
282 | extern int cache_unregister(struct cache_detail *cd); | ||
283 | |||
284 | extern void qword_add(char **bpp, int *lp, char *str); | ||
285 | extern void qword_addhex(char **bpp, int *lp, char *buf, int blen); | ||
286 | extern int qword_get(char **bpp, char *dest, int bufsize); | ||
287 | |||
288 | static 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 | |||
302 | static 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 | */ | ||
24 | struct 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 | |||
33 | struct rpc_inode; | ||
34 | |||
35 | /* | ||
36 | * The high-level client handle | ||
37 | */ | ||
38 | struct 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 | ||
79 | struct 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 | |||
88 | struct 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 | */ | ||
97 | struct 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 | |||
111 | struct rpc_clnt *rpc_create_client(struct rpc_xprt *xprt, char *servname, | ||
112 | struct rpc_program *info, | ||
113 | u32 version, rpc_authflavor_t authflavor); | ||
114 | struct rpc_clnt *rpc_clone_client(struct rpc_clnt *); | ||
115 | int rpc_shutdown_client(struct rpc_clnt *); | ||
116 | int rpc_destroy_client(struct rpc_clnt *); | ||
117 | void rpc_release_client(struct rpc_clnt *); | ||
118 | void rpc_getport(struct rpc_task *, struct rpc_clnt *); | ||
119 | int rpc_register(u32, u32, int, unsigned short, int *); | ||
120 | |||
121 | void rpc_call_setup(struct rpc_task *, struct rpc_message *, int); | ||
122 | |||
123 | int rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, | ||
124 | int flags, rpc_action callback, void *clntdata); | ||
125 | int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, | ||
126 | int flags); | ||
127 | void rpc_restart_call(struct rpc_task *); | ||
128 | void rpc_clnt_sigmask(struct rpc_clnt *clnt, sigset_t *oldset); | ||
129 | void rpc_clnt_sigunmask(struct rpc_clnt *clnt, sigset_t *oldset); | ||
130 | void rpc_setbufsize(struct rpc_clnt *, unsigned int, unsigned int); | ||
131 | size_t rpc_max_payload(struct rpc_clnt *); | ||
132 | |||
133 | static __inline__ | ||
134 | int 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 | |||
145 | extern void rpciod_wake_up(void); | ||
146 | |||
147 | /* | ||
148 | * Helper function for NFSroot support | ||
149 | */ | ||
150 | int 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 | ||
47 | extern unsigned int rpc_debug; | ||
48 | extern unsigned int nfs_debug; | ||
49 | extern unsigned int nfsd_debug; | ||
50 | extern 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 | ||
76 | void rpc_register_sysctl(void); | ||
77 | void 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 | |||
90 | enum { | ||
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: */ | ||
22 | struct 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. */ | ||
36 | int 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); | ||
41 | u32 gss_get_mic( | ||
42 | struct gss_ctx *ctx_id, | ||
43 | u32 qop, | ||
44 | struct xdr_buf *message, | ||
45 | struct xdr_netobj *mic_token); | ||
46 | u32 gss_verify_mic( | ||
47 | struct gss_ctx *ctx_id, | ||
48 | struct xdr_buf *message, | ||
49 | struct xdr_netobj *mic_token, | ||
50 | u32 *qstate); | ||
51 | u32 gss_delete_sec_context( | ||
52 | struct gss_ctx **ctx_id); | ||
53 | |||
54 | u32 gss_pseudoflavor_to_service(struct gss_api_mech *, u32 pseudoflavor); | ||
55 | char *gss_service_to_auth_domain_name(struct gss_api_mech *, u32 service); | ||
56 | |||
57 | struct 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: */ | ||
69 | struct 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: */ | ||
81 | struct 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 | |||
100 | int gss_mech_register(struct gss_api_mech *); | ||
101 | void gss_mech_unregister(struct gss_api_mech *); | ||
102 | |||
103 | /* returns a mechanism descriptor given an OID, and increments the mechanism's | ||
104 | * reference count. */ | ||
105 | struct 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. */ | ||
108 | struct gss_api_mech *gss_mech_get_by_name(const char *); | ||
109 | |||
110 | /* Similar, but get by pseudoflavor. */ | ||
111 | struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32); | ||
112 | |||
113 | /* Just increments the mechanism's reference count and returns its input: */ | ||
114 | struct 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. */ | ||
118 | void 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 | |||
68 | u32 g_verify_token_header( | ||
69 | struct xdr_netobj *mech, | ||
70 | int *body_size, | ||
71 | unsigned char **buf_in, | ||
72 | int toksize); | ||
73 | |||
74 | int g_token_size( | ||
75 | struct xdr_netobj *mech, | ||
76 | unsigned int body_size); | ||
77 | |||
78 | void 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 | |||
39 | typedef 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 | |||
43 | struct 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 | |||
59 | enum 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 | }; | ||
67 | enum 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 | |||
117 | s32 | ||
118 | make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, | ||
119 | struct xdr_netobj *cksum); | ||
120 | |||
121 | u32 | ||
122 | krb5_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 | |||
126 | u32 | ||
127 | krb5_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 | |||
132 | u32 | ||
133 | krb5_encrypt(struct crypto_tfm * key, | ||
134 | void *iv, void *in, void *out, int length); | ||
135 | |||
136 | u32 | ||
137 | krb5_decrypt(struct crypto_tfm * key, | ||
138 | void *iv, void *in, void *out, int length); | ||
139 | |||
140 | s32 | ||
141 | krb5_make_seq_num(struct crypto_tfm * key, | ||
142 | int direction, | ||
143 | s32 seqnum, unsigned char *cksum, unsigned char *buf); | ||
144 | |||
145 | s32 | ||
146 | krb5_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 | |||
14 | struct 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 | |||
44 | u32 spkm3_make_token(struct spkm3_ctx *ctx, int qop_req, struct xdr_buf * text, struct xdr_netobj * token, int toktype); | ||
45 | |||
46 | u32 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 | |||
50 | s32 make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, | ||
51 | struct xdr_netobj *cksum); | ||
52 | void asn1_bitstring_len(struct xdr_netobj *in, int *enclen, int *zerobits); | ||
53 | int decode_asn1_bitstring(struct xdr_netobj *out, char *in, int enclen, | ||
54 | int explen); | ||
55 | void spkm3_mic_header(unsigned char **hdrbuf, unsigned int *hdrlen, | ||
56 | unsigned char *ctxhdr, int elen, int zbit); | ||
57 | void spkm3_make_mic_token(unsigned char **tokp, int toklen, | ||
58 | struct xdr_netobj *mic_hdr, | ||
59 | struct xdr_netobj *md5cksum, int md5elen, int md5zbit); | ||
60 | u32 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 */ | ||
15 | typedef u32 rpc_authflavor_t; | ||
16 | |||
17 | enum 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 | |||
37 | enum rpc_msg_type { | ||
38 | RPC_CALL = 0, | ||
39 | RPC_REPLY = 1 | ||
40 | }; | ||
41 | |||
42 | enum rpc_reply_stat { | ||
43 | RPC_MSG_ACCEPTED = 0, | ||
44 | RPC_MSG_DENIED = 1 | ||
45 | }; | ||
46 | |||
47 | enum 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 | |||
56 | enum rpc_reject_stat { | ||
57 | RPC_MISMATCH = 0, | ||
58 | RPC_AUTH_ERROR = 1 | ||
59 | }; | ||
60 | |||
61 | enum 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 | |||
6 | struct rpc_pipe_msg { | ||
7 | struct list_head list; | ||
8 | void *data; | ||
9 | size_t len; | ||
10 | size_t copied; | ||
11 | int errno; | ||
12 | }; | ||
13 | |||
14 | struct 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 | |||
21 | struct 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 | |||
36 | static inline struct rpc_inode * | ||
37 | RPC_I(struct inode *inode) | ||
38 | { | ||
39 | return container_of(inode, struct rpc_inode, vfs_inode); | ||
40 | } | ||
41 | |||
42 | extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *); | ||
43 | |||
44 | extern struct dentry *rpc_mkdir(char *, struct rpc_clnt *); | ||
45 | extern int rpc_rmdir(char *); | ||
46 | extern struct dentry *rpc_mkpipe(char *, void *, struct rpc_pipe_ops *, int flags); | ||
47 | extern 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 | */ | ||
22 | struct rpc_procinfo; | ||
23 | struct 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 | |||
30 | struct rpc_wait_queue; | ||
31 | struct 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 | */ | ||
41 | struct 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 | |||
113 | typedef 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 | */ | ||
185 | struct 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 | */ | ||
232 | struct rpc_task *rpc_new_task(struct rpc_clnt *, rpc_action, int flags); | ||
233 | struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent); | ||
234 | void rpc_init_task(struct rpc_task *, struct rpc_clnt *, | ||
235 | rpc_action exitfunc, int flags); | ||
236 | void rpc_release_task(struct rpc_task *); | ||
237 | void rpc_killall_tasks(struct rpc_clnt *); | ||
238 | int rpc_execute(struct rpc_task *); | ||
239 | void rpc_run_child(struct rpc_task *parent, struct rpc_task *child, | ||
240 | rpc_action action); | ||
241 | void rpc_init_priority_wait_queue(struct rpc_wait_queue *, const char *); | ||
242 | void rpc_init_wait_queue(struct rpc_wait_queue *, const char *); | ||
243 | void rpc_sleep_on(struct rpc_wait_queue *, struct rpc_task *, | ||
244 | rpc_action action, rpc_action timer); | ||
245 | void rpc_wake_up_task(struct rpc_task *); | ||
246 | void rpc_wake_up(struct rpc_wait_queue *); | ||
247 | struct rpc_task *rpc_wake_up_next(struct rpc_wait_queue *); | ||
248 | void rpc_wake_up_status(struct rpc_wait_queue *, int); | ||
249 | void rpc_delay(struct rpc_task *, unsigned long); | ||
250 | void * rpc_malloc(struct rpc_task *, size_t); | ||
251 | int rpciod_up(void); | ||
252 | void rpciod_down(void); | ||
253 | void rpciod_wake_up(void); | ||
254 | #ifdef RPC_DEBUG | ||
255 | void rpc_show_tasks(void); | ||
256 | #endif | ||
257 | int rpc_init_mempool(void); | ||
258 | void rpc_destroy_mempool(void); | ||
259 | |||
260 | static 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 | ||
267 | static 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 | |||
15 | struct 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 | |||
29 | struct 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 | |||
42 | void rpc_proc_init(void); | ||
43 | void rpc_proc_exit(void); | ||
44 | #ifdef MODULE | ||
45 | void rpc_modcount(struct inode *, int); | ||
46 | #endif | ||
47 | |||
48 | #ifdef CONFIG_PROC_FS | ||
49 | struct proc_dir_entry * rpc_proc_register(struct rpc_stat *); | ||
50 | void rpc_proc_unregister(const char *); | ||
51 | void rpc_proc_zero(struct rpc_program *); | ||
52 | struct proc_dir_entry * svc_proc_register(struct svc_stat *, | ||
53 | struct file_operations *); | ||
54 | void svc_proc_unregister(const char *); | ||
55 | |||
56 | void svc_seq_show(struct seq_file *, | ||
57 | const struct svc_stat *); | ||
58 | |||
59 | extern struct proc_dir_entry *proc_net_rpc; | ||
60 | |||
61 | #else | ||
62 | |||
63 | static inline struct proc_dir_entry *rpc_proc_register(struct rpc_stat *s) { return NULL; } | ||
64 | static inline void rpc_proc_unregister(const char *p) {} | ||
65 | static inline void rpc_proc_zero(struct rpc_program *p) {} | ||
66 | |||
67 | static inline struct proc_dir_entry *svc_proc_register(struct svc_stat *s, | ||
68 | struct file_operations *f) { return NULL; } | ||
69 | static inline void svc_proc_unregister(const char *p) {} | ||
70 | |||
71 | static 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 | */ | ||
30 | struct 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 | |||
81 | static 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 | |||
91 | static 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 | |||
98 | static 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 | */ | ||
111 | struct 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 | */ | ||
169 | static inline int | ||
170 | xdr_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 | |||
177 | static inline int | ||
178 | xdr_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 | |||
188 | static 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 | |||
199 | static 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 | |||
210 | static 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 | |||
223 | static 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 | |||
233 | struct 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 | */ | ||
245 | struct 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 | */ | ||
260 | struct 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 | */ | ||
276 | typedef int (*svc_procfunc)(struct svc_rqst *, void *argp, void *resp); | ||
277 | struct 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 | */ | ||
292 | typedef void (*svc_thread_fn)(struct svc_rqst *); | ||
293 | |||
294 | /* | ||
295 | * Function prototypes. | ||
296 | */ | ||
297 | struct svc_serv * svc_create(struct svc_program *, unsigned int); | ||
298 | int svc_create_thread(svc_thread_fn, struct svc_serv *); | ||
299 | void svc_exit_thread(struct svc_rqst *); | ||
300 | void svc_destroy(struct svc_serv *); | ||
301 | int svc_process(struct svc_serv *, struct svc_rqst *); | ||
302 | int svc_register(struct svc_serv *, int, unsigned short); | ||
303 | void svc_wake_up(struct svc_serv *); | ||
304 | void 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 | ||
20 | struct svc_cred { | ||
21 | uid_t cr_uid; | ||
22 | gid_t cr_gid; | ||
23 | struct group_info *cr_group_info; | ||
24 | }; | ||
25 | |||
26 | struct 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 | */ | ||
47 | struct 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 | */ | ||
90 | struct 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 | |||
111 | extern int svc_authenticate(struct svc_rqst *rqstp, u32 *authp); | ||
112 | extern int svc_authorise(struct svc_rqst *rqstp); | ||
113 | extern int svc_set_client(struct svc_rqst *rqstp); | ||
114 | extern int svc_auth_register(rpc_authflavor_t flavor, struct auth_ops *aops); | ||
115 | extern void svc_auth_unregister(rpc_authflavor_t flavor); | ||
116 | |||
117 | extern struct auth_domain *unix_domain_find(char *name); | ||
118 | extern void auth_domain_put(struct auth_domain *item); | ||
119 | extern int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom); | ||
120 | extern struct auth_domain *auth_domain_lookup(struct auth_domain *item, int set); | ||
121 | extern struct auth_domain *auth_domain_find(char *name); | ||
122 | extern struct auth_domain *auth_unix_lookup(struct in_addr addr); | ||
123 | extern int auth_unix_forget_old(struct auth_domain *dom); | ||
124 | extern void svcauth_unix_purge(void); | ||
125 | |||
126 | static 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 | |||
144 | static 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 | |||
163 | extern 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 | |||
22 | int gss_svc_init(void); | ||
23 | void gss_svc_shutdown(void); | ||
24 | int 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 | */ | ||
17 | struct 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 | */ | ||
58 | int svc_makesock(struct svc_serv *, int, unsigned short); | ||
59 | void svc_delete_socket(struct svc_sock *); | ||
60 | int svc_recv(struct svc_serv *, struct svc_rqst *, long); | ||
61 | int svc_send(struct svc_rqst *); | ||
62 | void svc_drop(struct svc_rqst *); | ||
63 | void 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 | |||
14 | struct 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 | |||
22 | extern void rpc_init_rtt(struct rpc_rtt *rt, unsigned long timeo); | ||
23 | extern void rpc_update_rtt(struct rpc_rtt *rt, unsigned timer, long m); | ||
24 | extern unsigned long rpc_calc_rto(struct rpc_rtt *rt, unsigned timer); | ||
25 | |||
26 | static 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 | |||
42 | static 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 | ||
25 | struct 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 | */ | ||
35 | typedef 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 | */ | ||
50 | struct 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 | */ | ||
91 | u32 * xdr_encode_opaque_fixed(u32 *p, const void *ptr, unsigned int len); | ||
92 | u32 * xdr_encode_opaque(u32 *p, const void *ptr, unsigned int len); | ||
93 | u32 * xdr_encode_string(u32 *p, const char *s); | ||
94 | u32 * xdr_decode_string(u32 *p, char **sp, int *lenp, int maxlen); | ||
95 | u32 * xdr_decode_string_inplace(u32 *p, char **sp, int *lenp, int maxlen); | ||
96 | u32 * xdr_encode_netobj(u32 *p, const struct xdr_netobj *); | ||
97 | u32 * xdr_decode_netobj(u32 *p, struct xdr_netobj *); | ||
98 | |||
99 | void xdr_encode_pages(struct xdr_buf *, struct page **, unsigned int, | ||
100 | unsigned int); | ||
101 | void xdr_inline_pages(struct xdr_buf *, unsigned int, | ||
102 | struct page **, unsigned int, unsigned int); | ||
103 | |||
104 | static 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 | */ | ||
112 | static inline u32 * | ||
113 | xdr_encode_hyper(u32 *p, __u64 val) | ||
114 | { | ||
115 | *p++ = htonl(val >> 32); | ||
116 | *p++ = htonl(val & 0xFFFFFFFF); | ||
117 | return p; | ||
118 | } | ||
119 | |||
120 | static inline u32 * | ||
121 | xdr_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 | */ | ||
131 | static inline int | ||
132 | xdr_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 | */ | ||
145 | extern void xdr_shift_buf(struct xdr_buf *, size_t); | ||
146 | extern void xdr_buf_from_iov(struct kvec *, struct xdr_buf *); | ||
147 | extern int xdr_buf_subsegment(struct xdr_buf *, struct xdr_buf *, int, int); | ||
148 | extern int xdr_buf_read_netobj(struct xdr_buf *, struct xdr_netobj *, int); | ||
149 | extern 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 | */ | ||
154 | typedef struct { | ||
155 | struct sk_buff *skb; | ||
156 | unsigned int offset; | ||
157 | size_t count; | ||
158 | unsigned int csum; | ||
159 | } skb_reader_t; | ||
160 | |||
161 | typedef size_t (*skb_read_actor_t)(skb_reader_t *desc, void *to, size_t len); | ||
162 | |||
163 | extern void xdr_partial_copy_from_skb(struct xdr_buf *, unsigned int, | ||
164 | skb_reader_t *, skb_read_actor_t); | ||
165 | |||
166 | struct socket; | ||
167 | struct sockaddr; | ||
168 | extern 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 | */ | ||
174 | struct 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 | |||
182 | extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p); | ||
183 | extern uint32_t *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); | ||
184 | extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, | ||
185 | unsigned int base, unsigned int len); | ||
186 | extern void xdr_init_decode(struct xdr_stream *xdr, struct xdr_buf *buf, uint32_t *p); | ||
187 | extern uint32_t *xdr_inline_decode(struct xdr_stream *xdr, size_t nbytes); | ||
188 | extern 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 | */ | ||
32 | extern unsigned int xprt_udp_slot_table_entries; | ||
33 | extern 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 | */ | ||
71 | struct 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 | */ | ||
82 | struct 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 | |||
129 | struct 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 | |||
204 | struct rpc_xprt * xprt_create_proto(int proto, struct sockaddr_in *addr, | ||
205 | struct rpc_timeout *toparms); | ||
206 | int xprt_destroy(struct rpc_xprt *); | ||
207 | void xprt_set_timeout(struct rpc_timeout *, unsigned int, | ||
208 | unsigned long); | ||
209 | |||
210 | void xprt_reserve(struct rpc_task *); | ||
211 | int xprt_prepare_transmit(struct rpc_task *); | ||
212 | void xprt_transmit(struct rpc_task *); | ||
213 | void xprt_receive(struct rpc_task *); | ||
214 | int xprt_adjust_timeout(struct rpc_rqst *req); | ||
215 | void xprt_release(struct rpc_task *); | ||
216 | void xprt_connect(struct rpc_task *); | ||
217 | void 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 */ | ||