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>
This commit is contained in:
Родитель
a02d692611
Коммит
ba809130bc
|
@ -41,7 +41,6 @@ enum rpc_display_format_t {
|
|||
RPC_DISPLAY_ALL,
|
||||
RPC_DISPLAY_HEX_ADDR,
|
||||
RPC_DISPLAY_HEX_PORT,
|
||||
RPC_DISPLAY_UNIVERSAL_ADDR,
|
||||
RPC_DISPLAY_NETID,
|
||||
RPC_DISPLAY_MAX,
|
||||
};
|
||||
|
|
|
@ -153,6 +153,7 @@ static void rpcb_map_release(void *data)
|
|||
|
||||
rpcb_wake_rpcbind_waiters(map->r_xprt, map->r_status);
|
||||
xprt_put(map->r_xprt);
|
||||
kfree(map->r_addr);
|
||||
kfree(map);
|
||||
}
|
||||
|
||||
|
@ -299,12 +300,9 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
|
|||
const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
|
||||
struct rpcbind_args *map = msg->rpc_argp;
|
||||
unsigned short port = ntohs(sin->sin_port);
|
||||
char buf[32];
|
||||
int result;
|
||||
|
||||
/* Construct AF_INET universal address */
|
||||
snprintf(buf, sizeof(buf), "%pI4.%u.%u",
|
||||
&sin->sin_addr.s_addr, port >> 8, port & 0xff);
|
||||
map->r_addr = buf;
|
||||
map->r_addr = rpc_sockaddr2uaddr(sap);
|
||||
|
||||
dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
|
||||
"local rpcbind\n", (port ? "" : "un"),
|
||||
|
@ -315,7 +313,9 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
|
|||
if (port)
|
||||
msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
|
||||
|
||||
return rpcb_register_call(RPCBVERS_4, msg);
|
||||
result = rpcb_register_call(RPCBVERS_4, msg);
|
||||
kfree(map->r_addr);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -327,16 +327,9 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
|
|||
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
|
||||
struct rpcbind_args *map = msg->rpc_argp;
|
||||
unsigned short port = ntohs(sin6->sin6_port);
|
||||
char buf[64];
|
||||
int result;
|
||||
|
||||
/* Construct AF_INET6 universal address */
|
||||
if (ipv6_addr_any(&sin6->sin6_addr))
|
||||
snprintf(buf, sizeof(buf), "::.%u.%u",
|
||||
port >> 8, port & 0xff);
|
||||
else
|
||||
snprintf(buf, sizeof(buf), "%pI6.%u.%u",
|
||||
&sin6->sin6_addr, port >> 8, port & 0xff);
|
||||
map->r_addr = buf;
|
||||
map->r_addr = rpc_sockaddr2uaddr(sap);
|
||||
|
||||
dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
|
||||
"local rpcbind\n", (port ? "" : "un"),
|
||||
|
@ -347,7 +340,9 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
|
|||
if (port)
|
||||
msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
|
||||
|
||||
return rpcb_register_call(RPCBVERS_4, msg);
|
||||
result = rpcb_register_call(RPCBVERS_4, msg);
|
||||
kfree(map->r_addr);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
|
||||
|
@ -570,6 +565,7 @@ void rpcb_getport_async(struct rpc_task *task)
|
|||
goto bailout_nofree;
|
||||
}
|
||||
|
||||
/* Parent transport's destination address */
|
||||
salen = rpc_peeraddr(clnt, sap, sizeof(addr));
|
||||
|
||||
/* Don't ever use rpcbind v2 for AF_INET6 requests */
|
||||
|
@ -620,11 +616,22 @@ void rpcb_getport_async(struct rpc_task *task)
|
|||
map->r_prot = xprt->prot;
|
||||
map->r_port = 0;
|
||||
map->r_xprt = xprt_get(xprt);
|
||||
map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
|
||||
map->r_addr = rpc_peeraddr2str(rpcb_clnt, RPC_DISPLAY_UNIVERSAL_ADDR);
|
||||
map->r_owner = "";
|
||||
map->r_status = -EIO;
|
||||
|
||||
switch (bind_version) {
|
||||
case RPCBVERS_4:
|
||||
case RPCBVERS_3:
|
||||
map->r_netid = rpc_peeraddr2str(clnt, RPC_DISPLAY_NETID);
|
||||
map->r_addr = rpc_sockaddr2uaddr(sap);
|
||||
map->r_owner = "";
|
||||
break;
|
||||
case RPCBVERS_2:
|
||||
map->r_addr = NULL;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
}
|
||||
|
||||
child = rpcb_call_async(rpcb_clnt, map, proc);
|
||||
rpc_release_client(rpcb_clnt);
|
||||
if (IS_ERR(child)) {
|
||||
|
@ -722,6 +729,9 @@ static int rpcb_decode_set(struct rpc_rqst *req, __be32 *p,
|
|||
static int rpcb_encode_getaddr(struct rpc_rqst *req, __be32 *p,
|
||||
struct rpcbind_args *rpcb)
|
||||
{
|
||||
if (rpcb->r_addr == NULL)
|
||||
return -EIO;
|
||||
|
||||
dprintk("RPC: encoding rpcb request (%u, %u, %s)\n",
|
||||
rpcb->r_prog, rpcb->r_vers, rpcb->r_addr);
|
||||
*p++ = htonl(rpcb->r_prog);
|
||||
|
|
|
@ -202,14 +202,6 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt)
|
|||
snprintf(buf, 8, "%4hx", ntohs(addr->sin_port));
|
||||
xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf;
|
||||
|
||||
buf = kzalloc(30, GFP_KERNEL);
|
||||
if (buf)
|
||||
snprintf(buf, 30, "%pI4.%u.%u",
|
||||
&addr->sin_addr.s_addr,
|
||||
ntohs(addr->sin_port) >> 8,
|
||||
ntohs(addr->sin_port) & 0xff);
|
||||
xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf;
|
||||
|
||||
/* netid */
|
||||
xprt->address_strings[RPC_DISPLAY_NETID] = "rdma";
|
||||
}
|
||||
|
|
|
@ -341,15 +341,6 @@ static void xs_format_ipv4_peer_addresses(struct rpc_xprt *xprt,
|
|||
}
|
||||
xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf;
|
||||
|
||||
buf = kzalloc(30, GFP_KERNEL);
|
||||
if (buf) {
|
||||
snprintf(buf, 30, "%pI4.%u.%u",
|
||||
&addr->sin_addr.s_addr,
|
||||
ntohs(addr->sin_port) >> 8,
|
||||
ntohs(addr->sin_port) & 0xff);
|
||||
}
|
||||
xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf;
|
||||
|
||||
xprt->address_strings[RPC_DISPLAY_NETID] = netid;
|
||||
}
|
||||
|
||||
|
@ -397,15 +388,6 @@ static void xs_format_ipv6_peer_addresses(struct rpc_xprt *xprt,
|
|||
}
|
||||
xprt->address_strings[RPC_DISPLAY_HEX_PORT] = buf;
|
||||
|
||||
buf = kzalloc(50, GFP_KERNEL);
|
||||
if (buf) {
|
||||
snprintf(buf, 50, "%pI6.%u.%u",
|
||||
&addr->sin6_addr,
|
||||
ntohs(addr->sin6_port) >> 8,
|
||||
ntohs(addr->sin6_port) & 0xff);
|
||||
}
|
||||
xprt->address_strings[RPC_DISPLAY_UNIVERSAL_ADDR] = buf;
|
||||
|
||||
xprt->address_strings[RPC_DISPLAY_NETID] = netid;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче