aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2009-08-09 15:09:35 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2009-08-09 15:09:35 -0400
commitba809130bc260fce04141aca01ef9e068d32af2a (patch)
tree8aa5fe3f46c679346120f2c28848bf4446133a4c
parenta02d692611348f11ee1bc37431a883c3ff2de23e (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.h1
-rw-r--r--net/sunrpc/rpcb_clnt.c48
-rw-r--r--net/sunrpc/xprtrdma/transport.c8
-rw-r--r--net/sunrpc/xprtsock.c18
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
353static int rpcb_unregister_all_protofamilies(struct rpc_message *msg) 348static 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,
722static int rpcb_encode_getaddr(struct rpc_rqst *req, __be32 *p, 729static 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