@@ -43,6 +43,7 @@ struct rpc_timeout {
enum rpc_display_format_t {
RPC_DISPLAY_ADDR = 0,
+ RPC_DISPLAY_SRC_ADDR,
RPC_DISPLAY_PORT,
RPC_DISPLAY_PROTO,
RPC_DISPLAY_HEX_ADDR,
@@ -175,9 +175,11 @@ xprt_info_show(struct seq_file *f, void *v)
{
struct rpc_xprt *xprt = f->private;
- seq_printf(f, "netid: %s\n", xprt->address_strings[RPC_DISPLAY_NETID]);
- seq_printf(f, "addr: %s\n", xprt->address_strings[RPC_DISPLAY_ADDR]);
- seq_printf(f, "port: %s\n", xprt->address_strings[RPC_DISPLAY_PORT]);
+ seq_printf(f, "netid: %s\n", xprt->address_strings[RPC_DISPLAY_NETID]);
+ seq_printf(f, "addr: %s\n", xprt->address_strings[RPC_DISPLAY_ADDR]);
+ seq_printf(f, "port: %s\n", xprt->address_strings[RPC_DISPLAY_PORT]);
+ seq_printf(f, "srcaddr: %s\n", xprt->address_strings[RPC_DISPLAY_SRC_ADDR]
+ ? xprt->address_strings[RPC_DISPLAY_SRC_ADDR] : "");
seq_printf(f, "state: 0x%lx\n", xprt->state);
return 0;
}
@@ -261,7 +261,7 @@ xprt_setup_rdma_bc(struct xprt_create *args)
memcpy(&xprt->addr, args->dstaddr, args->addrlen);
xprt->addrlen = args->addrlen;
- xprt_rdma_format_addresses(xprt, (struct sockaddr *)&xprt->addr);
+ xprt_rdma_format_addresses(xprt, (struct sockaddr *)&xprt->addr, NULL);
xprt->resvport = 0;
xprt->max_payload = xprt_rdma_max_inline_read;
@@ -181,7 +181,8 @@ xprt_rdma_format_addresses6(struct rpc_xprt *xprt, struct sockaddr *sap)
}
void
-xprt_rdma_format_addresses(struct rpc_xprt *xprt, struct sockaddr *sap)
+xprt_rdma_format_addresses(struct rpc_xprt *xprt, struct sockaddr *sap,
+ struct sockaddr *src_sap)
{
char buf[128];
@@ -200,6 +201,11 @@ xprt_rdma_format_addresses(struct rpc_xprt *xprt, struct sockaddr *sap)
(void)rpc_ntop(sap, buf, sizeof(buf));
xprt->address_strings[RPC_DISPLAY_ADDR] = kstrdup(buf, GFP_KERNEL);
+ if (src_sap) {
+ (void)rpc_ntop(src_sap, buf, sizeof(buf));
+ xprt->address_strings[RPC_DISPLAY_SRC_ADDR] = kstrdup(buf, GFP_KERNEL);
+ }
+
snprintf(buf, sizeof(buf), "%u", rpc_get_port(sap));
xprt->address_strings[RPC_DISPLAY_PORT] = kstrdup(buf, GFP_KERNEL);
@@ -352,7 +358,7 @@ xprt_setup_rdma(struct xprt_create *args)
if (rpc_get_port(sap))
xprt_set_bound(xprt);
- xprt_rdma_format_addresses(xprt, sap);
+ xprt_rdma_format_addresses(xprt, sap, args->srcaddr);
new_xprt = rpcx_to_rdmax(xprt);
@@ -573,7 +573,8 @@ static inline void rpcrdma_set_xdrlen(struct xdr_buf *xdr, size_t len)
*/
extern unsigned int xprt_rdma_max_inline_read;
extern unsigned int xprt_rdma_max_inline_write;
-void xprt_rdma_format_addresses(struct rpc_xprt *xprt, struct sockaddr *sap);
+void xprt_rdma_format_addresses(struct rpc_xprt *xprt, struct sockaddr *sap,
+ struct sockaddr *src_sap);
void xprt_rdma_free_addresses(struct rpc_xprt *xprt);
void xprt_rdma_close(struct rpc_xprt *xprt);
void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq);
@@ -229,6 +229,12 @@ static inline struct sockaddr *xs_addr(struct rpc_xprt *xprt)
return (struct sockaddr *) &xprt->addr;
}
+static inline struct sockaddr *xs_srcaddr(struct rpc_xprt *xprt)
+{
+ struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
+ return (struct sockaddr *) &transport->srcaddr;
+}
+
static inline struct sockaddr_un *xs_addr_un(struct rpc_xprt *xprt)
{
return (struct sockaddr_un *) &xprt->addr;
@@ -244,9 +250,11 @@ static inline struct sockaddr_in6 *xs_addr_in6(struct rpc_xprt *xprt)
return (struct sockaddr_in6 *) &xprt->addr;
}
-static void xs_format_common_peer_addresses(struct rpc_xprt *xprt)
+static void xs_format_common_addresses(struct rpc_xprt *xprt,
+ struct sockaddr *sap,
+ int display_addr,
+ int display_hex_addr)
{
- struct sockaddr *sap = xs_addr(xprt);
struct sockaddr_in6 *sin6;
struct sockaddr_in *sin;
struct sockaddr_un *sun;
@@ -256,19 +264,19 @@ static void xs_format_common_peer_addresses(struct rpc_xprt *xprt)
case AF_LOCAL:
sun = xs_addr_un(xprt);
strlcpy(buf, sun->sun_path, sizeof(buf));
- xprt->address_strings[RPC_DISPLAY_ADDR] =
+ xprt->address_strings[display_addr] =
kstrdup(buf, GFP_KERNEL);
break;
case AF_INET:
(void)rpc_ntop(sap, buf, sizeof(buf));
- xprt->address_strings[RPC_DISPLAY_ADDR] =
+ xprt->address_strings[display_addr] =
kstrdup(buf, GFP_KERNEL);
sin = xs_addr_in(xprt);
snprintf(buf, sizeof(buf), "%08x", ntohl(sin->sin_addr.s_addr));
break;
case AF_INET6:
(void)rpc_ntop(sap, buf, sizeof(buf));
- xprt->address_strings[RPC_DISPLAY_ADDR] =
+ xprt->address_strings[display_addr] =
kstrdup(buf, GFP_KERNEL);
sin6 = xs_addr_in6(xprt);
snprintf(buf, sizeof(buf), "%pi6", &sin6->sin6_addr);
@@ -277,7 +285,8 @@ static void xs_format_common_peer_addresses(struct rpc_xprt *xprt)
BUG();
}
- xprt->address_strings[RPC_DISPLAY_HEX_ADDR] = kstrdup(buf, GFP_KERNEL);
+ if (display_hex_addr != -1)
+ xprt->address_strings[display_hex_addr] = kstrdup(buf, GFP_KERNEL);
}
static void xs_format_common_peer_ports(struct rpc_xprt *xprt)
@@ -292,13 +301,17 @@ static void xs_format_common_peer_ports(struct rpc_xprt *xprt)
xprt->address_strings[RPC_DISPLAY_HEX_PORT] = kstrdup(buf, GFP_KERNEL);
}
-static void xs_format_peer_addresses(struct rpc_xprt *xprt,
- const char *protocol,
- const char *netid)
+static void xs_format_addresses(struct rpc_xprt *xprt,
+ const char *protocol,
+ const char *netid)
{
xprt->address_strings[RPC_DISPLAY_PROTO] = protocol;
xprt->address_strings[RPC_DISPLAY_NETID] = netid;
- xs_format_common_peer_addresses(xprt);
+ xs_format_common_addresses(xprt, xs_addr(xprt),
+ RPC_DISPLAY_ADDR, RPC_DISPLAY_HEX_ADDR);
+ if (xs_srcaddr(xprt)->sa_family != 0)
+ xs_format_common_addresses(xprt, xs_srcaddr(xprt),
+ RPC_DISPLAY_SRC_ADDR, -1);
xs_format_common_peer_ports(xprt);
}
@@ -2793,7 +2806,7 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args)
goto out_err;
}
xprt_set_bound(xprt);
- xs_format_peer_addresses(xprt, "local", RPCBIND_NETID_LOCAL);
+ xs_format_addresses(xprt, "local", RPCBIND_NETID_LOCAL);
ret = ERR_PTR(xs_local_setup_socket(transport));
if (ret)
goto out_err;
@@ -2860,13 +2873,13 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args)
if (((struct sockaddr_in *)addr)->sin_port != htons(0))
xprt_set_bound(xprt);
- xs_format_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP);
+ xs_format_addresses(xprt, "udp", RPCBIND_NETID_UDP);
break;
case AF_INET6:
if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0))
xprt_set_bound(xprt);
- xs_format_peer_addresses(xprt, "udp", RPCBIND_NETID_UDP6);
+ xs_format_addresses(xprt, "udp", RPCBIND_NETID_UDP6);
break;
default:
ret = ERR_PTR(-EAFNOSUPPORT);
@@ -2942,13 +2955,13 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args)
if (((struct sockaddr_in *)addr)->sin_port != htons(0))
xprt_set_bound(xprt);
- xs_format_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP);
+ xs_format_addresses(xprt, "tcp", RPCBIND_NETID_TCP);
break;
case AF_INET6:
if (((struct sockaddr_in6 *)addr)->sin6_port != htons(0))
xprt_set_bound(xprt);
- xs_format_peer_addresses(xprt, "tcp", RPCBIND_NETID_TCP6);
+ xs_format_addresses(xprt, "tcp", RPCBIND_NETID_TCP6);
break;
default:
ret = ERR_PTR(-EAFNOSUPPORT);
@@ -3006,11 +3019,11 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
switch (addr->sa_family) {
case AF_INET:
- xs_format_peer_addresses(xprt, "tcp",
- RPCBIND_NETID_TCP);
+ xs_format_addresses(xprt, "tcp",
+ RPCBIND_NETID_TCP);
break;
case AF_INET6:
- xs_format_peer_addresses(xprt, "tcp",
+ xs_format_addresses(xprt, "tcp",
RPCBIND_NETID_TCP6);
break;
default:
For easier inspection of transport state with regard to nconnect, with remoteports and localports of NFS, this helps us to know what is the source address used for each established transport. Signed-off-by: Dan Aloni <dan@kernelim.com> --- include/linux/sunrpc/xprt.h | 1 + net/sunrpc/debugfs.c | 8 ++-- net/sunrpc/xprtrdma/svc_rdma_backchannel.c | 2 +- net/sunrpc/xprtrdma/transport.c | 10 ++++- net/sunrpc/xprtrdma/xprt_rdma.h | 3 +- net/sunrpc/xprtsock.c | 49 ++++++++++++++-------- 6 files changed, 48 insertions(+), 25 deletions(-)