0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include <linux/module.h>
0017
0018 #include <linux/types.h>
0019 #include <linux/socket.h>
0020 #include <linux/un.h>
0021 #include <linux/in.h>
0022 #include <linux/in6.h>
0023 #include <linux/kernel.h>
0024 #include <linux/errno.h>
0025 #include <linux/mutex.h>
0026 #include <linux/slab.h>
0027 #include <net/ipv6.h>
0028
0029 #include <linux/sunrpc/clnt.h>
0030 #include <linux/sunrpc/addr.h>
0031 #include <linux/sunrpc/sched.h>
0032 #include <linux/sunrpc/xprtsock.h>
0033
0034 #include <trace/events/sunrpc.h>
0035
0036 #include "netns.h"
0037
0038 #define RPCBIND_SOCK_PATHNAME "/var/run/rpcbind.sock"
0039
0040 #define RPCBIND_PROGRAM (100000u)
0041 #define RPCBIND_PORT (111u)
0042
0043 #define RPCBVERS_2 (2u)
0044 #define RPCBVERS_3 (3u)
0045 #define RPCBVERS_4 (4u)
0046
0047 enum {
0048 RPCBPROC_NULL,
0049 RPCBPROC_SET,
0050 RPCBPROC_UNSET,
0051 RPCBPROC_GETPORT,
0052 RPCBPROC_GETADDR = 3,
0053 RPCBPROC_DUMP,
0054 RPCBPROC_CALLIT,
0055 RPCBPROC_BCAST = 5,
0056 RPCBPROC_GETTIME,
0057 RPCBPROC_UADDR2TADDR,
0058 RPCBPROC_TADDR2UADDR,
0059 RPCBPROC_GETVERSADDR,
0060 RPCBPROC_INDIRECT,
0061 RPCBPROC_GETADDRLIST,
0062 RPCBPROC_GETSTAT,
0063 };
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078 #define RPCB_OWNER_STRING "0"
0079 #define RPCB_MAXOWNERLEN sizeof(RPCB_OWNER_STRING)
0080
0081
0082
0083
0084 #define RPCB_program_sz (1)
0085 #define RPCB_version_sz (1)
0086 #define RPCB_protocol_sz (1)
0087 #define RPCB_port_sz (1)
0088 #define RPCB_boolean_sz (1)
0089
0090 #define RPCB_netid_sz (1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN))
0091 #define RPCB_addr_sz (1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN))
0092 #define RPCB_ownerstring_sz (1 + XDR_QUADLEN(RPCB_MAXOWNERLEN))
0093
0094
0095
0096
0097 #define RPCB_mappingargs_sz (RPCB_program_sz + RPCB_version_sz + \
0098 RPCB_protocol_sz + RPCB_port_sz)
0099 #define RPCB_getaddrargs_sz (RPCB_program_sz + RPCB_version_sz + \
0100 RPCB_netid_sz + RPCB_addr_sz + \
0101 RPCB_ownerstring_sz)
0102
0103 #define RPCB_getportres_sz RPCB_port_sz
0104 #define RPCB_setres_sz RPCB_boolean_sz
0105
0106
0107
0108
0109
0110 #define RPCB_getaddrres_sz RPCB_addr_sz
0111
0112 static void rpcb_getport_done(struct rpc_task *, void *);
0113 static void rpcb_map_release(void *data);
0114 static const struct rpc_program rpcb_program;
0115
0116 struct rpcbind_args {
0117 struct rpc_xprt * r_xprt;
0118
0119 u32 r_prog;
0120 u32 r_vers;
0121 u32 r_prot;
0122 unsigned short r_port;
0123 const char * r_netid;
0124 const char * r_addr;
0125 const char * r_owner;
0126
0127 int r_status;
0128 };
0129
0130 static const struct rpc_procinfo rpcb_procedures2[];
0131 static const struct rpc_procinfo rpcb_procedures3[];
0132 static const struct rpc_procinfo rpcb_procedures4[];
0133
0134 struct rpcb_info {
0135 u32 rpc_vers;
0136 const struct rpc_procinfo *rpc_proc;
0137 };
0138
0139 static const struct rpcb_info rpcb_next_version[];
0140 static const struct rpcb_info rpcb_next_version6[];
0141
0142 static const struct rpc_call_ops rpcb_getport_ops = {
0143 .rpc_call_done = rpcb_getport_done,
0144 .rpc_release = rpcb_map_release,
0145 };
0146
0147 static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status)
0148 {
0149 xprt_clear_binding(xprt);
0150 rpc_wake_up_status(&xprt->binding, status);
0151 }
0152
0153 static void rpcb_map_release(void *data)
0154 {
0155 struct rpcbind_args *map = data;
0156
0157 rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status);
0158 xprt_put(map->r_xprt);
0159 kfree(map->r_addr);
0160 kfree(map);
0161 }
0162
0163 static int rpcb_get_local(struct net *net)
0164 {
0165 int cnt;
0166 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
0167
0168 spin_lock(&sn->rpcb_clnt_lock);
0169 if (sn->rpcb_users)
0170 sn->rpcb_users++;
0171 cnt = sn->rpcb_users;
0172 spin_unlock(&sn->rpcb_clnt_lock);
0173
0174 return cnt;
0175 }
0176
0177 void rpcb_put_local(struct net *net)
0178 {
0179 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
0180 struct rpc_clnt *clnt = sn->rpcb_local_clnt;
0181 struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4;
0182 int shutdown = 0;
0183
0184 spin_lock(&sn->rpcb_clnt_lock);
0185 if (sn->rpcb_users) {
0186 if (--sn->rpcb_users == 0) {
0187 sn->rpcb_local_clnt = NULL;
0188 sn->rpcb_local_clnt4 = NULL;
0189 }
0190 shutdown = !sn->rpcb_users;
0191 }
0192 spin_unlock(&sn->rpcb_clnt_lock);
0193
0194 if (shutdown) {
0195
0196
0197
0198 if (clnt4)
0199 rpc_shutdown_client(clnt4);
0200 if (clnt)
0201 rpc_shutdown_client(clnt);
0202 }
0203 }
0204
0205 static void rpcb_set_local(struct net *net, struct rpc_clnt *clnt,
0206 struct rpc_clnt *clnt4,
0207 bool is_af_local)
0208 {
0209 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
0210
0211
0212 sn->rpcb_local_clnt = clnt;
0213 sn->rpcb_local_clnt4 = clnt4;
0214 sn->rpcb_is_af_local = is_af_local ? 1 : 0;
0215 smp_wmb();
0216 sn->rpcb_users = 1;
0217 }
0218
0219
0220
0221
0222
0223 static int rpcb_create_local_unix(struct net *net)
0224 {
0225 static const struct sockaddr_un rpcb_localaddr_rpcbind = {
0226 .sun_family = AF_LOCAL,
0227 .sun_path = RPCBIND_SOCK_PATHNAME,
0228 };
0229 struct rpc_create_args args = {
0230 .net = net,
0231 .protocol = XPRT_TRANSPORT_LOCAL,
0232 .address = (struct sockaddr *)&rpcb_localaddr_rpcbind,
0233 .addrsize = sizeof(rpcb_localaddr_rpcbind),
0234 .servername = "localhost",
0235 .program = &rpcb_program,
0236 .version = RPCBVERS_2,
0237 .authflavor = RPC_AUTH_NULL,
0238 .cred = current_cred(),
0239
0240
0241
0242
0243
0244
0245
0246 .flags = RPC_CLNT_CREATE_NO_IDLE_TIMEOUT,
0247 };
0248 struct rpc_clnt *clnt, *clnt4;
0249 int result = 0;
0250
0251
0252
0253
0254
0255
0256 clnt = rpc_create(&args);
0257 if (IS_ERR(clnt)) {
0258 result = PTR_ERR(clnt);
0259 goto out;
0260 }
0261
0262 clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4);
0263 if (IS_ERR(clnt4))
0264 clnt4 = NULL;
0265
0266 rpcb_set_local(net, clnt, clnt4, true);
0267
0268 out:
0269 return result;
0270 }
0271
0272
0273
0274
0275
0276 static int rpcb_create_local_net(struct net *net)
0277 {
0278 static const struct sockaddr_in rpcb_inaddr_loopback = {
0279 .sin_family = AF_INET,
0280 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
0281 .sin_port = htons(RPCBIND_PORT),
0282 };
0283 struct rpc_create_args args = {
0284 .net = net,
0285 .protocol = XPRT_TRANSPORT_TCP,
0286 .address = (struct sockaddr *)&rpcb_inaddr_loopback,
0287 .addrsize = sizeof(rpcb_inaddr_loopback),
0288 .servername = "localhost",
0289 .program = &rpcb_program,
0290 .version = RPCBVERS_2,
0291 .authflavor = RPC_AUTH_UNIX,
0292 .cred = current_cred(),
0293 .flags = RPC_CLNT_CREATE_NOPING,
0294 };
0295 struct rpc_clnt *clnt, *clnt4;
0296 int result = 0;
0297
0298 clnt = rpc_create(&args);
0299 if (IS_ERR(clnt)) {
0300 result = PTR_ERR(clnt);
0301 goto out;
0302 }
0303
0304
0305
0306
0307
0308
0309 clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4);
0310 if (IS_ERR(clnt4))
0311 clnt4 = NULL;
0312
0313 rpcb_set_local(net, clnt, clnt4, false);
0314
0315 out:
0316 return result;
0317 }
0318
0319
0320
0321
0322
0323 int rpcb_create_local(struct net *net)
0324 {
0325 static DEFINE_MUTEX(rpcb_create_local_mutex);
0326 int result = 0;
0327
0328 if (rpcb_get_local(net))
0329 return result;
0330
0331 mutex_lock(&rpcb_create_local_mutex);
0332 if (rpcb_get_local(net))
0333 goto out;
0334
0335 if (rpcb_create_local_unix(net) != 0)
0336 result = rpcb_create_local_net(net);
0337
0338 out:
0339 mutex_unlock(&rpcb_create_local_mutex);
0340 return result;
0341 }
0342
0343 static struct rpc_clnt *rpcb_create(struct net *net, const char *nodename,
0344 const char *hostname,
0345 struct sockaddr *srvaddr, size_t salen,
0346 int proto, u32 version,
0347 const struct cred *cred,
0348 const struct rpc_timeout *timeo)
0349 {
0350 struct rpc_create_args args = {
0351 .net = net,
0352 .protocol = proto,
0353 .address = srvaddr,
0354 .addrsize = salen,
0355 .timeout = timeo,
0356 .servername = hostname,
0357 .nodename = nodename,
0358 .program = &rpcb_program,
0359 .version = version,
0360 .authflavor = RPC_AUTH_UNIX,
0361 .cred = cred,
0362 .flags = (RPC_CLNT_CREATE_NOPING |
0363 RPC_CLNT_CREATE_NONPRIVPORT),
0364 };
0365
0366 switch (srvaddr->sa_family) {
0367 case AF_INET:
0368 ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT);
0369 break;
0370 case AF_INET6:
0371 ((struct sockaddr_in6 *)srvaddr)->sin6_port = htons(RPCBIND_PORT);
0372 break;
0373 default:
0374 return ERR_PTR(-EAFNOSUPPORT);
0375 }
0376
0377 return rpc_create(&args);
0378 }
0379
0380 static int rpcb_register_call(struct sunrpc_net *sn, struct rpc_clnt *clnt, struct rpc_message *msg, bool is_set)
0381 {
0382 int flags = RPC_TASK_NOCONNECT;
0383 int error, result = 0;
0384
0385 if (is_set || !sn->rpcb_is_af_local)
0386 flags = RPC_TASK_SOFTCONN;
0387 msg->rpc_resp = &result;
0388
0389 error = rpc_call_sync(clnt, msg, flags);
0390 if (error < 0)
0391 return error;
0392
0393 if (!result)
0394 return -EACCES;
0395 return 0;
0396 }
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431 int rpcb_register(struct net *net, u32 prog, u32 vers, int prot, unsigned short port)
0432 {
0433 struct rpcbind_args map = {
0434 .r_prog = prog,
0435 .r_vers = vers,
0436 .r_prot = prot,
0437 .r_port = port,
0438 };
0439 struct rpc_message msg = {
0440 .rpc_argp = &map,
0441 };
0442 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
0443 bool is_set = false;
0444
0445 trace_pmap_register(prog, vers, prot, port);
0446
0447 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET];
0448 if (port != 0) {
0449 msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
0450 is_set = true;
0451 }
0452
0453 return rpcb_register_call(sn, sn->rpcb_local_clnt, &msg, is_set);
0454 }
0455
0456
0457
0458
0459 static int rpcb_register_inet4(struct sunrpc_net *sn,
0460 const struct sockaddr *sap,
0461 struct rpc_message *msg)
0462 {
0463 const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
0464 struct rpcbind_args *map = msg->rpc_argp;
0465 unsigned short port = ntohs(sin->sin_port);
0466 bool is_set = false;
0467 int result;
0468
0469 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
0470
0471 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
0472 if (port != 0) {
0473 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
0474 is_set = true;
0475 }
0476
0477 result = rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, is_set);
0478 kfree(map->r_addr);
0479 return result;
0480 }
0481
0482
0483
0484
0485 static int rpcb_register_inet6(struct sunrpc_net *sn,
0486 const struct sockaddr *sap,
0487 struct rpc_message *msg)
0488 {
0489 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
0490 struct rpcbind_args *map = msg->rpc_argp;
0491 unsigned short port = ntohs(sin6->sin6_port);
0492 bool is_set = false;
0493 int result;
0494
0495 map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
0496
0497 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
0498 if (port != 0) {
0499 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
0500 is_set = true;
0501 }
0502
0503 result = rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, is_set);
0504 kfree(map->r_addr);
0505 return result;
0506 }
0507
0508 static int rpcb_unregister_all_protofamilies(struct sunrpc_net *sn,
0509 struct rpc_message *msg)
0510 {
0511 struct rpcbind_args *map = msg->rpc_argp;
0512
0513 trace_rpcb_unregister(map->r_prog, map->r_vers, map->r_netid);
0514
0515 map->r_addr = "";
0516 msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
0517
0518 return rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, false);
0519 }
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565 int rpcb_v4_register(struct net *net, const u32 program, const u32 version,
0566 const struct sockaddr *address, const char *netid)
0567 {
0568 struct rpcbind_args map = {
0569 .r_prog = program,
0570 .r_vers = version,
0571 .r_netid = netid,
0572 .r_owner = RPCB_OWNER_STRING,
0573 };
0574 struct rpc_message msg = {
0575 .rpc_argp = &map,
0576 };
0577 struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
0578
0579 if (sn->rpcb_local_clnt4 == NULL)
0580 return -EPROTONOSUPPORT;
0581
0582 if (address == NULL)
0583 return rpcb_unregister_all_protofamilies(sn, &msg);
0584
0585 trace_rpcb_register(map.r_prog, map.r_vers, map.r_addr, map.r_netid);
0586
0587 switch (address->sa_family) {
0588 case AF_INET:
0589 return rpcb_register_inet4(sn, address, &msg);
0590 case AF_INET6:
0591 return rpcb_register_inet6(sn, address, &msg);
0592 }
0593
0594 return -EAFNOSUPPORT;
0595 }
0596
0597 static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt,
0598 struct rpcbind_args *map, const struct rpc_procinfo *proc)
0599 {
0600 struct rpc_message msg = {
0601 .rpc_proc = proc,
0602 .rpc_argp = map,
0603 .rpc_resp = map,
0604 };
0605 struct rpc_task_setup task_setup_data = {
0606 .rpc_client = rpcb_clnt,
0607 .rpc_message = &msg,
0608 .callback_ops = &rpcb_getport_ops,
0609 .callback_data = map,
0610 .flags = RPC_TASK_ASYNC | RPC_TASK_SOFTCONN,
0611 };
0612
0613 return rpc_run_task(&task_setup_data);
0614 }
0615
0616
0617
0618
0619
0620
0621
0622
0623 static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt)
0624 {
0625 struct rpc_clnt *parent = clnt->cl_parent;
0626 struct rpc_xprt_switch *xps = rcu_access_pointer(clnt->cl_xpi.xpi_xpswitch);
0627
0628 while (parent != clnt) {
0629 if (rcu_access_pointer(parent->cl_xpi.xpi_xpswitch) != xps)
0630 break;
0631 if (clnt->cl_autobind)
0632 break;
0633 clnt = parent;
0634 parent = parent->cl_parent;
0635 }
0636 return clnt;
0637 }
0638
0639
0640
0641
0642
0643
0644
0645
0646 void rpcb_getport_async(struct rpc_task *task)
0647 {
0648 struct rpc_clnt *clnt;
0649 const struct rpc_procinfo *proc;
0650 u32 bind_version;
0651 struct rpc_xprt *xprt;
0652 struct rpc_clnt *rpcb_clnt;
0653 struct rpcbind_args *map;
0654 struct rpc_task *child;
0655 struct sockaddr_storage addr;
0656 struct sockaddr *sap = (struct sockaddr *)&addr;
0657 size_t salen;
0658 int status;
0659
0660 rcu_read_lock();
0661 clnt = rpcb_find_transport_owner(task->tk_client);
0662 rcu_read_unlock();
0663 xprt = xprt_get(task->tk_xprt);
0664
0665
0666
0667 rpc_sleep_on_timeout(&xprt->binding, task,
0668 NULL, jiffies + xprt->bind_timeout);
0669
0670 if (xprt_test_and_set_binding(xprt)) {
0671 xprt_put(xprt);
0672 return;
0673 }
0674
0675
0676 if (xprt_bound(xprt)) {
0677 status = 0;
0678 goto bailout_nofree;
0679 }
0680
0681
0682 salen = rpc_peeraddr(clnt, sap, sizeof(addr));
0683
0684
0685 switch (sap->sa_family) {
0686 case AF_INET:
0687 proc = rpcb_next_version[xprt->bind_index].rpc_proc;
0688 bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
0689 break;
0690 case AF_INET6:
0691 proc = rpcb_next_version6[xprt->bind_index].rpc_proc;
0692 bind_version = rpcb_next_version6[xprt->bind_index].rpc_vers;
0693 break;
0694 default:
0695 status = -EAFNOSUPPORT;
0696 goto bailout_nofree;
0697 }
0698 if (proc == NULL) {
0699 xprt->bind_index = 0;
0700 status = -EPFNOSUPPORT;
0701 goto bailout_nofree;
0702 }
0703
0704 trace_rpcb_getport(clnt, task, bind_version);
0705
0706 rpcb_clnt = rpcb_create(xprt->xprt_net,
0707 clnt->cl_nodename,
0708 xprt->servername, sap, salen,
0709 xprt->prot, bind_version,
0710 clnt->cl_cred,
0711 task->tk_client->cl_timeout);
0712 if (IS_ERR(rpcb_clnt)) {
0713 status = PTR_ERR(rpcb_clnt);
0714 goto bailout_nofree;
0715 }
0716
0717 map = kzalloc(sizeof(struct rpcbind_args), rpc_task_gfp_mask());
0718 if (!map) {
0719 status = -ENOMEM;
0720 goto bailout_release_client;
0721 }
0722 map->r_prog = clnt->cl_prog;
0723 map->r_vers = clnt->cl_vers;
0724 map->r_prot = xprt->prot;
0725 map->r_port = 0;
0726 map->r_xprt = xprt;
0727 map->r_status = -EIO;
0728
0729 switch (bind_version) {
0730 case RPCBVERS_4:
0731 case RPCBVERS_3:
0732 map->r_netid = xprt->address_strings[RPC_DISPLAY_NETID];
0733 map->r_addr = rpc_sockaddr2uaddr(sap, rpc_task_gfp_mask());
0734 if (!map->r_addr) {
0735 status = -ENOMEM;
0736 goto bailout_free_args;
0737 }
0738 map->r_owner = "";
0739 break;
0740 case RPCBVERS_2:
0741 map->r_addr = NULL;
0742 break;
0743 default:
0744 BUG();
0745 }
0746
0747 child = rpcb_call_async(rpcb_clnt, map, proc);
0748 rpc_release_client(rpcb_clnt);
0749
0750 xprt->stat.bind_count++;
0751 rpc_put_task(child);
0752 return;
0753
0754 bailout_free_args:
0755 kfree(map);
0756 bailout_release_client:
0757 rpc_release_client(rpcb_clnt);
0758 bailout_nofree:
0759 rpcb_wake_rpcbind_waiters(xprt, status);
0760 task->tk_status = status;
0761 xprt_put(xprt);
0762 }
0763 EXPORT_SYMBOL_GPL(rpcb_getport_async);
0764
0765
0766
0767
0768 static void rpcb_getport_done(struct rpc_task *child, void *data)
0769 {
0770 struct rpcbind_args *map = data;
0771 struct rpc_xprt *xprt = map->r_xprt;
0772
0773 map->r_status = child->tk_status;
0774
0775
0776 if (map->r_status == -EIO)
0777 map->r_status = -EPROTONOSUPPORT;
0778
0779
0780 if (map->r_status == -EPROTONOSUPPORT)
0781 xprt->bind_index++;
0782
0783 if (map->r_status < 0) {
0784
0785 map->r_port = 0;
0786
0787 } else if (map->r_port == 0) {
0788
0789 map->r_status = -EACCES;
0790 } else {
0791
0792 map->r_status = 0;
0793 }
0794
0795 trace_rpcb_setport(child, map->r_status, map->r_port);
0796 xprt->ops->set_port(xprt, map->r_port);
0797 if (map->r_port)
0798 xprt_set_bound(xprt);
0799 }
0800
0801
0802
0803
0804
0805 static void rpcb_enc_mapping(struct rpc_rqst *req, struct xdr_stream *xdr,
0806 const void *data)
0807 {
0808 const struct rpcbind_args *rpcb = data;
0809 __be32 *p;
0810
0811 p = xdr_reserve_space(xdr, RPCB_mappingargs_sz << 2);
0812 *p++ = cpu_to_be32(rpcb->r_prog);
0813 *p++ = cpu_to_be32(rpcb->r_vers);
0814 *p++ = cpu_to_be32(rpcb->r_prot);
0815 *p = cpu_to_be32(rpcb->r_port);
0816 }
0817
0818 static int rpcb_dec_getport(struct rpc_rqst *req, struct xdr_stream *xdr,
0819 void *data)
0820 {
0821 struct rpcbind_args *rpcb = data;
0822 unsigned long port;
0823 __be32 *p;
0824
0825 rpcb->r_port = 0;
0826
0827 p = xdr_inline_decode(xdr, 4);
0828 if (unlikely(p == NULL))
0829 return -EIO;
0830
0831 port = be32_to_cpup(p);
0832 if (unlikely(port > USHRT_MAX))
0833 return -EIO;
0834
0835 rpcb->r_port = port;
0836 return 0;
0837 }
0838
0839 static int rpcb_dec_set(struct rpc_rqst *req, struct xdr_stream *xdr,
0840 void *data)
0841 {
0842 unsigned int *boolp = data;
0843 __be32 *p;
0844
0845 p = xdr_inline_decode(xdr, 4);
0846 if (unlikely(p == NULL))
0847 return -EIO;
0848
0849 *boolp = 0;
0850 if (*p != xdr_zero)
0851 *boolp = 1;
0852 return 0;
0853 }
0854
0855 static void encode_rpcb_string(struct xdr_stream *xdr, const char *string,
0856 const u32 maxstrlen)
0857 {
0858 __be32 *p;
0859 u32 len;
0860
0861 len = strlen(string);
0862 WARN_ON_ONCE(len > maxstrlen);
0863 if (len > maxstrlen)
0864
0865 len = maxstrlen;
0866 p = xdr_reserve_space(xdr, 4 + len);
0867 xdr_encode_opaque(p, string, len);
0868 }
0869
0870 static void rpcb_enc_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr,
0871 const void *data)
0872 {
0873 const struct rpcbind_args *rpcb = data;
0874 __be32 *p;
0875
0876 p = xdr_reserve_space(xdr, (RPCB_program_sz + RPCB_version_sz) << 2);
0877 *p++ = cpu_to_be32(rpcb->r_prog);
0878 *p = cpu_to_be32(rpcb->r_vers);
0879
0880 encode_rpcb_string(xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN);
0881 encode_rpcb_string(xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN);
0882 encode_rpcb_string(xdr, rpcb->r_owner, RPCB_MAXOWNERLEN);
0883 }
0884
0885 static int rpcb_dec_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr,
0886 void *data)
0887 {
0888 struct rpcbind_args *rpcb = data;
0889 struct sockaddr_storage address;
0890 struct sockaddr *sap = (struct sockaddr *)&address;
0891 __be32 *p;
0892 u32 len;
0893
0894 rpcb->r_port = 0;
0895
0896 p = xdr_inline_decode(xdr, 4);
0897 if (unlikely(p == NULL))
0898 goto out_fail;
0899 len = be32_to_cpup(p);
0900
0901
0902
0903
0904
0905 if (len == 0)
0906 return 0;
0907
0908 if (unlikely(len > RPCBIND_MAXUADDRLEN))
0909 goto out_fail;
0910
0911 p = xdr_inline_decode(xdr, len);
0912 if (unlikely(p == NULL))
0913 goto out_fail;
0914
0915 if (rpc_uaddr2sockaddr(req->rq_xprt->xprt_net, (char *)p, len,
0916 sap, sizeof(address)) == 0)
0917 goto out_fail;
0918 rpcb->r_port = rpc_get_port(sap);
0919
0920 return 0;
0921
0922 out_fail:
0923 return -EIO;
0924 }
0925
0926
0927
0928
0929
0930
0931 static const struct rpc_procinfo rpcb_procedures2[] = {
0932 [RPCBPROC_SET] = {
0933 .p_proc = RPCBPROC_SET,
0934 .p_encode = rpcb_enc_mapping,
0935 .p_decode = rpcb_dec_set,
0936 .p_arglen = RPCB_mappingargs_sz,
0937 .p_replen = RPCB_setres_sz,
0938 .p_statidx = RPCBPROC_SET,
0939 .p_timer = 0,
0940 .p_name = "SET",
0941 },
0942 [RPCBPROC_UNSET] = {
0943 .p_proc = RPCBPROC_UNSET,
0944 .p_encode = rpcb_enc_mapping,
0945 .p_decode = rpcb_dec_set,
0946 .p_arglen = RPCB_mappingargs_sz,
0947 .p_replen = RPCB_setres_sz,
0948 .p_statidx = RPCBPROC_UNSET,
0949 .p_timer = 0,
0950 .p_name = "UNSET",
0951 },
0952 [RPCBPROC_GETPORT] = {
0953 .p_proc = RPCBPROC_GETPORT,
0954 .p_encode = rpcb_enc_mapping,
0955 .p_decode = rpcb_dec_getport,
0956 .p_arglen = RPCB_mappingargs_sz,
0957 .p_replen = RPCB_getportres_sz,
0958 .p_statidx = RPCBPROC_GETPORT,
0959 .p_timer = 0,
0960 .p_name = "GETPORT",
0961 },
0962 };
0963
0964 static const struct rpc_procinfo rpcb_procedures3[] = {
0965 [RPCBPROC_SET] = {
0966 .p_proc = RPCBPROC_SET,
0967 .p_encode = rpcb_enc_getaddr,
0968 .p_decode = rpcb_dec_set,
0969 .p_arglen = RPCB_getaddrargs_sz,
0970 .p_replen = RPCB_setres_sz,
0971 .p_statidx = RPCBPROC_SET,
0972 .p_timer = 0,
0973 .p_name = "SET",
0974 },
0975 [RPCBPROC_UNSET] = {
0976 .p_proc = RPCBPROC_UNSET,
0977 .p_encode = rpcb_enc_getaddr,
0978 .p_decode = rpcb_dec_set,
0979 .p_arglen = RPCB_getaddrargs_sz,
0980 .p_replen = RPCB_setres_sz,
0981 .p_statidx = RPCBPROC_UNSET,
0982 .p_timer = 0,
0983 .p_name = "UNSET",
0984 },
0985 [RPCBPROC_GETADDR] = {
0986 .p_proc = RPCBPROC_GETADDR,
0987 .p_encode = rpcb_enc_getaddr,
0988 .p_decode = rpcb_dec_getaddr,
0989 .p_arglen = RPCB_getaddrargs_sz,
0990 .p_replen = RPCB_getaddrres_sz,
0991 .p_statidx = RPCBPROC_GETADDR,
0992 .p_timer = 0,
0993 .p_name = "GETADDR",
0994 },
0995 };
0996
0997 static const struct rpc_procinfo rpcb_procedures4[] = {
0998 [RPCBPROC_SET] = {
0999 .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
1030 static 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
1040 static 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
1054 static unsigned int rpcb_version2_counts[ARRAY_SIZE(rpcb_procedures2)];
1055 static 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
1062 static unsigned int rpcb_version3_counts[ARRAY_SIZE(rpcb_procedures3)];
1063 static 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
1070 static unsigned int rpcb_version4_counts[ARRAY_SIZE(rpcb_procedures4)];
1071 static 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
1078 static const struct rpc_version *rpcb_version[] = {
1079 NULL,
1080 NULL,
1081 &rpcb_version2,
1082 &rpcb_version3,
1083 &rpcb_version4
1084 };
1085
1086 static struct rpc_stat rpcb_stats;
1087
1088 static 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 };