All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2] ss: Include -E option for socket destroy events
@ 2015-06-16 16:02 Craig Gallek
  2015-06-16 16:50 ` Eric Dumazet
  0 siblings, 1 reply; 3+ messages in thread
From: Craig Gallek @ 2015-06-16 16:02 UTC (permalink / raw)
  To: netdev; +Cc: stephen, edumazet, Craig Gallek

Use the IPv4/IPv6/TCP/UDP multicast groups of NETLINK_SOCK_DIAG
to filter and display socket statistics as they are destroyed.

Kernel support patch series: 24029a3603cfa633e8bc2b3fb3e48e76c497831d

Signed-off-by: Craig Gallek <kraig@google.com>
---
 include/linux/inet_diag.h |  3 +-
 include/linux/sock_diag.h | 10 +++++++
 misc/ss.c                 | 72 ++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 83 insertions(+), 2 deletions(-)

diff --git a/include/linux/inet_diag.h b/include/linux/inet_diag.h
index 0fb76bb..e83340b 100644
--- a/include/linux/inet_diag.h
+++ b/include/linux/inet_diag.h
@@ -111,9 +111,10 @@ enum {
 	INET_DIAG_SKMEMINFO,
 	INET_DIAG_SHUTDOWN,
 	INET_DIAG_DCTCPINFO,
+	INET_DIAG_PROTOCOL,  /* response attribute only */
 };
 
-#define INET_DIAG_MAX INET_DIAG_DCTCPINFO
+#define INET_DIAG_MAX INET_DIAG_PROTOCOL
 
 /* INET_DIAG_MEM */
 
diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
index 78996e2..024e1f4 100644
--- a/include/linux/sock_diag.h
+++ b/include/linux/sock_diag.h
@@ -23,4 +23,14 @@ enum {
 	SK_MEMINFO_VARS,
 };
 
+enum sknetlink_groups {
+	SKNLGRP_NONE,
+	SKNLGRP_INET_TCP_DESTROY,
+	SKNLGRP_INET_UDP_DESTROY,
+	SKNLGRP_INET6_TCP_DESTROY,
+	SKNLGRP_INET6_UDP_DESTROY,
+	__SKNLGRP_MAX,
+};
+#define SKNLGRP_MAX	(__SKNLGRP_MAX - 1)
+
 #endif /* __SOCK_DIAG_H__ */
diff --git a/misc/ss.c b/misc/ss.c
index dba0901..9e59257 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -99,6 +99,7 @@ int show_proc_ctx = 0;
 int show_sock_ctx = 0;
 /* If show_users & show_proc_ctx only do user_ent_hash_build() once */
 int user_ent_hash_build_init = 0;
+int follow_events = 0;
 
 int netid_width;
 int state_width;
@@ -2030,6 +2031,9 @@ static int inet_show_sock(struct nlmsghdr *nlh, struct filter *f, int protocol)
 	if (f && f->f && run_ssfilter(f->f, &s) == 0)
 		return 0;
 
+	if (tb[INET_DIAG_PROTOCOL])
+		protocol = *(__u8 *)RTA_DATA(tb[INET_DIAG_PROTOCOL]);
+
 	inet_stats_print(&s, protocol);
 
 	if (show_options) {
@@ -3217,6 +3221,64 @@ static int netlink_show(struct filter *f)
 	return 0;
 }
 
+struct sock_diag_msg {
+	__u8 sdiag_family;
+};
+
+static int generic_show_sock(const struct sockaddr_nl *addr,
+		struct nlmsghdr *nlh, void *arg)
+{
+	struct sock_diag_msg *r = NLMSG_DATA(nlh);
+	struct inet_diag_arg inet_arg = { .f = arg, .protocol = IPPROTO_MAX };
+
+	switch (r->sdiag_family) {
+	case AF_INET:
+	case AF_INET6:
+		return show_one_inet_sock(addr, nlh, &inet_arg);
+	case AF_UNIX:
+		return unix_show_sock(addr, nlh, arg);
+	case AF_PACKET:
+		return packet_show_sock(addr, nlh, arg);
+	case AF_NETLINK:
+		return netlink_show_sock(addr, nlh, arg);
+	default:
+		return -1;
+	}
+}
+
+static int handle_follow_request(struct filter *f)
+{
+	int ret = -1;
+	int groups = 0;
+	struct rtnl_handle rth;
+
+	if (f->families & (1 << AF_INET) && f->dbs & (1 << TCP_DB))
+		groups |= 1 << (SKNLGRP_INET_TCP_DESTROY - 1);
+	if (f->families & (1 << AF_INET) && f->dbs & (1 << UDP_DB))
+		groups |= 1 << (SKNLGRP_INET_UDP_DESTROY - 1);
+	if (f->families & (1 << AF_INET6) && f->dbs & (1 << TCP_DB))
+		groups |= 1 << (SKNLGRP_INET6_TCP_DESTROY - 1);
+	if (f->families & (1 << AF_INET6) && f->dbs & (1 << UDP_DB))
+		groups |= 1 << (SKNLGRP_INET6_UDP_DESTROY - 1);
+
+	if (groups == 0)
+		return -1;
+
+	if (rtnl_open_byproto(&rth, groups, NETLINK_SOCK_DIAG))
+		return -1;
+
+	rth.dump = 0;
+	rth.local.nl_pid = 0;
+
+	if (rtnl_dump_filter(&rth, generic_show_sock, f))
+		goto Exit;
+
+	ret = 0;
+Exit:
+	rtnl_close(&rth);
+	return ret;
+}
+
 struct snmpstat
 {
 	int tcp_estab;
@@ -3399,6 +3461,7 @@ static void _usage(FILE *dest)
 "   -i, --info          show internal TCP information\n"
 "   -s, --summary       show socket usage summary\n"
 "   -b, --bpf           show bpf filter socket information\n"
+"   -E, --events        continually display sockets as they are destroyed\n"
 "   -Z, --context       display process SELinux security contexts\n"
 "   -z, --contexts      display process and socket SELinux security contexts\n"
 "   -N, --net           switch to the specified network namespace name\n"
@@ -3481,6 +3544,7 @@ static const struct option long_opts[] = {
 	{ "info", 0, 0, 'i' },
 	{ "processes", 0, 0, 'p' },
 	{ "bpf", 0, 0, 'b' },
+	{ "events", 0, 0, 'E' },
 	{ "dccp", 0, 0, 'd' },
 	{ "tcp", 0, 0, 't' },
 	{ "udp", 0, 0, 'u' },
@@ -3516,7 +3580,7 @@ int main(int argc, char *argv[])
 	int ch;
 	int state_filter = 0;
 
-	while ((ch = getopt_long(argc, argv, "dhaletuwxnro460spbf:miA:D:F:vVzZN:",
+	while ((ch = getopt_long(argc, argv, "dhaletuwxnro460spbEf:miA:D:F:vVzZN:",
 				 long_opts, NULL)) != EOF) {
 		switch(ch) {
 		case 'n':
@@ -3546,6 +3610,9 @@ int main(int argc, char *argv[])
 			show_options = 1;
 			show_bpf++;
 			break;
+		case 'E':
+			follow_events = 1;
+			break;
 		case 'd':
 			filter_db_set(&current_filter, DCCP_DB);
 			break;
@@ -3838,6 +3905,9 @@ int main(int argc, char *argv[])
 
 	fflush(stdout);
 
+	if (follow_events)
+		exit(handle_follow_request(&current_filter));
+
 	if (current_filter.dbs & (1<<NETLINK_DB))
 		netlink_show(&current_filter);
 	if (current_filter.dbs & PACKET_DBM)
-- 
2.2.0.rc0.207.ga3a616c

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH iproute2] ss: Include -E option for socket destroy events
  2015-06-16 16:02 [PATCH iproute2] ss: Include -E option for socket destroy events Craig Gallek
@ 2015-06-16 16:50 ` Eric Dumazet
  2015-06-16 20:17   ` Craig Gallek
  0 siblings, 1 reply; 3+ messages in thread
From: Eric Dumazet @ 2015-06-16 16:50 UTC (permalink / raw)
  To: Craig Gallek; +Cc: netdev, stephen, edumazet

On Tue, 2015-06-16 at 12:02 -0400, Craig Gallek wrote:
> Use the IPv4/IPv6/TCP/UDP multicast groups of NETLINK_SOCK_DIAG
> to filter and display socket statistics as they are destroyed.
> 
> Kernel support patch series: 24029a3603cfa633e8bc2b3fb3e48e76c497831d
> 
> Signed-off-by: Craig Gallek <kraig@google.com>
> ---
>  include/linux/inet_diag.h |  3 +-
>  include/linux/sock_diag.h | 10 +++++++
>  misc/ss.c                 | 72 ++++++++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 83 insertions(+), 2 deletions(-)

I am not sure filter works, and apparently some fields are not properly
reported ? (source port for example looks wrong)

(Note : you probably need to filter in user space, but ss should already
have support for this)

lpaa23:~# ./ss -Eit dst 10.246.7.152
State       Recv-Q Send-Q Local Address:Port                 Peer Address:Port                
UNCONN      0      1         ::ffff:10.246.7.151:*                      ::ffff:10.126.178.16:14354                
	 wscale:7,7 rto:221 rtt:20.165/5.91 ato:40 mss:1448 cwnd:10 send 5.7Mbps lastsnd:21 lastrcv:15023 lastack:1 pacing_rate 11.5Mbps unacked:1 rcv_rtt:20 rcv_space:28960
UNCONN      0      1       127.0.0.1:*                     127.0.0.1:9551                 
	 rto:1000 mss:524 cwnd:10 lastsnd:67817 lastrcv:67817 lastack:67817 unacked:1
UNCONN      0      1       127.0.0.1:*                     127.0.0.1:9551                 
	 rto:1000 mss:524 cwnd:10 lastsnd:67818 lastrcv:67818 lastack:67818 unacked:1
UNCONN      0      1       127.0.0.1:*                     127.0.0.1:9551                 
	 rto:1000 mss:524 cwnd:10 lastsnd:68742 lastrcv:68742 lastack:68742 unacked:1
UNCONN      0      0      10.246.7.151:*                    10.246.7.152:50227                
	 wscale:7,7 rto:201 rtt:0.203/0.209 mss:1448 cwnd:254 ssthresh:251 send 14494.3Mbps lastsnd:1 lastrcv:71533 pacing_rate 28970.7Mbps retrans:0/5 rcv_space:29200
UNCONN      0      0      10.246.7.151:*                    10.246.7.152:12865                
	 wscale:7,7 rto:201 rtt:0.363/0.375 ato:40 mss:1448 cwnd:10 ssthresh:293 send 319.1Mbps lastsnd:1004 lastrcv:1 lastack:1 pacing_rate 636.7Mbps rcv_rtt:126.125 rcv_space:29200
UNCONN      0      1       127.0.0.1:*                     127.0.0.1:9551                 
	 rto:1000 mss:524 cwnd:10 lastsnd:73036 lastrcv:73036 lastack:73036 unacked:1
^C

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH iproute2] ss: Include -E option for socket destroy events
  2015-06-16 16:50 ` Eric Dumazet
