Commit 803a9067 authored by Trond Myklebust's avatar Trond Myklebust

SUNRPC: Fix an rpcbind breakage for the case of IPv6 lookups

Now that rpcb_next_version has been split into an IPv4 version and an IPv6
version, we Oops when rpcb_call_async attempts to look up the IPv6-specific
RPC procedure in rpcb_next_version.

Fix the Oops simply by having rpcb_getport_async pass the correct RPC
procedure as an argument.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 0d3a34b4
...@@ -243,10 +243,10 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot) ...@@ -243,10 +243,10 @@ int rpcb_getport_sync(struct sockaddr_in *sin, u32 prog, u32 vers, int prot)
} }
EXPORT_SYMBOL_GPL(rpcb_getport_sync); EXPORT_SYMBOL_GPL(rpcb_getport_sync);
static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, int version) static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc)
{ {
struct rpc_message msg = { struct rpc_message msg = {
.rpc_proc = rpcb_next_version[version].rpc_proc, .rpc_proc = proc,
.rpc_argp = map, .rpc_argp = map,
.rpc_resp = &map->r_port, .rpc_resp = &map->r_port,
}; };
...@@ -271,6 +271,7 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi ...@@ -271,6 +271,7 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
void rpcb_getport_async(struct rpc_task *task) void rpcb_getport_async(struct rpc_task *task)
{ {
struct rpc_clnt *clnt = task->tk_client; struct rpc_clnt *clnt = task->tk_client;
struct rpc_procinfo *proc;
u32 bind_version; u32 bind_version;
struct rpc_xprt *xprt = task->tk_xprt; struct rpc_xprt *xprt = task->tk_xprt;
struct rpc_clnt *rpcb_clnt; struct rpc_clnt *rpcb_clnt;
...@@ -280,7 +281,6 @@ void rpcb_getport_async(struct rpc_task *task) ...@@ -280,7 +281,6 @@ void rpcb_getport_async(struct rpc_task *task)
struct sockaddr *sap = (struct sockaddr *)&addr; struct sockaddr *sap = (struct sockaddr *)&addr;
size_t salen; size_t salen;
int status; int status;
struct rpcb_info *info;
dprintk("RPC: %5u %s(%s, %u, %u, %d)\n", dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
task->tk_pid, __func__, task->tk_pid, __func__,
...@@ -313,10 +313,12 @@ void rpcb_getport_async(struct rpc_task *task) ...@@ -313,10 +313,12 @@ void rpcb_getport_async(struct rpc_task *task)
/* Don't ever use rpcbind v2 for AF_INET6 requests */ /* Don't ever use rpcbind v2 for AF_INET6 requests */
switch (sap->sa_family) { switch (sap->sa_family) {
case AF_INET: case AF_INET:
info = rpcb_next_version; proc = rpcb_next_version[xprt->bind_index].rpc_proc;
bind_version = rpcb_next_version[xprt->bind_index].rpc_vers;
break; break;
case AF_INET6: case AF_INET6:
info = rpcb_next_version6; proc = rpcb_next_version6[xprt->bind_index].rpc_proc;
bind_version = rpcb_next_version6[xprt->bind_index].rpc_vers;
break; break;
default: default:
status = -EAFNOSUPPORT; status = -EAFNOSUPPORT;
...@@ -324,14 +326,13 @@ void rpcb_getport_async(struct rpc_task *task) ...@@ -324,14 +326,13 @@ void rpcb_getport_async(struct rpc_task *task)
task->tk_pid, __func__); task->tk_pid, __func__);
goto bailout_nofree; goto bailout_nofree;
} }
if (info[xprt->bind_index].rpc_proc == NULL) { if (proc == NULL) {
xprt->bind_index = 0; xprt->bind_index = 0;
status = -EPFNOSUPPORT; status = -EPFNOSUPPORT;
dprintk("RPC: %5u %s: no more getport versions available\n", dprintk("RPC: %5u %s: no more getport versions available\n",
task->tk_pid, __func__); task->tk_pid, __func__);
goto bailout_nofree; goto bailout_nofree;
} }
bind_version = info[xprt->bind_index].rpc_vers;
dprintk("RPC: %5u %s: trying rpcbind version %u\n", dprintk("RPC: %5u %s: trying rpcbind version %u\n",
task->tk_pid, __func__, bind_version); task->tk_pid, __func__, bind_version);
...@@ -361,7 +362,7 @@ void rpcb_getport_async(struct rpc_task *task) ...@@ -361,7 +362,7 @@ void rpcb_getport_async(struct rpc_task *task)
map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR); map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR);
map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */ map->r_owner = RPCB_OWNER_STRING; /* ignored for GETADDR */
child = rpcb_call_async(rpcb_clnt, map, xprt->bind_index); child = rpcb_call_async(rpcb_clnt, map, proc);
rpc_release_client(rpcb_clnt); rpc_release_client(rpcb_clnt);
if (IS_ERR(child)) { if (IS_ERR(child)) {
status = -EIO; status = -EIO;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment