aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2007-08-16 16:03:31 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2007-10-09 17:16:32 -0400
commit143b6c4008a7928de7e139c3a77a90e4cad8db2c (patch)
tree339ee78286645d5e3704772cdf542ff2bc6aedc2
parent756805e7a76bcd2aae07fe31786fe453375e60b1 (diff)
SUNRPC: Fix generation of universal addresses for
Fix some problems with rpcbind v3 and v4 queries from the in-kernel rpcbind client: 1. The r_addr argument must be a full universal address, not just an IP address, and 2. The universal address in r_addr is the address of the remote rpcbind server, not the RPC service being requested This addresses bugzilla.kernel.org report 8891 for 2.6.23-rc and greater. In addition, if the rpcbind client is unable to start the rpcbind request, make sure not to leak the xprt. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
-rw-r--r--net/sunrpc/rpcb_clnt.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 7db75e177e67..0bb6709018de 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -387,6 +387,15 @@ void rpcb_getport_async(struct rpc_task *task)
387 dprintk("RPC: %5u %s: trying rpcbind version %u\n", 387 dprintk("RPC: %5u %s: trying rpcbind version %u\n",
388 task->tk_pid, __FUNCTION__, bind_version); 388 task->tk_pid, __FUNCTION__, bind_version);
389 389
390 rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot,
391 bind_version, 0);
392 if (IS_ERR(rpcb_clnt)) {
393 status = PTR_ERR(rpcb_clnt);
394 dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
395 task->tk_pid, __FUNCTION__, PTR_ERR(rpcb_clnt));
396 goto bailout_nofree;
397 }
398
390 map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC); 399 map = kzalloc(sizeof(struct rpcbind_args), GFP_ATOMIC);
391 if (!map) { 400 if (!map) {
392 status = -ENOMEM; 401 status = -ENOMEM;
@@ -401,25 +410,18 @@ void rpcb_getport_async(struct rpc_task *task)
401 map->r_xprt = xprt_get(xprt); 410 map->r_xprt = xprt_get(xprt);
402 map->r_netid = (xprt->prot == IPPROTO_TCP) ? RPCB_NETID_TCP : 411 map->r_netid = (xprt->prot == IPPROTO_TCP) ? RPCB_NETID_TCP :
403 RPCB_NETID_UDP; 412 RPCB_NETID_UDP;
404 memcpy(&map->r_addr, rpc_peeraddr2str(clnt, RPC_DISPLAY_ADDR), 413 memcpy(&map->r_addr,
405 sizeof(map->r_addr)); 414 rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR),
415 sizeof(map->r_addr));
406 map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */ 416 map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */
407 417
408 rpcb_clnt = rpcb_create(clnt->cl_server, &addr, xprt->prot, bind_version, 0);
409 if (IS_ERR(rpcb_clnt)) {
410 status = PTR_ERR(rpcb_clnt);
411 dprintk("RPC: %5u %s: rpcb_create failed, error %ld\n",
412 task->tk_pid, __FUNCTION__, PTR_ERR(rpcb_clnt));
413 goto bailout;
414 }
415
416 child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map); 418 child = rpc_run_task(rpcb_clnt, RPC_TASK_ASYNC, &rpcb_getport_ops, map);
417 rpc_release_client(rpcb_clnt); 419 rpc_release_client(rpcb_clnt);
418 if (IS_ERR(child)) { 420 if (IS_ERR(child)) {
419 status = -EIO; 421 status = -EIO;
420 dprintk("RPC: %5u %s: rpc_run_task failed\n", 422 dprintk("RPC: %5u %s: rpc_run_task failed\n",
421 task->tk_pid, __FUNCTION__); 423 task->tk_pid, __FUNCTION__);
422 goto bailout_nofree; 424 goto bailout;
423 } 425 }
424 rpc_put_task(child); 426 rpc_put_task(child);
425 427