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