1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * In-kernel rpcbind client supporting versions 2, 3, and 4 of the rpcbind
4*4882a593Smuzhiyun * protocol
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Based on RFC 1833: "Binding Protocols for ONC RPC Version 2" and
7*4882a593Smuzhiyun * RFC 3530: "Network File System (NFS) version 4 Protocol"
8*4882a593Smuzhiyun *
9*4882a593Smuzhiyun * Original: Gilles Quillard, Bull Open Source, 2005 <gilles.quillard@bull.net>
10*4882a593Smuzhiyun * Updated: Chuck Lever, Oracle Corporation, 2007 <chuck.lever@oracle.com>
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun * Descended from net/sunrpc/pmap_clnt.c,
13*4882a593Smuzhiyun * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
14*4882a593Smuzhiyun */
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #include <linux/module.h>
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #include <linux/types.h>
19*4882a593Smuzhiyun #include <linux/socket.h>
20*4882a593Smuzhiyun #include <linux/un.h>
21*4882a593Smuzhiyun #include <linux/in.h>
22*4882a593Smuzhiyun #include <linux/in6.h>
23*4882a593Smuzhiyun #include <linux/kernel.h>
24*4882a593Smuzhiyun #include <linux/errno.h>
25*4882a593Smuzhiyun #include <linux/mutex.h>
26*4882a593Smuzhiyun #include <linux/slab.h>
27*4882a593Smuzhiyun #include <net/ipv6.h>
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun #include <linux/sunrpc/clnt.h>
30*4882a593Smuzhiyun #include <linux/sunrpc/addr.h>
31*4882a593Smuzhiyun #include <linux/sunrpc/sched.h>
32*4882a593Smuzhiyun #include <linux/sunrpc/xprtsock.h>
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #include <trace/events/sunrpc.h>
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #include "netns.h"
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun #define RPCBIND_SOCK_PATHNAME "/var/run/rpcbind.sock"
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun #define RPCBIND_PROGRAM (100000u)
41*4882a593Smuzhiyun #define RPCBIND_PORT (111u)
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun #define RPCBVERS_2 (2u)
44*4882a593Smuzhiyun #define RPCBVERS_3 (3u)
45*4882a593Smuzhiyun #define RPCBVERS_4 (4u)
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun enum {
48*4882a593Smuzhiyun RPCBPROC_NULL,
49*4882a593Smuzhiyun RPCBPROC_SET,
50*4882a593Smuzhiyun RPCBPROC_UNSET,
51*4882a593Smuzhiyun RPCBPROC_GETPORT,
52*4882a593Smuzhiyun RPCBPROC_GETADDR = 3, /* alias for GETPORT */
53*4882a593Smuzhiyun RPCBPROC_DUMP,
54*4882a593Smuzhiyun RPCBPROC_CALLIT,
55*4882a593Smuzhiyun RPCBPROC_BCAST = 5, /* alias for CALLIT */
56*4882a593Smuzhiyun RPCBPROC_GETTIME,
57*4882a593Smuzhiyun RPCBPROC_UADDR2TADDR,
58*4882a593Smuzhiyun RPCBPROC_TADDR2UADDR,
59*4882a593Smuzhiyun RPCBPROC_GETVERSADDR,
60*4882a593Smuzhiyun RPCBPROC_INDIRECT,
61*4882a593Smuzhiyun RPCBPROC_GETADDRLIST,
62*4882a593Smuzhiyun RPCBPROC_GETSTAT,
63*4882a593Smuzhiyun };
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /*
66*4882a593Smuzhiyun * r_owner
67*4882a593Smuzhiyun *
68*4882a593Smuzhiyun * The "owner" is allowed to unset a service in the rpcbind database.
69*4882a593Smuzhiyun *
70*4882a593Smuzhiyun * For AF_LOCAL SET/UNSET requests, rpcbind treats this string as a
71*4882a593Smuzhiyun * UID which it maps to a local user name via a password lookup.
72*4882a593Smuzhiyun * In all other cases it is ignored.
73*4882a593Smuzhiyun *
74*4882a593Smuzhiyun * For SET/UNSET requests, user space provides a value, even for
75*4882a593Smuzhiyun * network requests, and GETADDR uses an empty string. We follow
76*4882a593Smuzhiyun * those precedents here.
77*4882a593Smuzhiyun */
78*4882a593Smuzhiyun #define RPCB_OWNER_STRING "0"
79*4882a593Smuzhiyun #define RPCB_MAXOWNERLEN sizeof(RPCB_OWNER_STRING)
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun /*
82*4882a593Smuzhiyun * XDR data type sizes
83*4882a593Smuzhiyun */
84*4882a593Smuzhiyun #define RPCB_program_sz (1)
85*4882a593Smuzhiyun #define RPCB_version_sz (1)
86*4882a593Smuzhiyun #define RPCB_protocol_sz (1)
87*4882a593Smuzhiyun #define RPCB_port_sz (1)
88*4882a593Smuzhiyun #define RPCB_boolean_sz (1)
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun #define RPCB_netid_sz (1 + XDR_QUADLEN(RPCBIND_MAXNETIDLEN))
91*4882a593Smuzhiyun #define RPCB_addr_sz (1 + XDR_QUADLEN(RPCBIND_MAXUADDRLEN))
92*4882a593Smuzhiyun #define RPCB_ownerstring_sz (1 + XDR_QUADLEN(RPCB_MAXOWNERLEN))
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun /*
95*4882a593Smuzhiyun * XDR argument and result sizes
96*4882a593Smuzhiyun */
97*4882a593Smuzhiyun #define RPCB_mappingargs_sz (RPCB_program_sz + RPCB_version_sz + \
98*4882a593Smuzhiyun RPCB_protocol_sz + RPCB_port_sz)
99*4882a593Smuzhiyun #define RPCB_getaddrargs_sz (RPCB_program_sz + RPCB_version_sz + \
100*4882a593Smuzhiyun RPCB_netid_sz + RPCB_addr_sz + \
101*4882a593Smuzhiyun RPCB_ownerstring_sz)
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun #define RPCB_getportres_sz RPCB_port_sz
104*4882a593Smuzhiyun #define RPCB_setres_sz RPCB_boolean_sz
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun /*
107*4882a593Smuzhiyun * Note that RFC 1833 does not put any size restrictions on the
108*4882a593Smuzhiyun * address string returned by the remote rpcbind database.
109*4882a593Smuzhiyun */
110*4882a593Smuzhiyun #define RPCB_getaddrres_sz RPCB_addr_sz
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun static void rpcb_getport_done(struct rpc_task *, void *);
113*4882a593Smuzhiyun static void rpcb_map_release(void *data);
114*4882a593Smuzhiyun static const struct rpc_program rpcb_program;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun struct rpcbind_args {
117*4882a593Smuzhiyun struct rpc_xprt * r_xprt;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun u32 r_prog;
120*4882a593Smuzhiyun u32 r_vers;
121*4882a593Smuzhiyun u32 r_prot;
122*4882a593Smuzhiyun unsigned short r_port;
123*4882a593Smuzhiyun const char * r_netid;
124*4882a593Smuzhiyun const char * r_addr;
125*4882a593Smuzhiyun const char * r_owner;
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun int r_status;
128*4882a593Smuzhiyun };
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun static const struct rpc_procinfo rpcb_procedures2[];
131*4882a593Smuzhiyun static const struct rpc_procinfo rpcb_procedures3[];
132*4882a593Smuzhiyun static const struct rpc_procinfo rpcb_procedures4[];
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun struct rpcb_info {
135*4882a593Smuzhiyun u32 rpc_vers;
136*4882a593Smuzhiyun const struct rpc_procinfo *rpc_proc;
137*4882a593Smuzhiyun };
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun static const struct rpcb_info rpcb_next_version[];
140*4882a593Smuzhiyun static const struct rpcb_info rpcb_next_version6[];
141*4882a593Smuzhiyun
142*4882a593Smuzhiyun static const struct rpc_call_ops rpcb_getport_ops = {
143*4882a593Smuzhiyun .rpc_call_done = rpcb_getport_done,
144*4882a593Smuzhiyun .rpc_release = rpcb_map_release,
145*4882a593Smuzhiyun };
146*4882a593Smuzhiyun
rpcb_wake_rpcbind_waiters(struct rpc_xprt * xprt,int status)147*4882a593Smuzhiyun static void rpcb_wake_rpcbind_waiters(struct rpc_xprt *xprt, int status)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun xprt_clear_binding(xprt);
150*4882a593Smuzhiyun rpc_wake_up_status(&xprt->binding, status);
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun
rpcb_map_release(void * data)153*4882a593Smuzhiyun static void rpcb_map_release(void *data)
154*4882a593Smuzhiyun {
155*4882a593Smuzhiyun struct rpcbind_args *map = data;
156*4882a593Smuzhiyun
157*4882a593Smuzhiyun rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status);
158*4882a593Smuzhiyun xprt_put(map->r_xprt);
159*4882a593Smuzhiyun kfree(map->r_addr);
160*4882a593Smuzhiyun kfree(map);
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun
rpcb_get_local(struct net * net)163*4882a593Smuzhiyun static int rpcb_get_local(struct net *net)
164*4882a593Smuzhiyun {
165*4882a593Smuzhiyun int cnt;
166*4882a593Smuzhiyun struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun spin_lock(&sn->rpcb_clnt_lock);
169*4882a593Smuzhiyun if (sn->rpcb_users)
170*4882a593Smuzhiyun sn->rpcb_users++;
171*4882a593Smuzhiyun cnt = sn->rpcb_users;
172*4882a593Smuzhiyun spin_unlock(&sn->rpcb_clnt_lock);
173*4882a593Smuzhiyun
174*4882a593Smuzhiyun return cnt;
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun
rpcb_put_local(struct net * net)177*4882a593Smuzhiyun void rpcb_put_local(struct net *net)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
180*4882a593Smuzhiyun struct rpc_clnt *clnt = sn->rpcb_local_clnt;
181*4882a593Smuzhiyun struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4;
182*4882a593Smuzhiyun int shutdown = 0;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun spin_lock(&sn->rpcb_clnt_lock);
185*4882a593Smuzhiyun if (sn->rpcb_users) {
186*4882a593Smuzhiyun if (--sn->rpcb_users == 0) {
187*4882a593Smuzhiyun sn->rpcb_local_clnt = NULL;
188*4882a593Smuzhiyun sn->rpcb_local_clnt4 = NULL;
189*4882a593Smuzhiyun }
190*4882a593Smuzhiyun shutdown = !sn->rpcb_users;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun spin_unlock(&sn->rpcb_clnt_lock);
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun if (shutdown) {
195*4882a593Smuzhiyun /*
196*4882a593Smuzhiyun * cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
197*4882a593Smuzhiyun */
198*4882a593Smuzhiyun if (clnt4)
199*4882a593Smuzhiyun rpc_shutdown_client(clnt4);
200*4882a593Smuzhiyun if (clnt)
201*4882a593Smuzhiyun rpc_shutdown_client(clnt);
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
rpcb_set_local(struct net * net,struct rpc_clnt * clnt,struct rpc_clnt * clnt4,bool is_af_local)205*4882a593Smuzhiyun static void rpcb_set_local(struct net *net, struct rpc_clnt *clnt,
206*4882a593Smuzhiyun struct rpc_clnt *clnt4,
207*4882a593Smuzhiyun bool is_af_local)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun /* Protected by rpcb_create_local_mutex */
212*4882a593Smuzhiyun sn->rpcb_local_clnt = clnt;
213*4882a593Smuzhiyun sn->rpcb_local_clnt4 = clnt4;
214*4882a593Smuzhiyun sn->rpcb_is_af_local = is_af_local ? 1 : 0;
215*4882a593Smuzhiyun smp_wmb();
216*4882a593Smuzhiyun sn->rpcb_users = 1;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun /*
220*4882a593Smuzhiyun * Returns zero on success, otherwise a negative errno value
221*4882a593Smuzhiyun * is returned.
222*4882a593Smuzhiyun */
rpcb_create_local_unix(struct net * net)223*4882a593Smuzhiyun static int rpcb_create_local_unix(struct net *net)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun static const struct sockaddr_un rpcb_localaddr_rpcbind = {
226*4882a593Smuzhiyun .sun_family = AF_LOCAL,
227*4882a593Smuzhiyun .sun_path = RPCBIND_SOCK_PATHNAME,
228*4882a593Smuzhiyun };
229*4882a593Smuzhiyun struct rpc_create_args args = {
230*4882a593Smuzhiyun .net = net,
231*4882a593Smuzhiyun .protocol = XPRT_TRANSPORT_LOCAL,
232*4882a593Smuzhiyun .address = (struct sockaddr *)&rpcb_localaddr_rpcbind,
233*4882a593Smuzhiyun .addrsize = sizeof(rpcb_localaddr_rpcbind),
234*4882a593Smuzhiyun .servername = "localhost",
235*4882a593Smuzhiyun .program = &rpcb_program,
236*4882a593Smuzhiyun .version = RPCBVERS_2,
237*4882a593Smuzhiyun .authflavor = RPC_AUTH_NULL,
238*4882a593Smuzhiyun .cred = current_cred(),
239*4882a593Smuzhiyun /*
240*4882a593Smuzhiyun * We turn off the idle timeout to prevent the kernel
241*4882a593Smuzhiyun * from automatically disconnecting the socket.
242*4882a593Smuzhiyun * Otherwise, we'd have to cache the mount namespace
243*4882a593Smuzhiyun * of the caller and somehow pass that to the socket
244*4882a593Smuzhiyun * reconnect code.
245*4882a593Smuzhiyun */
246*4882a593Smuzhiyun .flags = RPC_CLNT_CREATE_NO_IDLE_TIMEOUT,
247*4882a593Smuzhiyun };
248*4882a593Smuzhiyun struct rpc_clnt *clnt, *clnt4;
249*4882a593Smuzhiyun int result = 0;
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun /*
252*4882a593Smuzhiyun * Because we requested an RPC PING at transport creation time,
253*4882a593Smuzhiyun * this works only if the user space portmapper is rpcbind, and
254*4882a593Smuzhiyun * it's listening on AF_LOCAL on the named socket.
255*4882a593Smuzhiyun */
256*4882a593Smuzhiyun clnt = rpc_create(&args);
257*4882a593Smuzhiyun if (IS_ERR(clnt)) {
258*4882a593Smuzhiyun result = PTR_ERR(clnt);
259*4882a593Smuzhiyun goto out;
260*4882a593Smuzhiyun }
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4);
263*4882a593Smuzhiyun if (IS_ERR(clnt4))
264*4882a593Smuzhiyun clnt4 = NULL;
265*4882a593Smuzhiyun
266*4882a593Smuzhiyun rpcb_set_local(net, clnt, clnt4, true);
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun out:
269*4882a593Smuzhiyun return result;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun /*
273*4882a593Smuzhiyun * Returns zero on success, otherwise a negative errno value
274*4882a593Smuzhiyun * is returned.
275*4882a593Smuzhiyun */
rpcb_create_local_net(struct net * net)276*4882a593Smuzhiyun static int rpcb_create_local_net(struct net *net)
277*4882a593Smuzhiyun {
278*4882a593Smuzhiyun static const struct sockaddr_in rpcb_inaddr_loopback = {
279*4882a593Smuzhiyun .sin_family = AF_INET,
280*4882a593Smuzhiyun .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
281*4882a593Smuzhiyun .sin_port = htons(RPCBIND_PORT),
282*4882a593Smuzhiyun };
283*4882a593Smuzhiyun struct rpc_create_args args = {
284*4882a593Smuzhiyun .net = net,
285*4882a593Smuzhiyun .protocol = XPRT_TRANSPORT_TCP,
286*4882a593Smuzhiyun .address = (struct sockaddr *)&rpcb_inaddr_loopback,
287*4882a593Smuzhiyun .addrsize = sizeof(rpcb_inaddr_loopback),
288*4882a593Smuzhiyun .servername = "localhost",
289*4882a593Smuzhiyun .program = &rpcb_program,
290*4882a593Smuzhiyun .version = RPCBVERS_2,
291*4882a593Smuzhiyun .authflavor = RPC_AUTH_UNIX,
292*4882a593Smuzhiyun .cred = current_cred(),
293*4882a593Smuzhiyun .flags = RPC_CLNT_CREATE_NOPING,
294*4882a593Smuzhiyun };
295*4882a593Smuzhiyun struct rpc_clnt *clnt, *clnt4;
296*4882a593Smuzhiyun int result = 0;
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun clnt = rpc_create(&args);
299*4882a593Smuzhiyun if (IS_ERR(clnt)) {
300*4882a593Smuzhiyun result = PTR_ERR(clnt);
301*4882a593Smuzhiyun goto out;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun /*
305*4882a593Smuzhiyun * This results in an RPC ping. On systems running portmapper,
306*4882a593Smuzhiyun * the v4 ping will fail. Proceed anyway, but disallow rpcb
307*4882a593Smuzhiyun * v4 upcalls.
308*4882a593Smuzhiyun */
309*4882a593Smuzhiyun clnt4 = rpc_bind_new_program(clnt, &rpcb_program, RPCBVERS_4);
310*4882a593Smuzhiyun if (IS_ERR(clnt4))
311*4882a593Smuzhiyun clnt4 = NULL;
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun rpcb_set_local(net, clnt, clnt4, false);
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun out:
316*4882a593Smuzhiyun return result;
317*4882a593Smuzhiyun }
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun /*
320*4882a593Smuzhiyun * Returns zero on success, otherwise a negative errno value
321*4882a593Smuzhiyun * is returned.
322*4882a593Smuzhiyun */
rpcb_create_local(struct net * net)323*4882a593Smuzhiyun int rpcb_create_local(struct net *net)
324*4882a593Smuzhiyun {
325*4882a593Smuzhiyun static DEFINE_MUTEX(rpcb_create_local_mutex);
326*4882a593Smuzhiyun int result = 0;
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun if (rpcb_get_local(net))
329*4882a593Smuzhiyun return result;
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun mutex_lock(&rpcb_create_local_mutex);
332*4882a593Smuzhiyun if (rpcb_get_local(net))
333*4882a593Smuzhiyun goto out;
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun if (rpcb_create_local_unix(net) != 0)
336*4882a593Smuzhiyun result = rpcb_create_local_net(net);
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun out:
339*4882a593Smuzhiyun mutex_unlock(&rpcb_create_local_mutex);
340*4882a593Smuzhiyun return result;
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
rpcb_create(struct net * net,const char * nodename,const char * hostname,struct sockaddr * srvaddr,size_t salen,int proto,u32 version,const struct cred * cred)343*4882a593Smuzhiyun static struct rpc_clnt *rpcb_create(struct net *net, const char *nodename,
344*4882a593Smuzhiyun const char *hostname,
345*4882a593Smuzhiyun struct sockaddr *srvaddr, size_t salen,
346*4882a593Smuzhiyun int proto, u32 version,
347*4882a593Smuzhiyun const struct cred *cred)
348*4882a593Smuzhiyun {
349*4882a593Smuzhiyun struct rpc_create_args args = {
350*4882a593Smuzhiyun .net = net,
351*4882a593Smuzhiyun .protocol = proto,
352*4882a593Smuzhiyun .address = srvaddr,
353*4882a593Smuzhiyun .addrsize = salen,
354*4882a593Smuzhiyun .servername = hostname,
355*4882a593Smuzhiyun .nodename = nodename,
356*4882a593Smuzhiyun .program = &rpcb_program,
357*4882a593Smuzhiyun .version = version,
358*4882a593Smuzhiyun .authflavor = RPC_AUTH_UNIX,
359*4882a593Smuzhiyun .cred = cred,
360*4882a593Smuzhiyun .flags = (RPC_CLNT_CREATE_NOPING |
361*4882a593Smuzhiyun RPC_CLNT_CREATE_NONPRIVPORT),
362*4882a593Smuzhiyun };
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun switch (srvaddr->sa_family) {
365*4882a593Smuzhiyun case AF_INET:
366*4882a593Smuzhiyun ((struct sockaddr_in *)srvaddr)->sin_port = htons(RPCBIND_PORT);
367*4882a593Smuzhiyun break;
368*4882a593Smuzhiyun case AF_INET6:
369*4882a593Smuzhiyun ((struct sockaddr_in6 *)srvaddr)->sin6_port = htons(RPCBIND_PORT);
370*4882a593Smuzhiyun break;
371*4882a593Smuzhiyun default:
372*4882a593Smuzhiyun return ERR_PTR(-EAFNOSUPPORT);
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun return rpc_create(&args);
376*4882a593Smuzhiyun }
377*4882a593Smuzhiyun
rpcb_register_call(struct sunrpc_net * sn,struct rpc_clnt * clnt,struct rpc_message * msg,bool is_set)378*4882a593Smuzhiyun static int rpcb_register_call(struct sunrpc_net *sn, struct rpc_clnt *clnt, struct rpc_message *msg, bool is_set)
379*4882a593Smuzhiyun {
380*4882a593Smuzhiyun int flags = RPC_TASK_NOCONNECT;
381*4882a593Smuzhiyun int error, result = 0;
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun if (is_set || !sn->rpcb_is_af_local)
384*4882a593Smuzhiyun flags = RPC_TASK_SOFTCONN;
385*4882a593Smuzhiyun msg->rpc_resp = &result;
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun error = rpc_call_sync(clnt, msg, flags);
388*4882a593Smuzhiyun if (error < 0)
389*4882a593Smuzhiyun return error;
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun if (!result)
392*4882a593Smuzhiyun return -EACCES;
393*4882a593Smuzhiyun return 0;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun
396*4882a593Smuzhiyun /**
397*4882a593Smuzhiyun * rpcb_register - set or unset a port registration with the local rpcbind svc
398*4882a593Smuzhiyun * @net: target network namespace
399*4882a593Smuzhiyun * @prog: RPC program number to bind
400*4882a593Smuzhiyun * @vers: RPC version number to bind
401*4882a593Smuzhiyun * @prot: transport protocol to register
402*4882a593Smuzhiyun * @port: port value to register
403*4882a593Smuzhiyun *
404*4882a593Smuzhiyun * Returns zero if the registration request was dispatched successfully
405*4882a593Smuzhiyun * and the rpcbind daemon returned success. Otherwise, returns an errno
406*4882a593Smuzhiyun * value that reflects the nature of the error (request could not be
407*4882a593Smuzhiyun * dispatched, timed out, or rpcbind returned an error).
408*4882a593Smuzhiyun *
409*4882a593Smuzhiyun * RPC services invoke this function to advertise their contact
410*4882a593Smuzhiyun * information via the system's rpcbind daemon. RPC services
411*4882a593Smuzhiyun * invoke this function once for each [program, version, transport]
412*4882a593Smuzhiyun * tuple they wish to advertise.
413*4882a593Smuzhiyun *
414*4882a593Smuzhiyun * Callers may also unregister RPC services that are no longer
415*4882a593Smuzhiyun * available by setting the passed-in port to zero. This removes
416*4882a593Smuzhiyun * all registered transports for [program, version] from the local
417*4882a593Smuzhiyun * rpcbind database.
418*4882a593Smuzhiyun *
419*4882a593Smuzhiyun * This function uses rpcbind protocol version 2 to contact the
420*4882a593Smuzhiyun * local rpcbind daemon.
421*4882a593Smuzhiyun *
422*4882a593Smuzhiyun * Registration works over both AF_INET and AF_INET6, and services
423*4882a593Smuzhiyun * registered via this function are advertised as available for any
424*4882a593Smuzhiyun * address. If the local rpcbind daemon is listening on AF_INET6,
425*4882a593Smuzhiyun * services registered via this function will be advertised on
426*4882a593Smuzhiyun * IN6ADDR_ANY (ie available for all AF_INET and AF_INET6
427*4882a593Smuzhiyun * addresses).
428*4882a593Smuzhiyun */
rpcb_register(struct net * net,u32 prog,u32 vers,int prot,unsigned short port)429*4882a593Smuzhiyun int rpcb_register(struct net *net, u32 prog, u32 vers, int prot, unsigned short port)
430*4882a593Smuzhiyun {
431*4882a593Smuzhiyun struct rpcbind_args map = {
432*4882a593Smuzhiyun .r_prog = prog,
433*4882a593Smuzhiyun .r_vers = vers,
434*4882a593Smuzhiyun .r_prot = prot,
435*4882a593Smuzhiyun .r_port = port,
436*4882a593Smuzhiyun };
437*4882a593Smuzhiyun struct rpc_message msg = {
438*4882a593Smuzhiyun .rpc_argp = &map,
439*4882a593Smuzhiyun };
440*4882a593Smuzhiyun struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
441*4882a593Smuzhiyun bool is_set = false;
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun trace_pmap_register(prog, vers, prot, port);
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun msg.rpc_proc = &rpcb_procedures2[RPCBPROC_UNSET];
446*4882a593Smuzhiyun if (port != 0) {
447*4882a593Smuzhiyun msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
448*4882a593Smuzhiyun is_set = true;
449*4882a593Smuzhiyun }
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun return rpcb_register_call(sn, sn->rpcb_local_clnt, &msg, is_set);
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun /*
455*4882a593Smuzhiyun * Fill in AF_INET family-specific arguments to register
456*4882a593Smuzhiyun */
rpcb_register_inet4(struct sunrpc_net * sn,const struct sockaddr * sap,struct rpc_message * msg)457*4882a593Smuzhiyun static int rpcb_register_inet4(struct sunrpc_net *sn,
458*4882a593Smuzhiyun const struct sockaddr *sap,
459*4882a593Smuzhiyun struct rpc_message *msg)
460*4882a593Smuzhiyun {
461*4882a593Smuzhiyun const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
462*4882a593Smuzhiyun struct rpcbind_args *map = msg->rpc_argp;
463*4882a593Smuzhiyun unsigned short port = ntohs(sin->sin_port);
464*4882a593Smuzhiyun bool is_set = false;
465*4882a593Smuzhiyun int result;
466*4882a593Smuzhiyun
467*4882a593Smuzhiyun map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
470*4882a593Smuzhiyun if (port != 0) {
471*4882a593Smuzhiyun msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
472*4882a593Smuzhiyun is_set = true;
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun result = rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, is_set);
476*4882a593Smuzhiyun kfree(map->r_addr);
477*4882a593Smuzhiyun return result;
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun /*
481*4882a593Smuzhiyun * Fill in AF_INET6 family-specific arguments to register
482*4882a593Smuzhiyun */
rpcb_register_inet6(struct sunrpc_net * sn,const struct sockaddr * sap,struct rpc_message * msg)483*4882a593Smuzhiyun static int rpcb_register_inet6(struct sunrpc_net *sn,
484*4882a593Smuzhiyun const struct sockaddr *sap,
485*4882a593Smuzhiyun struct rpc_message *msg)
486*4882a593Smuzhiyun {
487*4882a593Smuzhiyun const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
488*4882a593Smuzhiyun struct rpcbind_args *map = msg->rpc_argp;
489*4882a593Smuzhiyun unsigned short port = ntohs(sin6->sin6_port);
490*4882a593Smuzhiyun bool is_set = false;
491*4882a593Smuzhiyun int result;
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
494*4882a593Smuzhiyun
495*4882a593Smuzhiyun msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
496*4882a593Smuzhiyun if (port != 0) {
497*4882a593Smuzhiyun msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
498*4882a593Smuzhiyun is_set = true;
499*4882a593Smuzhiyun }
500*4882a593Smuzhiyun
501*4882a593Smuzhiyun result = rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, is_set);
502*4882a593Smuzhiyun kfree(map->r_addr);
503*4882a593Smuzhiyun return result;
504*4882a593Smuzhiyun }
505*4882a593Smuzhiyun
rpcb_unregister_all_protofamilies(struct sunrpc_net * sn,struct rpc_message * msg)506*4882a593Smuzhiyun static int rpcb_unregister_all_protofamilies(struct sunrpc_net *sn,
507*4882a593Smuzhiyun struct rpc_message *msg)
508*4882a593Smuzhiyun {
509*4882a593Smuzhiyun struct rpcbind_args *map = msg->rpc_argp;
510*4882a593Smuzhiyun
511*4882a593Smuzhiyun trace_rpcb_unregister(map->r_prog, map->r_vers, map->r_netid);
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun map->r_addr = "";
514*4882a593Smuzhiyun msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
515*4882a593Smuzhiyun
516*4882a593Smuzhiyun return rpcb_register_call(sn, sn->rpcb_local_clnt4, msg, false);
517*4882a593Smuzhiyun }
518*4882a593Smuzhiyun
519*4882a593Smuzhiyun /**
520*4882a593Smuzhiyun * rpcb_v4_register - set or unset a port registration with the local rpcbind
521*4882a593Smuzhiyun * @net: target network namespace
522*4882a593Smuzhiyun * @program: RPC program number of service to (un)register
523*4882a593Smuzhiyun * @version: RPC version number of service to (un)register
524*4882a593Smuzhiyun * @address: address family, IP address, and port to (un)register
525*4882a593Smuzhiyun * @netid: netid of transport protocol to (un)register
526*4882a593Smuzhiyun *
527*4882a593Smuzhiyun * Returns zero if the registration request was dispatched successfully
528*4882a593Smuzhiyun * and the rpcbind daemon returned success. Otherwise, returns an errno
529*4882a593Smuzhiyun * value that reflects the nature of the error (request could not be
530*4882a593Smuzhiyun * dispatched, timed out, or rpcbind returned an error).
531*4882a593Smuzhiyun *
532*4882a593Smuzhiyun * RPC services invoke this function to advertise their contact
533*4882a593Smuzhiyun * information via the system's rpcbind daemon. RPC services
534*4882a593Smuzhiyun * invoke this function once for each [program, version, address,
535*4882a593Smuzhiyun * netid] tuple they wish to advertise.
536*4882a593Smuzhiyun *
537*4882a593Smuzhiyun * Callers may also unregister RPC services that are registered at a
538*4882a593Smuzhiyun * specific address by setting the port number in @address to zero.
539*4882a593Smuzhiyun * They may unregister all registered protocol families at once for
540*4882a593Smuzhiyun * a service by passing a NULL @address argument. If @netid is ""
541*4882a593Smuzhiyun * then all netids for [program, version, address] are unregistered.
542*4882a593Smuzhiyun *
543*4882a593Smuzhiyun * This function uses rpcbind protocol version 4 to contact the
544*4882a593Smuzhiyun * local rpcbind daemon. The local rpcbind daemon must support
545*4882a593Smuzhiyun * version 4 of the rpcbind protocol in order for these functions
546*4882a593Smuzhiyun * to register a service successfully.
547*4882a593Smuzhiyun *
548*4882a593Smuzhiyun * Supported netids include "udp" and "tcp" for UDP and TCP over
549*4882a593Smuzhiyun * IPv4, and "udp6" and "tcp6" for UDP and TCP over IPv6,
550*4882a593Smuzhiyun * respectively.
551*4882a593Smuzhiyun *
552*4882a593Smuzhiyun * The contents of @address determine the address family and the
553*4882a593Smuzhiyun * port to be registered. The usual practice is to pass INADDR_ANY
554*4882a593Smuzhiyun * as the raw address, but specifying a non-zero address is also
555*4882a593Smuzhiyun * supported by this API if the caller wishes to advertise an RPC
556*4882a593Smuzhiyun * service on a specific network interface.
557*4882a593Smuzhiyun *
558*4882a593Smuzhiyun * Note that passing in INADDR_ANY does not create the same service
559*4882a593Smuzhiyun * registration as IN6ADDR_ANY. The former advertises an RPC
560*4882a593Smuzhiyun * service on any IPv4 address, but not on IPv6. The latter
561*4882a593Smuzhiyun * advertises the service on all IPv4 and IPv6 addresses.
562*4882a593Smuzhiyun */
rpcb_v4_register(struct net * net,const u32 program,const u32 version,const struct sockaddr * address,const char * netid)563*4882a593Smuzhiyun int rpcb_v4_register(struct net *net, const u32 program, const u32 version,
564*4882a593Smuzhiyun const struct sockaddr *address, const char *netid)
565*4882a593Smuzhiyun {
566*4882a593Smuzhiyun struct rpcbind_args map = {
567*4882a593Smuzhiyun .r_prog = program,
568*4882a593Smuzhiyun .r_vers = version,
569*4882a593Smuzhiyun .r_netid = netid,
570*4882a593Smuzhiyun .r_owner = RPCB_OWNER_STRING,
571*4882a593Smuzhiyun };
572*4882a593Smuzhiyun struct rpc_message msg = {
573*4882a593Smuzhiyun .rpc_argp = &map,
574*4882a593Smuzhiyun };
575*4882a593Smuzhiyun struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun if (sn->rpcb_local_clnt4 == NULL)
578*4882a593Smuzhiyun return -EPROTONOSUPPORT;
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun if (address == NULL)
581*4882a593Smuzhiyun return rpcb_unregister_all_protofamilies(sn, &msg);
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun trace_rpcb_register(map.r_prog, map.r_vers, map.r_addr, map.r_netid);
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun switch (address->sa_family) {
586*4882a593Smuzhiyun case AF_INET:
587*4882a593Smuzhiyun return rpcb_register_inet4(sn, address, &msg);
588*4882a593Smuzhiyun case AF_INET6:
589*4882a593Smuzhiyun return rpcb_register_inet6(sn, address, &msg);
590*4882a593Smuzhiyun }
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun return -EAFNOSUPPORT;
593*4882a593Smuzhiyun }
594*4882a593Smuzhiyun
rpcb_call_async(struct rpc_clnt * rpcb_clnt,struct rpcbind_args * map,const struct rpc_procinfo * proc)595*4882a593Smuzhiyun static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt,
596*4882a593Smuzhiyun struct rpcbind_args *map, const struct rpc_procinfo *proc)
597*4882a593Smuzhiyun {
598*4882a593Smuzhiyun struct rpc_message msg = {
599*4882a593Smuzhiyun .rpc_proc = proc,
600*4882a593Smuzhiyun .rpc_argp = map,
601*4882a593Smuzhiyun .rpc_resp = map,
602*4882a593Smuzhiyun };
603*4882a593Smuzhiyun struct rpc_task_setup task_setup_data = {
604*4882a593Smuzhiyun .rpc_client = rpcb_clnt,
605*4882a593Smuzhiyun .rpc_message = &msg,
606*4882a593Smuzhiyun .callback_ops = &rpcb_getport_ops,
607*4882a593Smuzhiyun .callback_data = map,
608*4882a593Smuzhiyun .flags = RPC_TASK_ASYNC | RPC_TASK_SOFTCONN,
609*4882a593Smuzhiyun };
610*4882a593Smuzhiyun
611*4882a593Smuzhiyun return rpc_run_task(&task_setup_data);
612*4882a593Smuzhiyun }
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun /*
615*4882a593Smuzhiyun * In the case where rpc clients have been cloned, we want to make
616*4882a593Smuzhiyun * sure that we use the program number/version etc of the actual
617*4882a593Smuzhiyun * owner of the xprt. To do so, we walk back up the tree of parents
618*4882a593Smuzhiyun * to find whoever created the transport and/or whoever has the
619*4882a593Smuzhiyun * autobind flag set.
620*4882a593Smuzhiyun */
rpcb_find_transport_owner(struct rpc_clnt * clnt)621*4882a593Smuzhiyun static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt)
622*4882a593Smuzhiyun {
623*4882a593Smuzhiyun struct rpc_clnt *parent = clnt->cl_parent;
624*4882a593Smuzhiyun struct rpc_xprt_switch *xps = rcu_access_pointer(clnt->cl_xpi.xpi_xpswitch);
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun while (parent != clnt) {
627*4882a593Smuzhiyun if (rcu_access_pointer(parent->cl_xpi.xpi_xpswitch) != xps)
628*4882a593Smuzhiyun break;
629*4882a593Smuzhiyun if (clnt->cl_autobind)
630*4882a593Smuzhiyun break;
631*4882a593Smuzhiyun clnt = parent;
632*4882a593Smuzhiyun parent = parent->cl_parent;
633*4882a593Smuzhiyun }
634*4882a593Smuzhiyun return clnt;
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun /**
638*4882a593Smuzhiyun * rpcb_getport_async - obtain the port for a given RPC service on a given host
639*4882a593Smuzhiyun * @task: task that is waiting for portmapper request
640*4882a593Smuzhiyun *
641*4882a593Smuzhiyun * This one can be called for an ongoing RPC request, and can be used in
642*4882a593Smuzhiyun * an async (rpciod) context.
643*4882a593Smuzhiyun */
rpcb_getport_async(struct rpc_task * task)644*4882a593Smuzhiyun void rpcb_getport_async(struct rpc_task *task)
645*4882a593Smuzhiyun {
646*4882a593Smuzhiyun struct rpc_clnt *clnt;
647*4882a593Smuzhiyun const struct rpc_procinfo *proc;
648*4882a593Smuzhiyun u32 bind_version;
649*4882a593Smuzhiyun struct rpc_xprt *xprt;
650*4882a593Smuzhiyun struct rpc_clnt *rpcb_clnt;
651*4882a593Smuzhiyun struct rpcbind_args *map;
652*4882a593Smuzhiyun struct rpc_task *child;
653*4882a593Smuzhiyun struct sockaddr_storage addr;
654*4882a593Smuzhiyun struct sockaddr *sap = (struct sockaddr *)&addr;
655*4882a593Smuzhiyun size_t salen;
656*4882a593Smuzhiyun int status;
657*4882a593Smuzhiyun
658*4882a593Smuzhiyun rcu_read_lock();
659*4882a593Smuzhiyun clnt = rpcb_find_transport_owner(task->tk_client);
660*4882a593Smuzhiyun rcu_read_unlock();
661*4882a593Smuzhiyun xprt = xprt_get(task->tk_xprt);
662*4882a593Smuzhiyun
663*4882a593Smuzhiyun /* Put self on the wait queue to ensure we get notified if
664*4882a593Smuzhiyun * some other task is already attempting to bind the port */
665*4882a593Smuzhiyun rpc_sleep_on_timeout(&xprt->binding, task,
666*4882a593Smuzhiyun NULL, jiffies + xprt->bind_timeout);
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun if (xprt_test_and_set_binding(xprt)) {
669*4882a593Smuzhiyun xprt_put(xprt);
670*4882a593Smuzhiyun return;
671*4882a593Smuzhiyun }
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun /* Someone else may have bound if we slept */
674*4882a593Smuzhiyun if (xprt_bound(xprt)) {
675*4882a593Smuzhiyun status = 0;
676*4882a593Smuzhiyun goto bailout_nofree;
677*4882a593Smuzhiyun }
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun /* Parent transport's destination address */
680*4882a593Smuzhiyun salen = rpc_peeraddr(clnt, sap, sizeof(addr));
681*4882a593Smuzhiyun
682*4882a593Smuzhiyun /* Don't ever use rpcbind v2 for AF_INET6 requests */
683*4882a593Smuzhiyun switch (sap->sa_family) {
684*4882a593Smuzhiyun case AF_INET:
685*4882a593Smuzhiyun proc = rpcb_next_version[xprt->bind_index].rpc_proc;
686*4882a593Smuzhiyun bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
687*4882a593Smuzhiyun break;
688*4882a593Smuzhiyun case AF_INET6:
689*4882a593Smuzhiyun proc = rpcb_next_version6[xprt->bind_index].rpc_proc;
690*4882a593Smuzhiyun bind_version = rpcb_next_version6[xprt->bind_index].rpc_vers;
691*4882a593Smuzhiyun break;
692*4882a593Smuzhiyun default:
693*4882a593Smuzhiyun status = -EAFNOSUPPORT;
694*4882a593Smuzhiyun goto bailout_nofree;
695*4882a593Smuzhiyun }
696*4882a593Smuzhiyun if (proc == NULL) {
697*4882a593Smuzhiyun xprt->bind_index = 0;
698*4882a593Smuzhiyun status = -EPFNOSUPPORT;
699*4882a593Smuzhiyun goto bailout_nofree;
700*4882a593Smuzhiyun }
701*4882a593Smuzhiyun
702*4882a593Smuzhiyun trace_rpcb_getport(clnt, task, bind_version);
703*4882a593Smuzhiyun
704*4882a593Smuzhiyun rpcb_clnt = rpcb_create(xprt->xprt_net,
705*4882a593Smuzhiyun clnt->cl_nodename,
706*4882a593Smuzhiyun xprt->servername, sap, salen,
707*4882a593Smuzhiyun xprt->prot, bind_version,
708*4882a593Smuzhiyun clnt->cl_cred);
709*4882a593Smuzhiyun if (IS_ERR(rpcb_clnt)) {
710*4882a593Smuzhiyun status = PTR_ERR(rpcb_clnt);
711*4882a593Smuzhiyun goto bailout_nofree;
712*4882a593Smuzhiyun }
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun map = kzalloc(sizeof(struct rpcbind_args), GFP_NOFS);
715*4882a593Smuzhiyun if (!map) {
716*4882a593Smuzhiyun status = -ENOMEM;
717*4882a593Smuzhiyun goto bailout_release_client;
718*4882a593Smuzhiyun }
719*4882a593Smuzhiyun map->r_prog = clnt->cl_prog;
720*4882a593Smuzhiyun map->r_vers = clnt->cl_vers;
721*4882a593Smuzhiyun map->r_prot = xprt->prot;
722*4882a593Smuzhiyun map->r_port = 0;
723*4882a593Smuzhiyun map->r_xprt = xprt;
724*4882a593Smuzhiyun map->r_status = -EIO;
725*4882a593Smuzhiyun
726*4882a593Smuzhiyun switch (bind_version) {
727*4882a593Smuzhiyun case RPCBVERS_4:
728*4882a593Smuzhiyun case RPCBVERS_3:
729*4882a593Smuzhiyun map->r_netid = xprt->address_strings[RPC_DISPLAY_NETID];
730*4882a593Smuzhiyun map->r_addr = rpc_sockaddr2uaddr(sap, GFP_NOFS);
731*4882a593Smuzhiyun if (!map->r_addr) {
732*4882a593Smuzhiyun status = -ENOMEM;
733*4882a593Smuzhiyun goto bailout_free_args;
734*4882a593Smuzhiyun }
735*4882a593Smuzhiyun map->r_owner = "";
736*4882a593Smuzhiyun break;
737*4882a593Smuzhiyun case RPCBVERS_2:
738*4882a593Smuzhiyun map->r_addr = NULL;
739*4882a593Smuzhiyun break;
740*4882a593Smuzhiyun default:
741*4882a593Smuzhiyun BUG();
742*4882a593Smuzhiyun }
743*4882a593Smuzhiyun
744*4882a593Smuzhiyun child = rpcb_call_async(rpcb_clnt, map, proc);
745*4882a593Smuzhiyun rpc_release_client(rpcb_clnt);
746*4882a593Smuzhiyun
747*4882a593Smuzhiyun xprt->stat.bind_count++;
748*4882a593Smuzhiyun rpc_put_task(child);
749*4882a593Smuzhiyun return;
750*4882a593Smuzhiyun
751*4882a593Smuzhiyun bailout_free_args:
752*4882a593Smuzhiyun kfree(map);
753*4882a593Smuzhiyun bailout_release_client:
754*4882a593Smuzhiyun rpc_release_client(rpcb_clnt);
755*4882a593Smuzhiyun bailout_nofree:
756*4882a593Smuzhiyun rpcb_wake_rpcbind_waiters(xprt, status);
757*4882a593Smuzhiyun task->tk_status = status;
758*4882a593Smuzhiyun xprt_put(xprt);
759*4882a593Smuzhiyun }
760*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(rpcb_getport_async);
761*4882a593Smuzhiyun
762*4882a593Smuzhiyun /*
763*4882a593Smuzhiyun * Rpcbind child task calls this callback via tk_exit.
764*4882a593Smuzhiyun */
rpcb_getport_done(struct rpc_task * child,void * data)765*4882a593Smuzhiyun static void rpcb_getport_done(struct rpc_task *child, void *data)
766*4882a593Smuzhiyun {
767*4882a593Smuzhiyun struct rpcbind_args *map = data;
768*4882a593Smuzhiyun struct rpc_xprt *xprt = map->r_xprt;
769*4882a593Smuzhiyun
770*4882a593Smuzhiyun map->r_status = child->tk_status;
771*4882a593Smuzhiyun
772*4882a593Smuzhiyun /* Garbage reply: retry with a lesser rpcbind version */
773*4882a593Smuzhiyun if (map->r_status == -EIO)
774*4882a593Smuzhiyun map->r_status = -EPROTONOSUPPORT;
775*4882a593Smuzhiyun
776*4882a593Smuzhiyun /* rpcbind server doesn't support this rpcbind protocol version */
777*4882a593Smuzhiyun if (map->r_status == -EPROTONOSUPPORT)
778*4882a593Smuzhiyun xprt->bind_index++;
779*4882a593Smuzhiyun
780*4882a593Smuzhiyun if (map->r_status < 0) {
781*4882a593Smuzhiyun /* rpcbind server not available on remote host? */
782*4882a593Smuzhiyun map->r_port = 0;
783*4882a593Smuzhiyun
784*4882a593Smuzhiyun } else if (map->r_port == 0) {
785*4882a593Smuzhiyun /* Requested RPC service wasn't registered on remote host */
786*4882a593Smuzhiyun map->r_status = -EACCES;
787*4882a593Smuzhiyun } else {
788*4882a593Smuzhiyun /* Succeeded */
789*4882a593Smuzhiyun map->r_status = 0;
790*4882a593Smuzhiyun }
791*4882a593Smuzhiyun
792*4882a593Smuzhiyun trace_rpcb_setport(child, map->r_status, map->r_port);
793*4882a593Smuzhiyun xprt->ops->set_port(xprt, map->r_port);
794*4882a593Smuzhiyun if (map->r_port)
795*4882a593Smuzhiyun xprt_set_bound(xprt);
796*4882a593Smuzhiyun }
797*4882a593Smuzhiyun
798*4882a593Smuzhiyun /*
799*4882a593Smuzhiyun * XDR functions for rpcbind
800*4882a593Smuzhiyun */
801*4882a593Smuzhiyun
rpcb_enc_mapping(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)802*4882a593Smuzhiyun static void rpcb_enc_mapping(struct rpc_rqst *req, struct xdr_stream *xdr,
803*4882a593Smuzhiyun const void *data)
804*4882a593Smuzhiyun {
805*4882a593Smuzhiyun const struct rpcbind_args *rpcb = data;
806*4882a593Smuzhiyun __be32 *p;
807*4882a593Smuzhiyun
808*4882a593Smuzhiyun p = xdr_reserve_space(xdr, RPCB_mappingargs_sz << 2);
809*4882a593Smuzhiyun *p++ = cpu_to_be32(rpcb->r_prog);
810*4882a593Smuzhiyun *p++ = cpu_to_be32(rpcb->r_vers);
811*4882a593Smuzhiyun *p++ = cpu_to_be32(rpcb->r_prot);
812*4882a593Smuzhiyun *p = cpu_to_be32(rpcb->r_port);
813*4882a593Smuzhiyun }
814*4882a593Smuzhiyun
rpcb_dec_getport(struct rpc_rqst * req,struct xdr_stream * xdr,void * data)815*4882a593Smuzhiyun static int rpcb_dec_getport(struct rpc_rqst *req, struct xdr_stream *xdr,
816*4882a593Smuzhiyun void *data)
817*4882a593Smuzhiyun {
818*4882a593Smuzhiyun struct rpcbind_args *rpcb = data;
819*4882a593Smuzhiyun unsigned long port;
820*4882a593Smuzhiyun __be32 *p;
821*4882a593Smuzhiyun
822*4882a593Smuzhiyun rpcb->r_port = 0;
823*4882a593Smuzhiyun
824*4882a593Smuzhiyun p = xdr_inline_decode(xdr, 4);
825*4882a593Smuzhiyun if (unlikely(p == NULL))
826*4882a593Smuzhiyun return -EIO;
827*4882a593Smuzhiyun
828*4882a593Smuzhiyun port = be32_to_cpup(p);
829*4882a593Smuzhiyun if (unlikely(port > USHRT_MAX))
830*4882a593Smuzhiyun return -EIO;
831*4882a593Smuzhiyun
832*4882a593Smuzhiyun rpcb->r_port = port;
833*4882a593Smuzhiyun return 0;
834*4882a593Smuzhiyun }
835*4882a593Smuzhiyun
rpcb_dec_set(struct rpc_rqst * req,struct xdr_stream * xdr,void * data)836*4882a593Smuzhiyun static int rpcb_dec_set(struct rpc_rqst *req, struct xdr_stream *xdr,
837*4882a593Smuzhiyun void *data)
838*4882a593Smuzhiyun {
839*4882a593Smuzhiyun unsigned int *boolp = data;
840*4882a593Smuzhiyun __be32 *p;
841*4882a593Smuzhiyun
842*4882a593Smuzhiyun p = xdr_inline_decode(xdr, 4);
843*4882a593Smuzhiyun if (unlikely(p == NULL))
844*4882a593Smuzhiyun return -EIO;
845*4882a593Smuzhiyun
846*4882a593Smuzhiyun *boolp = 0;
847*4882a593Smuzhiyun if (*p != xdr_zero)
848*4882a593Smuzhiyun *boolp = 1;
849*4882a593Smuzhiyun return 0;
850*4882a593Smuzhiyun }
851*4882a593Smuzhiyun
encode_rpcb_string(struct xdr_stream * xdr,const char * string,const u32 maxstrlen)852*4882a593Smuzhiyun static void encode_rpcb_string(struct xdr_stream *xdr, const char *string,
853*4882a593Smuzhiyun const u32 maxstrlen)
854*4882a593Smuzhiyun {
855*4882a593Smuzhiyun __be32 *p;
856*4882a593Smuzhiyun u32 len;
857*4882a593Smuzhiyun
858*4882a593Smuzhiyun len = strlen(string);
859*4882a593Smuzhiyun WARN_ON_ONCE(len > maxstrlen);
860*4882a593Smuzhiyun if (len > maxstrlen)
861*4882a593Smuzhiyun /* truncate and hope for the best */
862*4882a593Smuzhiyun len = maxstrlen;
863*4882a593Smuzhiyun p = xdr_reserve_space(xdr, 4 + len);
864*4882a593Smuzhiyun xdr_encode_opaque(p, string, len);
865*4882a593Smuzhiyun }
866*4882a593Smuzhiyun
rpcb_enc_getaddr(struct rpc_rqst * req,struct xdr_stream * xdr,const void * data)867*4882a593Smuzhiyun static void rpcb_enc_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr,
868*4882a593Smuzhiyun const void *data)
869*4882a593Smuzhiyun {
870*4882a593Smuzhiyun const struct rpcbind_args *rpcb = data;
871*4882a593Smuzhiyun __be32 *p;
872*4882a593Smuzhiyun
873*4882a593Smuzhiyun p = xdr_reserve_space(xdr, (RPCB_program_sz + RPCB_version_sz) << 2);
874*4882a593Smuzhiyun *p++ = cpu_to_be32(rpcb->r_prog);
875*4882a593Smuzhiyun *p = cpu_to_be32(rpcb->r_vers);
876*4882a593Smuzhiyun
877*4882a593Smuzhiyun encode_rpcb_string(xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN);
878*4882a593Smuzhiyun encode_rpcb_string(xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN);
879*4882a593Smuzhiyun encode_rpcb_string(xdr, rpcb->r_owner, RPCB_MAXOWNERLEN);
880*4882a593Smuzhiyun }
881*4882a593Smuzhiyun
rpcb_dec_getaddr(struct rpc_rqst * req,struct xdr_stream * xdr,void * data)882*4882a593Smuzhiyun static int rpcb_dec_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr,
883*4882a593Smuzhiyun void *data)
884*4882a593Smuzhiyun {
885*4882a593Smuzhiyun struct rpcbind_args *rpcb = data;
886*4882a593Smuzhiyun struct sockaddr_storage address;
887*4882a593Smuzhiyun struct sockaddr *sap = (struct sockaddr *)&address;
888*4882a593Smuzhiyun __be32 *p;
889*4882a593Smuzhiyun u32 len;
890*4882a593Smuzhiyun
891*4882a593Smuzhiyun rpcb->r_port = 0;
892*4882a593Smuzhiyun
893*4882a593Smuzhiyun p = xdr_inline_decode(xdr, 4);
894*4882a593Smuzhiyun if (unlikely(p == NULL))
895*4882a593Smuzhiyun goto out_fail;
896*4882a593Smuzhiyun len = be32_to_cpup(p);
897*4882a593Smuzhiyun
898*4882a593Smuzhiyun /*
899*4882a593Smuzhiyun * If the returned universal address is a null string,
900*4882a593Smuzhiyun * the requested RPC service was not registered.
901*4882a593Smuzhiyun */
902*4882a593Smuzhiyun if (len == 0)
903*4882a593Smuzhiyun return 0;
904*4882a593Smuzhiyun
905*4882a593Smuzhiyun if (unlikely(len > RPCBIND_MAXUADDRLEN))
906*4882a593Smuzhiyun goto out_fail;
907*4882a593Smuzhiyun
908*4882a593Smuzhiyun p = xdr_inline_decode(xdr, len);
909*4882a593Smuzhiyun if (unlikely(p == NULL))
910*4882a593Smuzhiyun goto out_fail;
911*4882a593Smuzhiyun
912*4882a593Smuzhiyun if (rpc_uaddr2sockaddr(req->rq_xprt->xprt_net, (char *)p, len,
913*4882a593Smuzhiyun sap, sizeof(address)) == 0)
914*4882a593Smuzhiyun goto out_fail;
915*4882a593Smuzhiyun rpcb->r_port = rpc_get_port(sap);
916*4882a593Smuzhiyun
917*4882a593Smuzhiyun return 0;
918*4882a593Smuzhiyun
919*4882a593Smuzhiyun out_fail:
920*4882a593Smuzhiyun return -EIO;
921*4882a593Smuzhiyun }
922*4882a593Smuzhiyun
923*4882a593Smuzhiyun /*
924*4882a593Smuzhiyun * Not all rpcbind procedures described in RFC 1833 are implemented
925*4882a593Smuzhiyun * since the Linux kernel RPC code requires only these.
926*4882a593Smuzhiyun */
927*4882a593Smuzhiyun
928*4882a593Smuzhiyun static const struct rpc_procinfo rpcb_procedures2[] = {
929*4882a593Smuzhiyun [RPCBPROC_SET] = {
930*4882a593Smuzhiyun .p_proc = RPCBPROC_SET,
931*4882a593Smuzhiyun .p_encode = rpcb_enc_mapping,
932*4882a593Smuzhiyun .p_decode = rpcb_dec_set,
933*4882a593Smuzhiyun .p_arglen = RPCB_mappingargs_sz,
934*4882a593Smuzhiyun .p_replen = RPCB_setres_sz,
935*4882a593Smuzhiyun .p_statidx = RPCBPROC_SET,
936*4882a593Smuzhiyun .p_timer = 0,
937*4882a593Smuzhiyun .p_name = "SET",
938*4882a593Smuzhiyun },
939*4882a593Smuzhiyun [RPCBPROC_UNSET] = {
940*4882a593Smuzhiyun .p_proc = RPCBPROC_UNSET,
941*4882a593Smuzhiyun .p_encode = rpcb_enc_mapping,
942*4882a593Smuzhiyun .p_decode = rpcb_dec_set,
943*4882a593Smuzhiyun .p_arglen = RPCB_mappingargs_sz,
944*4882a593Smuzhiyun .p_replen = RPCB_setres_sz,
945*4882a593Smuzhiyun .p_statidx = RPCBPROC_UNSET,
946*4882a593Smuzhiyun .p_timer = 0,
947*4882a593Smuzhiyun .p_name = "UNSET",
948*4882a593Smuzhiyun },
949*4882a593Smuzhiyun [RPCBPROC_GETPORT] = {
950*4882a593Smuzhiyun .p_proc = RPCBPROC_GETPORT,
951*4882a593Smuzhiyun .p_encode = rpcb_enc_mapping,
952*4882a593Smuzhiyun .p_decode = rpcb_dec_getport,
953*4882a593Smuzhiyun .p_arglen = RPCB_mappingargs_sz,
954*4882a593Smuzhiyun .p_replen = RPCB_getportres_sz,
955*4882a593Smuzhiyun .p_statidx = RPCBPROC_GETPORT,
956*4882a593Smuzhiyun .p_timer = 0,
957*4882a593Smuzhiyun .p_name = "GETPORT",
958*4882a593Smuzhiyun },
959*4882a593Smuzhiyun };
960*4882a593Smuzhiyun
961*4882a593Smuzhiyun static const struct rpc_procinfo rpcb_procedures3[] = {
962*4882a593Smuzhiyun [RPCBPROC_SET] = {
963*4882a593Smuzhiyun .p_proc = RPCBPROC_SET,
964*4882a593Smuzhiyun .p_encode = rpcb_enc_getaddr,
965*4882a593Smuzhiyun .p_decode = rpcb_dec_set,
966*4882a593Smuzhiyun .p_arglen = RPCB_getaddrargs_sz,
967*4882a593Smuzhiyun .p_replen = RPCB_setres_sz,
968*4882a593Smuzhiyun .p_statidx = RPCBPROC_SET,
969*4882a593Smuzhiyun .p_timer = 0,
970*4882a593Smuzhiyun .p_name = "SET",
971*4882a593Smuzhiyun },
972*4882a593Smuzhiyun [RPCBPROC_UNSET] = {
973*4882a593Smuzhiyun .p_proc = RPCBPROC_UNSET,
974*4882a593Smuzhiyun .p_encode = rpcb_enc_getaddr,
975*4882a593Smuzhiyun .p_decode = rpcb_dec_set,
976*4882a593Smuzhiyun .p_arglen = RPCB_getaddrargs_sz,
977*4882a593Smuzhiyun .p_replen = RPCB_setres_sz,
978*4882a593Smuzhiyun .p_statidx = RPCBPROC_UNSET,
979*4882a593Smuzhiyun .p_timer = 0,
980*4882a593Smuzhiyun .p_name = "UNSET",
981*4882a593Smuzhiyun },
982*4882a593Smuzhiyun [RPCBPROC_GETADDR] = {
983*4882a593Smuzhiyun .p_proc = RPCBPROC_GETADDR,
984*4882a593Smuzhiyun .p_encode = rpcb_enc_getaddr,
985*4882a593Smuzhiyun .p_decode = rpcb_dec_getaddr,
986*4882a593Smuzhiyun .p_arglen = RPCB_getaddrargs_sz,
987*4882a593Smuzhiyun .p_replen = RPCB_getaddrres_sz,
988*4882a593Smuzhiyun .p_statidx = RPCBPROC_GETADDR,
989*4882a593Smuzhiyun .p_timer = 0,
990*4882a593Smuzhiyun .p_name = "GETADDR",
991*4882a593Smuzhiyun },
992*4882a593Smuzhiyun };
993*4882a593Smuzhiyun
994*4882a593Smuzhiyun static const struct rpc_procinfo rpcb_procedures4[] = {
995*4882a593Smuzhiyun [RPCBPROC_SET] = {
996*4882a593Smuzhiyun .p_proc = RPCBPROC_SET,
997*4882a593Smuzhiyun .p_encode = rpcb_enc_getaddr,
998*4882a593Smuzhiyun .p_decode = rpcb_dec_set,
999*4882a593Smuzhiyun .p_arglen = RPCB_getaddrargs_sz,
1000*4882a593Smuzhiyun .p_replen = RPCB_setres_sz,
1001*4882a593Smuzhiyun .p_statidx = RPCBPROC_SET,
1002*4882a593Smuzhiyun .p_timer = 0,
1003*4882a593Smuzhiyun .p_name = "SET",
1004*4882a593Smuzhiyun },
1005*4882a593Smuzhiyun [RPCBPROC_UNSET] = {
1006*4882a593Smuzhiyun .p_proc = RPCBPROC_UNSET,
1007*4882a593Smuzhiyun .p_encode = rpcb_enc_getaddr,
1008*4882a593Smuzhiyun .p_decode = rpcb_dec_set,
1009*4882a593Smuzhiyun .p_arglen = RPCB_getaddrargs_sz,
1010*4882a593Smuzhiyun .p_replen = RPCB_setres_sz,
1011*4882a593Smuzhiyun .p_statidx = RPCBPROC_UNSET,
1012*4882a593Smuzhiyun .p_timer = 0,
1013*4882a593Smuzhiyun .p_name = "UNSET",
1014*4882a593Smuzhiyun },
1015*4882a593Smuzhiyun [RPCBPROC_GETADDR] = {
1016*4882a593Smuzhiyun .p_proc = RPCBPROC_GETADDR,
1017*4882a593Smuzhiyun .p_encode = rpcb_enc_getaddr,
1018*4882a593Smuzhiyun .p_decode = rpcb_dec_getaddr,
1019*4882a593Smuzhiyun .p_arglen = RPCB_getaddrargs_sz,
1020*4882a593Smuzhiyun .p_replen = RPCB_getaddrres_sz,
1021*4882a593Smuzhiyun .p_statidx = RPCBPROC_GETADDR,
1022*4882a593Smuzhiyun .p_timer = 0,
1023*4882a593Smuzhiyun .p_name = "GETADDR",
1024*4882a593Smuzhiyun },
1025*4882a593Smuzhiyun };
1026*4882a593Smuzhiyun
1027*4882a593Smuzhiyun static const struct rpcb_info rpcb_next_version[] = {
1028*4882a593Smuzhiyun {
1029*4882a593Smuzhiyun .rpc_vers = RPCBVERS_2,
1030*4882a593Smuzhiyun .rpc_proc = &rpcb_procedures2[RPCBPROC_GETPORT],
1031*4882a593Smuzhiyun },
1032*4882a593Smuzhiyun {
1033*4882a593Smuzhiyun .rpc_proc = NULL,
1034*4882a593Smuzhiyun },
1035*4882a593Smuzhiyun };
1036*4882a593Smuzhiyun
1037*4882a593Smuzhiyun static const struct rpcb_info rpcb_next_version6[] = {
1038*4882a593Smuzhiyun {
1039*4882a593Smuzhiyun .rpc_vers = RPCBVERS_4,
1040*4882a593Smuzhiyun .rpc_proc = &rpcb_procedures4[RPCBPROC_GETADDR],
1041*4882a593Smuzhiyun },
1042*4882a593Smuzhiyun {
1043*4882a593Smuzhiyun .rpc_vers = RPCBVERS_3,
1044*4882a593Smuzhiyun .rpc_proc = &rpcb_procedures3[RPCBPROC_GETADDR],
1045*4882a593Smuzhiyun },
1046*4882a593Smuzhiyun {
1047*4882a593Smuzhiyun .rpc_proc = NULL,
1048*4882a593Smuzhiyun },
1049*4882a593Smuzhiyun };
1050*4882a593Smuzhiyun
1051*4882a593Smuzhiyun static unsigned int rpcb_version2_counts[ARRAY_SIZE(rpcb_procedures2)];
1052*4882a593Smuzhiyun static const struct rpc_version rpcb_version2 = {
1053*4882a593Smuzhiyun .number = RPCBVERS_2,
1054*4882a593Smuzhiyun .nrprocs = ARRAY_SIZE(rpcb_procedures2),
1055*4882a593Smuzhiyun .procs = rpcb_procedures2,
1056*4882a593Smuzhiyun .counts = rpcb_version2_counts,
1057*4882a593Smuzhiyun };
1058*4882a593Smuzhiyun
1059*4882a593Smuzhiyun static unsigned int rpcb_version3_counts[ARRAY_SIZE(rpcb_procedures3)];
1060*4882a593Smuzhiyun static const struct rpc_version rpcb_version3 = {
1061*4882a593Smuzhiyun .number = RPCBVERS_3,
1062*4882a593Smuzhiyun .nrprocs = ARRAY_SIZE(rpcb_procedures3),
1063*4882a593Smuzhiyun .procs = rpcb_procedures3,
1064*4882a593Smuzhiyun .counts = rpcb_version3_counts,
1065*4882a593Smuzhiyun };
1066*4882a593Smuzhiyun
1067*4882a593Smuzhiyun static unsigned int rpcb_version4_counts[ARRAY_SIZE(rpcb_procedures4)];
1068*4882a593Smuzhiyun static const struct rpc_version rpcb_version4 = {
1069*4882a593Smuzhiyun .number = RPCBVERS_4,
1070*4882a593Smuzhiyun .nrprocs = ARRAY_SIZE(rpcb_procedures4),
1071*4882a593Smuzhiyun .procs = rpcb_procedures4,
1072*4882a593Smuzhiyun .counts = rpcb_version4_counts,
1073*4882a593Smuzhiyun };
1074*4882a593Smuzhiyun
1075*4882a593Smuzhiyun static const struct rpc_version *rpcb_version[] = {
1076*4882a593Smuzhiyun NULL,
1077*4882a593Smuzhiyun NULL,
1078*4882a593Smuzhiyun &rpcb_version2,
1079*4882a593Smuzhiyun &rpcb_version3,
1080*4882a593Smuzhiyun &rpcb_version4
1081*4882a593Smuzhiyun };
1082*4882a593Smuzhiyun
1083*4882a593Smuzhiyun static struct rpc_stat rpcb_stats;
1084*4882a593Smuzhiyun
1085*4882a593Smuzhiyun static const struct rpc_program rpcb_program = {
1086*4882a593Smuzhiyun .name = "rpcbind",
1087*4882a593Smuzhiyun .number = RPCBIND_PROGRAM,
1088*4882a593Smuzhiyun .nrvers = ARRAY_SIZE(rpcb_version),
1089*4882a593Smuzhiyun .version = rpcb_version,
1090*4882a593Smuzhiyun .stats = &rpcb_stats,
1091*4882a593Smuzhiyun };
1092