Re: [PATCH 4/6] cifs: display the endpoint IP details in DebugData

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Shyam,

On 06/09, Shyam Prasad N wrote:
With multichannel, it is useful to know the src port details
for each channel. This change will print the ip addr and
port details for both the socket dest and src endpoints.

Signed-off-by: Shyam Prasad N <sprasad@xxxxxxxxxxxxx>
---
fs/smb/client/cifs_debug.c | 46 ++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)

diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c
index 17c884724590..d5fd3681f56e 100644
--- a/fs/smb/client/cifs_debug.c
+++ b/fs/smb/client/cifs_debug.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
+#include <net/inet_sock.h>
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsproto.h"
@@ -146,6 +147,30 @@ cifs_dump_channel(struct seq_file *m, int i, struct cifs_chan *chan)
		   in_flight(server),
		   atomic_read(&server->in_send),
		   atomic_read(&server->num_waiters));
+
+#ifndef CONFIG_CIFS_SMB_DIRECT
+	if (server->ssocket) {
+		if (server->dstaddr.ss_family == AF_INET6) {
+			struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&server->dstaddr;
+			struct sock *sk = server->ssocket->sk;
+			struct inet_sock *inet = inet_sk(server->ssocket->sk);
+			seq_printf(m, "\n\t\tIPv6 Dest: [%pI6]:%d Src: [%pI6]:%d",
+				   &ipv6->sin6_addr,
+				   ntohs(ipv6->sin6_port),
+				   &sk->sk_v6_rcv_saddr.s6_addr32,
+				   ntohs(inet->inet_sport));
+		} else {
+			struct sockaddr_in *ipv4 = (struct sockaddr_in *)&server->dstaddr;
+			struct inet_sock *inet = inet_sk(server->ssocket->sk);
+			seq_printf(m, "\n\t\tIPv4 Dest: %pI4:%d Src: %pI4:%d",
+				   &ipv4->sin_addr,
+				   ntohs(ipv4->sin_port),
+				   &inet->inet_saddr,
+				   ntohs(inet->inet_sport));
+		}
+	}
+#endif
+
}

static void
@@ -351,6 +376,27 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
			atomic_read(&server->smbd_conn->mr_ready_count),
			atomic_read(&server->smbd_conn->mr_used_count));
skip_rdma:
+#else
+		if (server->ssocket) {
+			if (server->dstaddr.ss_family == AF_INET6) {
+				struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&server->dstaddr;
+				struct sock *sk = server->ssocket->sk;
+				struct inet_sock *inet = inet_sk(server->ssocket->sk);
+				seq_printf(m, "\nIPv6 Dest: [%pI6]:%d Src: [%pI6]:%d",
+					   &ipv6->sin6_addr,
+					   ntohs(ipv6->sin6_port),
+					   &sk->sk_v6_rcv_saddr.s6_addr32,
+					   ntohs(inet->inet_sport));
+			} else {
+				struct sockaddr_in *ipv4 = (struct sockaddr_in *)&server->dstaddr;
+				struct inet_sock *inet = inet_sk(server->ssocket->sk);
+				seq_printf(m, "\nIPv4 Dest: %pI4:%d Src: %pI4:%d",
+					   &ipv4->sin_addr,
+					   ntohs(ipv4->sin_port),
+					   &inet->inet_saddr,
+					   ntohs(inet->inet_sport));
+			}
+		}
#endif
		seq_printf(m, "\nNumber of credits: %d,%d,%d Dialect 0x%x",
			server->credits,

You could save a lot of lines by using the generic formats for IP
addresses (Documentation/printk-formats.txt, look for "IPv4/IPv6
addresses (generic, with port, flowinfo, scope)").

e.g. using %pISpc will give you:
1.2.3.4:12345 for IPv4 or [1:2:3:4:5:6:7:8]:12345 for IPv6, just by
passing &server->dstaddr (without any casts), and you don't have to
check address family every time as well.

And to properly get the source IP being used by the socket there's
kernel_getpeername().

e.g.:
{
	...
	struct sockaddr src;
	int addrlen;

	addrlen = kernel_getpeername(server->ssocket, &src);
	if (addrlen != sizeof(struct sockaddr_in) && addrlen != sizeof(struct sockaddr_in6))
		continue; // skip or "return addrlen < 0 ? addrlen : -EAFNOSUPPORT;"
	...
	seq_print(m, "IP: src=%pISpc, dest=%pISpc", &server->dstaddr, &src);
	...
}


Cheers,

Enzo



[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux