diff options
| author | Chuck Lever <chuck.lever@oracle.com> | 2009-08-09 15:09:35 -0400 |
|---|---|---|
| committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-08-09 15:09:35 -0400 |
| commit | ba809130bc260fce04141aca01ef9e068d32af2a (patch) | |
| tree | 8aa5fe3f46c679346120f2c28848bf4446133a4c | |
| parent | a02d692611348f11ee1bc37431a883c3ff2de23e (diff) | |
SUNRPC: Remove duplicate universal address generation
RPC universal address generation is currently done in several places:
rpcb_clnt.c, nfs4proc.c xprtsock.c, and xprtrdma.c. Remove the
redundant cases that convert a socket address to a universal
address. The nfs4proc.c case takes a pre-formatted presentation
address string, not a socket address, so we'll leave that one.
Because the new uaddr constructor uses the recently introduced
rpc_ntop(), it now supports proper "::" shorthanding for IPv6
addresses. This allows the kernel to register properly formed
universal addresses with the local rpcbind service, in _all_ cases.
The kernel can now also send properly formed universal addresses in
RPCB_GETADDR requests, and support link-local properly when
encoding and decoding IPv6 addresses.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
| -rw-r--r-- | include/linux/sunrpc/xprt.h | 1 | ||||
| -rw-r--r-- | net/sunrpc/rpcb_clnt.c | 48 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/transport.c | 8 | ||||
| -rw-r--r-- | net/sunrpc/xprtsock.c | 18 |
4 files changed, 29 insertions, 46 deletions
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 1175d58efc2e..65fad9534d93 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h | |||
| @@ -41,7 +41,6 @@ enum rpc_display_format_t { | |||
| 41 | RPC_DISPLAY_ALL, | 41 | RPC_DISPLAY_ALL, |
| 42 | RPC_DISPLAY_HEX_ADDR, | 42 | RPC_DISPLAY_HEX_ADDR, |
| 43 | RPC_DISPLAY_HEX_PORT, | 43 | RPC_DISPLAY_HEX_PORT, |
| 44 | RPC_DISPLAY_UNIVERSAL_ADDR, | ||
| 45 | RPC_DISPLAY_NETID, | 44 | RPC_DISPLAY_NETID, |
| 46 | RPC_DISPLAY_MAX, | 45 | RPC_DISPLAY_MAX, |
| 47 | }; | 46 | }; |
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index ad1d7315c498..1fb1c070c19d 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
| @@ -153,6 +153,7 @@ static void rpcb_map_release(void *data) | |||
| 153 | 153 | ||
| 154 | rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status); | 154 | rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status); |
| 155 | xprt_put(map->r_xprt); | 155 | xprt_put(map->r_xprt); |
| 156 | kfree(map->r_addr); | ||
| 156 | kfree(map); | 157 | kfree(map); |
| 157 | } | 158 | } |
| 158 | 159 | ||
| @@ -299,12 +300,9 @@ static int rpcb_register_inet4(const struct sockaddr *sap, | |||
| 299 | const struct sockaddr_in *sin = (const struct sockaddr_in *)sap; | 300 | const struct sockaddr_in *sin = (const struct sockaddr_in *)sap; |
| 300 | struct rpcbind_args *map = msg->rpc_argp; | 301 | struct rpcbind_args *map = msg->rpc_argp; |
| 301 | unsigned short port = ntohs(sin->sin_port); | 302 | unsigned short port = ntohs(sin->sin_port); |
| 302 | char buf[32]; | 303 | int result; |
| 303 | 304 | ||
| 304 | /* Construct AF_INET universal address */ | 305 | map->r_addr = rpc_sockaddr2uaddr(sap); |
| 305 | snprintf(buf, sizeof(buf), "%pI4.%u.%u", | ||
| 306 | &sin->sin_addr.s_addr, port >> 8, port & 0xff); | ||
| 307 | map->r_addr = buf; | ||
| 308 | 306 | ||
| 309 | dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with " | 307 | dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with " |
| 310 | "local rpcbind\n", (port ? "" : "un"), | 308 | "local rpcbind\n", (port ? "" : "un"), |
| @@ -315,7 +313,9 @@ static int rpcb_register_inet4(const struct sockaddr *sap, | |||
| 315 | if (port) | 313 | if (port) |
| 316 | msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; | 314 | msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; |
| 317 | 315 | ||
| 318 | return rpcb_register_call(RPCBVERS_4, msg); | 316 | result = rpcb_register_call(RPCBVERS_4, msg); |
| 317 | kfree(map->r_addr); | ||
| 318 | return result; | ||
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | /* | 321 | /* |
| @@ -327,16 +327,9 @@ static int rpcb_register_inet6(const struct sockaddr *sap, | |||
| 327 | const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap; | 327 | const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap; |
| 328 | struct rpcbind_args *map = msg->rpc_argp; | 328 | struct rpcbind_args *map = msg->rpc_argp; |
| 329 | unsigned short port = ntohs(sin6->sin6_port); | 329 | unsigned short port = ntohs(sin6->sin6_port); |
| 330 | char buf[64]; | 330 | int result; |
| 331 | 331 | ||
| 332 | /* Construct AF_INET6 universal address */ | 332 | map->r_addr = rpc_sockaddr2uaddr(sap); |
| 333 | if (ipv6_addr_any(&sin6->sin6_addr)) | ||
| 334 | snprintf(buf, sizeof(buf), "::.%u.%u", | ||
| 335 | port >> 8, port & 0xff); | ||
| 336 | else | ||
| 337 | snprintf(buf, sizeof(buf), "%pI6.%u.%u", | ||
| 338 | &sin6->sin6_addr, port >> 8, port & 0xff); | ||
| 339 | map->r_addr = buf; | ||
| 340 | 333 | ||
| 341 | dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with " | 334 | dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with " |
| 342 | "local rpcbind\n", (port ? "" : "un"), | 335 | "local rpcbind\n", (port ? "" : "un"), |
| @@ -347,7 +340,9 @@ static int rpcb_register_inet6(const struct sockaddr *sap, | |||
| 347 | if (port) | 340 | if (port) |
| 348 | msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; | 341 | msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET]; |
| 349 | 342 | ||
| 350 | return rpcb_register_call(RPCBVERS_4, msg); | 343 | result = rpcb_register_call(RPCBVERS_4, msg); |
| 344 | kfree(map->r_addr); | ||
| 345 | return result; | ||
| 351 | } | 346 | } |
| 352 | 347 | ||
| 353 | static int rpcb_unregister_all_protofamilies(struct rpc_message *msg) | 348 | static int rpcb_unregister_all_protofamilies(struct rpc_message *msg) |
| @@ -570,6 +565,7 @@ void rpcb_getport_async(struct rpc_task *task) | |||
| 570 | goto bailout_nofree; | 565 | goto bailout_nofree; |
| 571 | } | 566 | } |
| 572 | 567 | ||
| 568 | /* Parent transport's destination address */ | ||
| 573 | salen = rpc_peeraddr(clnt, sap, sizeof(addr)); | 569 | salen = rpc_peeraddr(clnt, sap, sizeof(addr)); |
| 574 | 570 | ||
| 575 | /* Don't ever use rpcbind v2 for AF_INET6 requests */ | 571 | /* Don't ever use rpcbind v2 for AF_INET6 requests */ |
| @@ -620,11 +616,22 @@ void rpcb_getport_async(struct rpc_task *task) | |||
| 620 | map->r_prot = xprt->prot; | 616 | map->r_prot = xprt->prot; |
| 621 | map->r_port = 0; | 617 | map->r_port = 0; |
| 622 | map->r_xprt = xprt_get(xprt); | 618 | map->r_xprt = xprt_get(xprt); |
| 623 | map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID); | ||
| 624 | map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR); | ||
| 625 | map->r_owner = ""; | ||
| 626 | map->r_status = -EIO; | 619 | map->r_status = -EIO; |
| 627 | 620 | ||
| 621 | switch (bind_version) { | ||
| 622 | case RPCBVERS_4: | ||
| 623 | case RPCBVERS_3: | ||
| 624 | map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID); | ||
| 625 | map->r_addr = rpc_sockaddr2uaddr(sap); | ||
| 626 | map->r_owner = ""; | ||
| 627 | break; | ||
| 628 | case RPCBVERS_2: | ||
| 629 | map->r_addr = NULL; | ||
| 630 | break; | ||
| 631 | default: | ||
| 632 | BUG(); | ||
| 633 | } | ||
| 634 | |||
| 628 | child = rpcb_call_async(rpcb_clnt, map, proc); | 635 | child = rpcb_call_async(rpcb_clnt, map, proc); |
| 629 | rpc_release_client(rpcb_clnt); | 636 | rpc_release_client(rpcb_clnt); |
| 630 | if (IS_ERR(child)) { | 637 | if (IS_ERR(child)) { |
| @@ -722,6 +729,9 @@ static int rpcb_decode_set(struct rpc_rqst *req, __be32 *p, | |||
| 722 | static int rpcb_encode_getaddr(struct rpc_rqst *req, __be32 *p, | 729 | static int rpcb_encode_getaddr(struct rpc_rqst *req, __be32 *p, |
| 723 | struct rpcbind_args *rpcb) | 730 | struct rpcbind_args *rpcb) |
| 724 | { | 731 | { |
| 732 | if (rpcb->r_addr == NULL) | ||
| 733 | return -EIO; | ||
| 734 | |||
| 725 | dprintk("RPC: encoding rpcb request (%u, %u, %s)\n", | 735 | dprintk("RPC: encoding rpcb request (%u, %u, %s)\n", |
| 726 | rpcb->r_prog, rpcb->r_vers, rpcb->r_addr); | 736 | rpcb->r_prog, rpcb->r_vers, rpcb->r_addr); |
| 727 | *p++ = htonl(rpcb->r_prog); | 737 | *p++ = htonl(rpcb->r_prog); |
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 1dd6123070e9..537c210a8b92 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c | |||
| @@ -202,14 +202,6 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt) | |||
| 202 | snprintf(buf, 8, "%4hx", ntohs(addr->sin_port)); | 202 | snprintf(buf, 8, "%4hx", ntohs(addr->sin_port)); |
| 203 | xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf; | 203 | xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf; |
| 204 | 204 | ||
| 205 | buf = kzalloc(30, GFP_KERNEL); | ||
| 206 | if (buf) | ||
| 207 | snprintf(buf, 30, "%pI4.%u.%u", | ||
| 208 | &addr->sin_addr.s_addr, | ||
| 209 | ntohs(addr->sin_port) >> 8, | ||
| 210 | ntohs(addr->sin_port) & 0xff); | ||
| 211 | xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf; | ||
| 212 | |||
| 213 | /* netid */ | 205 | /* netid */ |
| 214 | xprt->address_strings[RPC_DISPLAY_NETID] = "rdma"; | 206 | xprt->address_strings[RPC_DISPLAY_NETID] = "rdma"; |
| 215 | } | 207 | } |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 83c73c4d017a..a42c2adda59f 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -341,15 +341,6 @@ static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt, | |||
| 341 | } | 341 | } |
| 342 | xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf; | 342 | xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf; |
| 343 | 343 | ||
| 344 | buf = kzalloc(30, GFP_KERNEL); | ||
| 345 | if (buf) { | ||
| 346 | snprintf(buf, 30, "%pI4.%u.%u", | ||
| 347 | &addr->sin_addr.s_addr, | ||
| 348 | ntohs(addr->sin_port) >> 8, | ||
| 349 | ntohs(addr->sin_port) & 0xff); | ||
| 350 | } | ||
| 351 | xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf; | ||
| 352 | |||
| 353 | xprt->address_strings[RPC_DISPLAY_NETID] = netid; | 344 | xprt->address_strings[RPC_DISPLAY_NETID] = netid; |
| 354 | } | 345 | } |
| 355 | 346 | ||
| @@ -397,15 +388,6 @@ static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt, | |||
| 397 | } | 388 | } |
| 398 | xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf; | 389 | xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf; |
| 399 | 390 | ||
| 400 | buf = kzalloc(50, GFP_KERNEL); | ||
| 401 | if (buf) { | ||
| 402 | snprintf(buf, 50, "%pI6.%u.%u", | ||
| 403 | &addr->sin6_addr, | ||
| 404 | ntohs(addr->sin6_port) >> 8, | ||
| 405 | ntohs(addr->sin6_port) & 0xff); | ||
| 406 | } | ||
| 407 | xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf; | ||
| 408 | |||
| 409 | xprt->address_strings[RPC_DISPLAY_NETID] = netid; | 391 | xprt->address_strings[RPC_DISPLAY_NETID] = netid; |
| 410 | } | 392 | } |
| 411 | 393 | ||
