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{
349 struct rpc_create_args args = {
350 .net = net,
351 .protocol = proto,
352 .address = srvaddr,
353 .addrsize = salen,
354 .servername = hostname,
355 .nodename = nodename,
356 .program = &rpcb_program,
357 .version = version,
358 .authflavor = RPC_AUTH_UNIX,
359 .cred = cred,
360 .flags = (RPC_CLNT_CREATE_NOPING |
361 RPC_CLNT_CREATE_NONPRIVPORT),
362 };
363
364 switch (srvaddr->sa_family) {
365 case AF_INET:
366 ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT);
367 break;
368 case AF_INET6:
369 ((struct sockaddr_in6 *)srvaddr)->sin6_port = htons(RPCBIND_PORT);
370 break;
371 default:
372 return ERR_PTR(-EAFNOSUPPORT);
373 }
374
375 return rpc_create(&args);
376}
377
378static int rpcb_register_call(struct sunrpc_net *sn, struct rpc_clnt *clnt, struct rpc_message *msg, bool is_set)
379{
380 int flags = RPC_TASK_NOCONNECT;
381 int error, result = 0;
382
383 if (is_set || !sn->rpcb_is_af_local)
384 flags = RPC_TASK_SOFTCONN;
385 msg->rpc_resp = &result;
386
387 error = rpc_call_sync(clnt, msg, flags);
388 if (error < 0)
389 return error;
390
391 if (!result)
392 return -EACCES;
393 return 0;
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
423
424
425
426
427
428
429int rpcb_register(struct net *net, u32 prog, u32 vers, int prot, unsigned short port)
430{
431 struct rpcbind_args map = {
432 .r_prog = prog,
433 .r_vers = vers,
434 .r_prot = prot,
435 .r_port = port,
436 };
437 struct rpc_message msg = {
438 .rpc_argp = &map,
439 };
440 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
441 bool is_set = false;
442
443 trace_pmap_register(prog, vers, prot, port);
444
445 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET];
446 if (port != 0) {
447 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
448 is_set = true;
449 }
450
451 return rpcb_register_call(sn, sn->rpcb_local_clnt, &msg, is_set);
452}
453
454
455
456
457static int rpcb_register_inet4(struct sunrpc_net *sn,
458 const struct sockaddr *sap,
459 struct rpc_message *msg)
460{
461 const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
462 struct rpcbind_args *map = msg->rpc_argp;
463 unsigned short port = ntohs(sin->sin_port);
464 bool is_set = false;
465 int result;
466
467 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
468
469 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
470 if (port != 0) {
471 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
472 is_set = true;
473 }
474
475 result = rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, is_set);
476 kfree(map->r_addr);
477 return result;
478}
479
480
481
482
483static int rpcb_register_inet6(struct sunrpc_net *sn,
484 const struct sockaddr *sap,
485 struct rpc_message *msg)
486{
487 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
488 struct rpcbind_args *map = msg->rpc_argp;
489 unsigned short port = ntohs(sin6->sin6_port);
490 bool is_set = false;
491 int result;
492
493 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
494
495 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
496 if (port != 0) {
497 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
498 is_set = true;
499 }
500
501 result = rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, is_set);
502 kfree(map->r_addr);
503 return result;
504}
505
506static int rpcb_unregister_all_protofamilies(struct sunrpc_net *sn,
507 struct rpc_message *msg)
508{
509 struct rpcbind_args *map = msg->rpc_argp;
510
511 trace_rpcb_unregister(map->r_prog, map->r_vers, map->r_netid);
512
513 map->r_addr = "";
514 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
515
516 return rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, false);
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
557
558
559
560
561
562
563int rpcb_v4_register(struct net *net, const u32 program, const u32 version,
564 const struct sockaddr *address, const char *netid)
565{
566 struct rpcbind_args map = {
567 .r_prog = program,
568 .r_vers = version,
569 .r_netid = netid,
570 .r_owner = RPCB_OWNER_STRING,
571 };
572 struct rpc_message msg = {
573 .rpc_argp = &map,
574 };
575 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
576
577 if (sn->rpcb_local_clnt4 == NULL)
578 return -EPROTONOSUPPORT;
579
580 if (address == NULL)
581 return rpcb_unregister_all_protofamilies(sn, &msg);
582
583 trace_rpcb_register(map.r_prog, map.r_vers, map.r_addr, map.r_netid);
584
585 switch (address->sa_family) {
586 case AF_INET:
587 return rpcb_register_inet4(sn, address, &msg);
588 case AF_INET6:
589 return rpcb_register_inet6(sn, address, &msg);
590 }
591
592 return -EAFNOSUPPORT;
593}
594
595static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt,
596 struct rpcbind_args *map, const struct rpc_procinfo *proc)
597{
598 struct rpc_message msg = {
599 .rpc_proc = proc,
600 .rpc_argp = map,
601 .rpc_resp = map,
602 };
603 struct rpc_task_setup task_setup_data = {
604 .rpc_client = rpcb_clnt,
605 .rpc_message = &msg,
606 .callback_ops = &rpcb_getport_ops,
607 .callback_data = map,
608 .flags = RPC_TASK_ASYNC | RPC_TASK_SOFTCONN,
609 };
610
611 return rpc_run_task(&task_setup_data);
612}
613
614
615
616
617
618
619
620
621static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt)
622{
623 struct rpc_clnt *parent = clnt->cl_parent;
624 struct rpc_xprt_switch *xps = rcu_access_pointer(clnt->cl_xpi.xpi_xpswitch);
625
626 while (parent != clnt) {
627 if (rcu_access_pointer(parent->cl_xpi.xpi_xpswitch) != xps)
628 break;
629 if (clnt->cl_autobind)
630 break;
631 clnt = parent;
632 parent = parent->cl_parent;
633 }
634 return clnt;
635}
636
637
638
639
640
641
642
643
644void rpcb_getport_async(struct rpc_task *task)
645{
646 struct rpc_clnt *clnt;
647 const struct rpc_procinfo *proc;
648 u32 bind_version;
649 struct rpc_xprt *xprt;
650 struct rpc_clnt *rpcb_clnt;
651 struct rpcbind_args *map;
652 struct rpc_task *child;
653 struct sockaddr_storage addr;
654 struct sockaddr *sap = (struct sockaddr *)&addr;
655 size_t salen;
656 int status;
657
658 rcu_read_lock();
659 clnt = rpcb_find_transport_owner(task->tk_client);
660 rcu_read_unlock();
661 xprt = xprt_get(task->tk_xprt);
662
663
664
665 rpc_sleep_on_timeout(&xprt->binding, task,
666 NULL, jiffies + xprt->bind_timeout);
667
668 if (xprt_test_and_set_binding(xprt)) {
669 xprt_put(xprt);
670 return;
671 }
672
673
674 if (xprt_bound(xprt)) {
675 status = 0;
676 goto bailout_nofree;
677 }
678
679
680 salen = rpc_peeraddr(clnt, sap, sizeof(addr));
681
682
683 switch (sap->sa_family) {
684 case AF_INET:
685 proc = rpcb_next_version[xprt->bind_index].rpc_proc;
686 bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
687 break;
688 case AF_INET6:
689 proc = rpcb_next_version6[xprt->bind_index].rpc_proc;
690 bind_version = rpcb_next_version6[xprt->bind_index].rpc_vers;
691 break;
692 default:
693 status = -EAFNOSUPPORT;
694 goto bailout_nofree;
695 }
696 if (proc == NULL) {
697 xprt->bind_index = 0;
698 status = -EPFNOSUPPORT;
699 goto bailout_nofree;
700 }
701
702 trace_rpcb_getport(clnt, task, bind_version);
703
704 rpcb_clnt = rpcb_create(xprt->xprt_net,
705 clnt->cl_nodename,
706 xprt->servername, sap, salen,
707 xprt->prot, bind_version,
708 clnt->cl_cred);
709 if (IS_ERR(rpcb_clnt)) {
710 status = PTR_ERR(rpcb_clnt);
711 goto bailout_nofree;
712 }
713
714 map = kzalloc(sizeof(struct rpcbind_args), GFP_NOFS);
715 if (!map) {
716 status = -ENOMEM;
717 goto bailout_release_client;
718 }
719 map->r_prog = clnt->cl_prog;
720 map->r_vers = clnt->cl_vers;
721 map->r_prot = xprt->prot;
722 map->r_port = 0;
723 map->r_xprt = xprt;
724 map->r_status = -EIO;
725
726 switch (bind_version) {
727 case RPCBVERS_4:
728 case RPCBVERS_3:
729 map->r_netid = xprt->address_strings[RPC_DISPLAY_NETID];
730 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_NOFS);
731 if (!map->r_addr) {
732 status = -ENOMEM;
733 goto bailout_free_args;
734 }
735 map->r_owner = "";
736 break;
737 case RPCBVERS_2:
738 map->r_addr = NULL;
739 break;
740 default:
741 BUG();
742 }
743
744 child = rpcb_call_async(rpcb_clnt, map, proc);
745 rpc_release_client(rpcb_clnt);
746
747 xprt->stat.bind_count++;
748 rpc_put_task(child);
749 return;
750
751bailout_free_args:
752 kfree(map);
753bailout_release_client:
754 rpc_release_client(rpcb_clnt);
755bailout_nofree:
756 rpcb_wake_rpcbind_waiters(xprt, status);
757 task->tk_status = status;
758 xprt_put(xprt);
759}
760EXPORT_SYMBOL_GPL(rpcb_getport_async);
761
762
763
764
765static void rpcb_getport_done(struct rpc_task *child, void *data)
766{
767 struct rpcbind_args *map = data;
768 struct rpc_xprt *xprt = map->r_xprt;
769
770 map->r_status = child->tk_status;
771
772
773 if (map->r_status == -EIO)
774 map->r_status = -EPROTONOSUPPORT;
775
776
777 if (map->r_status == -EPROTONOSUPPORT)
778 xprt->bind_index++;
779
780 if (map->r_status < 0) {
781
782 map->r_port = 0;
783
784 } else if (map->r_port == 0) {
785
786 map->r_status = -EACCES;
787 } else {
788
789 map->r_status = 0;
790 }
791
792 trace_rpcb_setport(child, map->r_status, map->r_port);
793 xprt->ops->set_port(xprt, map->r_port);
794 if (map->r_port)
795 xprt_set_bound(xprt);
796}
797
798
799
800
801
802static void rpcb_enc_mapping(struct rpc_rqst *req, struct xdr_stream *xdr,
803 const void *data)
804{
805 const struct rpcbind_args *rpcb = data;
806 __be32 *p;
807
808 p = xdr_reserve_space(xdr, RPCB_mappingargs_sz << 2);
809 *p++ = cpu_to_be32(rpcb->r_prog);
810 *p++ = cpu_to_be32(rpcb->r_vers);
811 *p++ = cpu_to_be32(rpcb->r_prot);
812 *p = cpu_to_be32(rpcb->r_port);
813}
814
815static int rpcb_dec_getport(struct rpc_rqst *req, struct xdr_stream *xdr,
816 void *data)
817{
818 struct rpcbind_args *rpcb = data;
819 unsigned long port;
820 __be32 *p;
821
822 rpcb->r_port = 0;
823
824 p = xdr_inline_decode(xdr, 4);
825 if (unlikely(p == NULL))
826 return -EIO;
827
828 port = be32_to_cpup(p);
829 if (unlikely(port > USHRT_MAX))
830 return -EIO;
831
832 rpcb->r_port = port;
833 return 0;
834}
835
836static int rpcb_dec_set(struct rpc_rqst *req, struct xdr_stream *xdr,
837 void *data)
838{
839 unsigned int *boolp = data;
840 __be32 *p;
841
842 p = xdr_inline_decode(xdr, 4);
843 if (unlikely(p == NULL))
844 return -EIO;
845
846 *boolp = 0;
847 if (*p != xdr_zero)
848 *boolp = 1;
849 return 0;
850}
851
852static void encode_rpcb_string(struct xdr_stream *xdr, const char *string,
853 const u32 maxstrlen)
854{
855 __be32 *p;
856 u32 len;
857
858 len = strlen(string);
859 WARN_ON_ONCE(len > maxstrlen);
860 if (len > maxstrlen)
861
862 len = maxstrlen;
863 p = xdr_reserve_space(xdr, 4 + len);
864 xdr_encode_opaque(p, string, len);
865}
866
867static void rpcb_enc_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr,
868 const void *data)
869{
870 const struct rpcbind_args *rpcb = data;
871 __be32 *p;
872
873 p = xdr_reserve_space(xdr, (RPCB_program_sz + RPCB_version_sz) << 2);
874 *p++ = cpu_to_be32(rpcb->r_prog);
875 *p = cpu_to_be32(rpcb->r_vers);
876
877 encode_rpcb_string(xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN);
878 encode_rpcb_string(xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN);
879 encode_rpcb_string(xdr, rpcb->r_owner, RPCB_MAXOWNERLEN);
880}
881
882static int rpcb_dec_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr,
883 void *data)
884{
885 struct rpcbind_args *rpcb = data;
886 struct sockaddr_storage address;
887 struct sockaddr *sap = (struct sockaddr *)&address;
888 __be32 *p;
889 u32 len;
890
891 rpcb->r_port = 0;
892
893 p = xdr_inline_decode(xdr, 4);
894 if (unlikely(p == NULL))
895 goto out_fail;
896 len = be32_to_cpup(p);
897
898
899
900
901
902 if (len == 0)
903 return 0;
904
905 if (unlikely(len > RPCBIND_MAXUADDRLEN))
906 goto out_fail;
907
908 p = xdr_inline_decode(xdr, len);
909 if (unlikely(p == NULL))
910 goto out_fail;
911
912 if (rpc_uaddr2sockaddr(req->rq_xprt->xprt_net, (char *)p, len,
913 sap, sizeof(address)) == 0)
914 goto out_fail;
915 rpcb->r_port = rpc_get_port(sap);
916
917 return 0;
918
919out_fail:
920 return -EIO;
921}
922
923
924
925
926
927
928static const struct rpc_procinfo rpcb_procedures2[] = {
929 [RPCBPROC_SET] = {
930 .p_proc = RPCBPROC_SET,
931 .p_encode = rpcb_enc_mapping,
932 .p_decode = rpcb_dec_set,
933 .p_arglen = RPCB_mappingargs_sz,
934 .p_replen = RPCB_setres_sz,
935 .p_statidx = RPCBPROC_SET,
936 .p_timer = 0,
937 .p_name = "SET",
938 },
939 [RPCBPROC_UNSET] = {
940 .p_proc = RPCBPROC_UNSET,
941 .p_encode = rpcb_enc_mapping,
942 .p_decode = rpcb_dec_set,
943 .p_arglen = RPCB_mappingargs_sz,
944 .p_replen = RPCB_setres_sz,
945 .p_statidx = RPCBPROC_UNSET,
946 .p_timer = 0,
947 .p_name = "UNSET",
948 },
949 [RPCBPROC_GETPORT] = {
950 .p_proc = RPCBPROC_GETPORT,
951 .p_encode = rpcb_enc_mapping,
952 .p_decode = rpcb_dec_getport,
953 .p_arglen = RPCB_mappingargs_sz,
954 .p_replen = RPCB_getportres_sz,
955 .p_statidx = RPCBPROC_GETPORT,
956 .p_timer = 0,
957 .p_name = "GETPORT",
958 },
959};
960
961static const struct rpc_procinfo rpcb_procedures3[] = {
962 [RPCBPROC_SET] = {
963 .p_proc = RPCBPROC_SET,
964 .p_encode = rpcb_enc_getaddr,
965 .p_decode = rpcb_dec_set,
966 .p_arglen = RPCB_getaddrargs_sz,
967 .p_replen = RPCB_setres_sz,
968 .p_statidx = RPCBPROC_SET,
969 .p_timer = 0,
970 .p_name = "SET",
971 },
972 [RPCBPROC_UNSET] = {
973 .p_proc = RPCBPROC_UNSET,
974 .p_encode = rpcb_enc_getaddr,
975 .p_decode = rpcb_dec_set,
976 .p_arglen = RPCB_getaddrargs_sz,
977 .p_replen = RPCB_setres_sz,
978 .p_statidx = RPCBPROC_UNSET,
979 .p_timer = 0,
980 .p_name = "UNSET",
981 },
982 [RPCBPROC_GETADDR] = {
983 .p_proc = RPCBPROC_GETADDR,
984 .p_encode = rpcb_enc_getaddr,
985 .p_decode = rpcb_dec_getaddr,
986 .p_arglen = RPCB_getaddrargs_sz,
987 .p_replen = RPCB_getaddrres_sz,
988 .p_statidx = RPCBPROC_GETADDR,
989 .p_timer = 0,
990 .p_name = "GETADDR",
991 },
992};
993
994static const struct rpc_procinfo rpcb_procedures4[] = {
995 [RPCBPROC_SET] = {
996 .p_proc = RPCBPROC_SET,
997 .p_encode = rpcb_enc_getaddr,
998 .p_decode = rpcb_dec_set,
999 .p_arglen = RPCB_getaddrargs_sz,
1000 .p_replen = RPCB_setres_sz,
1001 .p_statidx = RPCBPROC_SET,
1002 .p_timer = 0,
1003 .p_name = "SET",
1004 },
1005 [RPCBPROC_UNSET] = {
1006 .p_proc = RPCBPROC_UNSET,
1007 .p_encode = rpcb_enc_getaddr,
1008 .p_decode = rpcb_dec_set,
1009 .p_arglen = RPCB_getaddrargs_sz,
1010 .p_replen = RPCB_setres_sz,
1011 .p_statidx = RPCBPROC_UNSET,
1012 .p_timer = 0,
1013 .p_name = "UNSET",
1014 },
1015 [RPCBPROC_GETADDR] = {
1016 .p_proc = RPCBPROC_GETADDR,
1017 .p_encode = rpcb_enc_getaddr,
1018 .p_decode = rpcb_dec_getaddr,
1019 .p_arglen = RPCB_getaddrargs_sz,
1020 .p_replen = RPCB_getaddrres_sz,
1021 .p_statidx = RPCBPROC_GETADDR,
1022 .p_timer = 0,
1023 .p_name = "GETADDR",
1024 },
1025};
1026
1027static const struct rpcb_info rpcb_next_version[] = {
1028 {
1029 .rpc_vers = RPCBVERS_2,
1030 .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT],
1031 },
1032 {
1033 .rpc_proc = NULL,
1034 },
1035};
1036
1037static const struct rpcb_info rpcb_next_version6[] = {
1038 {
1039 .rpc_vers = RPCBVERS_4,
1040 .rpc_proc = &rpcb_procedures4[RPCBPROC_GETADDR],
1041 },
1042 {
1043 .rpc_vers = RPCBVERS_3,
1044 .rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR],
1045 },
1046 {
1047 .rpc_proc = NULL,
1048 },
1049};
1050
1051static unsigned int rpcb_version2_counts[ARRAY_SIZE(rpcb_procedures2)];
1052static const struct rpc_version rpcb_version2 = {
1053 .number = RPCBVERS_2,
1054 .nrprocs = ARRAY_SIZE(rpcb_procedures2),
1055 .procs = rpcb_procedures2,
1056 .counts = rpcb_version2_counts,
1057};
1058
1059static unsigned int rpcb_version3_counts[ARRAY_SIZE(rpcb_procedures3)];
1060static const struct rpc_version rpcb_version3 = {
1061 .number = RPCBVERS_3,
1062 .nrprocs = ARRAY_SIZE(rpcb_procedures3),
1063 .procs = rpcb_procedures3,
1064 .counts = rpcb_version3_counts,
1065};
1066
1067static unsigned int rpcb_version4_counts[ARRAY_SIZE(rpcb_procedures4)];
1068static const struct rpc_version rpcb_version4 = {
1069 .number = RPCBVERS_4,
1070 .nrprocs = ARRAY_SIZE(rpcb_procedures4),
1071 .procs = rpcb_procedures4,
1072 .counts = rpcb_version4_counts,
1073};
1074
1075static const struct rpc_version *rpcb_version[] = {
1076 NULL,
1077 NULL,
1078 &rpcb_version2,
1079 &rpcb_version3,
1080 &rpcb_version4
1081};
1082
1083static struct rpc_stat rpcb_stats;
1084
1085static const struct rpc_program rpcb_program = {
1086 .name = "rpcbind",
1087 .number = RPCBIND_PROGRAM,
1088 .nrvers = ARRAY_SIZE(rpcb_version),
1089 .version = rpcb_version,
1090 .stats = &rpcb_stats,
1091};
1092