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_NOFS);
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_NOFS);
774 if (!map->r_addr) {
775 status = -ENOMEM;
776 dprintk("RPC: %5u %s: no memory available\n",
777 task->tk_pid, __func__);
778 goto bailout_free_args;
779 }
780 map->r_owner = "";
781 break;
782 case RPCBVERS_2:
783 map->r_addr = NULL;
784 break;
785 default:
786 BUG();
787 }
788
789 child = rpcb_call_async(rpcb_clnt, map, proc);
790 rpc_release_client(rpcb_clnt);
791 if (IS_ERR(child)) {
792
793 dprintk("RPC: %5u %s: rpc_run_task failed\n",
794 task->tk_pid, __func__);
795 return;
796 }
797
798 xprt->stat.bind_count++;
799 rpc_put_task(child);
800 return;
801
802bailout_free_args:
803 kfree(map);
804bailout_release_client:
805 rpc_release_client(rpcb_clnt);
806bailout_nofree:
807 rpcb_wake_rpcbind_waiters(xprt, status);
808 task->tk_status = status;
809 xprt_put(xprt);
810}
811EXPORT_SYMBOL_GPL(rpcb_getport_async);
812
813
814
815
816static void rpcb_getport_done(struct rpc_task *child, void *data)
817{
818 struct rpcbind_args *map = data;
819 struct rpc_xprt *xprt = map->r_xprt;
820 int status = child->tk_status;
821
822
823 if (status == -EIO)
824 status = -EPROTONOSUPPORT;
825
826
827 if (status == -EPROTONOSUPPORT)
828 xprt->bind_index++;
829
830 if (status < 0) {
831
832 xprt->ops->set_port(xprt, 0);
833 } else if (map->r_port == 0) {
834
835 xprt->ops->set_port(xprt, 0);
836 status = -EACCES;
837 } else {
838
839 xprt->ops->set_port(xprt, map->r_port);
840 xprt_set_bound(xprt);
841 status = 0;
842 }
843
844 dprintk("RPC: %5u rpcb_getport_done(status %d, port %u)\n",
845 child->tk_pid, status, map->r_port);
846
847 map->r_status = status;
848}
849
850
851
852
853
854static void rpcb_enc_mapping(struct rpc_rqst *req, struct xdr_stream *xdr,
855 const void *data)
856{
857 const struct rpcbind_args *rpcb = data;
858 __be32 *p;
859
860 dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n",
861 req->rq_task->tk_pid,
862 req->rq_task->tk_msg.rpc_proc->p_name,
863 rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port);
864
865 p = xdr_reserve_space(xdr, RPCB_mappingargs_sz << 2);
866 *p++ = cpu_to_be32(rpcb->r_prog);
867 *p++ = cpu_to_be32(rpcb->r_vers);
868 *p++ = cpu_to_be32(rpcb->r_prot);
869 *p = cpu_to_be32(rpcb->r_port);
870}
871
872static int rpcb_dec_getport(struct rpc_rqst *req, struct xdr_stream *xdr,
873 void *data)
874{
875 struct rpcbind_args *rpcb = data;
876 unsigned long port;
877 __be32 *p;
878
879 rpcb->r_port = 0;
880
881 p = xdr_inline_decode(xdr, 4);
882 if (unlikely(p == NULL))
883 return -EIO;
884
885 port = be32_to_cpup(p);
886 dprintk("RPC: %5u PMAP_%s result: %lu\n", req->rq_task->tk_pid,
887 req->rq_task->tk_msg.rpc_proc->p_name, port);
888 if (unlikely(port > USHRT_MAX))
889 return -EIO;
890
891 rpcb->r_port = port;
892 return 0;
893}
894
895static int rpcb_dec_set(struct rpc_rqst *req, struct xdr_stream *xdr,
896 void *data)
897{
898 unsigned int *boolp = data;
899 __be32 *p;
900
901 p = xdr_inline_decode(xdr, 4);
902 if (unlikely(p == NULL))
903 return -EIO;
904
905 *boolp = 0;
906 if (*p != xdr_zero)
907 *boolp = 1;
908
909 dprintk("RPC: %5u RPCB_%s call %s\n",
910 req->rq_task->tk_pid,
911 req->rq_task->tk_msg.rpc_proc->p_name,
912 (*boolp ? "succeeded" : "failed"));
913 return 0;
914}
915
916static void encode_rpcb_string(struct xdr_stream *xdr, const char *string,
917 const u32 maxstrlen)
918{
919 __be32 *p;
920 u32 len;
921
922 len = strlen(string);
923 WARN_ON_ONCE(len > maxstrlen);
924 if (len > maxstrlen)
925
926 len = maxstrlen;
927 p = xdr_reserve_space(xdr, 4 + len);
928 xdr_encode_opaque(p, string, len);
929}
930
931static void rpcb_enc_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr,
932 const void *data)
933{
934 const struct rpcbind_args *rpcb = data;
935 __be32 *p;
936
937 dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n",
938 req->rq_task->tk_pid,
939 req->rq_task->tk_msg.rpc_proc->p_name,
940 rpcb->r_prog, rpcb->r_vers,
941 rpcb->r_netid, rpcb->r_addr);
942
943 p = xdr_reserve_space(xdr, (RPCB_program_sz + RPCB_version_sz) << 2);
944 *p++ = cpu_to_be32(rpcb->r_prog);
945 *p = cpu_to_be32(rpcb->r_vers);
946
947 encode_rpcb_string(xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN);
948 encode_rpcb_string(xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN);
949 encode_rpcb_string(xdr, rpcb->r_owner, RPCB_MAXOWNERLEN);
950}
951
952static int rpcb_dec_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr,
953 void *data)
954{
955 struct rpcbind_args *rpcb = data;
956 struct sockaddr_storage address;
957 struct sockaddr *sap = (struct sockaddr *)&address;
958 __be32 *p;
959 u32 len;
960
961 rpcb->r_port = 0;
962
963 p = xdr_inline_decode(xdr, 4);
964 if (unlikely(p == NULL))
965 goto out_fail;
966 len = be32_to_cpup(p);
967
968
969
970
971
972 if (len == 0) {
973 dprintk("RPC: %5u RPCB reply: program not registered\n",
974 req->rq_task->tk_pid);
975 return 0;
976 }
977
978 if (unlikely(len > RPCBIND_MAXUADDRLEN))
979 goto out_fail;
980
981 p = xdr_inline_decode(xdr, len);
982 if (unlikely(p == NULL))
983 goto out_fail;
984 dprintk("RPC: %5u RPCB_%s reply: %s\n", req->rq_task->tk_pid,
985 req->rq_task->tk_msg.rpc_proc->p_name, (char *)p);
986
987 if (rpc_uaddr2sockaddr(req->rq_xprt->xprt_net, (char *)p, len,
988 sap, sizeof(address)) == 0)
989 goto out_fail;
990 rpcb->r_port = rpc_get_port(sap);
991
992 return 0;
993
994out_fail:
995 dprintk("RPC: %5u malformed RPCB_%s reply\n",
996 req->rq_task->tk_pid,
997 req->rq_task->tk_msg.rpc_proc->p_name);
998 return -EIO;
999}
1000
1001
1002
1003
1004
1005
1006static const struct rpc_procinfo rpcb_procedures2[] = {
1007 [RPCBPROC_SET] = {
1008 .p_proc = RPCBPROC_SET,
1009 .p_encode = rpcb_enc_mapping,
1010 .p_decode = rpcb_dec_set,
1011 .p_arglen = RPCB_mappingargs_sz,
1012 .p_replen = RPCB_setres_sz,
1013 .p_statidx = RPCBPROC_SET,
1014 .p_timer = 0,
1015 .p_name = "SET",
1016 },
1017 [RPCBPROC_UNSET] = {
1018 .p_proc = RPCBPROC_UNSET,
1019 .p_encode = rpcb_enc_mapping,
1020 .p_decode = rpcb_dec_set,
1021 .p_arglen = RPCB_mappingargs_sz,
1022 .p_replen = RPCB_setres_sz,
1023 .p_statidx = RPCBPROC_UNSET,
1024 .p_timer = 0,
1025 .p_name = "UNSET",
1026 },
1027 [RPCBPROC_GETPORT] = {
1028 .p_proc = RPCBPROC_GETPORT,
1029 .p_encode = rpcb_enc_mapping,
1030 .p_decode = rpcb_dec_getport,
1031 .p_arglen = RPCB_mappingargs_sz,
1032 .p_replen = RPCB_getportres_sz,
1033 .p_statidx = RPCBPROC_GETPORT,
1034 .p_timer = 0,
1035 .p_name = "GETPORT",
1036 },
1037};
1038
1039static const struct rpc_procinfo rpcb_procedures3[] = {
1040 [RPCBPROC_SET] = {
1041 .p_proc = RPCBPROC_SET,
1042 .p_encode = rpcb_enc_getaddr,
1043 .p_decode = rpcb_dec_set,
1044 .p_arglen = RPCB_getaddrargs_sz,
1045 .p_replen = RPCB_setres_sz,
1046 .p_statidx = RPCBPROC_SET,
1047 .p_timer = 0,
1048 .p_name = "SET",
1049 },
1050 [RPCBPROC_UNSET] = {
1051 .p_proc = RPCBPROC_UNSET,
1052 .p_encode = rpcb_enc_getaddr,
1053 .p_decode = rpcb_dec_set,
1054 .p_arglen = RPCB_getaddrargs_sz,
1055 .p_replen = RPCB_setres_sz,
1056 .p_statidx = RPCBPROC_UNSET,
1057 .p_timer = 0,
1058 .p_name = "UNSET",
1059 },
1060 [RPCBPROC_GETADDR] = {
1061 .p_proc = RPCBPROC_GETADDR,
1062 .p_encode = rpcb_enc_getaddr,
1063 .p_decode = rpcb_dec_getaddr,
1064 .p_arglen = RPCB_getaddrargs_sz,
1065 .p_replen = RPCB_getaddrres_sz,
1066 .p_statidx = RPCBPROC_GETADDR,
1067 .p_timer = 0,
1068 .p_name = "GETADDR",
1069 },
1070};
1071
1072static const struct rpc_procinfo rpcb_procedures4[] = {
1073 [RPCBPROC_SET] = {
1074 .p_proc = RPCBPROC_SET,
1075 .p_encode = rpcb_enc_getaddr,
1076 .p_decode = rpcb_dec_set,
1077 .p_arglen = RPCB_getaddrargs_sz,
1078 .p_replen = RPCB_setres_sz,
1079 .p_statidx = RPCBPROC_SET,
1080 .p_timer = 0,
1081 .p_name = "SET",
1082 },
1083 [RPCBPROC_UNSET] = {
1084 .p_proc = RPCBPROC_UNSET,
1085 .p_encode = rpcb_enc_getaddr,
1086 .p_decode = rpcb_dec_set,
1087 .p_arglen = RPCB_getaddrargs_sz,
1088 .p_replen = RPCB_setres_sz,
1089 .p_statidx = RPCBPROC_UNSET,
1090 .p_timer = 0,
1091 .p_name = "UNSET",
1092 },
1093 [RPCBPROC_GETADDR] = {
1094 .p_proc = RPCBPROC_GETADDR,
1095 .p_encode = rpcb_enc_getaddr,
1096 .p_decode = rpcb_dec_getaddr,
1097 .p_arglen = RPCB_getaddrargs_sz,
1098 .p_replen = RPCB_getaddrres_sz,
1099 .p_statidx = RPCBPROC_GETADDR,
1100 .p_timer = 0,
1101 .p_name = "GETADDR",
1102 },
1103};
1104
1105static const struct rpcb_info rpcb_next_version[] = {
1106 {
1107 .rpc_vers = RPCBVERS_2,
1108 .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT],
1109 },
1110 {
1111 .rpc_proc = NULL,
1112 },
1113};
1114
1115static const struct rpcb_info rpcb_next_version6[] = {
1116 {
1117 .rpc_vers = RPCBVERS_4,
1118 .rpc_proc = &rpcb_procedures4[RPCBPROC_GETADDR],
1119 },
1120 {
1121 .rpc_vers = RPCBVERS_3,
1122 .rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR],
1123 },
1124 {
1125 .rpc_proc = NULL,
1126 },
1127};
1128
1129static unsigned int rpcb_version2_counts[ARRAY_SIZE(rpcb_procedures2)];
1130static const struct rpc_version rpcb_version2 = {
1131 .number = RPCBVERS_2,
1132 .nrprocs = ARRAY_SIZE(rpcb_procedures2),
1133 .procs = rpcb_procedures2,
1134 .counts = rpcb_version2_counts,
1135};
1136
1137static unsigned int rpcb_version3_counts[ARRAY_SIZE(rpcb_procedures3)];
1138static const struct rpc_version rpcb_version3 = {
1139 .number = RPCBVERS_3,
1140 .nrprocs = ARRAY_SIZE(rpcb_procedures3),
1141 .procs = rpcb_procedures3,
1142 .counts = rpcb_version3_counts,
1143};
1144
1145static unsigned int rpcb_version4_counts[ARRAY_SIZE(rpcb_procedures4)];
1146static const struct rpc_version rpcb_version4 = {
1147 .number = RPCBVERS_4,
1148 .nrprocs = ARRAY_SIZE(rpcb_procedures4),
1149 .procs = rpcb_procedures4,
1150 .counts = rpcb_version4_counts,
1151};
1152
1153static const struct rpc_version *rpcb_version[] = {
1154 NULL,
1155 NULL,
1156 &rpcb_version2,
1157 &rpcb_version3,
1158 &rpcb_version4
1159};
1160
1161static struct rpc_stat rpcb_stats;
1162
1163static const struct rpc_program rpcb_program = {
1164 .name = "rpcbind",
1165 .number = RPCBIND_PROGRAM,
1166 .nrvers = ARRAY_SIZE(rpcb_version),
1167 .version = rpcb_version,
1168 .stats = &rpcb_stats,
1169};
1170