diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2007-12-10 14:56:24 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2008-01-30 02:05:49 -0500 |
commit | 510deb0d7035d4fd465627deb3a119ca854f9e00 (patch) | |
tree | ffc7af675601c88ef8843ddb5a64db8b8da7ee91 | |
parent | 40c553193df41920de659f0446e5d214c862e827 (diff) |
SUNRPC: rpc_create() default hostname should support AF_INET6 addresses
If the ULP doesn't pass a hostname string to rpc_create(), it manufactures
one based on the passed-in address. Be smart enough to handle an AF_INET6
address properly in this case.
Move the default servername logic before the xprt_create_transport() call
to simplify error handling in rpc_create().
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | net/sunrpc/clnt.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index e0a5e47a1d4b..3af35ab0e99d 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/smp_lock.h> | 30 | #include <linux/smp_lock.h> |
31 | #include <linux/utsname.h> | 31 | #include <linux/utsname.h> |
32 | #include <linux/workqueue.h> | 32 | #include <linux/workqueue.h> |
33 | #include <linux/in6.h> | ||
33 | 34 | ||
34 | #include <linux/sunrpc/clnt.h> | 35 | #include <linux/sunrpc/clnt.h> |
35 | #include <linux/sunrpc/rpc_pipe_fs.h> | 36 | #include <linux/sunrpc/rpc_pipe_fs.h> |
@@ -247,7 +248,7 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
247 | .addrlen = args->addrsize, | 248 | .addrlen = args->addrsize, |
248 | .timeout = args->timeout | 249 | .timeout = args->timeout |
249 | }; | 250 | }; |
250 | char servername[20]; | 251 | char servername[48]; |
251 | 252 | ||
252 | xprt = xprt_create_transport(&xprtargs); | 253 | xprt = xprt_create_transport(&xprtargs); |
253 | if (IS_ERR(xprt)) | 254 | if (IS_ERR(xprt)) |
@@ -258,13 +259,34 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args) | |||
258 | * up a string representation of the passed-in address. | 259 | * up a string representation of the passed-in address. |
259 | */ | 260 | */ |
260 | if (args->servername == NULL) { | 261 | if (args->servername == NULL) { |
261 | struct sockaddr_in *addr = | 262 | servername[0] = '\0'; |
262 | (struct sockaddr_in *) args->address; | 263 | switch (args->address->sa_family) { |
263 | snprintf(servername, sizeof(servername), NIPQUAD_FMT, | 264 | case AF_INET: { |
264 | NIPQUAD(addr->sin_addr.s_addr)); | 265 | struct sockaddr_in *sin = |
266 | (struct sockaddr_in *)args->address; | ||
267 | snprintf(servername, sizeof(servername), NIPQUAD_FMT, | ||
268 | NIPQUAD(sin->sin_addr.s_addr)); | ||
269 | break; | ||
270 | } | ||
271 | case AF_INET6: { | ||
272 | struct sockaddr_in6 *sin = | ||
273 | (struct sockaddr_in6 *)args->address; | ||
274 | snprintf(servername, sizeof(servername), NIP6_FMT, | ||
275 | NIP6(sin->sin6_addr)); | ||
276 | break; | ||
277 | } | ||
278 | default: | ||
279 | /* caller wants default server name, but | ||
280 | * address family isn't recognized. */ | ||
281 | return ERR_PTR(-EINVAL); | ||
282 | } | ||
265 | args->servername = servername; | 283 | args->servername = servername; |
266 | } | 284 | } |
267 | 285 | ||
286 | xprt = xprt_create_transport(&xprtargs); | ||
287 | if (IS_ERR(xprt)) | ||
288 | return (struct rpc_clnt *)xprt; | ||
289 | |||
268 | /* | 290 | /* |
269 | * By default, kernel RPC client connects from a reserved port. | 291 | * By default, kernel RPC client connects from a reserved port. |
270 | * CAP_NET_BIND_SERVICE will not be set for unprivileged requesters, | 292 | * CAP_NET_BIND_SERVICE will not be set for unprivileged requesters, |