1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#include <linux/module.h>
16
17#include <linux/types.h>
18#include <linux/socket.h>
19#include <linux/un.h>
20#include <linux/in.h>
21#include <linux/in6.h>
22#include <linux/kernel.h>
23#include <linux/errno.h>
24#include <linux/mutex.h>
25#include <linux/slab.h>
26#include <net/ipv6.h>
27
28#include <linux/sunrpc/clnt.h>
29#include <linux/sunrpc/sched.h>
30#include <linux/sunrpc/xprtsock.h>
31
32#ifdef RPC_DEBUG
33# define RPCDBG_FACILITY RPCDBG_BIND
34#endif
35
36#define RPCBIND_SOCK_PATHNAME "/var/run/rpcbind.sock"
37
38#define RPCBIND_PROGRAM (100000u)
39#define RPCBIND_PORT (111u)
40
41#define RPCBVERS_2 (2u)
42#define RPCBVERS_3 (3u)
43#define RPCBVERS_4 (4u)
44
45enum {
46 RPCBPROC_NULL,
47 RPCBPROC_SET,
48 RPCBPROC_UNSET,
49 RPCBPROC_GETPORT,
50 RPCBPROC_GETADDR = 3,
51 RPCBPROC_DUMP,
52 RPCBPROC_CALLIT,
53 RPCBPROC_BCAST = 5,
54 RPCBPROC_GETTIME,
55 RPCBPROC_UADDR2TADDR,
56 RPCBPROC_TADDR2UADDR,
57 RPCBPROC_GETVERSADDR,
58 RPCBPROC_INDIRECT,
59 RPCBPROC_GETADDRLIST,
60 RPCBPROC_GETSTAT,
61};
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76#define RPCB_OWNER_STRING "0"
77#define RPCB_MAXOWNERLEN sizeof(RPCB_OWNER_STRING)
78
79
80
81
82#define RPCB_program_sz (1)
83#define RPCB_version_sz (1)
84#define RPCB_protocol_sz (1)
85#define RPCB_port_sz (1)
86#define RPCB_boolean_sz (1)
87
88#define RPCB_netid_sz (1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN))
89#define RPCB_addr_sz (1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN))
90#define RPCB_ownerstring_sz (1 + XDR_QUADLEN(RPCB_MAXOWNERLEN))
91
92
93
94
95#define RPCB_mappingargs_sz (RPCB_program_sz + RPCB_version_sz + \
96 RPCB_protocol_sz + RPCB_port_sz)
97#define RPCB_getaddrargs_sz (RPCB_program_sz + RPCB_version_sz + \
98 RPCB_netid_sz + RPCB_addr_sz + \
99 RPCB_ownerstring_sz)
100
101#define RPCB_getportres_sz RPCB_port_sz
102#define RPCB_setres_sz RPCB_boolean_sz
103
104
105
106
107
108#define RPCB_getaddrres_sz RPCB_addr_sz
109
110static void rpcb_getport_done(struct rpc_task *, void *);
111static void rpcb_map_release(void *data);
112static struct rpc_program rpcb_program;
113
114static struct rpc_clnt * rpcb_local_clnt;
115static struct rpc_clnt * rpcb_local_clnt4;
116
117DEFINE_SPINLOCK(rpcb_clnt_lock);
118unsigned int rpcb_users;
119
120struct rpcbind_args {
121 struct rpc_xprt * r_xprt;
122
123 u32 r_prog;
124 u32 r_vers;
125 u32 r_prot;
126 unsigned short r_port;
127 const char * r_netid;
128 const char * r_addr;
129 const char * r_owner;
130
131 int r_status;
132};
133
134static struct rpc_procinfo rpcb_procedures2[];
135static struct rpc_procinfo rpcb_procedures3[];
136static struct rpc_procinfo rpcb_procedures4[];
137
138struct rpcb_info {
139 u32 rpc_vers;
140 struct rpc_procinfo * rpc_proc;
141};
142
143static struct rpcb_info rpcb_next_version[];
144static struct rpcb_info rpcb_next_version6[];
145
146static const struct rpc_call_ops rpcb_getport_ops = {
147 .rpc_call_done = rpcb_getport_done,
148 .rpc_release = rpcb_map_release,
149};
150
151static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status)
152{
153 xprt_clear_binding(xprt);
154 rpc_wake_up_status(&xprt->binding, status);
155}
156
157static void rpcb_map_release(void *data)
158{
159 struct rpcbind_args *map = data;
160
161 rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status);
162 xprt_put(map->r_xprt);
163 kfree(map->r_addr);
164 kfree(map);
165}
166
167static int rpcb_get_local(void)
168{
169 int cnt;
170
171 spin_lock(&rpcb_clnt_lock);
172 if (rpcb_users)
173 rpcb_users++;
174 cnt = rpcb_users;
175 spin_unlock(&rpcb_clnt_lock);
176
177 return cnt;
178}
179
180void rpcb_put_local(void)
181{
182 struct rpc_clnt *clnt = rpcb_local_clnt;
183 struct rpc_clnt *clnt4 = rpcb_local_clnt4;
184 int shutdown;
185
186 spin_lock(&rpcb_clnt_lock);
187 if (--rpcb_users == 0) {
188 rpcb_local_clnt = NULL;
189 rpcb_local_clnt4 = NULL;
190 }
191 shutdown = !rpcb_users;
192 spin_unlock(&rpcb_clnt_lock);
193
194 if (shutdown) {
195
196
197
198 if (clnt4)
199 rpc_shutdown_client(clnt4);
200 if (clnt)
201 rpc_shutdown_client(clnt);
202 }
203}
204
205static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
206{
207
208 rpcb_local_clnt = clnt;
209 rpcb_local_clnt4 = clnt4;
210 smp_wmb();
211 rpcb_users = 1;
212 dprintk("RPC: created new rpcb local clients (rpcb_local_clnt: "
213 "%p, rpcb_local_clnt4: %p)\n", rpcb_local_clnt,
214 rpcb_local_clnt4);
215}
216
217
218
219
220
221static int rpcb_create_local_unix(void)
222{
223 static const struct sockaddr_un rpcb_localaddr_rpcbind = {
224 .sun_family = AF_LOCAL,
225 .sun_path = RPCBIND_SOCK_PATHNAME,
226 };
227 struct rpc_create_args args = {
228 .net = &init_net,
229 .protocol = XPRT_TRANSPORT_LOCAL,
230 .address = (struct sockaddr *)&rpcb_localaddr_rpcbind,
231 .addrsize = sizeof(rpcb_localaddr_rpcbind),
232 .servername = "localhost",
233 .program = &rpcb_program,
234 .version = RPCBVERS_2,
235 .authflavor = RPC_AUTH_NULL,
236 };
237 struct rpc_clnt *clnt, *clnt4;
238 int result = 0;
239
240
241
242
243
244
245 clnt = rpc_create(&args);
246 if (IS_ERR(clnt)) {
247 dprintk("RPC: failed to create AF_LOCAL rpcbind "
248 "client (errno %ld).\n", PTR_ERR(clnt));
249 result = -PTR_ERR(clnt);
250 goto out;
251 }
252
253 clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4);
254 if (IS_ERR(clnt4)) {
255 dprintk("RPC: failed to bind second program to "
256 "rpcbind v4 client (errno %ld).\n",
257 PTR_ERR(clnt4));
258 clnt4 = NULL;
259 }
260
261 rpcb_set_local(clnt, clnt4);
262
263out:
264 return result;
265}
266
267
268
269
270
271static int rpcb_create_local_net(void)
272{
273 static const struct sockaddr_in rpcb_inaddr_loopback = {
274 .sin_family = AF_INET,
275 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
276 .sin_port = htons(RPCBIND_PORT),
277 };
278 struct rpc_create_args args = {
279 .net = &init_net,
280 .protocol = XPRT_TRANSPORT_TCP,
281 .address = (struct sockaddr *)&rpcb_inaddr_loopback,
282 .addrsize = sizeof(rpcb_inaddr_loopback),
283 .servername = "localhost",
284 .program = &rpcb_program,
285 .version = RPCBVERS_2,
286 .authflavor = RPC_AUTH_UNIX,
287 .flags = RPC_CLNT_CREATE_NOPING,
288 };
289 struct rpc_clnt *clnt, *clnt4;
290 int result = 0;
291
292 clnt = rpc_create(&args);
293 if (IS_ERR(clnt)) {
294 dprintk("RPC: failed to create local rpcbind "
295 "client (errno %ld).\n", PTR_ERR(clnt));
296 result = -PTR_ERR(clnt);
297 goto out;
298 }
299
300
301
302
303
304
305 clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4);
306 if (IS_ERR(clnt4)) {
307 dprintk("RPC: failed to bind second program to "
308 "rpcbind v4 client (errno %ld).\n",
309 PTR_ERR(clnt4));
310 clnt4 = NULL;
311 }
312
313 rpcb_set_local(clnt, clnt4);
314
315out:
316 return result;
317}
318
319
320
321
322
323int rpcb_create_local(void)
324{
325 static DEFINE_MUTEX(rpcb_create_local_mutex);
326 int result = 0;
327
328 if (rpcb_get_local())
329 return result;
330
331 mutex_lock(&rpcb_create_local_mutex);
332 if (rpcb_get_local())
333 goto out;
334
335 if (rpcb_create_local_unix() != 0)
336 result = rpcb_create_local_net();
337
338out:
339 mutex_unlock(&rpcb_create_local_mutex);
340 return result;
341}
342
343static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
344 size_t salen, int proto, u32 version)
345{
346 struct rpc_create_args args = {
347 .net = &init_net,
348 .protocol = proto,
349 .address = srvaddr,
350 .addrsize = salen,
351 .servername = hostname,
352 .program = &rpcb_program,
353 .version = version,
354 .authflavor = RPC_AUTH_UNIX,
355 .flags = (RPC_CLNT_CREATE_NOPING |
356 RPC_CLNT_CREATE_NONPRIVPORT),
357 };
358
359 switch (srvaddr->sa_family) {
360 case AF_INET:
361 ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT);
362 break;
363 case AF_INET6:
364 ((struct sockaddr_in6 *)srvaddr)->sin6_port = htons(RPCBIND_PORT);
365 break;
366 default:
367 return ERR_PTR(-EAFNOSUPPORT);
368 }
369
370 return rpc_create(&args);
371}
372
373static int rpcb_register_call(struct rpc_clnt *clnt, struct rpc_message *msg)
374{
375 int result, error = 0;
376
377 msg->rpc_resp = &result;
378
379 error = rpc_call_sync(clnt, msg, RPC_TASK_SOFTCONN);
380 if (error < 0) {
381 dprintk("RPC: failed to contact local rpcbind "
382 "server (errno %d).\n", -error);
383 return error;
384 }
385
386 if (!result)
387 return -EACCES;
388 return 0;
389}
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
424{
425 struct rpcbind_args map = {
426 .r_prog = prog,
427 .r_vers = vers,
428 .r_prot = prot,
429 .r_port = port,
430 };
431 struct rpc_message msg = {
432 .rpc_argp = &map,
433 };
434
435 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
436 "rpcbind\n", (port ? "" : "un"),
437 prog, vers, prot, port);
438
439 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET];
440 if (port)
441 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
442
443 return rpcb_register_call(rpcb_local_clnt, &msg);
444}
445
446
447
448
449static int rpcb_register_inet4(const struct sockaddr *sap,
450 struct rpc_message *msg)
451{
452 const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
453 struct rpcbind_args *map = msg->rpc_argp;
454 unsigned short port = ntohs(sin->sin_port);
455 int result;
456
457 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
458
459 dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
460 "local rpcbind\n", (port ? "" : "un"),
461 map->r_prog, map->r_vers,
462 map->r_addr, map->r_netid);
463
464 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
465 if (port)
466 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
467
468 result = rpcb_register_call(rpcb_local_clnt4, msg);
469 kfree(map->r_addr);
470 return result;
471}
472
473
474
475
476static int rpcb_register_inet6(const struct sockaddr *sap,
477 struct rpc_message *msg)
478{
479 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
480 struct rpcbind_args *map = msg->rpc_argp;
481 unsigned short port = ntohs(sin6->sin6_port);
482 int result;
483
484 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
485
486 dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
487 "local rpcbind\n", (port ? "" : "un"),
488 map->r_prog, map->r_vers,
489 map->r_addr, map->r_netid);
490
491 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
492 if (port)
493 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
494
495 result = rpcb_register_call(rpcb_local_clnt4, msg);
496 kfree(map->r_addr);
497 return result;
498}
499
500static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
501{
502 struct rpcbind_args *map = msg->rpc_argp;
503
504 dprintk("RPC: unregistering [%u, %u, '%s'] with "
505 "local rpcbind\n",
506 map->r_prog, map->r_vers, map->r_netid);
507
508 map->r_addr = "";
509 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
510
511 return rpcb_register_call(rpcb_local_clnt4, msg);
512}
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557int rpcb_v4_register(const u32 program, const u32 version,
558 const struct sockaddr *address, const char *netid)
559{
560 struct rpcbind_args map = {
561 .r_prog = program,
562 .r_vers = version,
563 .r_netid = netid,
564 .r_owner = RPCB_OWNER_STRING,
565 };
566 struct rpc_message msg = {
567 .rpc_argp = &map,
568 };
569
570 if (rpcb_local_clnt4 == NULL)
571 return -EPROTONOSUPPORT;
572
573 if (address == NULL)
574 return rpcb_unregister_all_protofamilies(&msg);
575
576 switch (address->sa_family) {
577 case AF_INET:
578 return rpcb_register_inet4(address, &msg);
579 case AF_INET6:
580 return rpcb_register_inet6(address, &msg);
581 }
582
583 return -EAFNOSUPPORT;
584}
585
586static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc)
587{
588 struct rpc_message msg = {
589 .rpc_proc = proc,
590 .rpc_argp = map,
591 .rpc_resp = map,
592 };
593 struct rpc_task_setup task_setup_data = {
594 .rpc_client = rpcb_clnt,
595 .rpc_message = &msg,
596 .callback_ops = &rpcb_getport_ops,
597 .callback_data = map,
598 .flags = RPC_TASK_ASYNC | RPC_TASK_SOFTCONN,
599 };
600
601 return rpc_run_task(&task_setup_data);
602}
603
604
605
606
607
608
609
610
611static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt)
612{
613 struct rpc_clnt *parent = clnt->cl_parent;
614
615 while (parent != clnt) {
616 if (parent->cl_xprt != clnt->cl_xprt)
617 break;
618 if (clnt->cl_autobind)
619 break;
620 clnt = parent;
621 parent = parent->cl_parent;
622 }
623 return clnt;
624}
625
626
627
628
629
630
631
632
633void rpcb_getport_async(struct rpc_task *task)
634{
635 struct rpc_clnt *clnt;
636 struct rpc_procinfo *proc;
637 u32 bind_version;
638 struct rpc_xprt *xprt;
639 struct rpc_clnt *rpcb_clnt;
640 struct rpcbind_args *map;
641 struct rpc_task *child;
642 struct sockaddr_storage addr;
643 struct sockaddr *sap = (struct sockaddr *)&addr;
644 size_t salen;
645 int status;
646
647 clnt = rpcb_find_transport_owner(task->tk_client);
648 xprt = clnt->cl_xprt;
649
650 dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
651 task->tk_pid, __func__,
652 clnt->cl_server, clnt->cl_prog, clnt->cl_vers, xprt->prot);
653
654
655
656 rpc_sleep_on(&xprt->binding, task, NULL);
657
658 if (xprt_test_and_set_binding(xprt)) {
659 dprintk("RPC: %5u %s: waiting for another binder\n",
660 task->tk_pid, __func__);
661 return;
662 }
663
664
665 if (xprt_bound(xprt)) {
666 status = 0;
667 dprintk("RPC: %5u %s: already bound\n",
668 task->tk_pid, __func__);
669 goto bailout_nofree;
670 }
671
672
673 salen = rpc_peeraddr(clnt, sap, sizeof(addr));
674
675
676 switch (sap->sa_family) {
677 case AF_INET:
678 proc = rpcb_next_version[xprt->bind_index].rpc_proc;
679 bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
680 break;
681 case AF_INET6:
682 proc = rpcb_next_version6[xprt->bind_index].rpc_proc;
683 bind_version = rpcb_next_version6[xprt->bind_index].rpc_vers;
684 break;
685 default:
686 status = -EAFNOSUPPORT;
687 dprintk("RPC: %5u %s: bad address family\n",
688 task->tk_pid, __func__);
689 goto bailout_nofree;
690 }
691 if (proc == NULL) {
692 xprt->bind_index = 0;
693 status = -EPFNOSUPPORT;
694 dprintk("RPC: %5u %s: no more getport versions available\n",
695 task->tk_pid, __func__);
696 goto bailout_nofree;
697 }
698
699 dprintk("RPC: %5u %s: trying rpcbind version %u\n",
700 task->tk_pid, __func__, bind_version);
701
702 rpcb_clnt = rpcb_create(clnt->cl_server, sap, salen, xprt->prot,
703 bind_version);
704 if (IS_ERR(rpcb_clnt)) {
705 status = PTR_ERR(rpcb_clnt);
706 dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
707 task->tk_pid, __func__, PTR_ERR(rpcb_clnt));
708 goto bailout_nofree;
709 }
710
711 map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC);
712 if (!map) {
713 status = -ENOMEM;
714 dprintk("RPC: %5u %s: no memory available\n",
715 task->tk_pid, __func__);
716 goto bailout_release_client;
717 }
718 map->r_prog = clnt->cl_prog;
719 map->r_vers = clnt->cl_vers;
720 map->r_prot = xprt->prot;
721 map->r_port = 0;
722 map->r_xprt = xprt_get(xprt);
723 map->r_status = -EIO;
724
725 switch (bind_version) {
726 case RPCBVERS_4:
727 case RPCBVERS_3:
728 map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
729 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_ATOMIC);
730 map->r_owner = "";
731 break;
732 case RPCBVERS_2:
733 map->r_addr = NULL;
734 break;
735 default:
736 BUG();
737 }
738
739 child = rpcb_call_async(rpcb_clnt, map, proc);
740 rpc_release_client(rpcb_clnt);
741 if (IS_ERR(child)) {
742
743 dprintk("RPC: %5u %s: rpc_run_task failed\n",
744 task->tk_pid, __func__);
745 return;
746 }
747
748 xprt->stat.bind_count++;
749 rpc_put_task(child);
750 return;
751
752bailout_release_client:
753 rpc_release_client(rpcb_clnt);
754bailout_nofree:
755 rpcb_wake_rpcbind_waiters(xprt, status);
756 task->tk_status = status;
757}
758EXPORT_SYMBOL_GPL(rpcb_getport_async);
759
760
761
762
763static void rpcb_getport_done(struct rpc_task *child, void *data)
764{
765 struct rpcbind_args *map = data;
766 struct rpc_xprt *xprt = map->r_xprt;
767 int status = child->tk_status;
768
769
770 if (status == -EIO)
771 status = -EPROTONOSUPPORT;
772
773
774 if (status == -EPROTONOSUPPORT)
775 xprt->bind_index++;
776
777 if (status < 0) {
778
779 xprt->ops->set_port(xprt, 0);
780 } else if (map->r_port == 0) {
781
782 xprt->ops->set_port(xprt, 0);
783 status = -EACCES;
784 } else {
785
786 xprt->ops->set_port(xprt, map->r_port);
787 xprt_set_bound(xprt);
788 status = 0;
789 }
790
791 dprintk("RPC: %5u rpcb_getport_done(status %d, port %u)\n",
792 child->tk_pid, status, map->r_port);
793
794 map->r_status = status;
795}
796
797
798
799
800
801static void rpcb_enc_mapping(struct rpc_rqst *req, struct xdr_stream *xdr,
802 const struct rpcbind_args *rpcb)
803{
804 struct rpc_task *task = req->rq_task;
805 __be32 *p;
806
807 dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n",
808 task->tk_pid, task->tk_msg.rpc_proc->p_name,
809 rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port);
810
811 p = xdr_reserve_space(xdr, RPCB_mappingargs_sz << 2);
812 *p++ = cpu_to_be32(rpcb->r_prog);
813 *p++ = cpu_to_be32(rpcb->r_vers);
814 *p++ = cpu_to_be32(rpcb->r_prot);
815 *p = cpu_to_be32(rpcb->r_port);
816}
817
818static int rpcb_dec_getport(struct rpc_rqst *req, struct xdr_stream *xdr,
819 struct rpcbind_args *rpcb)
820{
821 struct rpc_task *task = req->rq_task;
822 unsigned long port;
823 __be32 *p;
824
825 rpcb->r_port = 0;
826
827 p = xdr_inline_decode(xdr, 4);
828 if (unlikely(p == NULL))
829 return -EIO;
830
831 port = be32_to_cpup(p);
832 dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid,
833 task->tk_msg.rpc_proc->p_name, port);
834 if (unlikely(port > USHRT_MAX))
835 return -EIO;
836
837 rpcb->r_port = port;
838 return 0;
839}
840
841static int rpcb_dec_set(struct rpc_rqst *req, struct xdr_stream *xdr,
842 unsigned int *boolp)
843{
844 struct rpc_task *task = req->rq_task;
845 __be32 *p;
846
847 p = xdr_inline_decode(xdr, 4);
848 if (unlikely(p == NULL))
849 return -EIO;
850
851 *boolp = 0;
852 if (*p != xdr_zero)
853 *boolp = 1;
854
855 dprintk("RPC: %5u RPCB_%s call %s\n",
856 task->tk_pid, task->tk_msg.rpc_proc->p_name,
857 (*boolp ? "succeeded" : "failed"));
858 return 0;
859}
860
861static void encode_rpcb_string(struct xdr_stream *xdr, const char *string,
862 const u32 maxstrlen)
863{
864 __be32 *p;
865 u32 len;
866
867 len = strlen(string);
868 BUG_ON(len > maxstrlen);
869 p = xdr_reserve_space(xdr, 4 + len);
870 xdr_encode_opaque(p, string, len);
871}
872
873static void rpcb_enc_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr,
874 const struct rpcbind_args *rpcb)
875{
876 struct rpc_task *task = req->rq_task;
877 __be32 *p;
878
879 dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n",
880 task->tk_pid, task->tk_msg.rpc_proc->p_name,
881 rpcb->r_prog, rpcb->r_vers,
882 rpcb->r_netid, rpcb->r_addr);
883
884 p = xdr_reserve_space(xdr, (RPCB_program_sz + RPCB_version_sz) << 2);
885 *p++ = cpu_to_be32(rpcb->r_prog);
886 *p = cpu_to_be32(rpcb->r_vers);
887
888 encode_rpcb_string(xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN);
889 encode_rpcb_string(xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN);
890 encode_rpcb_string(xdr, rpcb->r_owner, RPCB_MAXOWNERLEN);
891}
892
893static int rpcb_dec_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr,
894 struct rpcbind_args *rpcb)
895{
896 struct sockaddr_storage address;
897 struct sockaddr *sap = (struct sockaddr *)&address;
898 struct rpc_task *task = req->rq_task;
899 __be32 *p;
900 u32 len;
901
902 rpcb->r_port = 0;
903
904 p = xdr_inline_decode(xdr, 4);
905 if (unlikely(p == NULL))
906 goto out_fail;
907 len = be32_to_cpup(p);
908
909
910
911
912
913 if (len == 0) {
914 dprintk("RPC: %5u RPCB reply: program not registered\n",
915 task->tk_pid);
916 return 0;
917 }
918
919 if (unlikely(len > RPCBIND_MAXUADDRLEN))
920 goto out_fail;
921
922 p = xdr_inline_decode(xdr, len);
923 if (unlikely(p == NULL))
924 goto out_fail;
925 dprintk("RPC: %5u RPCB_%s reply: %s\n", task->tk_pid,
926 task->tk_msg.rpc_proc->p_name, (char *)p);
927
928 if (rpc_uaddr2sockaddr((char *)p, len, sap, sizeof(address)) == 0)
929 goto out_fail;
930 rpcb->r_port = rpc_get_port(sap);
931
932 return 0;
933
934out_fail:
935 dprintk("RPC: %5u malformed RPCB_%s reply\n",
936 task->tk_pid, task->tk_msg.rpc_proc->p_name);
937 return -EIO;
938}
939
940
941
942
943
944
945static struct rpc_procinfo rpcb_procedures2[] = {
946 [RPCBPROC_SET] = {
947 .p_proc = RPCBPROC_SET,
948 .p_encode = (kxdreproc_t)rpcb_enc_mapping,
949 .p_decode = (kxdrdproc_t)rpcb_dec_set,
950 .p_arglen = RPCB_mappingargs_sz,
951 .p_replen = RPCB_setres_sz,
952 .p_statidx = RPCBPROC_SET,
953 .p_timer = 0,
954 .p_name = "SET",
955 },
956 [RPCBPROC_UNSET] = {
957 .p_proc = RPCBPROC_UNSET,
958 .p_encode = (kxdreproc_t)rpcb_enc_mapping,
959 .p_decode = (kxdrdproc_t)rpcb_dec_set,
960 .p_arglen = RPCB_mappingargs_sz,
961 .p_replen = RPCB_setres_sz,
962 .p_statidx = RPCBPROC_UNSET,
963 .p_timer = 0,
964 .p_name = "UNSET",
965 },
966 [RPCBPROC_GETPORT] = {
967 .p_proc = RPCBPROC_GETPORT,
968 .p_encode = (kxdreproc_t)rpcb_enc_mapping,
969 .p_decode = (kxdrdproc_t)rpcb_dec_getport,
970 .p_arglen = RPCB_mappingargs_sz,
971 .p_replen = RPCB_getportres_sz,
972 .p_statidx = RPCBPROC_GETPORT,
973 .p_timer = 0,
974 .p_name = "GETPORT",
975 },
976};
977
978static struct rpc_procinfo rpcb_procedures3[] = {
979 [RPCBPROC_SET] = {
980 .p_proc = RPCBPROC_SET,
981 .p_encode = (kxdreproc_t)rpcb_enc_getaddr,
982 .p_decode = (kxdrdproc_t)rpcb_dec_set,
983 .p_arglen = RPCB_getaddrargs_sz,
984 .p_replen = RPCB_setres_sz,
985 .p_statidx = RPCBPROC_SET,
986 .p_timer = 0,
987 .p_name = "SET",
988 },
989 [RPCBPROC_UNSET] = {
990 .p_proc = RPCBPROC_UNSET,
991 .p_encode = (kxdreproc_t)rpcb_enc_getaddr,
992 .p_decode = (kxdrdproc_t)rpcb_dec_set,
993 .p_arglen = RPCB_getaddrargs_sz,
994 .p_replen = RPCB_setres_sz,
995 .p_statidx = RPCBPROC_UNSET,
996 .p_timer = 0,
997 .p_name = "UNSET",
998 },
999 [RPCBPROC_GETADDR] = {
1000 .p_proc = RPCBPROC_GETADDR,
1001 .p_encode = (kxdreproc_t)rpcb_enc_getaddr,
1002 .p_decode = (kxdrdproc_t)rpcb_dec_getaddr,
1003 .p_arglen = RPCB_getaddrargs_sz,
1004 .p_replen = RPCB_getaddrres_sz,
1005 .p_statidx = RPCBPROC_GETADDR,
1006 .p_timer = 0,
1007 .p_name = "GETADDR",
1008 },
1009};
1010
1011static struct rpc_procinfo rpcb_procedures4[] = {
1012 [RPCBPROC_SET] = {
1013 .p_proc = RPCBPROC_SET,
1014 .p_encode = (kxdreproc_t)rpcb_enc_getaddr,
1015 .p_decode = (kxdrdproc_t)rpcb_dec_set,
1016 .p_arglen = RPCB_getaddrargs_sz,
1017 .p_replen = RPCB_setres_sz,
1018 .p_statidx = RPCBPROC_SET,
1019 .p_timer = 0,
1020 .p_name = "SET",
1021 },
1022 [RPCBPROC_UNSET] = {
1023 .p_proc = RPCBPROC_UNSET,
1024 .p_encode = (kxdreproc_t)rpcb_enc_getaddr,
1025 .p_decode = (kxdrdproc_t)rpcb_dec_set,
1026 .p_arglen = RPCB_getaddrargs_sz,
1027 .p_replen = RPCB_setres_sz,
1028 .p_statidx = RPCBPROC_UNSET,
1029 .p_timer = 0,
1030 .p_name = "UNSET",
1031 },
1032 [RPCBPROC_GETADDR] = {
1033 .p_proc = RPCBPROC_GETADDR,
1034 .p_encode = (kxdreproc_t)rpcb_enc_getaddr,
1035 .p_decode = (kxdrdproc_t)rpcb_dec_getaddr,
1036 .p_arglen = RPCB_getaddrargs_sz,
1037 .p_replen = RPCB_getaddrres_sz,
1038 .p_statidx = RPCBPROC_GETADDR,
1039 .p_timer = 0,
1040 .p_name = "GETADDR",
1041 },
1042};
1043
1044static struct rpcb_info rpcb_next_version[] = {
1045 {
1046 .rpc_vers = RPCBVERS_2,
1047 .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT],
1048 },
1049 {
1050 .rpc_proc = NULL,
1051 },
1052};
1053
1054static struct rpcb_info rpcb_next_version6[] = {
1055 {
1056 .rpc_vers = RPCBVERS_4,
1057 .rpc_proc = &rpcb_procedures4[RPCBPROC_GETADDR],
1058 },
1059 {
1060 .rpc_vers = RPCBVERS_3,
1061 .rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR],
1062 },
1063 {
1064 .rpc_proc = NULL,
1065 },
1066};
1067
1068static struct rpc_version rpcb_version2 = {
1069 .number = RPCBVERS_2,
1070 .nrprocs = ARRAY_SIZE(rpcb_procedures2),
1071 .procs = rpcb_procedures2
1072};
1073
1074static struct rpc_version rpcb_version3 = {
1075 .number = RPCBVERS_3,
1076 .nrprocs = ARRAY_SIZE(rpcb_procedures3),
1077 .procs = rpcb_procedures3
1078};
1079
1080static struct rpc_version rpcb_version4 = {
1081 .number = RPCBVERS_4,
1082 .nrprocs = ARRAY_SIZE(rpcb_procedures4),
1083 .procs = rpcb_procedures4
1084};
1085
1086static struct rpc_version *rpcb_version[] = {
1087 NULL,
1088 NULL,
1089 &rpcb_version2,
1090 &rpcb_version3,
1091 &rpcb_version4
1092};
1093
1094static struct rpc_stat rpcb_stats;
1095
1096static struct rpc_program rpcb_program = {
1097 .name = "rpcbind",
1098 .number = RPCBIND_PROGRAM,
1099 .nrvers = ARRAY_SIZE(rpcb_version),
1100 .version = rpcb_version,
1101 .stats = &rpcb_stats,
1102};
1103