diff options
Diffstat (limited to 'net/sunrpc/rpcb_clnt.c')
-rw-r--r-- | net/sunrpc/rpcb_clnt.c | 306 |
1 files changed, 146 insertions, 160 deletions
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index dac219a56ae1..e45d2fbbe5a8 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/socket.h> | 18 | #include <linux/socket.h> |
19 | #include <linux/un.h> | ||
19 | #include <linux/in.h> | 20 | #include <linux/in.h> |
20 | #include <linux/in6.h> | 21 | #include <linux/in6.h> |
21 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
@@ -32,6 +33,8 @@ | |||
32 | # define RPCDBG_FACILITY RPCDBG_BIND | 33 | # define RPCDBG_FACILITY RPCDBG_BIND |
33 | #endif | 34 | #endif |
34 | 35 | ||
36 | #define RPCBIND_SOCK_PATHNAME "/var/run/rpcbind.sock" | ||
37 | |||
35 | #define RPCBIND_PROGRAM (100000u) | 38 | #define RPCBIND_PROGRAM (100000u) |
36 | #define RPCBIND_PORT (111u) | 39 | #define RPCBIND_PORT (111u) |
37 | 40 | ||
@@ -57,10 +60,6 @@ enum { | |||
57 | RPCBPROC_GETSTAT, | 60 | RPCBPROC_GETSTAT, |
58 | }; | 61 | }; |
59 | 62 | ||
60 | #define RPCB_HIGHPROC_2 RPCBPROC_CALLIT | ||
61 | #define RPCB_HIGHPROC_3 RPCBPROC_TADDR2UADDR | ||
62 | #define RPCB_HIGHPROC_4 RPCBPROC_GETSTAT | ||
63 | |||
64 | /* | 63 | /* |
65 | * r_owner | 64 | * r_owner |
66 | * | 65 | * |
@@ -162,21 +161,71 @@ static void rpcb_map_release(void *data) | |||
162 | kfree(map); | 161 | kfree(map); |
163 | } | 162 | } |
164 | 163 | ||
165 | static const struct sockaddr_in rpcb_inaddr_loopback = { | 164 | /* |
166 | .sin_family = AF_INET, | 165 | * Returns zero on success, otherwise a negative errno value |
167 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), | 166 | * is returned. |
168 | .sin_port = htons(RPCBIND_PORT), | 167 | */ |
169 | }; | 168 | static int rpcb_create_local_unix(void) |
169 | { | ||
170 | static const struct sockaddr_un rpcb_localaddr_rpcbind = { | ||
171 | .sun_family = AF_LOCAL, | ||
172 | .sun_path = RPCBIND_SOCK_PATHNAME, | ||
173 | }; | ||
174 | struct rpc_create_args args = { | ||
175 | .net = &init_net, | ||
176 | .protocol = XPRT_TRANSPORT_LOCAL, | ||
177 | .address = (struct sockaddr *)&rpcb_localaddr_rpcbind, | ||
178 | .addrsize = sizeof(rpcb_localaddr_rpcbind), | ||
179 | .servername = "localhost", | ||
180 | .program = &rpcb_program, | ||
181 | .version = RPCBVERS_2, | ||
182 | .authflavor = RPC_AUTH_NULL, | ||
183 | }; | ||
184 | struct rpc_clnt *clnt, *clnt4; | ||
185 | int result = 0; | ||
186 | |||
187 | /* | ||
188 | * Because we requested an RPC PING at transport creation time, | ||
189 | * this works only if the user space portmapper is rpcbind, and | ||
190 | * it's listening on AF_LOCAL on the named socket. | ||
191 | */ | ||
192 | clnt = rpc_create(&args); | ||
193 | if (IS_ERR(clnt)) { | ||
194 | dprintk("RPC: failed to create AF_LOCAL rpcbind " | ||
195 | "client (errno %ld).\n", PTR_ERR(clnt)); | ||
196 | result = -PTR_ERR(clnt); | ||
197 | goto out; | ||
198 | } | ||
199 | |||
200 | clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4); | ||
201 | if (IS_ERR(clnt4)) { | ||
202 | dprintk("RPC: failed to bind second program to " | ||
203 | "rpcbind v4 client (errno %ld).\n", | ||
204 | PTR_ERR(clnt4)); | ||
205 | clnt4 = NULL; | ||
206 | } | ||
207 | |||
208 | /* Protected by rpcb_create_local_mutex */ | ||
209 | rpcb_local_clnt = clnt; | ||
210 | rpcb_local_clnt4 = clnt4; | ||
170 | 211 | ||
171 | static DEFINE_MUTEX(rpcb_create_local_mutex); | 212 | out: |
213 | return result; | ||
214 | } | ||
172 | 215 | ||
173 | /* | 216 | /* |
174 | * Returns zero on success, otherwise a negative errno value | 217 | * Returns zero on success, otherwise a negative errno value |
175 | * is returned. | 218 | * is returned. |
176 | */ | 219 | */ |
177 | static int rpcb_create_local(void) | 220 | static int rpcb_create_local_net(void) |
178 | { | 221 | { |
222 | static const struct sockaddr_in rpcb_inaddr_loopback = { | ||
223 | .sin_family = AF_INET, | ||
224 | .sin_addr.s_addr = htonl(INADDR_LOOPBACK), | ||
225 | .sin_port = htons(RPCBIND_PORT), | ||
226 | }; | ||
179 | struct rpc_create_args args = { | 227 | struct rpc_create_args args = { |
228 | .net = &init_net, | ||
180 | .protocol = XPRT_TRANSPORT_TCP, | 229 | .protocol = XPRT_TRANSPORT_TCP, |
181 | .address = (struct sockaddr *)&rpcb_inaddr_loopback, | 230 | .address = (struct sockaddr *)&rpcb_inaddr_loopback, |
182 | .addrsize = sizeof(rpcb_inaddr_loopback), | 231 | .addrsize = sizeof(rpcb_inaddr_loopback), |
@@ -189,13 +238,6 @@ static int rpcb_create_local(void) | |||
189 | struct rpc_clnt *clnt, *clnt4; | 238 | struct rpc_clnt *clnt, *clnt4; |
190 | int result = 0; | 239 | int result = 0; |
191 | 240 | ||
192 | if (rpcb_local_clnt) | ||
193 | return result; | ||
194 | |||
195 | mutex_lock(&rpcb_create_local_mutex); | ||
196 | if (rpcb_local_clnt) | ||
197 | goto out; | ||
198 | |||
199 | clnt = rpc_create(&args); | 241 | clnt = rpc_create(&args); |
200 | if (IS_ERR(clnt)) { | 242 | if (IS_ERR(clnt)) { |
201 | dprintk("RPC: failed to create local rpcbind " | 243 | dprintk("RPC: failed to create local rpcbind " |
@@ -211,15 +253,40 @@ static int rpcb_create_local(void) | |||
211 | */ | 253 | */ |
212 | clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4); | 254 | clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4); |
213 | if (IS_ERR(clnt4)) { | 255 | if (IS_ERR(clnt4)) { |
214 | dprintk("RPC: failed to create local rpcbind v4 " | 256 | dprintk("RPC: failed to bind second program to " |
215 | "cleint (errno %ld).\n", PTR_ERR(clnt4)); | 257 | "rpcbind v4 client (errno %ld).\n", |
258 | PTR_ERR(clnt4)); | ||
216 | clnt4 = NULL; | 259 | clnt4 = NULL; |
217 | } | 260 | } |
218 | 261 | ||
262 | /* Protected by rpcb_create_local_mutex */ | ||
219 | rpcb_local_clnt = clnt; | 263 | rpcb_local_clnt = clnt; |
220 | rpcb_local_clnt4 = clnt4; | 264 | rpcb_local_clnt4 = clnt4; |
221 | 265 | ||
222 | out: | 266 | out: |
267 | return result; | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * Returns zero on success, otherwise a negative errno value | ||
272 | * is returned. | ||
273 | */ | ||
274 | static int rpcb_create_local(void) | ||
275 | { | ||
276 | static DEFINE_MUTEX(rpcb_create_local_mutex); | ||
277 | int result = 0; | ||
278 | |||
279 | if (rpcb_local_clnt) | ||
280 | return result; | ||
281 | |||
282 | mutex_lock(&rpcb_create_local_mutex); | ||
283 | if (rpcb_local_clnt) | ||
284 | goto out; | ||
285 | |||
286 | if (rpcb_create_local_unix() != 0) | ||
287 | result = rpcb_create_local_net(); | ||
288 | |||
289 | out: | ||
223 | mutex_unlock(&rpcb_create_local_mutex); | 290 | mutex_unlock(&rpcb_create_local_mutex); |
224 | return result; | 291 | return result; |
225 | } | 292 | } |
@@ -228,6 +295,7 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, | |||
228 | size_t salen, int proto, u32 version) | 295 | size_t salen, int proto, u32 version) |
229 | { | 296 | { |
230 | struct rpc_create_args args = { | 297 | struct rpc_create_args args = { |
298 | .net = &init_net, | ||
231 | .protocol = proto, | 299 | .protocol = proto, |
232 | .address = srvaddr, | 300 | .address = srvaddr, |
233 | .addrsize = salen, | 301 | .addrsize = salen, |
@@ -247,7 +315,7 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr, | |||
247 | ((struct sockaddr_in6 *)srvaddr)->sin6_port = htons(RPCBIND_PORT); | 315 | ((struct sockaddr_in6 *)srvaddr)->sin6_port = htons(RPCBIND_PORT); |
248 | break; | 316 | break; |
249 | default: | 317 | default: |
250 | return NULL; | 318 | return ERR_PTR(-EAFNOSUPPORT); |
251 | } | 319 | } |
252 | 320 | ||
253 | return rpc_create(&args); | 321 | return rpc_create(&args); |
@@ -475,57 +543,6 @@ int rpcb_v4_register(const u32 program, const u32 version, | |||
475 | return -EAFNOSUPPORT; | 543 | return -EAFNOSUPPORT; |
476 | } | 544 | } |
477 | 545 | ||
478 | /** | ||
479 | * rpcb_getport_sync - obtain the port for an RPC service on a given host | ||
480 | * @sin: address of remote peer | ||
481 | * @prog: RPC program number to bind | ||
482 | * @vers: RPC version number to bind | ||
483 | * @prot: transport protocol to use to make this request | ||
484 | * | ||
485 | * Return value is the requested advertised port number, | ||
486 | * or a negative errno value. | ||
487 | * | ||
488 | * Called from outside the RPC client in a synchronous task context. | ||
489 | * Uses default timeout parameters specified by underlying transport. | ||
490 | * | ||
491 | * XXX: Needs to support IPv6 | ||
492 | */ | ||
493 | int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot) | ||
494 | { | ||
495 | struct rpcbind_args map = { | ||
496 | .r_prog = prog, | ||
497 | .r_vers = vers, | ||
498 | .r_prot = prot, | ||
499 | .r_port = 0, | ||
500 | }; | ||
501 | struct rpc_message msg = { | ||
502 | .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT], | ||
503 | .rpc_argp = &map, | ||
504 | .rpc_resp = &map, | ||
505 | }; | ||
506 | struct rpc_clnt *rpcb_clnt; | ||
507 | int status; | ||
508 | |||
509 | dprintk("RPC: %s(%pI4, %u, %u, %d)\n", | ||
510 | __func__, &sin->sin_addr.s_addr, prog, vers, prot); | ||
511 | |||
512 | rpcb_clnt = rpcb_create(NULL, (struct sockaddr *)sin, | ||
513 | sizeof(*sin), prot, RPCBVERS_2); | ||
514 | if (IS_ERR(rpcb_clnt)) | ||
515 | return PTR_ERR(rpcb_clnt); | ||
516 | |||
517 | status = rpc_call_sync(rpcb_clnt, &msg, 0); | ||
518 | rpc_shutdown_client(rpcb_clnt); | ||
519 | |||
520 | if (status >= 0) { | ||
521 | if (map.r_port != 0) | ||
522 | return map.r_port; | ||
523 | status = -EACCES; | ||
524 | } | ||
525 | return status; | ||
526 | } | ||
527 | EXPORT_SYMBOL_GPL(rpcb_getport_sync); | ||
528 | |||
529 | static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc) | 546 | static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc) |
530 | { | 547 | { |
531 | struct rpc_message msg = { | 548 | struct rpc_message msg = { |
@@ -580,7 +597,7 @@ void rpcb_getport_async(struct rpc_task *task) | |||
580 | u32 bind_version; | 597 | u32 bind_version; |
581 | struct rpc_xprt *xprt; | 598 | struct rpc_xprt *xprt; |
582 | struct rpc_clnt *rpcb_clnt; | 599 | struct rpc_clnt *rpcb_clnt; |
583 | static struct rpcbind_args *map; | 600 | struct rpcbind_args *map; |
584 | struct rpc_task *child; | 601 | struct rpc_task *child; |
585 | struct sockaddr_storage addr; | 602 | struct sockaddr_storage addr; |
586 | struct sockaddr *sap = (struct sockaddr *)&addr; | 603 | struct sockaddr *sap = (struct sockaddr *)&addr; |
@@ -741,46 +758,37 @@ static void rpcb_getport_done(struct rpc_task *child, void *data) | |||
741 | * XDR functions for rpcbind | 758 | * XDR functions for rpcbind |
742 | */ | 759 | */ |
743 | 760 | ||
744 | static int rpcb_enc_mapping(struct rpc_rqst *req, __be32 *p, | 761 | static void rpcb_enc_mapping(struct rpc_rqst *req, struct xdr_stream *xdr, |
745 | const struct rpcbind_args *rpcb) | 762 | const struct rpcbind_args *rpcb) |
746 | { | 763 | { |
747 | struct rpc_task *task = req->rq_task; | 764 | struct rpc_task *task = req->rq_task; |
748 | struct xdr_stream xdr; | 765 | __be32 *p; |
749 | 766 | ||
750 | dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n", | 767 | dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n", |
751 | task->tk_pid, task->tk_msg.rpc_proc->p_name, | 768 | task->tk_pid, task->tk_msg.rpc_proc->p_name, |
752 | rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port); | 769 | rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port); |
753 | 770 | ||
754 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 771 | p = xdr_reserve_space(xdr, RPCB_mappingargs_sz << 2); |
755 | 772 | *p++ = cpu_to_be32(rpcb->r_prog); | |
756 | p = xdr_reserve_space(&xdr, sizeof(__be32) * RPCB_mappingargs_sz); | 773 | *p++ = cpu_to_be32(rpcb->r_vers); |
757 | if (unlikely(p == NULL)) | 774 | *p++ = cpu_to_be32(rpcb->r_prot); |
758 | return -EIO; | 775 | *p = cpu_to_be32(rpcb->r_port); |
759 | |||
760 | *p++ = htonl(rpcb->r_prog); | ||
761 | *p++ = htonl(rpcb->r_vers); | ||
762 | *p++ = htonl(rpcb->r_prot); | ||
763 | *p = htonl(rpcb->r_port); | ||
764 | |||
765 | return 0; | ||
766 | } | 776 | } |
767 | 777 | ||
768 | static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p, | 778 | static int rpcb_dec_getport(struct rpc_rqst *req, struct xdr_stream *xdr, |
769 | struct rpcbind_args *rpcb) | 779 | struct rpcbind_args *rpcb) |
770 | { | 780 | { |
771 | struct rpc_task *task = req->rq_task; | 781 | struct rpc_task *task = req->rq_task; |
772 | struct xdr_stream xdr; | ||
773 | unsigned long port; | 782 | unsigned long port; |
774 | 783 | __be32 *p; | |
775 | xdr_init_decode(&xdr, &req->rq_rcv_buf, p); | ||
776 | 784 | ||
777 | rpcb->r_port = 0; | 785 | rpcb->r_port = 0; |
778 | 786 | ||
779 | p = xdr_inline_decode(&xdr, sizeof(__be32)); | 787 | p = xdr_inline_decode(xdr, 4); |
780 | if (unlikely(p == NULL)) | 788 | if (unlikely(p == NULL)) |
781 | return -EIO; | 789 | return -EIO; |
782 | 790 | ||
783 | port = ntohl(*p); | 791 | port = be32_to_cpup(p); |
784 | dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid, | 792 | dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid, |
785 | task->tk_msg.rpc_proc->p_name, port); | 793 | task->tk_msg.rpc_proc->p_name, port); |
786 | if (unlikely(port > USHRT_MAX)) | 794 | if (unlikely(port > USHRT_MAX)) |
@@ -790,20 +798,18 @@ static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p, | |||
790 | return 0; | 798 | return 0; |
791 | } | 799 | } |
792 | 800 | ||
793 | static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p, | 801 | static int rpcb_dec_set(struct rpc_rqst *req, struct xdr_stream *xdr, |
794 | unsigned int *boolp) | 802 | unsigned int *boolp) |
795 | { | 803 | { |
796 | struct rpc_task *task = req->rq_task; | 804 | struct rpc_task *task = req->rq_task; |
797 | struct xdr_stream xdr; | 805 | __be32 *p; |
798 | |||
799 | xdr_init_decode(&xdr, &req->rq_rcv_buf, p); | ||
800 | 806 | ||
801 | p = xdr_inline_decode(&xdr, sizeof(__be32)); | 807 | p = xdr_inline_decode(xdr, 4); |
802 | if (unlikely(p == NULL)) | 808 | if (unlikely(p == NULL)) |
803 | return -EIO; | 809 | return -EIO; |
804 | 810 | ||
805 | *boolp = 0; | 811 | *boolp = 0; |
806 | if (*p) | 812 | if (*p != xdr_zero) |
807 | *boolp = 1; | 813 | *boolp = 1; |
808 | 814 | ||
809 | dprintk("RPC: %5u RPCB_%s call %s\n", | 815 | dprintk("RPC: %5u RPCB_%s call %s\n", |
@@ -812,73 +818,53 @@ static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p, | |||
812 | return 0; | 818 | return 0; |
813 | } | 819 | } |
814 | 820 | ||
815 | static int encode_rpcb_string(struct xdr_stream *xdr, const char *string, | 821 | static void encode_rpcb_string(struct xdr_stream *xdr, const char *string, |
816 | const u32 maxstrlen) | 822 | const u32 maxstrlen) |
817 | { | 823 | { |
818 | u32 len; | ||
819 | __be32 *p; | 824 | __be32 *p; |
825 | u32 len; | ||
820 | 826 | ||
821 | if (unlikely(string == NULL)) | ||
822 | return -EIO; | ||
823 | len = strlen(string); | 827 | len = strlen(string); |
824 | if (unlikely(len > maxstrlen)) | 828 | BUG_ON(len > maxstrlen); |
825 | return -EIO; | 829 | p = xdr_reserve_space(xdr, 4 + len); |
826 | |||
827 | p = xdr_reserve_space(xdr, sizeof(__be32) + len); | ||
828 | if (unlikely(p == NULL)) | ||
829 | return -EIO; | ||
830 | xdr_encode_opaque(p, string, len); | 830 | xdr_encode_opaque(p, string, len); |
831 | |||
832 | return 0; | ||
833 | } | 831 | } |
834 | 832 | ||
835 | static int rpcb_enc_getaddr(struct rpc_rqst *req, __be32 *p, | 833 | static void rpcb_enc_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr, |
836 | const struct rpcbind_args *rpcb) | 834 | const struct rpcbind_args *rpcb) |
837 | { | 835 | { |
838 | struct rpc_task *task = req->rq_task; | 836 | struct rpc_task *task = req->rq_task; |
839 | struct xdr_stream xdr; | 837 | __be32 *p; |
840 | 838 | ||
841 | dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n", | 839 | dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n", |
842 | task->tk_pid, task->tk_msg.rpc_proc->p_name, | 840 | task->tk_pid, task->tk_msg.rpc_proc->p_name, |
843 | rpcb->r_prog, rpcb->r_vers, | 841 | rpcb->r_prog, rpcb->r_vers, |
844 | rpcb->r_netid, rpcb->r_addr); | 842 | rpcb->r_netid, rpcb->r_addr); |
845 | 843 | ||
846 | xdr_init_encode(&xdr, &req->rq_snd_buf, p); | 844 | p = xdr_reserve_space(xdr, (RPCB_program_sz + RPCB_version_sz) << 2); |
847 | 845 | *p++ = cpu_to_be32(rpcb->r_prog); | |
848 | p = xdr_reserve_space(&xdr, | 846 | *p = cpu_to_be32(rpcb->r_vers); |
849 | sizeof(__be32) * (RPCB_program_sz + RPCB_version_sz)); | ||
850 | if (unlikely(p == NULL)) | ||
851 | return -EIO; | ||
852 | *p++ = htonl(rpcb->r_prog); | ||
853 | *p = htonl(rpcb->r_vers); | ||
854 | 847 | ||
855 | if (encode_rpcb_string(&xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN)) | 848 | encode_rpcb_string(xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN); |
856 | return -EIO; | 849 | encode_rpcb_string(xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN); |
857 | if (encode_rpcb_string(&xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN)) | 850 | encode_rpcb_string(xdr, rpcb->r_owner, RPCB_MAXOWNERLEN); |
858 | return -EIO; | ||
859 | if (encode_rpcb_string(&xdr, rpcb->r_owner, RPCB_MAXOWNERLEN)) | ||
860 | return -EIO; | ||
861 | |||
862 | return 0; | ||
863 | } | 851 | } |
864 | 852 | ||
865 | static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p, | 853 | static int rpcb_dec_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr, |
866 | struct rpcbind_args *rpcb) | 854 | struct rpcbind_args *rpcb) |
867 | { | 855 | { |
868 | struct sockaddr_storage address; | 856 | struct sockaddr_storage address; |
869 | struct sockaddr *sap = (struct sockaddr *)&address; | 857 | struct sockaddr *sap = (struct sockaddr *)&address; |
870 | struct rpc_task *task = req->rq_task; | 858 | struct rpc_task *task = req->rq_task; |
871 | struct xdr_stream xdr; | 859 | __be32 *p; |
872 | u32 len; | 860 | u32 len; |
873 | 861 | ||
874 | rpcb->r_port = 0; | 862 | rpcb->r_port = 0; |
875 | 863 | ||
876 | xdr_init_decode(&xdr, &req->rq_rcv_buf, p); | 864 | p = xdr_inline_decode(xdr, 4); |
877 | |||
878 | p = xdr_inline_decode(&xdr, sizeof(__be32)); | ||
879 | if (unlikely(p == NULL)) | 865 | if (unlikely(p == NULL)) |
880 | goto out_fail; | 866 | goto out_fail; |
881 | len = ntohl(*p); | 867 | len = be32_to_cpup(p); |
882 | 868 | ||
883 | /* | 869 | /* |
884 | * If the returned universal address is a null string, | 870 | * If the returned universal address is a null string, |
@@ -893,7 +879,7 @@ static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p, | |||
893 | if (unlikely(len > RPCBIND_MAXUADDRLEN)) | 879 | if (unlikely(len > RPCBIND_MAXUADDRLEN)) |
894 | goto out_fail; | 880 | goto out_fail; |
895 | 881 | ||
896 | p = xdr_inline_decode(&xdr, len); | 882 | p = xdr_inline_decode(xdr, len); |
897 | if (unlikely(p == NULL)) | 883 | if (unlikely(p == NULL)) |
898 | goto out_fail; | 884 | goto out_fail; |
899 | dprintk("RPC: %5u RPCB_%s reply: %s\n", task->tk_pid, | 885 | dprintk("RPC: %5u RPCB_%s reply: %s\n", task->tk_pid, |
@@ -919,8 +905,8 @@ out_fail: | |||
919 | static struct rpc_procinfo rpcb_procedures2[] = { | 905 | static struct rpc_procinfo rpcb_procedures2[] = { |
920 | [RPCBPROC_SET] = { | 906 | [RPCBPROC_SET] = { |
921 | .p_proc = RPCBPROC_SET, | 907 | .p_proc = RPCBPROC_SET, |
922 | .p_encode = (kxdrproc_t)rpcb_enc_mapping, | 908 | .p_encode = (kxdreproc_t)rpcb_enc_mapping, |
923 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 909 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
924 | .p_arglen = RPCB_mappingargs_sz, | 910 | .p_arglen = RPCB_mappingargs_sz, |
925 | .p_replen = RPCB_setres_sz, | 911 | .p_replen = RPCB_setres_sz, |
926 | .p_statidx = RPCBPROC_SET, | 912 | .p_statidx = RPCBPROC_SET, |
@@ -929,8 +915,8 @@ static struct rpc_procinfo rpcb_procedures2[] = { | |||
929 | }, | 915 | }, |
930 | [RPCBPROC_UNSET] = { | 916 | [RPCBPROC_UNSET] = { |
931 | .p_proc = RPCBPROC_UNSET, | 917 | .p_proc = RPCBPROC_UNSET, |
932 | .p_encode = (kxdrproc_t)rpcb_enc_mapping, | 918 | .p_encode = (kxdreproc_t)rpcb_enc_mapping, |
933 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 919 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
934 | .p_arglen = RPCB_mappingargs_sz, | 920 | .p_arglen = RPCB_mappingargs_sz, |
935 | .p_replen = RPCB_setres_sz, | 921 | .p_replen = RPCB_setres_sz, |
936 | .p_statidx = RPCBPROC_UNSET, | 922 | .p_statidx = RPCBPROC_UNSET, |
@@ -939,8 +925,8 @@ static struct rpc_procinfo rpcb_procedures2[] = { | |||
939 | }, | 925 | }, |
940 | [RPCBPROC_GETPORT] = { | 926 | [RPCBPROC_GETPORT] = { |
941 | .p_proc = RPCBPROC_GETPORT, | 927 | .p_proc = RPCBPROC_GETPORT, |
942 | .p_encode = (kxdrproc_t)rpcb_enc_mapping, | 928 | .p_encode = (kxdreproc_t)rpcb_enc_mapping, |
943 | .p_decode = (kxdrproc_t)rpcb_dec_getport, | 929 | .p_decode = (kxdrdproc_t)rpcb_dec_getport, |
944 | .p_arglen = RPCB_mappingargs_sz, | 930 | .p_arglen = RPCB_mappingargs_sz, |
945 | .p_replen = RPCB_getportres_sz, | 931 | .p_replen = RPCB_getportres_sz, |
946 | .p_statidx = RPCBPROC_GETPORT, | 932 | .p_statidx = RPCBPROC_GETPORT, |
@@ -952,8 +938,8 @@ static struct rpc_procinfo rpcb_procedures2[] = { | |||
952 | static struct rpc_procinfo rpcb_procedures3[] = { | 938 | static struct rpc_procinfo rpcb_procedures3[] = { |
953 | [RPCBPROC_SET] = { | 939 | [RPCBPROC_SET] = { |
954 | .p_proc = RPCBPROC_SET, | 940 | .p_proc = RPCBPROC_SET, |
955 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 941 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
956 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 942 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
957 | .p_arglen = RPCB_getaddrargs_sz, | 943 | .p_arglen = RPCB_getaddrargs_sz, |
958 | .p_replen = RPCB_setres_sz, | 944 | .p_replen = RPCB_setres_sz, |
959 | .p_statidx = RPCBPROC_SET, | 945 | .p_statidx = RPCBPROC_SET, |
@@ -962,8 +948,8 @@ static struct rpc_procinfo rpcb_procedures3[] = { | |||
962 | }, | 948 | }, |
963 | [RPCBPROC_UNSET] = { | 949 | [RPCBPROC_UNSET] = { |
964 | .p_proc = RPCBPROC_UNSET, | 950 | .p_proc = RPCBPROC_UNSET, |
965 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 951 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
966 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 952 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
967 | .p_arglen = RPCB_getaddrargs_sz, | 953 | .p_arglen = RPCB_getaddrargs_sz, |
968 | .p_replen = RPCB_setres_sz, | 954 | .p_replen = RPCB_setres_sz, |
969 | .p_statidx = RPCBPROC_UNSET, | 955 | .p_statidx = RPCBPROC_UNSET, |
@@ -972,8 +958,8 @@ static struct rpc_procinfo rpcb_procedures3[] = { | |||
972 | }, | 958 | }, |
973 | [RPCBPROC_GETADDR] = { | 959 | [RPCBPROC_GETADDR] = { |
974 | .p_proc = RPCBPROC_GETADDR, | 960 | .p_proc = RPCBPROC_GETADDR, |
975 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 961 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
976 | .p_decode = (kxdrproc_t)rpcb_dec_getaddr, | 962 | .p_decode = (kxdrdproc_t)rpcb_dec_getaddr, |
977 | .p_arglen = RPCB_getaddrargs_sz, | 963 | .p_arglen = RPCB_getaddrargs_sz, |
978 | .p_replen = RPCB_getaddrres_sz, | 964 | .p_replen = RPCB_getaddrres_sz, |
979 | .p_statidx = RPCBPROC_GETADDR, | 965 | .p_statidx = RPCBPROC_GETADDR, |
@@ -985,8 +971,8 @@ static struct rpc_procinfo rpcb_procedures3[] = { | |||
985 | static struct rpc_procinfo rpcb_procedures4[] = { | 971 | static struct rpc_procinfo rpcb_procedures4[] = { |
986 | [RPCBPROC_SET] = { | 972 | [RPCBPROC_SET] = { |
987 | .p_proc = RPCBPROC_SET, | 973 | .p_proc = RPCBPROC_SET, |
988 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 974 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
989 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 975 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
990 | .p_arglen = RPCB_getaddrargs_sz, | 976 | .p_arglen = RPCB_getaddrargs_sz, |
991 | .p_replen = RPCB_setres_sz, | 977 | .p_replen = RPCB_setres_sz, |
992 | .p_statidx = RPCBPROC_SET, | 978 | .p_statidx = RPCBPROC_SET, |
@@ -995,8 +981,8 @@ static struct rpc_procinfo rpcb_procedures4[] = { | |||
995 | }, | 981 | }, |
996 | [RPCBPROC_UNSET] = { | 982 | [RPCBPROC_UNSET] = { |
997 | .p_proc = RPCBPROC_UNSET, | 983 | .p_proc = RPCBPROC_UNSET, |
998 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 984 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
999 | .p_decode = (kxdrproc_t)rpcb_dec_set, | 985 | .p_decode = (kxdrdproc_t)rpcb_dec_set, |
1000 | .p_arglen = RPCB_getaddrargs_sz, | 986 | .p_arglen = RPCB_getaddrargs_sz, |
1001 | .p_replen = RPCB_setres_sz, | 987 | .p_replen = RPCB_setres_sz, |
1002 | .p_statidx = RPCBPROC_UNSET, | 988 | .p_statidx = RPCBPROC_UNSET, |
@@ -1005,8 +991,8 @@ static struct rpc_procinfo rpcb_procedures4[] = { | |||
1005 | }, | 991 | }, |
1006 | [RPCBPROC_GETADDR] = { | 992 | [RPCBPROC_GETADDR] = { |
1007 | .p_proc = RPCBPROC_GETADDR, | 993 | .p_proc = RPCBPROC_GETADDR, |
1008 | .p_encode = (kxdrproc_t)rpcb_enc_getaddr, | 994 | .p_encode = (kxdreproc_t)rpcb_enc_getaddr, |
1009 | .p_decode = (kxdrproc_t)rpcb_dec_getaddr, | 995 | .p_decode = (kxdrdproc_t)rpcb_dec_getaddr, |
1010 | .p_arglen = RPCB_getaddrargs_sz, | 996 | .p_arglen = RPCB_getaddrargs_sz, |
1011 | .p_replen = RPCB_getaddrres_sz, | 997 | .p_replen = RPCB_getaddrres_sz, |
1012 | .p_statidx = RPCBPROC_GETADDR, | 998 | .p_statidx = RPCBPROC_GETADDR, |
@@ -1041,19 +1027,19 @@ static struct rpcb_info rpcb_next_version6[] = { | |||
1041 | 1027 | ||
1042 | static struct rpc_version rpcb_version2 = { | 1028 | static struct rpc_version rpcb_version2 = { |
1043 | .number = RPCBVERS_2, | 1029 | .number = RPCBVERS_2, |
1044 | .nrprocs = RPCB_HIGHPROC_2, | 1030 | .nrprocs = ARRAY_SIZE(rpcb_procedures2), |
1045 | .procs = rpcb_procedures2 | 1031 | .procs = rpcb_procedures2 |
1046 | }; | 1032 | }; |
1047 | 1033 | ||
1048 | static struct rpc_version rpcb_version3 = { | 1034 | static struct rpc_version rpcb_version3 = { |
1049 | .number = RPCBVERS_3, | 1035 | .number = RPCBVERS_3, |
1050 | .nrprocs = RPCB_HIGHPROC_3, | 1036 | .nrprocs = ARRAY_SIZE(rpcb_procedures3), |
1051 | .procs = rpcb_procedures3 | 1037 | .procs = rpcb_procedures3 |
1052 | }; | 1038 | }; |
1053 | 1039 | ||
1054 | static struct rpc_version rpcb_version4 = { | 1040 | static struct rpc_version rpcb_version4 = { |
1055 | .number = RPCBVERS_4, | 1041 | .number = RPCBVERS_4, |
1056 | .nrprocs = RPCB_HIGHPROC_4, | 1042 | .nrprocs = ARRAY_SIZE(rpcb_procedures4), |
1057 | .procs = rpcb_procedures4 | 1043 | .procs = rpcb_procedures4 |
1058 | }; | 1044 | }; |
1059 | 1045 | ||