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