@ 2015-06-16 20:17   ` Craig Gallek
  0 siblings, 0 replies; 3+ messages in thread
From: Craig Gallek @ 2015-06-16 20:17 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, Stephen Hemminger, Eric Dumazet

> I am not sure filter works, and apparently some fields are not properly
> reported ? (source port for example looks wrong)
>
> (Note : you probably need to filter in user space, but ss should already
> have support for this)
Ah, good catch on the filter.  It can be fixed by
- if ((err = inet_show_sock(h, NULL, diag_arg->protocol)) < 0)
+ if ((err = inet_show_sock(h, diag_arg->f, diag_arg->protocol)) < 0)
in show_one_inet_sock.  I believe this worked previously because the
filter determined the parameters of the netlink request, effectively
causing the filtering to happen in the kernel.  However, if the
ssfilter defined a parameter that could not be used select sockets via
the netlink request (either because it is a concept not available in
the request structure or because the multicast groups have no request
concept), this user space filtering parameter would be necessary.
Perhaps this was an optimization to not do userspace filtering when we
know we won't need it?  In that case, my updated version of this patch
should probably set the filter parameter of inet_diag_arg to NULL in
the case of a get request and to the actual userspace filter in the
case of monitoring the broadcast data.

The source port issue is a harder problem (related to the kernel
patches, not this one).  The point at which socket information is
broadcast happens after the unhash callback of the appropriate
protocol (called in sk_common_release).  This process sets the source
port of the socket to zero (via __inet_put_port for tcp and
udp_lib_unhash for udp).  If we want the source port to be returned, I
believe the only options are broadcasting earlier in the destruction
path (potentially missing any activity that may happen after that
point) or to store the source port in an additional location for later
use...

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2015-06-16 20:17 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-16 16:02 [PATCH iproute2] ss: Include -E option for socket destroy events Craig Gallek
2015-06-16 16:50 ` Eric Dumazet
2015-06-16 20:17   ` Craig Gallek

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.